OSSIA
Open Scenario System for Interactive Application
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 
20 namespace ossia
21 {
22 template <typename Vector>
23 using iterator_t = typename std::remove_reference<Vector>::type::iterator;
24 
25 template <typename Vector, typename Value>
26 auto find(Vector&& v, const Value& val) noexcept
27 {
28  return std::find(std::begin(v), std::end(v), val);
29 }
30 
31 template <typename Vector, typename Fun>
32 auto find_if(Vector&& v, Fun fun)
33 {
34  return std::find_if(std::begin(v), std::end(v), fun);
35 }
36 
37 template <typename Vector, typename Value>
38 auto* 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 
52 template <typename Vector, typename Fun>
53 auto* 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 
59 template <typename Vector, typename Value>
60 bool contains(Vector&& v, const Value& val) noexcept
61 {
62  return find(v, val) != std::end(v);
63 }
64 
65 template <typename Vector, typename Value>
66 void 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 
75 template <typename Vector, typename Function>
76 void 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 
85 template <typename Vector, typename Value>
86 void remove_erase(Vector& v, const Value& val)
87 {
88  v.erase(std::remove(v.begin(), v.end(), val), v.end());
89 }
90 
91 template <typename Vector, typename Function>
92 void remove_erase_if(Vector& v, const Function& val)
93 {
94  v.erase(std::remove_if(v.begin(), v.end(), val), v.end());
95 }
96 
97 template <typename Vector, typename Fun>
98 void 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 
106 template <typename Vector, typename Fun>
107 bool any_of(Vector&& v, Fun fun) noexcept
108 {
109  return std::any_of(std::begin(v), std::end(v), fun);
110 }
111 
112 template <typename Vector, typename Fun>
113 auto all_of(Vector&& v, Fun fun) noexcept
114 {
115  return std::all_of(std::begin(v), std::end(v), fun);
116 }
117 
118 template <typename Vector, typename Fun>
119 bool none_of(Vector&& v, Fun fun) noexcept
120 {
121  return std::none_of(std::begin(v), std::end(v), fun);
122 }
123 
124 template <typename Vector, typename Fun>
125 auto remove_if(Vector&& v, Fun fun)
126 {
127  return std::remove_if(std::begin(v), std::end(v), fun);
128 }
129 
130 template <typename Vector, typename Fun>
131 auto count_if(Vector&& v, Fun fun)
132 {
133  return std::count_if(std::begin(v), std::end(v), fun);
134 }
135 
136 template <typename Vector, typename Fun>
137 auto max_element(Vector&& v, Fun fun)
138 {
139  return std::max_element(std::begin(v), std::end(v), fun);
140 }
141 
142 template <typename Vector>
143 auto sort(Vector&& v)
144 {
145  return std::sort(std::begin(v), std::end(v));
146 }
147 
148 template <typename Vector, typename T>
149 auto fill(Vector&& v, const T& val)
150 {
151  return std::fill(std::begin(v), std::end(v), val);
152 }
153 
154 template <typename Vector>
155 auto unique(Vector&& v)
156 {
157  return std::unique(std::begin(v), std::end(v));
158 }
159 
160 template <typename Vector, typename Fun>
161 auto sort(Vector&& v, Fun fun)
162 {
163  return std::sort(std::begin(v), std::end(v), fun);
164 }
165 
166 template <typename Vector, typename OutputIterator, typename Fun>
167 auto transform(Vector&& v, OutputIterator it, Fun f)
168 {
169  return std::transform(v.begin(), v.end(), it, f);
170 }
171 
172 template <typename Array1, typename Array2>
173 auto equal(const Array1& v, const Array2& v2) noexcept
174 {
175  return std::equal(std::begin(v), std::end(v), std::begin(v2));
176 }
177 
178 template <typename Vector1, typename Vector2>
179 void 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 
185 template <typename Vector1, typename Vector2, typename Pred>
186 void 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 
191 template <typename T, typename K>
192 auto 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 
202 template <typename T, typename K>
203 auto 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 
209 template <std::size_t N>
210 struct num
211 {
212  static const constexpr auto value = N;
213 };
214 
215 template <class F, std::size_t... Is>
216 void for_each_in_range(F&& func, std::index_sequence<Is...>)
217 {
218  (std::forward<F>(func)(num<Is>{}), ...);
219 }
220 
221 template <std::size_t N, typename F>
222 void for_each_in_range(F&& func)
223 {
224  for_each_in_range(std::forward<F>(func), std::make_index_sequence<N>());
225 }
226 
227 namespace detail
228 {
229 template <class T, std::size_t N, std::size_t... I>
230 constexpr std::array<std::remove_cv_t<T>, N>
231 to_array_impl(T (&a)[N], std::index_sequence<I...>) noexcept
232 {
233  return {{a[I]...}};
234 }
235 }
236 
237 template <class T, std::size_t N>
238 constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&a)[N]) noexcept
239 {
240  return detail::to_array_impl(a, std::make_index_sequence<N>{});
241 }
242 
243 template <typename... Args>
244 constexpr std::array<const char*, sizeof...(Args)> make_array(Args&&... args) noexcept
245 {
246  return {args...};
247 }
248 
249 template <typename T>
250 void remove_duplicates(T& vec)
251 {
252  if(vec.size() <= 1)
253  return;
254 
255  std::sort(vec.begin(), vec.end());
256  vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
257 }
258 
259 template <typename T, typename Comp>
260 void remove_duplicates(T& vec, Comp comparator)
261 {
262  if(vec.size() <= 1)
263  return;
264 
265  std::sort(vec.begin(), vec.end(), comparator);
266  vec.erase(std::unique(vec.begin(), vec.end(), comparator), vec.end());
267 }
268 
269 template <typename Container, typename K, typename Comp, typename... Args>
270 auto emplace_sorted(Container& vec, const K& k, Comp&& comp, Args&&... args)
271  -> decltype(auto)
272 {
273  auto it = std::lower_bound(vec.begin(), vec.end(), k, std::forward<Comp>(comp));
274  return vec.emplace(it, std::forward<Args>(args)...);
275 }
276 
277 template <
278  typename D, template <typename, typename> typename S, typename T, typename Alloc>
279 auto insert_at_end(D& dest, S<T, Alloc>&& src)
280 {
281  dest.insert(
282  dest.end(), std::make_move_iterator(src.begin()),
283  std::make_move_iterator(src.end()));
284 }
285 
286 // https://stackoverflow.com/questions/45447361/how-to-move-certain-elements-of-stdvector-to-a-new-index-within-the-vector
287 template <typename T>
288 void change_item_position(T& v, size_t oldIndex, size_t newIndex)
289 {
290  if(oldIndex > newIndex)
291  std::rotate(v.rend() - oldIndex - 1, v.rend() - oldIndex, v.rend() - newIndex);
292  else
293  std::rotate(
294  v.begin() + oldIndex, v.begin() + oldIndex + 1, v.begin() + newIndex + 1);
295 }
296 
297 template <typename Container, typename Item>
298 int index_in_container(Container& vec, Item i) noexcept
299 {
300  auto it = std::find(vec.begin(), vec.end(), i);
301  if(it != vec.end())
302  return std::distance(vec.begin(), it);
303  else
304  return -1;
305 }
306 }
Definition: git_info.h:7