20 #ifndef OPM_ORDERED_MAP_HPP 21 #define OPM_ORDERED_MAP_HPP 31 #include <string_view> 32 #include <unordered_map> 38 namespace OrderedMapDetail {
40 template<
class T,
class A>
42 findSimilarStrings(std::string str,
43 const std::vector<std::pair<std::string, T>,A>& storage)
45 auto toUpper = [](
const char c){
return std::toupper(c);};
46 std::ranges::transform(str, str.begin(), toUpper);
47 std::set<std::string> alternatives;
49 for(
const auto& entry: storage)
51 std::string upper = entry.first;
52 std::ranges::transform(upper, upper.begin(), toUpper);
54 if(upper.find(str) != std::string::npos || str.find(upper) != std::string::npos)
56 alternatives.insert(entry.first);
60 if (alternatives.empty())
65 std::string concatedStr;
66 for (
const auto& alt : alternatives) {
70 return concatedStr.substr(0, concatedStr.size()-2);
73 template<std::
string_view::
size_type MAX_CHARS>
77 std::size_t operator()(std::string_view key)
const 79 return hasher(key.substr(0, MAX_CHARS));
82 std::hash<std::string_view> hasher;
90 template<std::
string_view::
size_type MAX_CHARS>
93 bool operator()(std::string_view str1, std::string_view str2)
const 95 return str1.substr(0, MAX_CHARS) == str2.substr(0, MAX_CHARS);
117 template <
typename T, std::
string_view::
size_type MAX_CHARS = std::
string_view::npos>
120 using storage_type = std::vector<std::pair<std::string, T>>;
121 using index_type = std::unordered_map<std::string,
typename storage_type::size_type,
124 using iter_type =
typename storage_type::iterator;
125 using const_iter_type =
typename storage_type::const_iterator;
129 storage_type m_vector;
135 OrderedMap(
const index_type& index,
const storage_type& storage)
141 const index_type& getIndex()
const {
return m_map; }
143 const storage_type& getStorage()
const {
return m_vector; }
145 std::size_t count(
const std::string& key)
const {
146 return this->m_map.count(key);
151 T& operator[](
const std::string& key) {
152 if (this->count(key) == 0)
153 this->insert( std::make_pair(key, T()));
155 return this->at(key);
159 std::size_t erase(
const std::string& key) {
160 if (this->count(key) == 0)
163 const std::size_t idx = this->m_map.at(key);
164 this->m_map.erase(key);
165 this->m_vector.erase(this->m_vector.begin() + idx);
167 for (
const auto& index_pair : this->m_map) {
168 auto target_index = index_pair.second;
169 if (target_index > idx) {
173 this->m_map[index_pair.first] = target_index;
179 void insert(std::pair<std::string,T> key_value_pair) {
180 if (this->count(key_value_pair.first) > 0) {
181 auto iter = m_map.find( key_value_pair.first );
182 const std::size_t idx = iter->second;
183 m_vector[idx] = key_value_pair;
185 const std::size_t idx = m_vector.size();
186 this->m_map.emplace(key_value_pair.first, idx);
187 this->m_vector.push_back(std::move(key_value_pair));
192 T&
get(
const std::string& key) {
193 auto iter = m_map.find( key );
194 if (iter == m_map.end())
196 using namespace std::string_literals;
197 auto startsWithSame = OrderedMapDetail::findSimilarStrings(key, m_vector);
198 if (!startsWithSame.empty())
200 startsWithSame =
" Similar entries are "s +
201 startsWithSame +
"."s;
203 throw std::invalid_argument(
"Key "s + key +
" not found."s
207 const std::size_t idx = iter->second;
213 T& iget(std::size_t index) {
214 if (index >= m_vector.size())
215 throw std::invalid_argument(
"Invalid index");
216 return m_vector[index].second;
219 const T&
get(
const std::string& key)
const {
220 const auto& iter = this->m_map.find( key );
221 if (iter == m_map.end())
223 auto startsWithSame = OrderedMapDetail::findSimilarStrings(key, m_vector);
224 if (!startsWithSame.empty())
226 startsWithSame = std::string(
" Similar entries are ") +
227 startsWithSame + std::string(
".");
229 using namespace std::string_literals;
230 throw std::invalid_argument(
"Key "s + key +
" not found."s
234 const std::size_t idx = iter->second;
240 const T& iget(std::size_t index)
const {
241 if (index >= m_vector.size())
243 using namespace std::string_literals;
244 throw std::invalid_argument(
"Invalid index "s +
245 std::to_string(index) +
246 " is larger than container size"s);
248 return m_vector[index].second;
251 const T& at(std::size_t index)
const {
252 return this->iget(index);
255 const T& at(
const std::string& key)
const {
256 return this->
get(key);
259 T& at(std::size_t index) {
260 return this->iget(index);
263 T& at(
const std::string& key) {
264 return this->
get(key);
267 std::size_t size()
const {
268 return m_vector.size();
272 const_iter_type begin()
const {
273 return m_vector.begin();
277 const_iter_type end()
const {
278 return m_vector.end();
282 return m_vector.begin();
286 return m_vector.end();
289 iter_type find(
const std::string& key) {
290 const auto map_iter = this->m_map.find(key);
291 if (map_iter == this->m_map.end())
292 return this->m_vector.end();
294 return std::next(this->m_vector.begin(), map_iter->second);
297 const_iter_type find(
const std::string& key)
const {
298 const auto map_iter = this->m_map.find(key);
299 if (map_iter == this->m_map.end())
300 return this->m_vector.end();
302 return std::next(this->m_vector.begin(), map_iter->second);
305 template<std::
size_t n>
307 return this->getIndex() == data.getIndex() &&
308 this->getStorage() == data.getStorage();
311 template<
class Serializer>
315 serializer(m_vector);
Definition: OrderedMap.hpp:91
Definition: OrderedMap.hpp:74
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
A map with iteration in the order of insertion.
Definition: OrderedMap.hpp:118
Class for (de-)serializing.
Definition: Serializer.hpp:94