1 // Copyright 2020 The Pigweed Authors
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
7 // https://www.apache.org/licenses/LICENSE-2.0
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
16 #include "pw_polyfill/standard_library/namespace.h"
18 _PW_POLYFILL_BEGIN_NAMESPACE_STD
20 #define __cpp_lib_transformation_trait_aliases 201304L
21 #define __cpp_lib_type_trait_variable_templates 201510L
22 #define __cpp_lib_logical_traits 201510L
24 template <decltype(sizeof(0)) kLength,
25 decltype(sizeof(0)) kAlignment> // no default
26 struct aligned_storage {
28 alignas(kAlignment) unsigned char __data[kLength];
32 template <decltype(sizeof(0)) kLength,
33 decltype(sizeof(0)) kAlignment> // no default
34 using aligned_storage_t = typename aligned_storage<kLength, kAlignment>::type;
36 #define __cpp_lib_integral_constant_callable 201304L
38 template <typename T, T kValue>
39 struct integral_constant {
41 using type = integral_constant;
43 static constexpr T value = kValue;
45 constexpr operator value_type() const noexcept { return value; }
47 constexpr value_type operator()() const noexcept { return value; }
50 #define __cpp_lib_bool_constant 201505L
52 template <bool kValue>
53 using bool_constant = integral_constant<bool, kValue>;
55 using true_type = bool_constant<true>;
56 using false_type = bool_constant<false>;
59 struct is_array : false_type {};
62 struct is_array<T[]> : true_type {};
64 template <typename T, decltype(sizeof(int)) kSize>
65 struct is_array<T[kSize]> : true_type {};
68 inline constexpr bool is_array_v = is_array<T>::value;
71 struct is_const : false_type {};
74 struct is_const<const T> : true_type {};
76 // NOT IMPLEMENTED: is_enum requires compiler builtins.
78 struct is_enum : false_type {};
81 inline constexpr bool is_enum_v = is_enum<T>::value;
84 struct remove_cv; // Forward declaration
89 struct is_floating_point : false_type {};
92 struct is_floating_point<float> : true_type {};
94 struct is_floating_point<double> : true_type {};
96 struct is_floating_point<long double> : true_type {};
100 template <typename T>
101 struct is_floating_point
102 : impl::is_floating_point<typename remove_cv<T>::type> {};
104 template <typename T>
105 inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
109 template <typename T>
110 struct is_integral : false_type {};
113 struct is_integral<bool> : true_type {};
115 struct is_integral<char> : true_type {};
117 struct is_integral<char16_t> : true_type {};
119 struct is_integral<char32_t> : true_type {};
121 struct is_integral<wchar_t> : true_type {};
124 struct is_integral<short> : true_type {};
126 struct is_integral<unsigned short> : true_type {};
128 struct is_integral<int> : true_type {};
130 struct is_integral<unsigned int> : true_type {};
132 struct is_integral<long> : true_type {};
134 struct is_integral<unsigned long> : true_type {};
136 struct is_integral<long long> : true_type {};
138 struct is_integral<unsigned long long> : true_type {};
142 template <typename T>
143 struct is_integral : impl::is_integral<typename remove_cv<T>::type> {};
145 template <typename T>
146 inline constexpr bool is_integral_v = is_integral<T>::value;
148 template <typename T>
150 : bool_constant<is_integral_v<T> || is_floating_point_v<T>> {};
152 template <typename T>
153 inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
155 #define __cpp_lib_is_null_pointer 201309L
157 template <typename T>
158 struct is_null_pointer : false_type {};
161 struct is_null_pointer<decltype(nullptr)> : true_type {};
163 template <typename T>
164 inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
166 template <typename T>
167 struct is_pointer : false_type {};
169 template <typename T>
170 struct is_pointer<T*> : true_type {};
172 template <typename T>
173 inline constexpr bool is_pointer_v = is_pointer<T>::value;
175 template <typename T, typename U>
176 struct is_same : false_type {};
178 template <typename T>
179 struct is_same<T, T> : true_type {};
181 template <typename T, typename U>
182 inline constexpr bool is_same_v = is_same<T, U>::value;
186 template <typename T, bool = is_arithmetic<T>::value>
187 struct is_signed : integral_constant<bool, T(-1) < T(0)> {};
189 template <typename T>
190 struct is_signed<T, false> : false_type {};
194 template <typename T>
195 struct is_signed : impl::is_signed<T>::type {};
197 template <typename T>
198 inline constexpr bool is_signed_v = is_signed<T>::value;
200 template <typename T>
201 struct is_unsigned : bool_constant<!is_signed_v<T>> {};
203 template <typename T>
204 inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
206 template <typename T>
207 struct is_void : is_same<void, typename remove_cv<T>::type> {};
209 template <typename T>
210 inline constexpr bool is_void_v = is_void<T>::value;
212 template <typename T>
213 struct negation : bool_constant<!bool(T::value)> {};
215 template <typename T>
216 inline constexpr bool negation_v = negation<T>::value;
218 template <bool kBool, typename TrueType, typename FalseType>
220 using type = TrueType;
223 template <typename TrueType, typename FalseType>
224 struct conditional<false, TrueType, FalseType> {
225 using type = FalseType;
228 template <bool kBool, typename TrueType, typename FalseType>
229 using conditional_t = typename conditional<kBool, TrueType, FalseType>::type;
231 template <bool kEnable, typename T = void>
236 template <typename T>
237 struct enable_if<false, T> {};
239 template <bool kEnable, typename T = void>
240 using enable_if_t = typename enable_if<kEnable, T>::type;
242 template <typename T>
243 struct remove_const {
247 template <typename T>
248 struct remove_const<const T> {
252 template <typename T>
253 using remove_const_t = typename remove_const<T>::type;
255 template <typename T>
256 struct remove_volatile {
260 template <typename T>
261 struct remove_volatile<volatile T> {
265 template <typename T>
266 using remove_volatile_t = typename remove_volatile<T>::type;
268 template <typename T>
270 using type = remove_volatile_t<remove_const_t<T>>;
273 template <typename T>
274 using remove_cv_t = typename remove_cv<T>::type;
276 template <typename T>
277 struct remove_extent {
281 template <typename T>
282 struct remove_extent<T[]> {
286 template <typename T, decltype(sizeof(0)) kSize>
287 struct remove_extent<T[kSize]> {
291 template <typename T>
292 using remove_extent_t = typename remove_extent<T>::type;
294 template <typename T>
295 struct remove_pointer {
299 template <typename T>
300 struct remove_pointer<T*> {
304 template <typename T>
305 struct remove_pointer<T* const> {
309 template <typename T>
310 struct remove_pointer<T* volatile> {
314 template <typename T>
315 struct remove_pointer<T* const volatile> {
319 template <typename T>
320 using remove_pointer_t = typename remove_pointer<T>::type;
322 template <typename T>
323 struct remove_reference {
327 template <typename T>
328 struct remove_reference<T&> {
332 template <typename T>
333 struct remove_reference<T&&> {
337 template <typename T>
338 using remove_reference_t = typename remove_reference<T>::type;
340 // NOT IMPLEMENTED: This implementation is INCOMPLETE, as it does not cover
342 template <typename T>
345 using U = remove_reference_t<T>;
349 conditional_t<is_array<U>::value, remove_extent_t<U>*, remove_cv_t<U>>;
352 template <typename T>
353 using decay_t = typename decay<T>::type;
355 #define __cpp_lib_type_identity 201806
358 struct type_identity {
362 template <typename T>
363 using type_identity_t = typename type_identity<T>::type;
365 #define __cpp_lib_void_t void_t 201411L
367 template <typename...>
372 template <typename T>
373 type_identity<T&> AddLValueReference(int);
375 template <typename T>
376 type_identity<T> AddLValueReference(...);
378 template <typename T>
379 type_identity<T&&> AddRValueReference(int);
381 template <typename T>
382 type_identity<T> AddRValueReference(...);
387 struct add_lvalue_reference : decltype(impl::AddLValueReference<T>(0)) {};
389 template <typename T>
390 using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
393 struct add_rvalue_reference : decltype(impl::AddRValueReference<T>(0)) {};
395 template <typename T>
396 using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
398 template <typename T>
399 add_rvalue_reference_t<T> declval() noexcept;
404 using templated_true = true_type;
406 template <typename T>
407 auto returnable(int) -> templated_true<T()>;
410 auto returnable(...) -> false_type;
412 template <typename From, typename To>
413 auto convertible(int)
414 -> templated_true<decltype(declval<void (&)(To)>()(declval<From>()))>;
416 template <typename, typename>
417 auto convertible(...) -> false_type;
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>)> {};
427 template <typename T, typename U>
428 inline constexpr bool is_convertible_v = is_convertible<T, U>::value;
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 {
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;
453 _PW_POLYFILL_END_NAMESPACE_STD