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 "MinMax.hh" 20 #include "Error.hh" 21 22 namespace sta { 23 24 template <class TYPE> 25 class MinMaxValues 26 { 27 public: MinMaxValues()28 MinMaxValues() 29 { 30 clear(); 31 } 32 MinMaxValues(TYPE init_value)33 MinMaxValues(TYPE init_value) 34 { 35 int mm_index; 36 37 mm_index = MinMax::minIndex(); 38 values_[mm_index] = init_value; 39 exists_[mm_index] = true; 40 41 mm_index = MinMax::maxIndex(); 42 values_[mm_index] = init_value; 43 exists_[mm_index] = true; 44 } 45 46 void clear()47 clear() 48 { 49 exists_[MinMax::minIndex()] = false; 50 exists_[MinMax::maxIndex()] = false; 51 } 52 53 void clear(const MinMaxAll * min_max)54 clear(const MinMaxAll *min_max) 55 { 56 exists_[min_max->index()] = false; 57 } 58 59 bool empty()60 empty() 61 { 62 return !exists_[MinMax::minIndex()] 63 && !exists_[MinMax::maxIndex()]; 64 } 65 66 void setValue(TYPE value)67 setValue(TYPE value) 68 { 69 for (auto mm_index : MinMax::rangeIndex()) { 70 values_[mm_index] = value; 71 exists_[mm_index] = true; 72 } 73 } 74 75 void setValue(const MinMaxAll * min_max,TYPE value)76 setValue(const MinMaxAll *min_max, 77 TYPE value) 78 { 79 for (auto mm_index : min_max->rangeIndex()) { 80 values_[mm_index] = value; 81 exists_[mm_index] = true; 82 } 83 } 84 85 void setValue(const MinMax * min_max,TYPE value)86 setValue(const MinMax *min_max, 87 TYPE value) 88 { 89 int mm_index = min_max->index(); 90 values_[mm_index] = value; 91 exists_[mm_index] = true; 92 } 93 94 void mergeValue(const MinMax * min_max,TYPE value)95 mergeValue(const MinMax *min_max, 96 TYPE value) 97 { 98 int mm_index = min_max->index(); 99 if (!exists_[mm_index] 100 || min_max->compare(value, values_[mm_index])) { 101 values_[mm_index] = value; 102 exists_[mm_index] = true; 103 } 104 } 105 106 TYPE value(const MinMax * min_max) const107 value(const MinMax *min_max) const 108 { 109 int mm_index = min_max->index(); 110 bool exists = exists_[mm_index]; 111 if (exists) 112 return values_[mm_index]; 113 else 114 criticalError(226, "uninitialized value reference"); 115 } 116 117 void value(const MinMax * min_max,TYPE & value,bool & exists) const118 value(const MinMax *min_max, 119 // Return values. 120 TYPE &value, 121 bool &exists) const 122 { 123 int mm_index = min_max->index(); 124 exists = exists_[mm_index]; 125 value = values_[mm_index]; 126 } 127 128 bool hasValue(const MinMax * min_max) const129 hasValue(const MinMax *min_max) const 130 { 131 int mm_index = min_max->index(); 132 return exists_[mm_index]; 133 } 134 135 void removeValue(const MinMaxAll * min_max)136 removeValue(const MinMaxAll *min_max) 137 { 138 for (auto mm_index : min_max->rangeIndex()) 139 exists_[mm_index] = false; 140 } 141 equal(MinMaxValues * values1,MinMaxValues * values2)142 static bool equal(MinMaxValues *values1, 143 MinMaxValues *values2) 144 { 145 return ((!values1->exists_[MinMax::minIndex()] 146 && !values2->exists_[MinMax::minIndex()]) 147 || (values1->exists_[MinMax::minIndex()] 148 && values2->exists_[MinMax::minIndex()] 149 && values1->values_[MinMax::minIndex()] 150 == values2->values_[MinMax::minIndex()])) 151 && ((!values1->exists_[MinMax::maxIndex()] 152 && !values2->exists_[MinMax::maxIndex()]) 153 || (values1->exists_[MinMax::maxIndex()] 154 && values2->exists_[MinMax::maxIndex()] 155 && values1->values_[MinMax::maxIndex()] 156 == values2->values_[MinMax::maxIndex()])); 157 } 158 159 private: 160 TYPE values_[MinMax::index_count]; 161 bool exists_[MinMax::index_count]; 162 }; 163 164 typedef MinMaxValues<float> MinMaxFloatValues; 165 typedef MinMaxValues<int> MinMaxIntValues; 166 167 } // namespace 168