OGS 6.2.1-97-g73d1aeda3
Algorithm.h
Go to the documentation of this file.
1 
12 #pragma once
13 
14 #include <algorithm>
15 #include <boost/optional.hpp>
16 #include <cassert>
17 #include <typeindex>
18 #include <typeinfo>
19 #include "Error.h"
20 
21 namespace BaseLib
22 {
23 
32 template <typename T>
33 std::vector<T> excludeObjectCopy(std::vector<T> const& src_vec,
34  std::vector<std::size_t> const& exclude_positions)
35 {
36  std::vector<T> dest_vec;
37  if (exclude_positions.empty()) {
38  dest_vec = src_vec;
39  return dest_vec;
40  }
41 
42  assert (exclude_positions.back() < src_vec.size());
43 
44  std::copy_n(src_vec.cbegin(), exclude_positions[0], std::back_inserter(dest_vec));
45  for (std::size_t i=1; i<exclude_positions.size(); ++i) {
46  std::copy_n(
47  src_vec.cbegin()+exclude_positions[i-1]+1,
48  exclude_positions[i]-(exclude_positions[i-1]+1),
49  std::back_inserter(dest_vec)
50  );
51  }
52  std::copy(src_vec.cbegin()+exclude_positions.back()+1,
53  src_vec.cend(), std::back_inserter(dest_vec));
54 
55  return dest_vec;
56 }
57 
58 template <typename T>
59 void excludeObjectCopy(std::vector<T> const& src_vec,
60  std::vector<std::size_t> const& exclude_positions,
61  std::vector<T> & dest_vec)
62 {
63  dest_vec = excludeObjectCopy(src_vec, exclude_positions);
64 }
65 
66 template <typename InputIt, typename Predicate>
67 typename std::iterator_traits<InputIt>::reference findElementOrError(
68  InputIt begin, InputIt end, Predicate predicate,
69  std::string const& error = "")
70 {
71  auto it = std::find_if(begin, end, predicate);
72  if (it == end)
73  {
74  OGS_FATAL("Element not found in the input range; %s", error.c_str());
75  }
76  return *it;
77 }
78 
85 template <typename Map, typename Key, typename Value>
86 void insertIfTypeIndexKeyUniqueElseError(Map& map, Key const& key,
87  Value&& value,
88  std::string const& error_message)
89 {
90  auto const inserted = map.emplace(key, std::forward<Value>(value));
91  if (!inserted.second)
92  { // insertion failed, i.e., key already exists
93  OGS_FATAL("%s Key `%s' already exists.", error_message.c_str(),
94  tostring(key.hash_code()).c_str());
95  }
96 }
97 
103 template <typename Map, typename Key, typename Value>
104 void insertIfKeyUniqueElseError(Map& map, Key const& key, Value&& value,
105  std::string const& error_message)
106 {
107  auto const inserted = map.emplace(key, std::forward<Value>(value));
108  if (!inserted.second)
109  { // insertion failed, i.e., key already exists
110  OGS_FATAL("%s Key `%s' already exists.", error_message.c_str(),
111  tostring(key).c_str());
112  }
113 }
114 
119 template <typename Map, typename Key, typename Value>
120 void insertIfKeyValueUniqueElseError(Map& map, Key const& key, Value&& value,
121  std::string const& error_message)
122 {
123  auto value_compare = [&value](typename Map::value_type const& elem) {
124  return value == elem.second;
125  };
126 
127  if (std::find_if(map.cbegin(), map.cend(), value_compare) != map.cend())
128  {
129  OGS_FATAL("%s Value `%s' already exists.", error_message.c_str(),
130  tostring(value).c_str());
131  }
132 
133  auto const inserted = map.emplace(key, std::forward<Value>(value));
134  if (!inserted.second)
135  { // insertion failed, i.e., key already exists
136  OGS_FATAL("%s Key `%s' already exists.", error_message.c_str(),
137  tostring(key).c_str());
138  }
139 }
140 
146 template <typename Map, typename Key>
147 typename Map::mapped_type& getOrError(Map& map, Key const& key,
148  std::string const& error_message)
149 {
150  auto it = map.find(key);
151  if (it == map.end())
152  {
153  OGS_FATAL("%s Key `%s' does not exist.", error_message.c_str(),
154  tostring(key).c_str());
155  }
156 
157  return it->second;
158 }
160 template <typename Map, typename Key>
161 typename Map::mapped_type const& getOrError(Map const& map, Key const& key,
162  std::string const& error_message)
163 {
164  auto it = map.find(key);
165  if (it == map.end())
166  {
167  OGS_FATAL("%s Key `%s' does not exist.", error_message.c_str(),
168  tostring(key).c_str());
169  }
170 
171  return it->second;
172 }
173 
177 template <typename Container, typename Predicate>
178 typename Container::value_type const& getIfOrError(
179  Container const& container,
180  Predicate&& predicate,
181  std::string const& error_message)
182 {
183  auto it = std::find_if(begin(container), end(container), predicate);
184  if (it == end(container))
185  {
186  OGS_FATAL("Could not find element matching the predicate: %s",
187  error_message.c_str());
188  }
189  return *it;
190 }
191 
194 template <typename T>
195 void makeVectorUnique(std::vector<T>& v)
196 {
197  std::sort(v.begin(), v.end());
198  auto it = std::unique(v.begin(), v.end());
199  v.erase(it, v.end());
200 }
201 
204 template <typename T, class Compare>
205 void makeVectorUnique(std::vector<T>& v, Compare comp)
206 {
207  std::sort(v.begin(), v.end(), comp);
208  auto it = std::unique(v.begin(), v.end());
209  v.erase(it, v.end());
210 }
211 
217 template <typename ValueType, typename IndexType>
218 void reorderVector(std::vector<ValueType>& v,
219  std::vector<IndexType> const& order)
220 {
221  std::vector<ValueType> temp_v(v.size());
222  temp_v.swap(v);
223 
224  for (std::size_t i=0; i<order.size(); i++)
225  {
226  std::swap(v[i], temp_v[order[i]]);
227  }
228 }
229 
230 template <typename Container>
231 void uniquePushBack(Container& container,
232  typename Container::value_type const& element)
233 {
234  if (std::find(container.begin(), container.end(), element) ==
235  container.end())
236  {
237  container.push_back(element);
238  }
239 }
240 
241 template <typename Container>
242 bool contains(Container const& container,
243  typename Container::value_type const& element)
244 {
245  return std::find(container.begin(), container.end(), element) !=
246  container.end();
247 }
248 
249 template <typename Container, typename Predicate>
250 bool containsIf(Container const& container, Predicate&& predicate)
251 {
252  return std::find_if(container.begin(), container.end(), predicate) !=
253  container.end();
254 }
255 
256 template <typename Container>
257 boost::optional<typename Container::value_type> findFirstNotEqualElement(
258  Container const& container, typename Container::value_type const& element)
259 {
260  auto const it =
261  std::find_if_not(container.begin(), container.end(),
262  [&element](typename Container::value_type const& e) {
263  return e == element;
264  });
265  return it == container.end() ? boost::none : boost::make_optional(*it);
266 }
267 
273 template <typename Container>
274 std::size_t findIndex(Container const& container,
275  typename Container::value_type const& element)
276 {
277  auto const it = std::find(container.begin(), container.end(), element);
278  if (it == container.end())
279  {
280  return std::numeric_limits<std::size_t>::max();
281  }
282  return std::distance(container.begin(), it);
283 }
284 } // namespace BaseLib
void reorderVector(std::vector< ValueType > &v, std::vector< IndexType > const &order)
Definition: Algorithm.h:218
bool containsIf(Container const &container, Predicate &&predicate)
Definition: Algorithm.h:250
void makeVectorUnique(std::vector< T > &v)
Definition: Algorithm.h:195
Map::mapped_type & getOrError(Map &map, Key const &key, std::string const &error_message)
Definition: Algorithm.h:147
void uniquePushBack(Container &container, typename Container::value_type const &element)
Definition: Algorithm.h:231
boost::optional< typename Container::value_type > findFirstNotEqualElement(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:257
std::vector< T > excludeObjectCopy(std::vector< T > const &src_vec, std::vector< std::size_t > const &exclude_positions)
Definition: Algorithm.h:33
Container::value_type const & getIfOrError(Container const &container, Predicate &&predicate, std::string const &error_message)
Definition: Algorithm.h:178
std::string const & tostring(std::string const &value)
Definition: StringTools.cpp:92
std::size_t findIndex(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:274
Definition of the quicksort function.
void insertIfTypeIndexKeyUniqueElseError(Map &map, Key const &key, Value &&value, std::string const &error_message)
Definition: Algorithm.h:86
void insertIfKeyValueUniqueElseError(Map &map, Key const &key, Value &&value, std::string const &error_message)
Definition: Algorithm.h:120
void insertIfKeyUniqueElseError(Map &map, Key const &key, Value &&value, std::string const &error_message)
Definition: Algorithm.h:104
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
void copy(MatrixOrVector const &x, MatrixOrVector &y)
Copies x to y.
Definition: LinAlg.h:36
std::iterator_traits< InputIt >::reference findElementOrError(InputIt begin, InputIt end, Predicate predicate, std::string const &error="")
Definition: Algorithm.h:67
bool contains(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:242