mpc
Haskell-like feature supports in C++
type_traits.hpp
Go to the documentation of this file.
1
2#pragma once
4
6namespace mpc::detail {
7 // make_reversed_index_sequence
8 // https://stackoverflow.com/questions/51408771/c-reversed-integer-sequence-implementation
9
11 template <std::size_t... Idx>
12 constexpr auto reversed_index_sequence_impl(std::index_sequence<Idx...> const&)
13 -> decltype(std::index_sequence<sizeof...(Idx) - 1U - Idx...>{});
15
17 template <std::size_t N>
18 using make_reversed_index_sequence = decltype(reversed_index_sequence_impl(std::make_index_sequence<N>{}));
19
20 // is_implicitly_default_constructible
21 // https://github.com/llvm/llvm-project/blob/main/libcxx/include/type_traits#L3025
22
24 template <class T>
25 void test_implicitly_default_constructible_impl(T);
26
27 template <class T, class = void>
28 struct is_implicitly_default_constructible_impl : std::false_type {};
29
30 template <class T>
31 struct is_implicitly_default_constructible_impl<
32 T, decltype(test_implicitly_default_constructible_impl<const T&>({}))> : std::true_type {};
34
36 template <class T>
38 : _and<std::is_default_constructible<T>, is_implicitly_default_constructible_impl<T>> {};
39
41 template <class T>
44
45 // is_explicitly_convertible
46 // https://github.com/llvm/llvm-project/blob/main/libcxx/include/__ranges/counted.h#L39
47
49 template <class, class, class = void>
50 struct is_explicitly_convertible : std::false_type {};
51
53 template <class From, class To>
54 struct is_explicitly_convertible<From, To, std::void_t<decltype(To(std::declval<From>()))>>
55 : std::true_type {};
56
58 template <class From, class To>
60
61 // is_implicitly_convertible
62 // https://github.com/llvm/llvm-project/blob/main/clang/test/Analysis/gtest.cpp#L43
63
65 template <class From, class To>
67 private:
68 using yes = char[1];
69 using no = char[2];
70 static std::add_lvalue_reference_t<From> make_from();
71 static yes& test(To);
72 static no& test(...);
73
74 public:
75 static const bool value = sizeof(test(is_implicitly_convertible::make_from())) == sizeof(yes);
76 };
77
79 template <class From, class To>
81
82 // Type modification traits
83 // https://github.com/vreverdy/type-utilities/blob/master/include/type_utilities.hpp
84
86 template <class From, class To>
87 struct copy_const {
88 using type = std::conditional_t<std::is_const_v<From>, std::add_const_t<To>, To>;
89 };
90
92 template <class From, class To>
93 struct clone_const {
94 using type = typename copy_const<From, std::remove_const_t<To>>::type;
95 };
96
98 template <class From, class To>
100 using type = std::conditional_t<std::is_volatile_v<From>, std::add_volatile_t<To>, To>;
101 };
102
104 template <class From, class To>
106 using type = typename copy_volatile<From, std::remove_volatile_t<To>>::type;
107 };
108
110 template <class From, class To>
111 struct copy_cv {
113 };
114
116 template <class From, class To>
117 struct clone_cv {
118 using type = typename copy_cv<From, std::remove_cv_t<To>>::type;
119 };
120
122 // clang-format off
123 template <class From, class To>
125 using type = std::conditional_t<
126 std::is_rvalue_reference_v<From>,
127 std::add_rvalue_reference_t<To>,
128 std::conditional_t<
129 std::is_lvalue_reference_v<From>,
130 std::add_lvalue_reference_t<To>,
131 To
132 >
133 >;
134 };
135 // clang-format on
136
138 template <class From, class To>
140 using type = typename copy_reference<From, std::remove_reference_t<To>>::type;
141 };
142
144 // clang-format off
145 template <class From, class To>
146 struct copy_cvref {
147 using type = typename copy_reference<
148 From,
149 typename copy_reference<
150 To,
151 typename copy_cv<
152 std::remove_reference_t<From>,
153 std::remove_reference_t<To>
154 >::type
155 >::type
156 >::type;
157 };
158 // clang-format on
159
161 template <class From, class To>
162 struct clone_cvref {
164 };
165
167 template <class From, class To>
168 using copy_const_t = typename copy_const<From, To>::type;
169
171 template <class From, class To>
172 using clone_const_t = typename clone_const<From, To>::type;
173
175 template <class From, class To>
176 using copy_volatile_t = typename copy_volatile<From, To>::type;
177
179 template <class From, class To>
180 using clone_volatile_t = typename clone_volatile<From, To>::type;
181
183 template <class From, class To>
184 using copy_cv_t = typename copy_cv<From, To>::type;
185
187 template <class From, class To>
188 using clone_cv_t = typename clone_cv<From, To>::type;
189
191 template <class From, class To>
192 using copy_reference_t = typename copy_reference<From, To>::type;
193
195 template <class From, class To>
196 using clone_reference_t = typename clone_reference<From, To>::type;
197
199 template <class From, class To>
200 using copy_cvref_t = typename copy_cvref<From, To>::type;
201
203 template <class From, class To>
204 using clone_cvref_t = typename clone_cvref<From, To>::type;
205} // namespace mpc::detail
Implementation details are here.
Definition: alternative.hpp:16
constexpr bool is_implicitly_convertible_v
A helper inline variable for is_implicitly_convertible.
Definition: type_traits.hpp:80
typename clone_reference< From, To >::type clone_reference_t
A helper alias template for clone_reference.
Definition: type_traits.hpp:196
decltype(reversed_index_sequence_impl(std::make_index_sequence< N >{})) make_reversed_index_sequence
make_reversed_index_sequence
Definition: type_traits.hpp:18
typename copy_cv< From, To >::type copy_cv_t
A helper alias template for copy_cv.
Definition: type_traits.hpp:184
typename copy_cvref< From, To >::type copy_cvref_t
A helper alias template for copy_cvref.
Definition: type_traits.hpp:200
constexpr bool is_explicitly_convertible_v
A helper inline variable for is_explicitly_convertible.
Definition: type_traits.hpp:59
typename copy_const< From, To >::type copy_const_t
A helper alias template for copy_const.
Definition: type_traits.hpp:168
constexpr bool is_implicitly_default_constructible_v
A helper inline variable for is_implicitly_default_constructible.
Definition: type_traits.hpp:42
typename clone_cv< From, To >::type clone_cv_t
A helper alias template for clone_cv.
Definition: type_traits.hpp:188
typename copy_volatile< From, To >::type copy_volatile_t
A helper alias template for copy_volatile.
Definition: type_traits.hpp:176
typename clone_const< From, To >::type clone_const_t
A helper alias template for clone_const.
Definition: type_traits.hpp:172
typename clone_volatile< From, To >::type clone_volatile_t
A helper alias template for clone_volatile.
Definition: type_traits.hpp:180
typename copy_reference< From, To >::type copy_reference_t
A helper alias template for copy_reference.
Definition: type_traits.hpp:192
typename clone_cvref< From, To >::type clone_cvref_t
A helper alias template for clone_cvref.
Definition: type_traits.hpp:204
std::conjunction< Bn... > _and
_and
Definition: stdfundamental.hpp:28
Clones the const qualifier.
Definition: type_traits.hpp:93
Clones cv qualifiers.
Definition: type_traits.hpp:117
Clones cv and reference qualifiers.
Definition: type_traits.hpp:162
Clones the reference qualifier.
Definition: type_traits.hpp:139
Clones the volatile qualifier.
Definition: type_traits.hpp:105
Copies the const qualifier.
Definition: type_traits.hpp:87
Copies cv qualifiers.
Definition: type_traits.hpp:111
Copies cv and reference qualifiers.
Definition: type_traits.hpp:146
Copies the reference qualifier.
Definition: type_traits.hpp:124
Copies the volatile qualifier.
Definition: type_traits.hpp:99
is_explicitly_convertible
Definition: type_traits.hpp:50
is_implicitly_convertible
Definition: type_traits.hpp:66
is_implicitly_default_constructible
Definition: type_traits.hpp:38