LeviLamina
Loading...
Searching...
No Matches
TypeTraits.h
1#pragma once
2
3#include <array>
4#include <concepts>
5#include <type_traits>
6#include <utility>
7
8namespace ll::traits {
9
10template <class T, template <class...> class Z, class... Ts>
11concept Require = Z<T, Ts...>::value;
12
13template <size_t N, class T, class... Ts>
14struct get_type {
15 using type = typename get_type<N - 1, Ts...>::type;
16};
17
18template <class T, class... Ts>
19struct get_type<0, T, Ts...> {
20 using type = T;
21};
22
23template <size_t N, class... Ts>
24using get_type_t = typename get_type<N, Ts...>::type;
25
26template <class T, class U, class... Args>
27struct max_type {
28 using type = typename max_type<T, typename max_type<U, Args...>::type>::type;
29};
30
31template <class T, class U>
32struct max_type<T, U> {
33 using type = typename std::conditional<(sizeof(T) < sizeof(U)), U, T>::type;
34};
35
36template <class T, class... Ts>
37struct index_of;
38
39template <class T, class... Ts>
40struct index_of<T, T, Ts...> : std::integral_constant<size_t, 0> {};
41
42template <class T, class U, class... Ts>
43struct index_of<T, U, Ts...> : std::integral_constant<size_t, 1 + index_of<T, Ts...>::value> {};
44
45
46template <class>
47struct function_traits;
48
49template <class Ret, class... Args>
50struct function_traits<Ret (*)(Args...)> : function_traits<Ret(Args...)> {};
51
52template <class F>
53struct function_traits : function_traits<decltype(&F::operator())> {};
54
55#ifndef LL_BUILD_FUNCTION_SIGNATURE
56#define LL_BUILD_FUNCTION_SIGNATURE(CVREF, NOEXCEPT) \
57 template <class Ret, class... Args> \
58 struct function_traits<Ret(Args...) CVREF noexcept(NOEXCEPT)> { \
59 using function_type = Ret(Args...); \
60 using function_type_noexcept = Ret(Args...) noexcept(NOEXCEPT); \
61 template <class T> \
62 using cvref = T CVREF; \
63 static constexpr bool is_noexcept = NOEXCEPT; \
64 static constexpr bool is_const = std::is_const_v<cvref<int>>; \
65 static constexpr bool is_volatile = std::is_volatile_v<cvref<int>>; \
66 static constexpr bool is_reference = std::is_reference_v<cvref<int>>; \
67 static constexpr bool is_lvalue_reference = std::is_lvalue_reference_v<cvref<int>>; \
68 static constexpr bool is_rvalue_reference = std::is_rvalue_reference_v<cvref<int>>; \
69 }; \
70 template <class Ret, class Cls, class... Args> \
71 struct function_traits<Ret (Cls::*)(Args...) CVREF noexcept(NOEXCEPT)> \
72 : function_traits<Ret(Args...) CVREF noexcept(NOEXCEPT)> {};
73
74LL_BUILD_FUNCTION_SIGNATURE(, false)
75LL_BUILD_FUNCTION_SIGNATURE(const, false)
76LL_BUILD_FUNCTION_SIGNATURE(volatile, false)
77LL_BUILD_FUNCTION_SIGNATURE(const volatile, false)
78LL_BUILD_FUNCTION_SIGNATURE(, true)
79LL_BUILD_FUNCTION_SIGNATURE(const, true)
80LL_BUILD_FUNCTION_SIGNATURE(volatile, true)
81LL_BUILD_FUNCTION_SIGNATURE(const volatile, true)
82LL_BUILD_FUNCTION_SIGNATURE(&, false)
83LL_BUILD_FUNCTION_SIGNATURE(const&, false)
84LL_BUILD_FUNCTION_SIGNATURE(volatile&, false)
85LL_BUILD_FUNCTION_SIGNATURE(const volatile&, false)
86LL_BUILD_FUNCTION_SIGNATURE(&, true)
87LL_BUILD_FUNCTION_SIGNATURE(const&, true)
88LL_BUILD_FUNCTION_SIGNATURE(volatile&, true)
89LL_BUILD_FUNCTION_SIGNATURE(const volatile&, true)
90LL_BUILD_FUNCTION_SIGNATURE(&&, false)
91LL_BUILD_FUNCTION_SIGNATURE(const&&, false)
92LL_BUILD_FUNCTION_SIGNATURE(volatile&&, false)
93LL_BUILD_FUNCTION_SIGNATURE(const volatile&&, false)
94LL_BUILD_FUNCTION_SIGNATURE(&&, true)
95LL_BUILD_FUNCTION_SIGNATURE(const&&, true)
96LL_BUILD_FUNCTION_SIGNATURE(volatile&&, true)
97LL_BUILD_FUNCTION_SIGNATURE(const volatile&&, true)
98#undef LL_BUILD_FUNCTION_SIGNATURE
99#endif
100
101template <class T, class U>
103
104template <class T, template <class...> class U, class... Ts>
105struct is_in_types<T, U<Ts...>> : std::bool_constant<(std::is_same_v<T, Ts> || ...)> {};
106
107template <class T, class U>
108constexpr bool is_in_types_v = is_in_types<T, U>::value;
109
110template <class T, class... Ts>
111constexpr bool is_one_of_v = (std::is_same_v<T, Ts> || ...);
112
113template <class T, class... Ts>
114struct is_one_of : std::bool_constant<is_one_of_v<T, Ts...>> {};
115
116template <class T, class... Ts>
117constexpr bool is_all_same_v = (std::is_same_v<T, Ts> && ...);
118
119template <class T, class... Ts>
120struct is_all_same : std::bool_constant<is_all_same_v<T, Ts...>> {};
121
122template <class T>
123constexpr bool is_string_v = std::is_constructible_v<std::string, T>;
124
125template <class T>
126constexpr bool is_char_v = is_one_of_v<std::remove_cv_t<T>, char, wchar_t, char8_t, char16_t, char32_t>;
127
128template <class T, template <class...> class Z>
129constexpr bool is_specialization_of_v = false;
130
131template <template <class...> class Z, class... Args>
132constexpr bool is_specialization_of_v<Z<Args...>, Z> = true;
133
134template <class T, template <class...> class Z>
135struct is_specialization_of : std::bool_constant<is_specialization_of_v<T, Z>> {};
136
137template <class>
138constexpr bool is_std_array_v = false;
139
140template <class T, size_t N>
141constexpr bool is_std_array_v<::std::array<T, N>> = true;
142
143template <class>
144constexpr bool is_subrange_v = false;
145
146template <class I, class S, ::std::ranges::subrange_kind K>
147constexpr bool is_subrange_v<::std::ranges::subrange<I, S, K>> = true;
148
149template <template <class...> class T, class... Ts>
150void derivedFromSpecializationImpl(T<Ts...> const&);
151
152template <class T, template <class...> class Z>
153constexpr bool is_derived_from_specialization_of_v = requires(T const& t) { derivedFromSpecializationImpl<Z>(t); };
154
155template <class T, template <class...> class Z>
156struct is_derived_from_specialization_of : std::bool_constant<is_derived_from_specialization_of_v<T, Z>> {};
157
158template <class...>
159constexpr bool always_false = false;
160
161template <class T>
162constexpr bool is_virtual_cloneable_v =
163 std::is_polymorphic_v<T> && (requires(std::remove_cv_t<T> const& t) {
164 static_cast<T*>(t.clone());
165 } || requires(std::remove_cv_t<T> const& t) { static_cast<T*>(t.clone().release()); });
166
167template <class T>
168constexpr bool is_awaiter_v = requires(std::remove_cv_t<T>& t) {
169 { t.await_ready() } -> std::same_as<bool>;
170 t.await_resume();
171};
172template <class T>
173struct is_awaiter : std::bool_constant<is_awaiter_v<T>> {};
174
175template <class T>
176constexpr bool has_member_operator_co_await_v = requires(T t) {
177 { t.operator co_await() } -> Require<is_awaiter>;
178};
179template <class T>
180struct has_member_operator_co_await : std::bool_constant<has_member_operator_co_await_v<T>> {};
181
182template <class T>
183constexpr bool has_non_member_operator_co_await_v = requires(T t) {
184 { operator co_await(t) } -> Require<is_awaiter>;
185};
186template <class T>
187struct has_non_member_operator_co_await : std::bool_constant<has_non_member_operator_co_await_v<T>> {};
188
189template <class T>
190constexpr bool is_awaitable_v =
191 has_member_operator_co_await_v<T> || has_non_member_operator_co_await_v<T> || is_awaiter_v<T>;
192
193template <class T>
194struct is_awaitable : std::bool_constant<is_awaitable_v<T>> {};
195
196} // namespace ll::traits
Definition TypeTraits.h:11
Definition TypeTraits.h:53
Definition TypeTraits.h:14
Definition TypeTraits.h:180
Definition TypeTraits.h:37
Definition TypeTraits.h:120
Definition TypeTraits.h:194
Definition TypeTraits.h:173
Definition TypeTraits.h:102
Definition TypeTraits.h:114
Definition TypeTraits.h:135
Definition TypeTraits.h:27