Sequoia
Loading...
Searching...
No Matches
TypeTraits.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2018. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
10#include <array>
11#include <concepts>
12#include <iterator>
13#include <type_traits>
14#include <tuple>
15#include <utility>
16#include <variant>
17
23namespace sequoia
24{
26 template<class T>
27 struct dependent_false : std::false_type {};
28
30 template<class T, class... Args>
32 : std::bool_constant<
33 (sizeof...(Args) == 1)
34 && (std::is_same_v<std::remove_cvref_t<Args>, std::remove_cvref_t<T>> && ...)
35 >
36 {};
37
38 template<class T, class... Args>
39 inline constexpr bool resolve_to_copy_v{resolve_to_copy<T, Args...>::value};
40
41 template<class T, class... Args>
42 using resolve_to_copy_t = typename resolve_to_copy<T, Args...>::type;
43
44
46 template<class T>
47 struct is_const_pointer : std::false_type {};
48
49 template<class T>
50 struct is_const_pointer<const T*> : std::true_type {};
51
52 template<class T>
53 struct is_const_pointer<const T* volatile> : std::true_type {};
54
55 template<class T>
56 struct is_const_pointer<const T* const> : std::true_type {};
57
58 template<class T>
59 struct is_const_pointer<const T* const volatile> : std::true_type {};
60
61 template<class T>
62 inline constexpr bool is_const_pointer_v{is_const_pointer<T>::value};
63
64 template<class T>
65 using is_const_pointer_t = typename is_const_pointer<T>::type;
66
68 template<class T>
70 : std::bool_constant<std::is_reference_v<T> && std::is_const_v<std::remove_reference_t<T>>>
71 {};
72
73 template<class T>
74 inline constexpr bool is_const_reference_v{is_const_reference<T>::value};
75
76 template<class T>
77 using is_const_reference_t = typename is_const_reference<T>::type;
78
80 template<class T>
81 struct is_tuple : std::false_type{};
82
83 template<class... Ts>
84 struct is_tuple<std::tuple<Ts...>> : std::true_type{};
85
86 template<class... Ts>
87 using is_tuple_t = typename is_tuple<Ts...>::type;
88
89 template<class... Ts>
90 inline constexpr bool is_tuple_v{is_tuple<Ts...>::value};
91
95 template<class T, class... Args>
96 struct is_initializable : std::false_type
97 {};
98
99 template<class T, class... Args>
100 requires requires (Args&&... args) { T{std::forward<Args>(args)...}; }
101 struct is_initializable<T, Args...> : std::true_type {};
102
103 template<class T, class... Args>
104 using is_initializable_t = typename is_initializable<T, Args...>::type;
105
106 template<class T, class... Args>
107 inline constexpr bool is_initializable_v{is_initializable<T, Args...>::value};
108
109
111 template<class T>
112 struct has_allocator_type : std::bool_constant< requires { typename T::allocator_type; } >
113 {};
114
115 template<class T>
116 using has_allocator_type_t = typename has_allocator_type<T>::type;
117
118 template<class T>
119 inline constexpr bool has_allocator_type_v{has_allocator_type<T>::value};
120
122 template<class T>
123 inline constexpr bool has_value_type_v{requires { typename T::value_type; }};
124
126 template<class T>
127 inline constexpr bool has_element_type_v{requires { typename T::element_type; }};
128
129 // Machinery for deep equality checking, which will hopefully one day
130 // be obviated if the stl properly constrains operator==
131
144 template<class T>
145 inline constexpr bool has_gettable_elements{requires (T & t) { std::get<0>(t); }};
146
147 template<class T>
148 struct is_deep_equality_comparable;
149
150 template<class T, std::size_t... I>
151 inline constexpr bool heterogeneous_deep_equality_v{
152 requires(T & t, std::index_sequence<I...>) {
153 requires (is_deep_equality_comparable<std::remove_cvref_t<decltype(std::get<I>(t))>>::value && ...);
154 }
155 };
156
157 template<class T, std::size_t...I>
158 constexpr bool has_heterogeneous_deep_equality(std::index_sequence<I...>)
159 {
160 return heterogeneous_deep_equality_v<T, I...>;
161 }
162
163 template<class T>
165
166 template<template<class...> class T, class... Ts>
168 : std::bool_constant<has_heterogeneous_deep_equality<T<Ts...>>(std::make_index_sequence<sizeof...(Ts)>{})>
169 {};
170
171 template<class T>
172 struct is_deep_equality_comparable : std::bool_constant<std::equality_comparable<T> && !std::is_array_v<T>>
173 {};
174
175 template<class T>
176 requires has_value_type_v<T>
177 struct is_deep_equality_comparable<T> : std::bool_constant<std::equality_comparable<T>&& is_deep_equality_comparable<typename T::value_type>::value>
178 {};
179
180 template<template<class...> class T, class... Ts>
181 requires (!has_value_type_v<T<Ts...>> && has_gettable_elements<T<Ts...>>)
182 struct is_deep_equality_comparable<T<Ts...>> : std::bool_constant<std::equality_comparable<T<Ts...>> && heterogeneous_deep_equality<T<Ts...>>::value>
183 {};
184
185 template<class T>
186 inline constexpr bool is_deep_equality_comparable_v{is_deep_equality_comparable<T>::value};
187
188 template<class T>
189 using is_deep_equality_comparable_t = typename is_deep_equality_comparable<T>::type;
190 // end of deep_equality group
192
202 template<std::floating_point T, class U>
203 struct is_compatible : std::bool_constant<!std::is_same_v<U, bool> && ((std::floating_point<U> && is_initializable_v<T, U>) || std::is_integral_v<U>)> {};
204
205 template<std::floating_point T, class U>
206 using is_compatible_t = typename is_compatible<T, U>::type;
207
208 template<std::floating_point T, class U>
209 inline constexpr bool is_compatible_v{is_compatible<T, U>::value};
210}
constexpr bool has_value_type_v
Checks for dependent type value_type
Definition: TypeTraits.hpp:123
constexpr bool has_element_type_v
Checks for dependent type element_type
Definition: TypeTraits.hpp:127
Standard meta-programming utility.
Definition: TypeTraits.hpp:27
Class template for determining if a type defines a nested type allocator_type
Definition: TypeTraits.hpp:113
Definition: TypeTraits.hpp:164
class template for determining if a type is compatible with a floating-point type.
Definition: TypeTraits.hpp:203
Primary class template for determining if a type is a const pointer.
Definition: TypeTraits.hpp:47
class template for determining if a type is a const reference
Definition: TypeTraits.hpp:71
Definition: TypeTraits.hpp:173
Primary class template for determining if a type can be brace-initialized by Args....
Definition: TypeTraits.hpp:97
Primary class template for determining if a type is a std::tuple
Definition: TypeTraits.hpp:81
class template for determining whether a constructor template should resolve to the copy constructor
Definition: TypeTraits.hpp:36