OGS 6.1.0-1721-g6382411ad
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 
176 template <typename T>
177 void makeVectorUnique(std::vector<T>& v)
178 {
179  std::sort(v.begin(), v.end());
180  auto it = std::unique(v.begin(), v.end());
181  v.erase(it, v.end());
182 }
183 
186 template <typename T, class Compare>
187 void makeVectorUnique(std::vector<T>& v, Compare comp)
188 {
189  std::sort(v.begin(), v.end(), comp);
190  auto it = std::unique(v.begin(), v.end());
191  v.erase(it, v.end());
192 }
193 
199 template <typename ValueType, typename IndexType>
200 void reorderVector(std::vector<ValueType>& v,
201  std::vector<IndexType> const& order)
202 {
203  std::vector<ValueType> temp_v(v.size());
204  temp_v.swap(v);
205 
206  for (std::size_t i=0; i<order.size(); i++)
207  {
208  std::swap(v[i], temp_v[order[i]]);
209  }
210 }
211 
212 template <typename Container>
213 void uniquePushBack(Container& container,
214  typename Container::value_type const& element)
215 {
216  if (std::find(container.begin(), container.end(), element) ==
217  container.end())
218  container.push_back(element);
219 }
220 
221 template <typename Container>
222 bool contains(Container const& container,
223  typename Container::value_type const& element)
224 {
225  return std::find(container.begin(), container.end(), element) !=
226  container.end();
227 }
228 
229 template <typename Container>
230 boost::optional<typename Container::value_type> findFirstNotEqualElement(
231  Container const& container, typename Container::value_type const& element)
232 {
233  auto const it =
234  std::find_if_not(container.begin(), container.end(),
235  [&element](typename Container::value_type const& e) {
236  return e == element;
237  });
238  return it == container.end() ? boost::none : boost::make_optional(*it);
239 }
240 
246 template <typename Container>
247 std::size_t findIndex(Container const& container,
248  typename Container::value_type const& element)
249 {
250  auto const it = std::find(container.begin(), container.end(), element);
251  if (it == container.end())
252  {
253  return std::numeric_limits<std::size_t>::max();
254  }
255  return std::distance(container.begin(), it);
256 }
257 } // namespace BaseLib
void reorderVector(std::vector< ValueType > &v, std::vector< IndexType > const &order)
Definition: Algorithm.h:200
void makeVectorUnique(std::vector< T > &v)
Definition: Algorithm.h:177
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:213
boost::optional< typename Container::value_type > findFirstNotEqualElement(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:230
std::vector< T > excludeObjectCopy(std::vector< T > const &src_vec, std::vector< std::size_t > const &exclude_positions)
Definition: Algorithm.h:33
std::string const & tostring(std::string const &value)
Definition: StringTools.cpp:86
std::size_t findIndex(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:247
Build information.
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:71
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:222