Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_minimal_cpp_stdlib / public / internal / type_traits.h
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15
16 #include "pw_polyfill/standard_library/namespace.h"
17
18 _PW_POLYFILL_BEGIN_NAMESPACE_STD
19
20 #define __cpp_lib_transformation_trait_aliases 201304L
21 #define __cpp_lib_type_trait_variable_templates 201510L
22 #define __cpp_lib_logical_traits 201510L
23
24 template <decltype(sizeof(0)) kLength,
25           decltype(sizeof(0)) kAlignment>  // no default
26 struct aligned_storage {
27   struct type {
28     alignas(kAlignment) unsigned char __data[kLength];
29   };
30 };
31
32 template <decltype(sizeof(0)) kLength,
33           decltype(sizeof(0)) kAlignment>  // no default
34 using aligned_storage_t = typename aligned_storage<kLength, kAlignment>::type;
35
36 #define __cpp_lib_integral_constant_callable 201304L
37
38 template <typename T, T kValue>
39 struct integral_constant {
40   using value_type = T;
41   using type = integral_constant;
42
43   static constexpr T value = kValue;
44
45   constexpr operator value_type() const noexcept { return value; }
46
47   constexpr value_type operator()() const noexcept { return value; }
48 };
49
50 #define __cpp_lib_bool_constant 201505L
51
52 template <bool kValue>
53 using bool_constant = integral_constant<bool, kValue>;
54
55 using true_type = bool_constant<true>;
56 using false_type = bool_constant<false>;
57
58 template <typename T>
59 struct is_array : false_type {};
60
61 template <typename T>
62 struct is_array<T[]> : true_type {};
63
64 template <typename T, decltype(sizeof(int)) kSize>
65 struct is_array<T[kSize]> : true_type {};
66
67 template <typename T>
68 inline constexpr bool is_array_v = is_array<T>::value;
69
70 template <typename T>
71 struct is_const : false_type {};
72
73 template <typename T>
74 struct is_const<const T> : true_type {};
75
76 // NOT IMPLEMENTED: is_enum requires compiler builtins.
77 template <typename T>
78 struct is_enum : false_type {};
79
80 template <typename T>
81 inline constexpr bool is_enum_v = is_enum<T>::value;
82
83 template <typename T>
84 struct remove_cv;  // Forward declaration
85
86 namespace impl {
87
88 template <typename T>
89 struct is_floating_point : false_type {};
90
91 template <>
92 struct is_floating_point<float> : true_type {};
93 template <>
94 struct is_floating_point<double> : true_type {};
95 template <>
96 struct is_floating_point<long double> : true_type {};
97
98 }  // namespace impl
99
100 template <typename T>
101 struct is_floating_point
102     : impl::is_floating_point<typename remove_cv<T>::type> {};
103
104 template <typename T>
105 inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
106
107 namespace impl {
108
109 template <typename T>
110 struct is_integral : false_type {};
111
112 template <>
113 struct is_integral<bool> : true_type {};
114 template <>
115 struct is_integral<char> : true_type {};
116 template <>
117 struct is_integral<char16_t> : true_type {};
118 template <>
119 struct is_integral<char32_t> : true_type {};
120 template <>
121 struct is_integral<wchar_t> : true_type {};
122
123 template <>
124 struct is_integral<short> : true_type {};
125 template <>
126 struct is_integral<unsigned short> : true_type {};
127 template <>
128 struct is_integral<int> : true_type {};
129 template <>
130 struct is_integral<unsigned int> : true_type {};
131 template <>
132 struct is_integral<long> : true_type {};
133 template <>
134 struct is_integral<unsigned long> : true_type {};
135 template <>
136 struct is_integral<long long> : true_type {};
137 template <>
138 struct is_integral<unsigned long long> : true_type {};
139
140 }  // namespace impl
141
142 template <typename T>
143 struct is_integral : impl::is_integral<typename remove_cv<T>::type> {};
144
145 template <typename T>
146 inline constexpr bool is_integral_v = is_integral<T>::value;
147
148 template <typename T>
149 struct is_arithmetic
150     : bool_constant<is_integral_v<T> || is_floating_point_v<T>> {};
151
152 template <typename T>
153 inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
154
155 #define __cpp_lib_is_null_pointer 201309L
156
157 template <typename T>
158 struct is_null_pointer : false_type {};
159
160 template <>
161 struct is_null_pointer<decltype(nullptr)> : true_type {};
162
163 template <typename T>
164 inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
165
166 template <typename T>
167 struct is_pointer : false_type {};
168
169 template <typename T>
170 struct is_pointer<T*> : true_type {};
171
172 template <typename T>
173 inline constexpr bool is_pointer_v = is_pointer<T>::value;
174
175 template <typename T, typename U>
176 struct is_same : false_type {};
177
178 template <typename T>
179 struct is_same<T, T> : true_type {};
180
181 template <typename T, typename U>
182 inline constexpr bool is_same_v = is_same<T, U>::value;
183
184 namespace impl {
185
186 template <typename T, bool = is_arithmetic<T>::value>
187 struct is_signed : integral_constant<bool, T(-1) < T(0)> {};
188
189 template <typename T>
190 struct is_signed<T, false> : false_type {};
191
192 }  // namespace impl
193
194 template <typename T>
195 struct is_signed : impl::is_signed<T>::type {};
196
197 template <typename T>
198 inline constexpr bool is_signed_v = is_signed<T>::value;
199
200 template <typename T>
201 struct is_unsigned : bool_constant<!is_signed_v<T>> {};
202
203 template <typename T>
204 inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
205
206 template <typename T>
207 struct is_void : is_same<void, typename remove_cv<T>::type> {};
208
209 template <typename T>
210 inline constexpr bool is_void_v = is_void<T>::value;
211
212 template <typename T>
213 struct negation : bool_constant<!bool(T::value)> {};
214
215 template <typename T>
216 inline constexpr bool negation_v = negation<T>::value;
217
218 template <bool kBool, typename TrueType, typename FalseType>
219 struct conditional {
220   using type = TrueType;
221 };
222
223 template <typename TrueType, typename FalseType>
224 struct conditional<false, TrueType, FalseType> {
225   using type = FalseType;
226 };
227
228 template <bool kBool, typename TrueType, typename FalseType>
229 using conditional_t = typename conditional<kBool, TrueType, FalseType>::type;
230
231 template <bool kEnable, typename T = void>
232 struct enable_if {
233   using type = T;
234 };
235
236 template <typename T>
237 struct enable_if<false, T> {};
238
239 template <bool kEnable, typename T = void>
240 using enable_if_t = typename enable_if<kEnable, T>::type;
241
242 template <typename T>
243 struct remove_const {
244   using type = T;
245 };
246
247 template <typename T>
248 struct remove_const<const T> {
249   using type = T;
250 };
251
252 template <typename T>
253 using remove_const_t = typename remove_const<T>::type;
254
255 template <typename T>
256 struct remove_volatile {
257   using type = T;
258 };
259
260 template <typename T>
261 struct remove_volatile<volatile T> {
262   using type = T;
263 };
264
265 template <typename T>
266 using remove_volatile_t = typename remove_volatile<T>::type;
267
268 template <typename T>
269 struct remove_cv {
270   using type = remove_volatile_t<remove_const_t<T>>;
271 };
272
273 template <typename T>
274 using remove_cv_t = typename remove_cv<T>::type;
275
276 template <typename T>
277 struct remove_extent {
278   using type = T;
279 };
280
281 template <typename T>
282 struct remove_extent<T[]> {
283   using type = T;
284 };
285
286 template <typename T, decltype(sizeof(0)) kSize>
287 struct remove_extent<T[kSize]> {
288   using type = T;
289 };
290
291 template <typename T>
292 using remove_extent_t = typename remove_extent<T>::type;
293
294 template <typename T>
295 struct remove_pointer {
296   using type = T;
297 };
298
299 template <typename T>
300 struct remove_pointer<T*> {
301   using type = T;
302 };
303
304 template <typename T>
305 struct remove_pointer<T* const> {
306   using type = T;
307 };
308
309 template <typename T>
310 struct remove_pointer<T* volatile> {
311   using type = T;
312 };
313
314 template <typename T>
315 struct remove_pointer<T* const volatile> {
316   using type = T;
317 };
318
319 template <typename T>
320 using remove_pointer_t = typename remove_pointer<T>::type;
321
322 template <typename T>
323 struct remove_reference {
324   using type = T;
325 };
326
327 template <typename T>
328 struct remove_reference<T&> {
329   using type = T;
330 };
331
332 template <typename T>
333 struct remove_reference<T&&> {
334   using type = T;
335 };
336
337 template <typename T>
338 using remove_reference_t = typename remove_reference<T>::type;
339
340 // NOT IMPLEMENTED: This implementation is INCOMPLETE, as it does not cover
341 // function types.
342 template <typename T>
343 struct decay {
344  private:
345   using U = remove_reference_t<T>;
346
347  public:
348   using type =
349       conditional_t<is_array<U>::value, remove_extent_t<U>*, remove_cv_t<U>>;
350 };
351
352 template <typename T>
353 using decay_t = typename decay<T>::type;
354
355 #define __cpp_lib_type_identity 201806
356
357 template <class T>
358 struct type_identity {
359   using type = T;
360 };
361
362 template <typename T>
363 using type_identity_t = typename type_identity<T>::type;
364
365 #define __cpp_lib_void_t void_t 201411L
366
367 template <typename...>
368 using void_t = void;
369
370 namespace impl {
371
372 template <typename T>
373 type_identity<T&> AddLValueReference(int);
374
375 template <typename T>
376 type_identity<T> AddLValueReference(...);
377
378 template <typename T>
379 type_identity<T&&> AddRValueReference(int);
380
381 template <typename T>
382 type_identity<T> AddRValueReference(...);
383
384 }  // namespace impl
385
386 template <class T>
387 struct add_lvalue_reference : decltype(impl::AddLValueReference<T>(0)) {};
388
389 template <typename T>
390 using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
391
392 template <class T>
393 struct add_rvalue_reference : decltype(impl::AddRValueReference<T>(0)) {};
394
395 template <typename T>
396 using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
397
398 template <typename T>
399 add_rvalue_reference_t<T> declval() noexcept;
400
401 namespace impl {
402
403 template <typename>
404 using templated_true = true_type;
405
406 template <typename T>
407 auto returnable(int) -> templated_true<T()>;
408
409 template <typename>
410 auto returnable(...) -> false_type;
411
412 template <typename From, typename To>
413 auto convertible(int)
414     -> templated_true<decltype(declval<void (&)(To)>()(declval<From>()))>;
415
416 template <typename, typename>
417 auto convertible(...) -> false_type;
418
419 }  // namespace impl
420
421 template <typename From, typename To>
422 struct is_convertible
423     : bool_constant<(decltype(impl::returnable<To>(0))() &&
424                      decltype(impl::convertible<From, To>(0))()) ||
425                     (is_void_v<From> && is_void_v<To>)> {};
426
427 template <typename T, typename U>
428 inline constexpr bool is_convertible_v = is_convertible<T, U>::value;
429
430 // NOT IMPLEMENTED: Stubs are provided for these traits classes, but they do not
431 // return useful values. Many of these would require compiler builtins.
432 template <typename T>
433 struct is_function : false_type {};
434 template <typename T>
435 struct is_trivially_copyable : true_type {};
436 template <typename T>
437 struct is_polymorphic : false_type {};
438 template <typename T, typename U>
439 struct is_base_of : false_type {};
440 template <typename T>
441 struct extent : integral_constant<decltype(sizeof(int)), 1> {};
442 template <typename T>
443 inline constexpr bool extent_v = extent<T>::value;
444 template <typename T>
445 struct underlying_type {
446   using type = T;
447 };
448 template <typename T>
449 using underlying_type_t = typename underlying_type<T>::type;
450 template <typename T>
451 inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
452
453 _PW_POLYFILL_END_NAMESPACE_STD