20#ifndef OPM_ORDERED_MAP_HPP
21#define OPM_ORDERED_MAP_HPP
23#include <unordered_map>
34namespace OrderedMapDetail
37template<
class T,
class A>
39findSimilarStrings(std::string str,
40 const std::vector<std::pair<std::string, T>,A>& storage)
42 auto toUpper = [](
const char c){
return std::toupper(c);};
43 std::transform(str.begin(), str.end(), str.begin(), toUpper);
44 std::set<std::string> alternatives;
46 for(
const auto& entry: storage)
48 std::string upper = entry.first;
49 std::transform(upper.begin(), upper.end(), upper.begin(),
52 if(upper.find(str) != std::string::npos || str.find(upper) != std::string::npos)
54 alternatives.insert(entry.first);
58 if (alternatives.empty())
63 std::string concatedStr;
64 for (
const auto& alt : alternatives) {
68 return concatedStr.substr(0, concatedStr.size()-2);
71template<std::
size_t MAX_CHARS>
75 std::size_t operator()(
const std::string_view& key)
const
77 return hasher(key.substr(0, MAX_CHARS));
80 std::hash<std::string_view> hasher;
88template<std::
size_t MAX_CHARS>
91 bool operator()(
const std::string& str1,
const std::string& str2)
const
93 return str1.substr(0, MAX_CHARS) == str2.substr(0, MAX_CHARS);
113template <
typename T, std::
size_t MAX_CHARS = std::
string::npos>
116 using storage_type =
typename std::vector<std::pair<std::string,T>>;
117 using index_type =
typename std::unordered_map<std::string,std::size_t,
120 using iter_type =
typename storage_type::iterator;
121 using const_iter_type =
typename storage_type::const_iterator;
125 storage_type m_vector;
131 OrderedMap(
const index_type& index,
const storage_type& storage)
137 const index_type& getIndex()
const {
return m_map; }
139 const storage_type& getStorage()
const {
return m_vector; }
141 std::size_t count(
const std::string& key)
const {
142 return this->m_map.count(key);
147 T& operator[](
const std::string& key) {
148 if (this->count(key) == 0)
149 this->insert( std::make_pair(key, T()));
151 return this->at(key);
155 std::size_t erase(
const std::string& key) {
156 if (this->count(key) == 0)
159 std::size_t index = this->m_map.at(key);
160 this->m_map.erase(key);
161 this->m_vector.erase(this->m_vector.begin() + index);
163 for (
const auto& index_pair : this->m_map) {
164 auto target_index = index_pair.second;
165 if (target_index > index)
168 this->m_map[index_pair.first] = target_index;
174 void insert(std::pair<std::string,T> key_value_pair) {
175 if (this->count(key_value_pair.first) > 0) {
176 auto iter = m_map.find( key_value_pair.first );
177 size_t index = iter->second;
178 m_vector[index] = key_value_pair;
180 size_t index = m_vector.size();
181 this->m_map.emplace(key_value_pair.first, index);
182 this->m_vector.push_back( std::move( key_value_pair ) );
187 T& get(
const std::string& key) {
188 auto iter = m_map.find( key );
189 if (iter == m_map.end())
191 using namespace std::string_literals;
192 auto startsWithSame = OrderedMapDetail::findSimilarStrings(key, m_vector);
193 if (!startsWithSame.empty())
195 startsWithSame =
" Similar entries are "s +
196 startsWithSame +
"."s;
198 throw std::invalid_argument(
"Key "s + key +
" not found."s
202 size_t index = iter->second;
208 T& iget(
size_t index) {
209 if (index >= m_vector.size())
210 throw std::invalid_argument(
"Invalid index");
211 return m_vector[index].second;
214 const T& get(
const std::string& key)
const {
215 const auto& iter = this->m_map.find( key );
216 if (iter == m_map.end())
218 auto startsWithSame = OrderedMapDetail::findSimilarStrings(key, m_vector);
219 if (!startsWithSame.empty())
221 startsWithSame = std::string(
" Similar entries are ") +
222 startsWithSame + std::string(
".");
224 using namespace std::string_literals;
225 throw std::invalid_argument(
"Key "s + key +
" not found."s
229 size_t index = iter->second;
235 const T& iget(
size_t index)
const {
236 if (index >= m_vector.size())
238 using namespace std::string_literals;
239 throw std::invalid_argument(
"Invalid index "s +
240 std::to_string(index) +
241 " is larger than container size"s);
243 return m_vector[index].second;
246 const T& at(
size_t index)
const {
247 return this->iget(index);
250 const T& at(
const std::string& key)
const {
251 return this->get(key);
254 T& at(
size_t index) {
255 return this->iget(index);
258 T& at(
const std::string& key) {
259 return this->get(key);
262 size_t size()
const {
263 return m_vector.size();
267 const_iter_type begin()
const {
268 return m_vector.begin();
272 const_iter_type end()
const {
273 return m_vector.end();
277 return m_vector.begin();
281 return m_vector.end();
284 iter_type find(
const std::string& key) {
285 const auto map_iter = this->m_map.find(key);
286 if (map_iter == this->m_map.end())
287 return this->m_vector.end();
289 return std::next(this->m_vector.begin(), map_iter->second);
292 const_iter_type find(
const std::string& key)
const {
293 const auto map_iter = this->m_map.find(key);
294 if (map_iter == this->m_map.end())
295 return this->m_vector.end();
297 return std::next(this->m_vector.begin(), map_iter->second);
302 return this->getIndex() == data.getIndex() &&
303 this->getStorage() == data.getStorage();
306 template<
class Serializer>
310 serializer(m_vector);
Definition: OrderedMap.hpp:73
A map with iteration in the order of insertion.
Definition: OrderedMap.hpp:114
Class for (de-)serializing.
Definition: Serializer.hpp:84
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
Definition: OrderedMap.hpp:90