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