1 // OpenSTA, Static Timing Analyzer
2 // Copyright (c) 2020, Parallax Software, Inc.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 
17 #pragma once
18 
19 #include <map>
20 #include <algorithm>
21 
22 namespace sta {
23 
24 // Add convenience functions around STL container.
25 template <class KEY, class VALUE, class CMP = std::less<KEY> >
26 class Map : public std::map<KEY, VALUE, CMP>
27 {
28 public:
Map()29   Map() :
30     std::map<KEY, VALUE, CMP>()
31   {
32   }
Map(const CMP & cmp)33   explicit Map(const CMP &cmp) :
34     std::map<KEY, VALUE, CMP>(cmp)
35   {
36   }
37 
38   // Find out if key is in the set.
39   bool
hasKey(const KEY key) const40   hasKey(const KEY key) const
41   {
42     return this->find(key) != this->end();
43   }
44 
45   // Find the value corresponding to key.
46   VALUE
findKey(const KEY key) const47   findKey(const KEY key) const
48   {
49     auto find_iter = this->find(key);
50     if (find_iter != this->end())
51       return find_iter->second;
52     else
53       return nullptr;
54   }
55   void
findKey(const KEY key,VALUE & value,bool & exists) const56   findKey(const KEY key,
57 	  // Return Values.
58 	  VALUE &value,
59 	  bool &exists) const
60   {
61     auto find_iter = this->find(key);
62     if (find_iter != this->end()) {
63       value = find_iter->second;
64       exists = true;
65     }
66     else
67       exists = false;
68   }
69   void
findKey(const KEY & key,KEY & map_key,VALUE & value,bool & exists) const70   findKey(const KEY &key,
71 	  // Return Values.
72 	  KEY &map_key,
73 	  VALUE &value,
74 	  bool &exists) const
75   {
76     auto find_iter = this->find(key);
77     if (find_iter != this->end()) {
78       map_key = find_iter->first;
79       value = find_iter->second;
80       exists = true;
81     }
82     else
83       exists = false;
84   }
85 
86   void
insert(const KEY & key,VALUE value)87   insert(const KEY &key,
88 	 VALUE value)
89   {
90     this->operator[](key) = value;
91   }
92 
93   void
deleteContents()94   deleteContents()
95   {
96     Iterator iter(this);
97     while (iter.hasNext())
98       delete iter.next();
99   }
100 
101   void
deleteArrayContents()102   deleteArrayContents()
103   {
104     Iterator iter(this);
105     while (iter.hasNext())
106       delete [] iter.next();
107   }
108 
109   void
deleteContentsClear()110   deleteContentsClear()
111   {
112     deleteContents();
113     std::map<KEY, VALUE, CMP>::clear();
114   }
115 
116   // Java style container itererator
117   //  Map::Iterator<string *, Value, stringLess> iter(map);
118   //  while (iter.hasNext()) {
119   //    Value *v = iter.next();
120   //  }
121   class Iterator
122   {
123   public:
Iterator()124     Iterator() : container_(nullptr) {}
Iterator(std::map<KEY,VALUE,CMP> * container)125     explicit Iterator(std::map<KEY, VALUE, CMP> *container) :
126       container_(container)
127     { if (container_ != nullptr) iter_ = container_->begin(); }
Iterator(std::map<KEY,VALUE,CMP> & container)128     explicit Iterator(std::map<KEY, VALUE, CMP> &container) :
129       container_(&container)
130     { if (container_ != nullptr) iter_ = container_->begin(); }
init(std::map<KEY,VALUE,CMP> * container)131     void init(std::map<KEY, VALUE, CMP> *container)
132     { container_ = container; if (container_ != nullptr) iter_=container_->begin();}
init(std::map<KEY,VALUE,CMP> & container)133     void init(std::map<KEY, VALUE, CMP> &container)
134     { container_ = &container; if (container_ != nullptr) iter_=container_->begin();}
hasNext()135     bool hasNext() { return container_ != nullptr && iter_ != container_->end(); }
next()136     VALUE next() { return iter_++->second; }
next(KEY & key,VALUE & value)137     void next(KEY &key,
138 	      VALUE &value)
139     { key = iter_->first; value = iter_->second; iter_++; }
container()140     std::map<KEY, VALUE, CMP> *container() { return container_; }
141 
142   private:
143     std::map<KEY, VALUE, CMP> *container_;
144     typename std::map<KEY, VALUE, CMP>::iterator iter_;
145   };
146 
147   class ConstIterator
148   {
149   public:
ConstIterator()150     ConstIterator() : container_(nullptr) {}
ConstIterator(const std::map<KEY,VALUE,CMP> * container)151     explicit ConstIterator(const std::map<KEY, VALUE, CMP> *container) :
152       container_(container)
153     { if (container_ != nullptr) iter_ = container_->begin(); }
ConstIterator(const std::map<KEY,VALUE,CMP> & container)154     explicit ConstIterator(const std::map<KEY, VALUE, CMP> &container) :
155       container_(&container)
156     { if (container_ != nullptr) iter_ = container_->begin(); }
init(const std::map<KEY,VALUE,CMP> * container)157     void init(const std::map<KEY, VALUE, CMP> *container)
158     { container_ = container; if (container_ != nullptr) iter_=container_->begin();}
init(const std::map<KEY,VALUE,CMP> & container)159     void init(const std::map<KEY, VALUE, CMP> &container)
160     { container_ = &container; if (container_ != nullptr) iter_=container_->begin();}
hasNext()161     bool hasNext() { return container_ != nullptr && iter_ != container_->end(); }
next()162     VALUE next() { return iter_++->second; }
next(KEY & key,VALUE & value)163     void next(KEY &key,
164 	      VALUE &value)
165     { key = iter_->first; value = iter_->second; iter_++; }
container()166     const std::map<KEY, VALUE, CMP> *container() { return container_; }
167 
168   private:
169     const std::map<KEY, VALUE, CMP> *container_;
170     typename std::map<KEY, VALUE, CMP>::const_iterator iter_;
171   };
172 };
173 
174 } // namespace
175