koutil
Loading...
Searching...
No Matches
types.h
Go to the documentation of this file.
1#ifndef KOUTIL_UTIL_TYPES_H
2#define KOUTIL_UTIL_TYPES_H
3
4#include <array>
5#include <cassert>
6#include <cstddef>
7#include <tuple>
8#include <type_traits>
9#include <utility>
10#include <variant>
11#include <vector>
12
13namespace koutil::type {
14
20template <typename... T> struct types {
21 static constexpr std::size_t size = sizeof...(T);
22};
23
24template <typename T> struct are_types : std::false_type { };
25
26template <typename... Types> struct are_types<types<Types...>> : std::true_type { };
27
28template <typename T> inline constexpr bool are_types_v = are_types<T>::value;
29
30template <typename T>
32
39template <types_concept T, types_concept U> struct types_cat;
40
47template <typename... T, typename... U> struct types_cat<types<T...>, types<U...>> {
48 using type = types<T..., U...>;
49};
50
57template <types_concept T, types_concept U> using types_cat_t = types_cat<T, U>::type;
58
62template <typename T>
63concept types_transform = requires() {
64 typename T::template transform<int>;
65 typename T::template transform<int, int>;
66 typename T::template transform<int, int, int, int, int>;
67};
68
72template <typename T>
73concept types_container = requires() { typename T::template container<int>; };
74
82 struct tuple {
83 template <typename... Types> using transform = std::tuple<Types...>;
84 };
85
89 struct variant {
90 template <typename... Types> using transform = std::variant<Types...>;
91 };
92
96 struct reference {
97 template <typename... Types> using transform = types<Types&...>;
98 };
99
103 struct constant {
104 template <typename... Types> using transform = types<const Types...>;
105 };
106
107 /*
108 * @brief Provides a `const T&` transform.
109 */
111 template <typename... Types> using transform = types<const Types&...>;
112 };
113
118 template <typename... Types> using transform = types<typename std::vector<Types>::reference...>;
119 };
120
121 /*
122 * @brief Provides a `std::vector<T>::const_reference` transform.
123 */
125 template <typename... Types> using transform = types<typename std::vector<Types>::const_reference...>;
126 };
127};
128
136 struct vector {
137 template <typename T> using container = std::vector<T>;
138 };
139};
140
146template <types_concept Types> struct types_count;
147
153template <typename... Types> struct types_count<types<Types...>> {
160 template <typename T> static constexpr std::size_t value = 0 + (std::is_same_v<T, Types> + ...);
161};
162
163namespace detail {
171 template <typename T, typename... Other> consteval bool contains_type() {
172 return (std::is_same_v<T, Other> || ...);
173 }
174
180 template <typename... Types> struct unique_types_impl;
181
187 template <typename T> struct unique_types_impl<T> {
188 using type = types<T>;
189 };
190
197 template <typename T, typename... Other> struct unique_types_impl<T, Other...> {
198 using other_types = unique_types_impl<Other...>::type;
199 using type = std::conditional_t<contains_type<T, Other...>(), other_types, types_cat_t<types<T>, other_types>>;
200 };
201
208 template <types_concept T, types_container Container> struct types_to_containers;
209
216 template <typename... Types, types_container Container> struct types_to_containers<types<Types...>, Container> {
218 };
219
226 template <types_concept T, types_transform Transform> struct types_transform_impl;
227
234 template <typename... Types, types_transform Transform> struct types_transform_impl<types<Types...>, Transform> {
235 using type = Transform::template transform<Types...>;
236 };
237
248 template <typename T, std::size_t N, std::size_t I, typename Type, typename... Other>
249 constexpr std::size_t types_index_of_impl() {
250 if constexpr (std::is_same_v<T, Type>) {
251 if constexpr (N == 0) {
252 return I;
253 } else if constexpr (sizeof...(Other) != 0) {
254 return types_index_of_impl<T, N - 1, I + 1, Other...>();
255 }
256 } else if constexpr (sizeof...(Other) != 0) {
257 return types_index_of_impl<T, N, I + 1, Other...>();
258 }
259 assert(false);
260 }
261
269 template <typename T, types_concept Types, std::size_t N> struct types_index_of;
270
278 template <typename T, typename... Types, std::size_t N> struct types_index_of<T, types<Types...>, N> {
279 static constexpr std::size_t value = types_index_of_impl<T, N, 0, Types...>();
280 };
281
288 template <types_concept Types, std::size_t I> struct types_get_impl;
289
296 template <typename... Types, std::size_t I>
297 requires(sizeof...(Types) > 0)
298 struct types_get_impl<types<Types...>, I> {
299 using type = std::tuple_element_t<I, std::tuple<Types...>>;
300 };
301
302 template <std::size_t I> struct types_get_impl<types<>, I> {
303 using type = void;
304 };
305
311 template <types_concept Types> struct types_unique_impl;
312
318 template <typename... Types> struct types_unique_impl<types<Types...>> {
319 using type = unique_types_impl<Types...>::type;
320 };
321
328 template <types_concept Types, typename Unique> struct types_to_arrays;
329
336 template <typename... Types, typename... Unique> struct types_to_arrays<types<Types...>, types<Unique...>> {
337 using type = types<std::array<Unique, types_count<types<Types...>>::template value<Unique>>...>;
338 };
339
340 template <typename Search, typename Type, typename... Other> struct types_remove_impl {
341 using rest = types_remove_impl<Search, Other...>::type;
342
343 using type = std::conditional_t<std::is_same_v<Type, Search>, rest, types_cat_t<types<Type>, rest>>;
344 };
345
346 template <typename Search, typename Type> struct types_remove_impl<Search, Type> {
347 using type = std::conditional_t<std::is_same_v<Type, Search>, types<>, types<Type>>;
348 };
349
350 template <typename Types, typename Type> struct types_remove;
351
352 template <typename... Types, typename Type>
353 requires(sizeof...(Types) > 0)
354 struct types_remove<types<Types...>, Type> {
355 using type = types_remove_impl<Type, Types...>::type;
356 };
357
358 template <typename Type> struct types_remove<types<>, Type> {
359 using type = types<>;
360 };
361
362 template <std::size_t N, types_concept Types> struct types_view;
363
364 template <std::size_t N, typename Type, typename... Other> struct types_view<N, types<Type, Other...>> {
367 std::conditional_t<(N > 1), typename types_view<N - 1, types<Other...>>::type, types<>>>;
368 };
369
370 template <std::size_t N> struct types_view<N, types<>> {
371 using type = types<>;
372 };
373}
374
381template <types_concept Types, std::size_t I> using types_get_t = detail::types_get_impl<Types, I>::type;
382
388template <typename... Types> using unique_types_t = detail::unique_types_impl<Types...>::type;
389
395template <types_concept Types> using types_unique_t = detail::types_unique_impl<Types>::type;
396
403template <types_concept Types, types_transform Transform>
405
412template <types_concept Types, types_container Container = types_containers::vector>
414
422template <types_concept Types, typename T, std::size_t Skip = 0>
424
431
432/*
433 * @brief Alias for removing type from a types list
434 *
435 * @tparam Types The types list.
436 * @tparam T The type to remove
437 */
438template <types_concept Types, typename T> using types_remove_t = detail::types_remove<Types, T>::type;
439
440template <types_concept Types, std::size_t N> using types_view_t = detail::types_view<N, Types>::type;
441
442}
443
444#endif
Definition types.h:31
Concept for a type that provides a container template.
Definition types.h:73
Concept for a type that provides a transform template.
Definition types.h:63
consteval bool contains_type()
Helper to check if a type is contained in a list of types.
Definition types.h:171
constexpr std::size_t types_index_of_impl()
Helper to get the index of a type in a types list.
Definition types.h:249
Definition types.h:13
detail::types_get_impl< Types, I >::type types_get_t
Alias for getting a type by index in a types list.
Definition types.h:381
detail::types_to_arrays< Types, types_unique_t< Types > >::type types_to_arrays_t
Alias for converting a types list to arrays of unique types.
Definition types.h:430
constexpr bool are_types_v
Definition types.h:28
detail::unique_types_impl< Types... >::type unique_types_t
Alias for creating a unique types list from a list of types.
Definition types.h:388
detail::types_to_containers< Types, Container >::type types_to_containers_t
Alias for transforming a types list to a containers list.
Definition types.h:413
detail::types_remove< Types, T >::type types_remove_t
Definition types.h:438
detail::types_unique_impl< Types >::type types_unique_t
Alias for creating a unique types list from a types list.
Definition types.h:395
types_cat< T, U >::type types_cat_t
Alias for the concatenated types list.
Definition types.h:57
detail::types_transform_impl< Types, Transform >::type types_transform_t
Alias for transforming a types list using a transform template.
Definition types.h:404
constexpr std::size_t types_index_of_v
Gets the index of a type in a types list.
Definition types.h:423
detail::types_view< N, Types >::type types_view_t
Definition types.h:440
Definition types.h:24
std::tuple_element_t< I, std::tuple< Types... > > type
Definition types.h:299
Implementation for getting a type by index in a types list.
Definition types.h:288
Structure to get the index of a type in a types list.
Definition types.h:269
types_remove_impl< Type, Types... >::type type
Definition types.h:355
std::conditional_t< std::is_same_v< Type, Search >, types<>, types< Type > > type
Definition types.h:347
types_remove_impl< Search, Other... >::type rest
Definition types.h:341
std::conditional_t< std::is_same_v< Type, Search >, rest, types_cat_t< types< Type >, rest > > type
Definition types.h:343
Implementation for converting a types list to arrays of unique types.
Definition types.h:328
Transforms a types list to a containers list.
Definition types.h:208
Transform::template transform< Types... > type
Definition types.h:235
Implementation for transforming a types list using a transform template.
Definition types.h:226
unique_types_impl< Types... >::type type
Definition types.h:319
Implementation for creating a unique types list from a types list.
Definition types.h:311
types_cat_t< types< Type >, std::conditional_t<(N > 1), typename types_view< N - 1, types< Other... > >::type, types<> > > type
Definition types.h:365
Definition types.h:362
std::conditional_t< contains_type< T, Other... >(), other_types, types_cat_t< types< T >, other_types > > type
Definition types.h:199
unique_types_impl< Other... >::type other_types
Definition types.h:198
Implementation for creating a unique types list.
Definition types.h:180
Concatenates two types lists.
Definition types.h:39
Provides a std::vector container.
Definition types.h:136
std::vector< T > container
Definition types.h:137
A namespace containing container templates for types lists.
Definition types.h:132
A template structure to count occurrences of a specific type in a types list.
Definition types.h:146
Provides a const T transform.
Definition types.h:103
Provides a T& transform.
Definition types.h:96
Provides a std::tuple transform.
Definition types.h:82
std::tuple< Types... > transform
Definition types.h:83
Provides a std::variant transform.
Definition types.h:89
std::variant< Types... > transform
Definition types.h:90
Provides a std::vector<T>::reference transform.
Definition types.h:117
A namespace containing transform templates for types lists.
Definition types.h:78
A structure representing a variadic list of types.
Definition types.h:20
static constexpr std::size_t size
Definition types.h:21