di 0.1.0
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/meta/constexpr.h"
4#include "di/meta/core.h"
5#include "di/meta/function.h"
6#include "di/types/integers.h"
7
8namespace di::meta {
9namespace detail {
10#if __has_builtin(__type_pack_element)
11 template<usize index, typename... Types>
12 struct AtHelper : TypeConstant<__type_pack_element<index, Types...>> {};
13#elif __has_builtin(__builtin_type_pack_element)
14 template<usize index, typename... Types>
15 struct AtHelper : TypeConstant<__builtin_type_pack_element(index, Types...)> {};
16#else
17 template<usize index, typename... Types>
18 struct AtHelper {};
19
20 template<typename T, typename... Rest>
21 struct AtHelper<0, T, Rest...> : TypeConstant<T> {};
22
23 template<usize index, typename T, typename... Rest>
24 struct AtHelper<index, T, Rest...> : AtHelper<index - 1, Rest...> {};
25#endif
26}
27
28namespace detail {
29 template<typename Needle, typename... Types>
30 struct LookupHelper : Constexpr<0ZU> {};
31
32 template<typename Needle, typename T, typename... Rest>
33 struct LookupHelper<Needle, T, Rest...>
34 : Constexpr<concepts::SameAs<T, Needle> ? 0ZU : 1 + LookupHelper<Needle, Rest...>::value> {};
35}
36
37namespace detail {
38 template<typename... Types>
39 struct BackHelper {};
40
41 template<typename T>
42 struct BackHelper<T> : TypeConstant<T> {};
43
44 template<typename Head, typename... Tail>
45 struct BackHelper<Head, Tail...> : BackHelper<Tail...> {};
46}
47
48template<typename Head, typename... Rest>
49struct List<Head, Rest...> {
50 using Front = Head;
51
52 using Back = Type<detail::BackHelper<Rest...>>;
53
54 constexpr static usize size = sizeof...(Rest) + 1;
55
56 template<usize index>
57 using At = Type<detail::AtHelper<index, Head, Rest...>>;
58
59 template<typename T>
60 constexpr static auto Lookup = detail::LookupHelper<T, Head, Rest...>::value;
61
62 template<typename T>
63 constexpr static bool UniqueType =
64 (static_cast<usize>(concepts::SameAs<T, Head>) + ... + static_cast<usize>(concepts::SameAs<T, Rest>)) == 1ZU;
65};
66
67template<typename T>
68struct List<T> {
69 using Front = T;
70 using Back = T;
71
72 constexpr static usize size = 1;
73
74 template<usize index>
75 using At = detail::AtHelper<index, T>::Type;
76
77 template<typename U>
79
80 template<typename U>
81 constexpr static bool UniqueType = concepts::SameAs<T, U>;
82};
83
84template<>
85struct List<> {
86 constexpr static usize size = 0;
87
88 template<typename U>
89 constexpr static bool UniqueType = false;
90
91 template<usize index>
92 requires(false)
93 using At = void;
94
95 template<usize index>
96 requires(false)
97 using Front = void;
98
99 template<usize index>
100 requires(false)
101 using Back = void;
102
103 template<typename U>
104 constexpr static usize Lookup = 0;
105};
106
107template<concepts::TypeList T>
108using Front = T::Front;
109
110template<concepts::TypeList T>
111using Back = T::Back;
112
113template<concepts::TypeList T>
114constexpr inline usize Size = T::size;
115
116template<concepts::TypeList T, usize index>
117requires(index < Size<T>)
118using At = typename T::template At<index>;
119
120template<typename T, concepts::TypeList List>
121constexpr static inline auto Lookup = List::template Lookup<T>;
122
123template<typename T, typename List>
125
126template<typename List, typename T>
127concept Contains = concepts::TypeList<List> && (Lookup<T, List> < Size<List>);
128
129namespace detail {
130 template<typename T, typename List>
131 struct CountHelper;
132
133 template<typename T>
134 struct CountHelper<T, List<>> : meta::Constexpr<0ZU> {};
135
136 template<typename T, typename U, typename... Rest>
137 struct CountHelper<T, List<U, Rest...>> {
138 constexpr static auto value = (concepts::SameAs<T, U> ? 1 : 0) + CountHelper<T, List<Rest...>>::value;
139 };
140}
141
142template<concepts::TypeList List, typename T>
143constexpr static auto Count = detail::CountHelper<T, List>::value;
144
145template<typename List, typename T>
146concept ExactlyOnce = concepts::TypeList<List> && Count<List, T> == 1;
147}
Definition core.h:114
Definition core.h:164
Definition list.h:127
Definition list.h:146
Definition list.h:124
Definition merge_interfaces.h:6
typename T::template At< index > At
Definition list.h:118
T::Type Type
Definition core.h:26
constexpr usize Size
Definition list.h:114
T::Back Back
Definition list.h:111
T::Front Front
Definition list.h:108
size_t usize
Definition integers.h:33
constexpr auto size
Definition size.h:62
static constexpr auto value
Definition constexpr.h:40
A wrapper for a constexpr value.
Definition constexpr.h:36
Type< detail::BackHelper< Rest... > > Back
Definition list.h:52
Head Front
Definition list.h:50
Type< detail::AtHelper< index, Head, Rest... > > At
Definition list.h:57
static constexpr usize size
Definition list.h:54
static constexpr auto Lookup
Definition list.h:60
static constexpr usize size
Definition list.h:72
detail::AtHelper< index, T >::Type At
Definition list.h:75
static constexpr auto Lookup
Definition list.h:78
T Front
Definition list.h:69
T Back
Definition list.h:70
Definition core.h:5