Tatooine
type_traits.h
Go to the documentation of this file.
1#ifndef TATOOINE_TYPE_TRAITS_H
2#define TATOOINE_TYPE_TRAITS_H
3//==============================================================================
5#include <tatooine/void_t.h>
6
7#include <array>
8#include <complex>
9#include <type_traits>
10//==============================================================================
11namespace tatooine {
12//==============================================================================
13template <typename T, std::size_t = sizeof(T)>
14auto type_exists_impl(T*) -> std::true_type;
15auto type_exists_impl(...) -> std::false_type;
16
17template <typename T>
18static constexpr auto type_exists =
19 decltype(type_exists_impl(std::declval<T*>()))::value;
20//==============================================================================
21template <typename T>
22static constexpr auto is_pointer = std::is_pointer<T>::value;
23//==============================================================================
24template <typename T>
25struct is_array_impl : std::false_type {};
26template <typename T, std::size_t N>
27struct is_array_impl<std::array<T, N>> : std::true_type {};
28template <typename T>
29static auto constexpr is_array = is_array_impl<T>::value;
30//==============================================================================
31template <typename... Ts>
33template <typename T0, typename T1, typename T2, typename... Ts>
34struct is_same_impl<T0, T1, T2, Ts...>
35 : std::integral_constant<bool, is_same_impl<T0, T1>::value &&
36 is_same_impl<T1, T2, Ts...>::value> {};
37template <typename T0, typename T1>
38struct is_same_impl<T0, T1> : std::is_same<T0, T1> {};
39template <typename T0>
40struct is_same_impl<T0> : std::true_type {};
41template <typename... Ts>
42static constexpr auto is_same = is_same_impl<Ts...>::value;
43//==============================================================================
44template <typename... Ts>
45static constexpr auto is_void = (is_same<Ts, void> && ...);
46//==============================================================================
47template <typename... Ts>
48static constexpr auto is_float = (is_same<Ts, float> && ...);
49//==============================================================================
50template <typename... Ts>
51static constexpr auto is_double = (is_same<Ts, double> && ...);
52//==============================================================================
53template <typename... Ts>
54static constexpr auto is_int = (is_same<Ts, int> && ...);
55//==============================================================================
56template <typename... Ts>
57static constexpr auto is_size_t = (is_same<Ts, size_t> && ...);
58//==============================================================================
59template <typename Query, typename... Others>
60static constexpr auto is_either_of = (is_same<Query, Others> || ...);
61//==============================================================================
62template <typename F, typename... Args>
63using invoke_result = std::invoke_result_t<F, Args...>;
64//==============================================================================
65template <typename F, typename... Args>
66static constexpr auto is_invocable = std::is_invocable<F, Args...>::value;
67// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
68template <typename R, typename F, typename... Args>
69static constexpr auto is_invocable_r = std::is_invocable<R, F, Args...>::value;
70//==============================================================================
71template <typename F, typename... Ts>
72static constexpr auto is_predicate =
73 is_same<bool, std::invoke_result_t<F, Ts...>>;
74//==============================================================================
75template <typename... Ts>
76static constexpr auto is_floating_point = (std::is_floating_point<Ts>::value &&
77 ...);
78//------------------------------------------------------------------------------
79template <typename... Ts>
80static constexpr auto is_arithmetic = (std::is_arithmetic<Ts>::value && ...);
81//------------------------------------------------------------------------------
82template <typename... Ts>
83static constexpr auto is_integral = (std::is_integral<Ts>::value && ...);
84//------------------------------------------------------------------------------
85template <typename... Ts>
86static constexpr auto is_const = (std::is_const<Ts>::value && ...);
87//------------------------------------------------------------------------------
88template <typename... Ts>
89static constexpr auto is_non_const = (!std::is_const<Ts>::value && ...);
90//------------------------------------------------------------------------------
91template <typename... Ts>
92static constexpr auto is_signed = (std::is_signed<Ts>::value && ...);
93//------------------------------------------------------------------------------
94template <typename... Ts>
95static constexpr auto is_unsigned = (std::is_unsigned<Ts>::value && ...);
96//------------------------------------------------------------------------------
97template <typename... Ts>
98static constexpr auto is_signed_integral = ((is_signed<Ts> && ...) &&
99 (is_integral<Ts> && ...));
100//------------------------------------------------------------------------------
101template <typename... Ts>
102static constexpr auto is_unsigned_integral = ((is_unsigned<Ts> && ...) &&
103 (is_integral<Ts> && ...));
104//------------------------------------------------------------------------------
105template <typename From, typename To>
106static constexpr auto is_convertible = std::is_convertible<From, To>::value;
107//------------------------------------------------------------------------------
108template <typename From>
109static constexpr auto is_convertible_to_integral =
110 is_convertible<From, bool> || is_convertible<From, char> ||
111 is_convertible<From, unsigned char> || is_convertible<From, char16_t> ||
112 is_convertible<From, char32_t> || is_convertible<From, wchar_t> ||
113 is_convertible<From, unsigned short> || is_convertible<From, short> ||
114 is_convertible<From, int> || is_convertible<From, unsigned int> ||
115 is_convertible<From, long> || is_convertible<From, unsigned long>;
116//------------------------------------------------------------------------------
117template <typename From>
118static constexpr auto is_convertible_to_floating_point =
119 is_convertible<From, float> || is_convertible<From, double> ||
120 is_convertible<From, long double>;
121//------------------------------------------------------------------------------
122template <typename T>
123struct is_complex_impl : std::false_type {};
124// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
125template <typename... Ts>
126static constexpr auto is_complex = (is_complex_impl<Ts>::value && ...);
127// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
128template <typename... Ts>
129static constexpr auto is_arithmetic_or_complex = ((is_arithmetic<Ts> ||
130 is_complex<Ts>)&&...);
131// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
132template <typename T>
133struct is_complex_impl<std::complex<T>> : std::true_type {};
134//------------------------------------------------------------------------------
135template <typename T, typename = void>
136struct is_range_impl : std::false_type {};
137// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
138template <typename T>
139struct is_range_impl<T, void_t<decltype(std::declval<T>().begin()),
140 decltype(std::declval<T>().end())>>
141 : std::true_type {};
142// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
143template <typename... Ts>
144static constexpr auto is_range = (is_range_impl<Ts>::value && ...);
145//------------------------------------------------------------------------------
146template <typename T, typename = void>
147struct is_indexable_impl : std::false_type {};
148// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
149template <typename T>
150struct is_indexable_impl<T, void_t<decltype(std::declval<T>().at(size_t{})),
151 decltype(std::declval<T>()[size_t{}])>>
152 : std::true_type {};
153// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
154template <typename... Ts>
155static constexpr auto is_indexable = (is_indexable_impl<Ts>::value && ...);
156//------------------------------------------------------------------------------
157template <typename T, typename = void>
158struct is_dereferencable_impl : std::false_type {};
159// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
160template <typename T>
161struct is_dereferencable_impl<T*> : std::true_type {};
162// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
163template <typename T>
164struct is_dereferencable_impl<T, void_t<decltype(*std::declval<T>())>>
165 : std::true_type {};
166// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
167template <typename... Ts>
169 ...);
170//------------------------------------------------------------------------------
171template <typename T, typename = void>
172struct is_post_incrementable_impl : std::false_type {};
173// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
174template <typename T>
175struct is_post_incrementable_impl<T, void_t<decltype(std::declval<T>()++)>>
176 : std::true_type {};
177// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
178template <typename T>
179struct is_post_incrementable_impl<T*> : std::true_type {};
180// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
181template <typename T>
182struct is_post_incrementable_impl<T const*> : std::true_type {};
183// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
184template <typename... Ts>
185static constexpr auto is_post_incrementable =
187//------------------------------------------------------------------------------
188template <typename T, typename = void>
189struct is_pre_incrementable_impl : std::false_type {};
190// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
191template <typename T>
192struct is_pre_incrementable_impl<T, void_t<decltype(++std::declval<T>())>>
193 : std::true_type {};
194// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
195template <typename T>
196struct is_pre_incrementable_impl<T*> : std::true_type {};
197// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
198template <typename T>
199struct is_pre_incrementable_impl<T const*> : std::true_type {};
200// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
201template <typename T>
202static constexpr auto is_pre_incrementable =
204//------------------------------------------------------------------------------
205template <typename T, typename = void>
206struct is_post_decrementable_impl : std::false_type {};
207// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
208template <typename T>
209struct is_post_decrementable_impl<T, void_t<decltype(std::declval<T>()--)>>
210 : std::true_type {};
211// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
212template <typename T>
213struct is_post_decrementable_impl<T*> : std::true_type {};
214// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
215template <typename T>
216struct is_post_decrementable_impl<T const*> : std::true_type {};
217// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
218template <typename T>
219static constexpr auto is_post_decrementable =
221//------------------------------------------------------------------------------
222template <typename T, typename = void>
223struct is_pre_decrementable_impl : std::false_type {};
224// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
225template <typename T>
226struct is_pre_decrementable_impl<T, void_t<decltype(--std::declval<T>())>>
227 : std::true_type {};
228// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
229template <typename T>
230struct is_pre_decrementable_impl<T*> : std::true_type {};
231// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
232template <typename T>
233struct is_pre_decrementable_impl<T const*> : std::true_type {};
234// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
235template <typename T>
236static constexpr auto is_pre_decrementable =
238//------------------------------------------------------------------------------
239template <typename T, typename S, typename = void>
240struct are_equality_comparable_impl : std::false_type {};
241// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
242template <typename T, typename S>
244 T, S, void_t<decltype(std::declval<T>() == std::declval<S>())>>
245 : std::true_type {};
246// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
247template <typename T, typename S>
248static constexpr auto are_equality_comparable =
250//------------------------------------------------------------------------------
251template <typename T>
252static constexpr auto is_forward_iterator = are_equality_comparable<T, T>&&
253 is_pre_incrementable<T>&& is_dereferencable<T>;
254//------------------------------------------------------------------------------
255template <typename T>
256static constexpr auto is_backward_iterator = are_equality_comparable<T, T>&&
257 is_pre_decrementable<T>&& is_dereferencable<T>;
258//------------------------------------------------------------------------------
259template <typename T>
260static constexpr auto is_bidirectional_iterator =
261 are_equality_comparable<T, T>&& is_pre_incrementable<T>&&
262 is_pre_decrementable<T>&& is_dereferencable<T>;
263//==============================================================================
264template <typename T>
266//------------------------------------------------------------------------------
267template <typename T>
268requires requires { typename std::decay_t<T>::value_type; }
270 using type = typename std::decay_t<T>::value_type;
271};
272//------------------------------------------------------------------------------
273template <typename T>
274requires is_arithmetic<T>
275struct value_type_impl<T> {
276 using type = T;
277};
278//------------------------------------------------------------------------------
279template <typename T>
281//==============================================================================
282template <typename T>
283struct is_pair_impl : std::false_type {};
284//------------------------------------------------------------------------------
285template <typename First, typename Second>
286struct is_pair_impl<std::pair<First, Second>> : std::true_type {};
287//------------------------------------------------------------------------------
288template <typename T>
289static constexpr auto is_pair = is_pair_impl<T>::value;
290//==============================================================================
291} // namespace tatooine
292//==============================================================================
293#endif
Definition: algorithm.h:6
static constexpr auto is_post_decrementable
Definition: type_traits.h:219
static constexpr auto is_either_of
Definition: type_traits.h:60
static constexpr auto is_pre_incrementable
Definition: type_traits.h:202
auto begin(Range &&range)
Definition: iterator_facade.h:318
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
static constexpr auto is_integral
Definition: type_traits.h:83
static constexpr auto is_unsigned_integral
Definition: type_traits.h:102
static constexpr auto is_indexable
Definition: type_traits.h:155
static constexpr auto is_void
Definition: type_traits.h:45
static constexpr auto is_post_incrementable
Definition: type_traits.h:185
std::invoke_result_t< F, Args... > invoke_result
Definition: concepts.h:127
static constexpr auto is_signed_integral
Definition: type_traits.h:98
static constexpr auto is_arithmetic
Definition: type_traits.h:80
auto type_exists_impl(T *) -> std::true_type
static constexpr auto is_predicate
Definition: type_traits.h:72
void void_t
Definition: void_t.h:7
static constexpr auto is_range
Definition: type_traits.h:144
static constexpr auto is_const
Definition: type_traits.h:86
static constexpr auto is_size_t
Definition: type_traits.h:57
static constexpr auto is_arithmetic_or_complex
Definition: type_traits.h:129
static constexpr auto is_bidirectional_iterator
Definition: type_traits.h:260
static constexpr auto is_floating_point
Definition: type_traits.h:76
static constexpr auto is_convertible_to_floating_point
Definition: type_traits.h:118
static constexpr auto is_backward_iterator
Definition: type_traits.h:256
static constexpr auto is_complex
Definition: type_traits.h:126
static constexpr auto is_convertible
Definition: type_traits.h:106
static auto constexpr is_array
Definition: type_traits.h:29
static constexpr auto is_same
Definition: type_traits.h:42
static constexpr auto is_int
Definition: type_traits.h:54
static constexpr auto is_float
Definition: type_traits.h:48
static constexpr auto is_convertible_to_integral
Definition: type_traits.h:109
static constexpr auto is_dereferencable
Definition: type_traits.h:168
static constexpr auto is_invocable_r
Definition: type_traits.h:69
static constexpr auto is_invocable
Definition: type_traits.h:66
static constexpr auto is_pre_decrementable
Definition: type_traits.h:236
static constexpr auto is_pointer
Definition: type_traits.h:22
static constexpr auto is_pair
Definition: type_traits.h:289
static constexpr auto is_forward_iterator
Definition: type_traits.h:252
static constexpr auto is_unsigned
Definition: type_traits.h:95
static constexpr auto type_exists
Definition: type_traits.h:18
static constexpr auto is_non_const
Definition: type_traits.h:89
static constexpr auto are_equality_comparable
Definition: type_traits.h:248
static constexpr auto is_double
Definition: type_traits.h:51
static constexpr auto is_signed
Definition: type_traits.h:92
Definition: type_traits.h:240
T type
Definition: common_type.h:13
Definition: type_traits.h:25
Definition: type_traits.h:123
Definition: type_traits.h:158
Definition: type_traits.h:147
Definition: type_traits.h:283
Definition: type_traits.h:206
Definition: type_traits.h:172
Definition: type_traits.h:223
Definition: type_traits.h:189
Definition: type_traits.h:136
Definition: type_traits.h:32
typename std::decay_t< T >::value_type type
Definition: type_traits.h:270
Definition: type_traits.h:265