My Project
IOrderSet.hpp
1 /*
2  Copyright 2019 Equinor 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_IORDER_SET_HPP
21 #define OPM_IORDER_SET_HPP
22 
23 #include <algorithm>
24 #include <iterator>
25 #include <stdexcept>
26 #include <string>
27 #include <unordered_set>
28 #include <vector>
29 
30 namespace Opm {
31 
32 
33 /*
34  Small class which implements a container which behaves roughly like
35  std::set<T>, but the insert order is preserved - i.e. when iterating over the
36  elements in the container they will come out in the order they have been
37  inserted. If an element is added multiple times the order in the container
38  will not be updated.
39 
40  The set has an erase() method which can be used to remove elements, otherwise
41  the elements in the container are immutable.
42 
43  The elements are duplicated in the std::set<T> and std::vector<T>, and the
44  class should not be used for large objects.
45 */
46 
47 template <typename T>
48 class IOrderSet {
49 public:
50  using storage_type = typename std::vector<T>;
51  using index_type = typename std::unordered_set<T>;
52  using const_iter_type = typename storage_type::const_iterator;
53 
54 private:
55  index_type m_index;
56  storage_type m_data;
57 
58 public:
59  IOrderSet() = default;
60  IOrderSet(const index_type& index, const storage_type& data)
61  : m_index(index)
62  , m_data(data)
63  {}
64 
65  std::size_t size() const {
66  return this->m_index.size();
67  }
68 
69  bool empty() const {
70  return (this->size() == 0);
71  }
72 
73  std::size_t count(const T& value) const {
74  return this->m_index.count(value);
75  }
76 
77  bool contains(const T& value) const {
78  return (this->count(value) != 0);
79  }
80 
81  bool insert(const T& value) {
82  if (this->contains(value))
83  return false;
84 
85  this->m_index.insert(value);
86  this->m_data.push_back(value);
87  return true;
88  }
89 
90  std::size_t erase(const T& value) {
91  if (!this->contains(value))
92  return 0;
93 
94  this->m_index.erase(value);
95  auto data_iter = std::find(this->m_data.begin(), this->m_data.end(), value);
96  this->m_data.erase(data_iter);
97  return 1;
98  }
99 
100  const_iter_type begin() const {
101  return this->m_data.begin();
102  }
103 
104  const_iter_type end() const {
105  return this->m_data.end();
106  }
107 
108  const T& operator[](std::size_t i) const {
109  return this->m_data.at(i);
110  }
111 
112  const std::vector<T>& data() const {
113  return this->m_data;
114  };
115 
116  bool operator==(const IOrderSet<T>& data) const {
117  return this->m_index == data.m_index &&
118  this->data() == data.data();
119  }
120 
121  template<class Serializer>
122  void serializeOp(Serializer& serializer)
123  {
124  serializer(m_index);
125  serializer(m_data);
126  }
127 };
128 }
129 
130 #endif
Definition: IOrderSet.hpp:48
Class for (de-)serializing.
Definition: Serializer.hpp:75
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29