My Project
OrderedMap.hpp
1 /*
2  Copyright 2014 Statoil ASA.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef OPM_ORDERED_MAP_HPP
21 #define OPM_ORDERED_MAP_HPP
22 
23 #include <unordered_map>
24 #include <vector>
25 #include <string>
26 #include <stdexcept>
27 #include <iterator>
28 
29 namespace Opm {
30 
31 template <typename K, typename T>
32 class OrderedMap {
33 public:
34  using storage_type = typename std::vector<std::pair<K,T>>;
35  using index_type = typename std::unordered_map<K,std::size_t>;
36  using iter_type = typename storage_type::iterator;
37  using const_iter_type = typename storage_type::const_iterator;
38 
39 private:
40  index_type m_map;
41  storage_type m_vector;
42 
43 public:
44 
45  OrderedMap() = default;
46 
47  OrderedMap(const index_type& index, const storage_type& storage)
48  : m_map(index)
49  , m_vector(storage)
50  {
51  }
52 
53  const index_type& getIndex() const { return m_map; }
54 
55  const storage_type& getStorage() const { return m_vector; }
56 
57  std::size_t count(const K& key) const {
58  return this->m_map.count(key);
59  }
60 
61 
62 
63  T& operator[](const K& key) {
64  if (this->count(key) == 0)
65  this->insert( std::make_pair(key, T()));
66 
67  return this->at(key);
68  }
69 
70 
71  std::size_t erase(const K& key) {
72  if (this->count(key) == 0)
73  return 0;
74 
75  std::size_t index = this->m_map.at(key);
76  this->m_map.erase(key);
77  this->m_vector.erase(this->m_vector.begin() + index);
78 
79  for (const auto& index_pair : this->m_map) {
80  auto target_index = index_pair.second;
81  if (target_index > index)
82  target_index--;
83 
84  this->m_map[index_pair.first] = target_index;
85  }
86  return 1;
87  }
88 
89 
90  void insert(std::pair<K,T> key_value_pair) {
91  if (this->count(key_value_pair.first) > 0) {
92  auto iter = m_map.find( key_value_pair.first );
93  size_t index = iter->second;
94  m_vector[index] = key_value_pair;
95  } else {
96  size_t index = m_vector.size();
97  this->m_map.emplace(key_value_pair.first, index);
98  this->m_vector.push_back( std::move( key_value_pair ) );
99  }
100  }
101 
102 
103  T& get(const K& key) {
104  auto iter = m_map.find( key );
105  if (iter == m_map.end())
106  throw std::invalid_argument("Key not found:");
107  else {
108  size_t index = iter->second;
109  return iget(index);
110  }
111  }
112 
113 
114  T& iget(size_t index) {
115  if (index >= m_vector.size())
116  throw std::invalid_argument("Invalid index");
117  return m_vector[index].second;
118  }
119 
120  const T& get(const K& key) const {
121  const auto& iter = this->m_map.find( key );
122  if (iter == m_map.end())
123  throw std::invalid_argument("Key not found: ??");
124  else {
125  size_t index = iter->second;
126  return iget(index);
127  }
128  }
129 
130 
131  const T& iget(size_t index) const {
132  if (index >= m_vector.size())
133  throw std::invalid_argument("Invalid index");
134  return m_vector[index].second;
135  }
136 
137  const T& at(size_t index) const {
138  return this->iget(index);
139  }
140 
141  const T& at(const K& key) const {
142  return this->get(key);
143  }
144 
145  T& at(size_t index) {
146  return this->iget(index);
147  }
148 
149  T& at(const K& key) {
150  return this->get(key);
151  }
152 
153  size_t size() const {
154  return m_vector.size();
155  }
156 
157 
158  const_iter_type begin() const {
159  return m_vector.begin();
160  }
161 
162 
163  const_iter_type end() const {
164  return m_vector.end();
165  }
166 
167  iter_type begin() {
168  return m_vector.begin();
169  }
170 
171  iter_type end() {
172  return m_vector.end();
173  }
174 
175  iter_type find(const K& key) {
176  const auto map_iter = this->m_map.find(key);
177  if (map_iter == this->m_map.end())
178  return this->m_vector.end();
179 
180  return std::next(this->m_vector.begin(), map_iter->second);
181  }
182 
183  const_iter_type find(const K& key) const {
184  const auto map_iter = this->m_map.find(key);
185  if (map_iter == this->m_map.end())
186  return this->m_vector.end();
187 
188  return std::next(this->m_vector.begin(), map_iter->second);
189  }
190 
191  bool operator==(const OrderedMap<K,T>& data) const {
192  return this->getIndex() == data.getIndex() &&
193  this->getStorage() == data.getStorage();
194  }
195 
196  template<class Serializer>
197  void serializeOp(Serializer& serializer)
198  {
199  serializer(m_map);
200  serializer.vector(m_vector);
201  }
202 };
203 }
204 
205 #endif
Definition: OrderedMap.hpp:32
Definition: Serializer.hpp:38
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29