OGS
Algorithm.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <algorithm>
14#include <cassert>
15#include <optional>
16#include <string>
17#include <typeindex>
18#include <typeinfo>
19
20#include "Error.h"
21
22namespace BaseLib
23{
32template <typename T>
33std::vector<T> excludeObjectCopy(
34 std::vector<T> const& src_vec,
35 std::vector<std::size_t> const& exclude_positions)
36{
37 std::vector<T> dest_vec;
38 if (exclude_positions.empty())
39 {
40 dest_vec = src_vec;
41 return dest_vec;
42 }
43
44 assert(exclude_positions.back() < src_vec.size());
45
46 std::copy_n(src_vec.cbegin(), exclude_positions[0],
47 std::back_inserter(dest_vec));
48 for (std::size_t i = 1; i < exclude_positions.size(); ++i)
49 {
50 std::copy_n(src_vec.cbegin() + exclude_positions[i - 1] + 1,
51 exclude_positions[i] - (exclude_positions[i - 1] + 1),
52 std::back_inserter(dest_vec));
53 }
54 std::copy(src_vec.cbegin() + exclude_positions.back() + 1, src_vec.cend(),
55 std::back_inserter(dest_vec));
56
57 return dest_vec;
58}
59
60template <typename T>
61void excludeObjectCopy(std::vector<T> const& src_vec,
62 std::vector<std::size_t> const& exclude_positions,
63 std::vector<T>& dest_vec)
64{
65 dest_vec = excludeObjectCopy(src_vec, exclude_positions);
66}
67
68template <typename InputIt, typename Predicate>
69typename std::iterator_traits<InputIt>::reference findElementOrError(
70 InputIt begin, InputIt end, Predicate predicate,
71 std::string const& error = "")
72{
73 auto it = std::find_if(begin, end, predicate);
74 if (it == end)
75 {
76 OGS_FATAL("Element not found in the input range; {:s}", error);
77 }
78 return *it;
79}
80
86template <typename Map, typename Key, typename Value>
87void insertIfKeyUniqueElseError(Map& map, Key const& key, 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("{} Key `{}' already exists.", error_message, key);
94 }
95}
96
102template <typename Map, typename Key>
103typename Map::mapped_type& getOrError(Map& map, Key const& key,
104 std::string const& error_message)
105{
106 auto it = map.find(key);
107 if (it == map.end())
108 {
109 if constexpr (std::is_convertible<Key, std::string>::value)
110 {
111 OGS_FATAL("{:s} Key `{:s}' does not exist.", error_message, key);
112 }
113 else
114 {
115 OGS_FATAL("{:s} Key `{:s}' does not exist.", error_message,
116 std::to_string(key));
117 }
118 }
119
120 return it->second;
121}
123template <typename Map, typename Key>
124typename Map::mapped_type const& getOrError(Map const& map, Key const& key,
125 std::string const& error_message)
126{
127 auto it = map.find(key);
128 if (it == map.end())
129 {
130 if constexpr (std::is_convertible<Key, std::string>::value)
131 {
132 OGS_FATAL("{:s} Key `{:s}' does not exist.", error_message, key);
133 }
134 else
135 {
136 OGS_FATAL("{:s} Key `{:s}' does not exist.", error_message,
137 std::to_string(key));
138 }
139 }
140
141 return it->second;
142}
143
147template <typename Container, typename Predicate>
148typename Container::value_type const& getIfOrError(
149 Container const& container,
150 Predicate&& predicate,
151 std::string const& error_message)
152{
153 auto it = std::find_if(begin(container), end(container), predicate);
154 if (it == end(container))
155 {
156 OGS_FATAL("Could not find element matching the predicate: {:s}",
157 error_message);
158 }
159 return *it;
160}
161
164template <typename T>
165void makeVectorUnique(std::vector<T>& v)
166{
167 std::sort(v.begin(), v.end());
168 auto it = std::unique(v.begin(), v.end());
169 v.erase(it, v.end());
170}
171
174template <typename T, class Compare>
175void makeVectorUnique(std::vector<T>& v, Compare comp)
176{
177 std::sort(v.begin(), v.end(), comp);
178 auto it = std::unique(v.begin(), v.end());
179 v.erase(it, v.end());
180}
181
187template <typename ValueType, typename IndexType>
188void reorderVector(std::vector<ValueType>& v,
189 std::vector<IndexType> const& order)
190{
191 std::vector<ValueType> temp_v(v.size());
192 temp_v.swap(v);
193
194 for (std::size_t i = 0; i < order.size(); i++)
195 {
196 std::swap(v[i], temp_v[order[i]]);
197 }
198}
199
200template <typename Container>
201void uniquePushBack(Container& container,
202 typename Container::value_type const& element)
203{
204 if (std::find(container.begin(), container.end(), element) ==
205 container.end())
206 {
207 container.push_back(element);
208 }
209}
210
211template <typename Container>
212std::optional<typename Container::value_type> findFirstNotEqualElement(
213 Container const& container, typename Container::value_type const& element)
214{
215 auto const it =
216 std::find_if_not(container.begin(), container.end(),
217 [&element](typename Container::value_type const& e)
218 { return e == element; });
219 return it == container.end() ? std::nullopt : std::make_optional(*it);
220}
221
227template <typename Container>
228std::size_t findIndex(Container const& container,
229 typename Container::value_type const& element)
230{
231 auto const it = std::find(container.begin(), container.end(), element);
232 if (it == container.end())
233 {
234 return std::numeric_limits<std::size_t>::max();
235 }
236 return std::distance(container.begin(), it);
237}
238
240template <typename T>
241void cleanupVectorElements(std::vector<T*>& items)
242{
243 for (auto item : items)
244 {
245 delete item;
246 }
247 items.clear();
248}
249
257template <typename T1, typename... Args>
258void cleanupVectorElements(std::vector<T1*>& dependent_items, Args&&... args)
259{
260 cleanupVectorElements(dependent_items);
261 cleanupVectorElements(std::forward<Args>(args)...);
262}
263
265template <typename List>
266constexpr bool any_of(List const& values)
267{
268 // std::any_of is not constexpr enough in some STLs
269 for (auto& value : values)
270 {
271 if (static_cast<bool>(value))
272 {
273 return true;
274 }
275 }
276
277 return false;
278}
279
281template <typename List>
282constexpr bool all_of(List const& values)
283{
284 // std::all_of is not constexpr enough in some STLs
285 for (auto& value : values)
286 {
287 if (!static_cast<bool>(value))
288 {
289 return false;
290 }
291 }
292
293 return true;
294}
295
297template <typename List>
298constexpr bool none_of(List const& values)
299{
300 return !any_of(values);
301}
302
303} // namespace BaseLib
#define OGS_FATAL(...)
Definition: Error.h:26
std::vector< T > excludeObjectCopy(std::vector< T > const &src_vec, std::vector< std::size_t > const &exclude_positions)
Definition: Algorithm.h:33
Map::mapped_type & getOrError(Map &map, Key const &key, std::string const &error_message)
Definition: Algorithm.h:103
std::size_t findIndex(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:228
std::iterator_traits< InputIt >::reference findElementOrError(InputIt begin, InputIt end, Predicate predicate, std::string const &error="")
Definition: Algorithm.h:69
void insertIfKeyUniqueElseError(Map &map, Key const &key, Value &&value, std::string const &error_message)
Definition: Algorithm.h:87
constexpr bool none_of(List const &values)
Checks if none of the elements in the given list are true.
Definition: Algorithm.h:298
void cleanupVectorElements(std::vector< T * > &items)
Definition: Algorithm.h:241
void uniquePushBack(Container &container, typename Container::value_type const &element)
Definition: Algorithm.h:201
constexpr bool all_of(List const &values)
Checks if all of the elements in the given list are true.
Definition: Algorithm.h:282
Container::value_type const & getIfOrError(Container const &container, Predicate &&predicate, std::string const &error_message)
Definition: Algorithm.h:148
void reorderVector(std::vector< ValueType > &v, std::vector< IndexType > const &order)
Definition: Algorithm.h:188
void makeVectorUnique(std::vector< T > &v)
Definition: Algorithm.h:165
std::optional< typename Container::value_type > findFirstNotEqualElement(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:212
constexpr bool any_of(List const &values)
Checks if any of the elements in the given list is true.
Definition: Algorithm.h:266