OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
algorithms.hpp
Go to the documentation of this file.
1#pragma once
2#include <ossia/detail/config.hpp>
3
4#include <ossia/detail/string_view.hpp>
5
6#include <algorithm>
7#include <array>
8#include <iterator>
9#include <type_traits>
10#include <utility>
11
20namespace ossia
21{
22template <typename Vector>
23using iterator_t = typename std::remove_reference<Vector>::type::iterator;
24
25template <typename Vector, typename Value>
26auto find(Vector&& v, const Value& val) noexcept
27{
28 return std::find(std::begin(v), std::end(v), val);
29}
30
31template <typename Vector, typename Fun>
32auto find_if(Vector&& v, Fun fun)
33{
34 return std::find_if(std::begin(v), std::end(v), fun);
35}
36
37template <typename Vector, typename Value>
38auto* ptr_find(Vector&& v, const Value& val) noexcept
39{
40 if constexpr(requires { v.find(val) != v.end(); })
41 {
42 auto it = v.find(val);
43 return it != v.end() ? &it->second : nullptr;
44 }
45 else
46 {
47 auto it = std::find(std::begin(v), std::end(v), val);
48 return it != std::end(v) ? &*it : nullptr;
49 }
50}
51
52template <typename Vector, typename Fun>
53auto* ptr_find_if(Vector&& v, Fun fun)
54{
55 auto it = std::find_if(std::begin(v), std::end(v), fun);
56 return it != std::end(v) ? &*it : nullptr;
57}
58
59template <typename Vector, typename Value>
60bool contains(Vector&& v, const Value& val) noexcept
61{
62 return find(v, val) != std::end(v);
63}
64
65template <typename Vector, typename Value>
66void remove_one(Vector&& v, const Value& val)
67{
68 auto it = find(v, val);
69 if(it != v.end())
70 {
71 v.erase(it);
72 }
73}
74
75template <typename Vector, typename Function>
76void remove_one_if(Vector& v, const Function& val)
77{
78 auto it = find_if(v, val);
79 if(it != v.end())
80 {
81 v.erase(it);
82 }
83}
84
85template <typename Vector, typename Value>
86void remove_erase(Vector& v, const Value& val)
87{
88 v.erase(std::remove(v.begin(), v.end(), val), v.end());
89}
90
91template <typename Vector, typename Function>
92void remove_erase_if(Vector& v, const Function& val)
93{
94 v.erase(std::remove_if(v.begin(), v.end(), val), v.end());
95}
96
97template <typename Vector, typename Fun>
98void erase_if(Vector& r, Fun f)
99{
100 for(auto it = std::begin(r); it != std::end(r);)
101 {
102 it = f(*it) ? r.erase(it) : ++it;
103 }
104}
105
106template <typename Vector, typename Fun>
107bool any_of(Vector&& v, Fun fun) noexcept
108{
109 return std::any_of(std::begin(v), std::end(v), fun);
110}
111
112template <typename Vector, typename Fun>
113auto all_of(Vector&& v, Fun fun) noexcept
114{
115 return std::all_of(std::begin(v), std::end(v), fun);
116}
117
118template <typename Vector, typename Fun>
119bool none_of(Vector&& v, Fun fun) noexcept
120{
121 return std::none_of(std::begin(v), std::end(v), fun);
122}
123
124template <typename Vector, typename Fun>
125auto remove_if(Vector&& v, Fun fun)
126{
127 return std::remove_if(std::begin(v), std::end(v), fun);
128}
129
130template <typename Vector, typename Fun>
131auto count_if(Vector&& v, Fun fun)
132{
133 return std::count_if(std::begin(v), std::end(v), fun);
134}
135
136template <typename Vector, typename Fun>
137auto max_element(Vector&& v, Fun fun)
138{
139 return std::max_element(std::begin(v), std::end(v), fun);
140}
141
142template <typename Vector>
143auto sort(Vector&& v)
144{
145 return std::sort(std::begin(v), std::end(v));
146}
147
148template <typename Vector, typename T>
149auto fill(Vector&& v, const T& val)
150{
151 return std::fill(std::begin(v), std::end(v), val);
152}
153
154template <typename Vector>
155auto unique(Vector&& v)
156{
157 return std::unique(std::begin(v), std::end(v));
158}
159
160template <typename Vector, typename Fun>
161auto sort(Vector&& v, Fun fun)
162{
163 return std::sort(std::begin(v), std::end(v), fun);
164}
165
166template <typename Vector, typename OutputIterator, typename Fun>
167auto transform(Vector&& v, OutputIterator it, Fun f)
168{
169 return std::transform(v.begin(), v.end(), it, f);
170}
171
172template <typename Array1, typename Array2>
173auto equal(const Array1& v, const Array2& v2) noexcept
174{
175 return std::equal(std::begin(v), std::end(v), std::begin(v2));
176}
177
178template <typename Vector1, typename Vector2>
179void copy(const Vector1& source, Vector2& destination)
180{
181 destination.reserve(destination.size() + source.size());
182 std::copy(source.begin(), source.end(), std::back_inserter(destination));
183}
184
185template <typename Vector1, typename Vector2, typename Pred>
186void copy_if(const Vector1& source, Vector2& destination, Pred predicate)
187{
188 std::copy_if(source.begin(), source.end(), std::back_inserter(destination), predicate);
189}
190
191template <typename T, typename K>
192auto last_before(T&& container, const K& k)
193{
194 auto it = container.upper_bound(k);
195 if(it != container.begin())
196 {
197 std::advance(it, -1);
198 }
199 return it;
200}
201
202template <typename T, typename K>
203auto find_key(T&& vec, const K& key) noexcept
204{
205 return std::find_if(
206 vec.begin(), vec.end(), [&](const auto& elt) { return elt.first == key; });
207}
208
209template <typename T, typename K0, typename K1>
210auto find_key(T&& vec, const K0& k0, const K1& k1) noexcept
211{
212 return std::find_if(vec.begin(), vec.end(), [&](const auto& elt) {
213 using namespace std;
214 return get<0>(elt) == k0 && get<1>(elt) == k1;
215 });
216}
217
218template <std::size_t N>
219struct num
220{
221 static const constexpr auto value = N;
222};
223
224template <class F, std::size_t... Is>
225void for_each_in_range(F&& func, std::index_sequence<Is...>)
226{
227 (std::forward<F>(func)(num<Is>{}), ...);
228}
229
230template <std::size_t N, typename F>
231void for_each_in_range(F&& func)
232{
233 for_each_in_range(std::forward<F>(func), std::make_index_sequence<N>());
234}
235
236namespace detail
237{
238template <class T, std::size_t N, std::size_t... I>
239constexpr std::array<std::remove_cv_t<T>, N>
240to_array_impl(T (&a)[N], std::index_sequence<I...>) noexcept
241{
242 return {{a[I]...}};
243}
244}
245
246template <class T, std::size_t N>
247constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&a)[N]) noexcept
248{
249 return detail::to_array_impl(a, std::make_index_sequence<N>{});
250}
251
252template <typename... Args>
253constexpr std::array<const char*, sizeof...(Args)> make_array(Args&&... args) noexcept
254{
255 return {args...};
256}
257
258template <typename T>
259void remove_duplicates(T& vec)
260{
261 if(vec.size() <= 1)
262 return;
263
264 std::sort(vec.begin(), vec.end());
265 vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
266}
267
268template <typename T, typename Comp>
269void remove_duplicates(T& vec, Comp comparator)
270{
271 if(vec.size() <= 1)
272 return;
273
274 std::sort(vec.begin(), vec.end(), comparator);
275 vec.erase(std::unique(vec.begin(), vec.end(), comparator), vec.end());
276}
277
278template <typename Container, typename K, typename Comp, typename... Args>
279auto emplace_sorted(Container& vec, const K& k, Comp&& comp, Args&&... args)
280 -> decltype(auto)
281{
282 auto it = std::lower_bound(vec.begin(), vec.end(), k, std::forward<Comp>(comp));
283 return vec.emplace(it, std::forward<Args>(args)...);
284}
285
286template <
287 typename D, template <typename, typename> typename S, typename T, typename Alloc>
288auto insert_at_end(D& dest, S<T, Alloc>&& src)
289{
290 dest.insert(
291 dest.end(), std::make_move_iterator(src.begin()),
292 std::make_move_iterator(src.end()));
293}
294
295// https://stackoverflow.com/questions/45447361/how-to-move-certain-elements-of-stdvector-to-a-new-index-within-the-vector
296template <typename T>
297void change_item_position(T& v, size_t oldIndex, size_t newIndex)
298{
299 if(oldIndex > newIndex)
300 std::rotate(v.rend() - oldIndex - 1, v.rend() - oldIndex, v.rend() - newIndex);
301 else
302 std::rotate(
303 v.begin() + oldIndex, v.begin() + oldIndex + 1, v.begin() + newIndex + 1);
304}
305
306template <typename Container, typename Item>
307int index_in_container(Container& vec, Item i) noexcept
308{
309 auto it = std::find(vec.begin(), vec.end(), i);
310 if(it != vec.end())
311 return std::distance(vec.begin(), it);
312 else
313 return -1;
314}
315}
Definition git_info.h:7