Templa 0.0.1-alpha
C++ Metaprogramming Utilities
Loading...
Searching...
No Matches
algorithms.hpp
Go to the documentation of this file.
1#pragma once
2#include <array>
3#include <iostream>
4#include <vector>
5#include <set>
6#include "concepts.hpp"
7#include "pack.hpp"
8#include <algorithm>
9#include "static_for.hpp"
10
14
19namespace templa::algorithms
20{
21
37
38 template <typename T, typename... Formats, std::size_t N, std::size_t... Is>
39 std::tuple<Formats...> as_tuple(std::array<T, N> const &arr, std::index_sequence<Is...>)
40 {
41 return std::make_tuple(Formats{arr[Is]}...);
42 }
43
53
54 template <typename T, typename... Formats, std::size_t N>
55 std::tuple<Formats...> as_tuple(std::array<T, N> const &arr)
56 {
57 return as_tuple<Formats...>(arr, std::make_index_sequence<N>{});
58 };
59
76
77 template <typename T1, typename T2, std::size_t... I>
78 constexpr static auto zip(T1 const &t1, T2 const &t2, std::index_sequence<I...>)
79 {
80 return std::make_tuple((std::pair{std::get<I>(t1), std::get<I>(t2)})...);
81 };
82
100
101 template <typename... Ts, typename... Us>
102 requires(sizeof...(Ts) == sizeof...(Us))
103 constexpr static auto zip(std::tuple<Ts...> const &t1, std::tuple<Us...> const &t2)
104 {
105 return zip(t1, t2, std::make_index_sequence<sizeof...(Ts)>{});
106 };
107
108 namespace internal
109 {
110 template <typename T, std::size_t N, std::size_t M, std::size_t... I, std::size_t... J>
111 constexpr auto concat_impl(std::array<T, N> const &lhs, std::array<T, M> const &rhs, std::index_sequence<I...>, std::index_sequence<J...>)
112 {
113 return std::array<T, N + M>{lhs[I]..., rhs[J]...};
114 };
115
116 template <typename T, std::size_t N>
117 consteval static bool exists_until(std::array<T, N> const &arr, const T &elem, std::size_t until)
118 {
119 for (std::size_t i = 0; i < until; i++)
120 {
121 if (arr[i] == elem)
122 return true;
123 }
124 return false;
125 };
126
127 template <typename T, std::size_t N>
128 consteval static std::size_t count_unique(std::array<T, N> const &arr)
129 {
130 std::size_t cnt = 0;
131 for (std::size_t i = 0; i < N; i++)
132 {
133 if (!internal::exists_until(arr, arr[i], i))
134 cnt++;
135 }
136 return cnt;
137 };
138 };
139
148 template <auto... Es>
150 {
153
155 using typename identity_type::value_type;
156
158 constexpr static value_type value =
159 *std::min_element(identity_type::identity_value.begin(), identity_type::identity_value.end());
160 };
161
171 template <auto e>
172 requires(concepts::Container<std::remove_cv_t<decltype(e)>>)
173 struct min_from
174 {
175 public:
177 using type = typename decltype(e)::value_type;
178
180 constexpr static std::size_t size = e.size();
181
187 constexpr static auto value =
188 []<std::size_t... I>(std::index_sequence<I...>) consteval noexcept
189 {
190 return min<e[I]...>::value;
191 }(std::make_index_sequence<size>{});
192 };
193
203 template <auto... Es>
205 {
208
210 using typename identity_type::value_type;
211
213 constexpr static value_type value =
214 *std::max_element(identity_type::identity_value.begin(), identity_type::identity_value.end(),
215 [](const value_type &a, const value_type &b)
216 { return a < b; });
217 };
218
228 template <auto e>
229 requires(concepts::Container<std::remove_cv_t<decltype(e)>>)
230 struct max_from
231 {
232 public:
234 using type = typename decltype(e)::value_type;
235
237 constexpr static std::size_t size = e.size();
238
244 constexpr static auto value =
245 []<std::size_t... I>(std::index_sequence<I...>) consteval noexcept
246 {
247 return max<e[I]...>::value;
248 }(std::make_index_sequence<size>{});
249 };
250
259 template <auto... Es>
261 {
264
266 using old_array_type = typename identity_type::uniform_type;
267
268 public:
275 constexpr static auto unique_sequence = []() consteval
276 {
277 constexpr std::size_t n_unique = internal::count_unique(identity_type::identity_value);
278 std::array<typename identity_type::value_type, n_unique> new_arr{};
279 std::size_t idx = 0;
280 constexpr auto lam = []<std::size_t... I>(
281 std::array<typename identity_type::value_type, n_unique> &n,
282 std::size_t &idx)
283 {
284 constexpr auto &old = identity_type::identity_value;
285 ((!internal::exists_until(old, old[I], I) ? (n[idx++] = old[I], void()) : void()), ...);
286 };
287 static_for<identity_type::size>(lam, new_arr, idx);
288 return new_arr;
289 }();
290 };
291
302 template <auto a>
303 requires(concepts::Container<std::remove_cv_t<decltype(a)>>) &&
304 (concepts::Comparable<std::remove_cv_t<decltype(a)>>)
306 {
307 private:
309 using forwarded_type = templa::internal::forward_elements_from<a>;
310
312 using old_array_type = std::array<typename forwarded_type::type, forwarded_type::size>;
313
315 constexpr static auto old = templa::internal::forward_elements_from<a>::value;
316
317 public:
324 constexpr static auto unique_sequence = []() consteval
325 {
326 std::array<typename forwarded_type::type, internal::count_unique(old)> new_arr{};
327 std::size_t idx = 0;
328 constexpr auto lam = []<std::size_t... I>(
329 const old_array_type &o,
330 std::array<typename forwarded_type::type, internal::count_unique(old)> &n,
331 std::size_t &idx)
332 {
333 ((!internal::exists_until(old, old[I], I) ? (n[idx++] = old[I], void()) : void()), ...);
334 };
335 static_for<old.size()>(lam, old, new_arr, idx);
336 return new_arr;
337 }();
338 };
339
348 template <auto... elems>
350 {
353
355 using array_type = typename identity_type::uniform_type;
356
363 constexpr static auto reverse_sequence = []()
364 {
365 auto lam = []<std::size_t... I>(const array_type &in, array_type &out) constexpr
366 {
367 ((out[I] = in[in.size() - I - 1]), ...);
368 };
369
370 std::array<int, identity_type::size> ret{};
371 static_for<identity_type::size>(lam, identity_type::identity_value, ret);
372 return ret;
373 }();
374 };
375
385 template <auto a>
386 requires(concepts::Container<std::remove_cv_t<decltype(a)>>)
388 {
389 private:
391 constexpr static auto old = templa::internal::forward_elements_from<a>::value;
392
393 public:
399 constexpr static auto reverse_sequence = []<std::size_t... I>(std::index_sequence<I...>)
400 {
401 constexpr decltype(a) ret{old[a.size() - I - 1]...};
402 return ret;
403 }(std::make_index_sequence<a.size()>{});
404 };
405
421 template <typename T, std::size_t N, std::size_t M>
422 constexpr static auto concat(const std::array<T, N> &lhs, const std::array<T, M> &rhs)
423 {
424 return internal::concat_impl(lhs, rhs, std::make_index_sequence<N>{}, std::make_index_sequence<M>{});
425 };
426
438 template <const std::string_view &...Strs>
439 struct join
440 {
441 private:
448 constexpr static auto arr = []() consteval
449 {
450 constexpr std::size_t length = (Strs.size() + ... + 0);
451 std::array<char, length + 1> arr;
452 auto Joiner = [i = 0, &arr](const std::string_view &s) consteval mutable
453 {
454 for (auto c : s)
455 {
456 arr[i++] = c;
457 }
458 };
459 (Joiner(Strs), ...);
460 arr[length] = 0;
461 return arr;
462 }();
463
464 public:
468 constexpr static std::string_view value = {arr.data(), arr.size() - 1};
469 };
470
476 template <std::string_view const &...Strs>
477 constexpr static std::string_view join_v = join<Strs...>::value;
478
489 template <typename T, typename O>
490 void flatten(const std::vector<T> &in, std::vector<O> &out)
491 {
492 out.insert(out.end(), in.begin(), in.end());
493 };
494
505 template <typename T, typename O>
506 void flatten(const std::vector<std::vector<T>> &in, std::vector<O> &out)
507 {
508 for (const auto &e : in)
509 {
510 flatten(e, out);
511 };
512 };
513
529 template <typename Callable, typename... Ts>
530 constexpr static void apply_to_tuple_cat(Callable &&c, Ts &&...tuples)
531 {
532 auto cat = std::tuple_cat<Ts...>(std::forward<Ts>(tuples)...);
533 std::apply(std::forward<Callable>(c), std::move(cat));
534 };
535
536}
void flatten(const std::vector< T > &in, std::vector< O > &out)
Flattens a single-level std::vector<T> into another vector.
Definition algorithms.hpp:490
std::tuple< Formats... > as_tuple(std::array< T, N > const &arr, std::index_sequence< Is... >)
Converts a fixed-size array into a tuple using specified format types.
Definition algorithms.hpp:39
Concepts.
Concept to check if a type supports common comparison operators.
Definition concepts.hpp:57
Concept that models an STL-like container.
Definition concepts.hpp:245
Internal utilities and implementation details.
Compile-time string concatenation of multiple std::string_view references.
Definition algorithms.hpp:440
static constexpr std::string_view value
The resulting joined string as a std::string_view.
Definition algorithms.hpp:468
Computes the maximum value from a container-like object at compile time.
Definition algorithms.hpp:231
static constexpr std::size_t size
The number of elements in the container.
Definition algorithms.hpp:237
static constexpr auto value
The maximum value computed at compile time from the container.
Definition algorithms.hpp:244
typename decltype(e)::value_type type
The type of the elements in the container.
Definition algorithms.hpp:234
Computes the maximum value among a pack of compile-time constants.
Definition algorithms.hpp:205
typename templa::internal::uniform_element_identity< Es... > identity_type
The type that provides the uniform container of values.
Definition algorithms.hpp:207
static constexpr value_type value
The maximum value among the compile-time constants.
Definition algorithms.hpp:213
Computes the minimum value from a container-like object at compile time.
Definition algorithms.hpp:174
typename decltype(e)::value_type type
The type of the elements in the container.
Definition algorithms.hpp:177
static constexpr std::size_t size
The size of the container.
Definition algorithms.hpp:180
static constexpr auto value
The minimum value computed at compile time from the container.
Definition algorithms.hpp:187
Computes the minimum value among a pack of compile-time constants.
Definition algorithms.hpp:150
typename templa::internal::uniform_element_identity< Es... > identity_type
Alias for the identity type that represents the uniform compile-time values.
Definition algorithms.hpp:152
static constexpr value_type value
The minimum value among the compile-time constants.
Definition algorithms.hpp:158
Reverses the elements of a constexpr container at compile time.
Definition algorithms.hpp:388
static constexpr auto reverse_sequence
The reversed version of the input container.
Definition algorithms.hpp:399
Reverses a compile-time pack of constant values.
Definition algorithms.hpp:350
static constexpr auto reverse_sequence
The reversed array, computed at compile time.
Definition algorithms.hpp:363
typename templa::internal::uniform_element_identity< elems... > identity_type
The identity type wrapping the parameter pack.
Definition algorithms.hpp:352
typename identity_type::uniform_type array_type
The array type representing the uniform values.
Definition algorithms.hpp:355
Computes a compile-time unique sequence from a container expression.
Definition algorithms.hpp:306
static constexpr auto unique_sequence
The resulting array with unique elements from the input container.
Definition algorithms.hpp:324
Computes a compile-time unique sequence from a pack of values.
Definition algorithms.hpp:261
typename templa::internal::uniform_element_identity< Es... > identity_type
Type containing the uniform array of input values.
Definition algorithms.hpp:263
static constexpr auto unique_sequence
The resulting array with unique elements from the input pack.
Definition algorithms.hpp:275
typename identity_type::uniform_type old_array_type
The type of the original uniform array.
Definition algorithms.hpp:266
Extract elements from a container-like template parameter as a new container.
Definition pack.hpp:95
decltype(a)::value_type type
Value type of the container.
Definition pack.hpp:97
static constexpr auto value
Compile-time generated container with the elements of a. Uses index_sequence to access each element.
Definition pack.hpp:103
Uniform element identity helper for a list of values.
Definition pack.hpp:121
typename uniform_type::value_type value_type
Definition pack.hpp:147
std::integral_constant< std::size_t, x > value
Integral constant wrapper for a size_t value.
Definition type_list.hpp:242