mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Add etl::is_standard_layout and other type traits according to std (#1545)
* Update _index.md * Update _index.md * Cherry pick the Docker fixes for PowerPC (#1563) Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com> * Add etl::is_standard_layout and further type traits Added type traits: * etl::is_standard_layout * etl::is_null_pointer * etl::is_union * etl::is_scalar * etl::is_empty * etl::is_polymorphic * etl::is_abstract * etl::is_final * etl::is_aggregate * etl::is_destructible * etl::is_nothrow_destructible * etl::has_virtual_destructor * etl::is_swappable * etl::is_swappable_with * etl::is_nothrow_swappable * etl::is_nothrow_swappable_with * etl::has_unique_object_representation * etl::is_bounded_array * etl::is_unbounded_array * etl::is_trivial Document etl::is_pod Note that etl::swap needed adjustment to enable nothrow detection via SFINAE constraints. This change closes in to the standard. * Fix preprocessor directive formatting in header --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
This commit is contained in:
parent
25e2d6e8a3
commit
fa3ac28f55
@ -32,6 +32,26 @@ Not all traits have been defined as some rely on compiler intrinsics that are no
|
|||||||
`is_compound`
|
`is_compound`
|
||||||
`is_array`
|
`is_array`
|
||||||
`is_pointer`
|
`is_pointer`
|
||||||
|
`is_null_pointer`
|
||||||
|
`is_scalar`
|
||||||
|
`is_union`
|
||||||
|
`is_empty`
|
||||||
|
`is_polymorphic`
|
||||||
|
`is_abstract`
|
||||||
|
`is_final`
|
||||||
|
`is_aggregate`
|
||||||
|
`is_trivial`
|
||||||
|
`is_standard_layout`
|
||||||
|
`is_destructible`
|
||||||
|
`is_nothrow_destructible`
|
||||||
|
`has_virtual_destructor`
|
||||||
|
`has_unique_object_representations`
|
||||||
|
`is_bounded_array`
|
||||||
|
`is_unbounded_array`
|
||||||
|
`is_swappable`
|
||||||
|
`is_swappable_with`
|
||||||
|
`is_nothrow_swappable`
|
||||||
|
`is_nothrow_swappable_with`
|
||||||
`is_reference`
|
`is_reference`
|
||||||
`is_base_of`
|
`is_base_of`
|
||||||
`make_signed`
|
`make_signed`
|
||||||
@ -476,3 +496,382 @@ template <typename T>
|
|||||||
inline constexpr bool is_object_pointer_v = etl::is_object_pointer<T>::value;
|
inline constexpr bool is_object_pointer_v = etl::is_object_pointer<T>::value;
|
||||||
```
|
```
|
||||||
C++17
|
C++17
|
||||||
|
|
||||||
|
## is_pod
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_pod
|
||||||
|
```
|
||||||
|
Checks if `T` is a POD (Plain Old Data) type.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When using the STL, this is defined as `is_standard_layout<T> && is_trivially_default_constructible<T> && is_trivially_copyable<T>`.
|
||||||
|
 When not using the STL, this is conservatively defined as `is_fundamental<T> || is_pointer<T>`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_pod_v = etl::is_pod<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_standard_layout
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_standard_layout
|
||||||
|
```
|
||||||
|
Checks if `T` is a standard-layout type.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_standard_layout_v = etl::is_standard_layout<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_trivial
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_trivial
|
||||||
|
```
|
||||||
|
Checks if `T` is a trivial type; i.e. it is trivially copyable and has one or more
|
||||||
|
default constructors, all of which are trivial.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_trivial_v = etl::is_trivial<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
**Note:** When not using the STL, this trait requires compiler support (the `__is_trivial` intrinsic).
|
||||||
|
If that is not available then the trait is not defined, as there is no portable way of
|
||||||
|
determining whether a type is trivial.
|
||||||
|
|
||||||
|
## is_bounded_array
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_bounded_array
|
||||||
|
```
|
||||||
|
Checks if `T` is an array type of known bound.
|
||||||
|
`T[N]` returns `true`, `T[]` and all other types return `false`.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_bounded_array_v = etl::is_bounded_array<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_unbounded_array
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_unbounded_array
|
||||||
|
```
|
||||||
|
Checks if `T` is an array type of unknown bound.
|
||||||
|
`T[]` returns `true`, `T[N]` and all other types return `false`.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_unbounded_array_v = etl::is_unbounded_array<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_destructible
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible
|
||||||
|
```
|
||||||
|
Checks if `T` is a destructible type; that is, an object type whose destructor is not deleted and is accessible, a reference type, or an array of a destructible type.
|
||||||
|
Incomplete types, `void`, function types and arrays of unknown bound are not destructible.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When not using the STL, the trait is detected by checking whether `declval<T&>().~T()` is a valid expression.
|
||||||
|
 Requires either compiler support or C++11. When neither is available, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_destructible_v = etl::is_destructible<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_nothrow_destructible
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible
|
||||||
|
```
|
||||||
|
Checks if `T` is a destructible type whose destructor is known not to throw.
|
||||||
|
Types that are not destructible are not nothrow destructible.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When not using the STL, the trait is detected by checking `noexcept(declval<T&>().~T())` for destructible types.
|
||||||
|
 Requires either compiler support or C++11. When neither is available, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_nothrow_destructible_v = etl::is_nothrow_destructible<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_swappable
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_swappable
|
||||||
|
```
|
||||||
|
Checks if `T` is a referenceable type and lvalues of type `T` can be swapped by an unqualified call to `swap`.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When using the STL and C++17, this is defined as `std::is_swappable<T>`.
|
||||||
|
 Otherwise the trait checks whether `swap(declval<T&>(), declval<T&>())` is a valid expression, where the `swap` considered is `etl::swap`, `std::swap` if it is available, and any `swap` found by argument dependent lookup.
|
||||||
|
 Requires C++11. Without it there is no way of detecting the validity of an expression, so this trait is not defined.
|
||||||
|
 Note that when using the STL with C++11 or C++14, the accuracy of this trait depends on `std::swap` being constrained by the standard library implementation. Standard libraries that only constrain `std::swap` from C++17 will cause this trait to report `true` for types that cannot actually be swapped.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_swappable_v = etl::is_swappable<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_swappable_with
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_swappable_with
|
||||||
|
```
|
||||||
|
Checks if expressions of type `T` and `U` can be swapped by unqualified calls to `swap`, in both directions.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When using the STL and C++17, this is defined as `std::is_swappable_with<T, U>`.
|
||||||
|
 Otherwise the trait checks whether both `swap(declval<T>(), declval<U>())` and `swap(declval<U>(), declval<T>())` are valid expressions, where the `swap` considered is `etl::swap`, `std::swap` if it is available, and any `swap` found by argument dependent lookup.
|
||||||
|
 Note that, unlike `is_swappable`, no references are added to `T` and `U`, so the value categories of the arguments are those of `T` and `U`. `is_swappable_with<int, int>::value` is `false`, whereas `is_swappable_with<int&, int&>::value` is `true`.
|
||||||
|
 Requires C++11. Without it there is no way of detecting the validity of an expression, so this trait is not defined.
|
||||||
|
 Note that when using the STL with C++11 or C++14, the accuracy of this trait depends on `std::swap` being constrained by the standard library implementation. Standard libraries that only constrain `std::swap` from C++17 will cause this trait to report `true` for types that cannot actually be swapped.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline constexpr bool is_swappable_with_v = etl::is_swappable_with<T, U>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_nothrow_swappable
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_swappable
|
||||||
|
```
|
||||||
|
Checks if `T` is a referenceable type and lvalues of type `T` can be swapped by an unqualified call to `swap`, and that the swap cannot throw.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When using the STL and C++17, this is defined as `std::is_nothrow_swappable<T>`.
|
||||||
|
 Otherwise the trait checks that `etl::is_swappable<T>::value` is `true` and that `swap(declval<T&>(), declval<T&>())` is `noexcept`.
|
||||||
|
 Requires C++11. Without it there is no way of detecting the validity of an expression, so this trait is not defined.
|
||||||
|
 Note that when neither the STL nor the type traits builtins are available, `etl::is_nothrow_move_constructible` and `etl::is_nothrow_move_assignable` are conservatively `false` for class types, so `etl::swap` is not `noexcept` for them and this trait is conservatively `false` too.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_nothrow_swappable_v = etl::is_nothrow_swappable<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_nothrow_swappable_with
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_nothrow_swappable_with
|
||||||
|
```
|
||||||
|
Checks if expressions of type `T` and `U` can be swapped by unqualified calls to `swap`, in both directions, and that neither swap can throw.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When using the STL and C++17, this is defined as `std::is_nothrow_swappable_with<T, U>`.
|
||||||
|
 Otherwise the trait checks that `etl::is_swappable_with<T, U>::value` is `true` and that both `swap(declval<T>(), declval<U>())` and `swap(declval<U>(), declval<T>())` are `noexcept`.
|
||||||
|
 Note that, as for `is_swappable_with`, no references are added to `T` and `U`, so the value categories of the arguments are those of `T` and `U`. `is_nothrow_swappable_with<int, int>::value` is `false`, whereas `is_nothrow_swappable_with<int&, int&>::value` is `true`.
|
||||||
|
 Requires C++11. Without it there is no way of detecting the validity of an expression, so this trait is not defined.
|
||||||
|
 Note that when neither the STL nor the type traits builtins are available, `etl::is_nothrow_move_constructible` and `etl::is_nothrow_move_assignable` are conservatively `false` for class types, so `etl::swap` is not `noexcept` for them and this trait is conservatively `false` too.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline constexpr bool is_nothrow_swappable_with_v = etl::is_nothrow_swappable_with<T, U>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_union
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_union
|
||||||
|
```
|
||||||
|
Checks if `T` is a union type.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When the compiler does not provide the required intrinsic, this trait conservatively reports `false` for every type.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_union_v = etl::is_union<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_empty
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_empty
|
||||||
|
```
|
||||||
|
Checks if `T` is an empty class type; that is, a non-union class type with no non-static data members other than zero-sized bit-fields, no virtual functions, no virtual base classes and no non-empty base classes.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 Requires compiler support. When the compiler does not provide the required intrinsic, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_empty_v = etl::is_empty<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_polymorphic
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_polymorphic
|
||||||
|
```
|
||||||
|
Checks if `T` is a polymorphic class type; that is, a class that declares or inherits at least one virtual function.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 Requires compiler support. When the compiler does not provide the required intrinsic, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_polymorphic_v = etl::is_polymorphic<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_abstract
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_abstract
|
||||||
|
```
|
||||||
|
Checks if `T` is an abstract class type; that is, a class that declares or inherits at least one pure virtual function.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 Requires compiler support. When the compiler does not provide the required intrinsic, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_abstract_v = etl::is_abstract<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_final
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_final
|
||||||
|
```
|
||||||
|
Checks if `T` is a class or union type marked `final`, optionally cv-qualified.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When using the STL, this requires C++14 or above. Otherwise it requires compiler support. When neither is available, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_final_v = etl::is_final<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_aggregate
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_aggregate
|
||||||
|
```
|
||||||
|
Checks if `T` is an aggregate type, optionally cv-qualified.
|
||||||
|
An aggregate is an array type or a class type that has no user-declared or inherited constructors, no private or protected non-static data members, no virtual functions and no virtual, private or protected base classes.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When using the STL, this requires C++17 or above. Otherwise it requires compiler support. When neither is available, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_aggregate_v = etl::is_aggregate<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## has_virtual_destructor
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct has_virtual_destructor
|
||||||
|
```
|
||||||
|
Checks if `T` is a class type with a virtual destructor, optionally cv-qualified.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When not using the STL, this requires compiler support. When it is not available, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool has_virtual_destructor_v = etl::has_virtual_destructor<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## has_unique_object_representations
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct has_unique_object_representations
|
||||||
|
```
|
||||||
|
Checks if `T` is trivially copyable and any two objects of type `T` with the same value have the same object representation; that is, the type has no padding bits and no two distinct object representations compare equal.
|
||||||
|
Arrays and cv-qualifiers are ignored; the trait is applied to `etl::remove_all_extents<typename etl::remove_cv<T>::type>::type`.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
 When using the STL, this requires C++17 or above. Otherwise it requires compiler support. When neither is available, this trait is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool has_unique_object_representations_v = etl::has_unique_object_representations<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_null_pointer
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_null_pointer
|
||||||
|
```
|
||||||
|
Checks if `T` is `etl::nullptr_t`, optionally cv-qualified.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_null_pointer_v = etl::is_null_pointer<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|
||||||
|
## is_scalar
|
||||||
|
From: `20.49.0`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
struct is_scalar
|
||||||
|
```
|
||||||
|
Checks if `T` is a scalar type; that is, an arithmetic, enumeration, pointer, pointer to member or `etl::nullptr_t` type, optionally cv-qualified.
|
||||||
|
The result is found in the member `value`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_scalar_v = etl::is_scalar<T>::value;
|
||||||
|
```
|
||||||
|
C++17
|
||||||
|
|||||||
@ -57,10 +57,58 @@ SOFTWARE.
|
|||||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 1
|
#define ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_DESTRUCTIBLE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_DESTRUCTIBLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_NOTHROW_DESTRUCTIBLE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_NOTHROW_DESTRUCTIBLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE)
|
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE)
|
||||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE 1
|
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_STANDARD_LAYOUT)
|
||||||
|
#define ETL_USING_BUILTIN_IS_STANDARD_LAYOUT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_TRIVIAL)
|
||||||
|
#define ETL_USING_BUILTIN_IS_TRIVIAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_UNION)
|
||||||
|
#define ETL_USING_BUILTIN_IS_UNION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_EMPTY)
|
||||||
|
#define ETL_USING_BUILTIN_IS_EMPTY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_POLYMORPHIC)
|
||||||
|
#define ETL_USING_BUILTIN_IS_POLYMORPHIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_ABSTRACT)
|
||||||
|
#define ETL_USING_BUILTIN_IS_ABSTRACT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_FINAL)
|
||||||
|
#define ETL_USING_BUILTIN_IS_FINAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_AGGREGATE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_AGGREGATE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR)
|
||||||
|
#define ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS)
|
||||||
|
#define ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
|
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
|
||||||
#define ETL_USING_BUILTIN_UNDERLYING_TYPE 1
|
#define ETL_USING_BUILTIN_UNDERLYING_TYPE 1
|
||||||
#endif
|
#endif
|
||||||
@ -124,10 +172,58 @@ SOFTWARE.
|
|||||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE (__has_builtin(__has_trivial_destructor) || __has_builtin(__is_trivially_destructible))
|
#define ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE (__has_builtin(__has_trivial_destructor) || __has_builtin(__is_trivially_destructible))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_DESTRUCTIBLE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_DESTRUCTIBLE __has_builtin(__is_destructible)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_NOTHROW_DESTRUCTIBLE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_NOTHROW_DESTRUCTIBLE __has_builtin(__is_nothrow_destructible)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE)
|
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE)
|
||||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE (__has_builtin(__has_trivial_copy) || __has_builtin(__is_trivially_copyable))
|
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE (__has_builtin(__has_trivial_copy) || __has_builtin(__is_trivially_copyable))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_STANDARD_LAYOUT)
|
||||||
|
#define ETL_USING_BUILTIN_IS_STANDARD_LAYOUT __has_builtin(__is_standard_layout)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_TRIVIAL)
|
||||||
|
#define ETL_USING_BUILTIN_IS_TRIVIAL __has_builtin(__is_trivial)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_UNION)
|
||||||
|
#define ETL_USING_BUILTIN_IS_UNION __has_builtin(__is_union)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_EMPTY)
|
||||||
|
#define ETL_USING_BUILTIN_IS_EMPTY __has_builtin(__is_empty)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_POLYMORPHIC)
|
||||||
|
#define ETL_USING_BUILTIN_IS_POLYMORPHIC __has_builtin(__is_polymorphic)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_ABSTRACT)
|
||||||
|
#define ETL_USING_BUILTIN_IS_ABSTRACT __has_builtin(__is_abstract)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_FINAL)
|
||||||
|
#define ETL_USING_BUILTIN_IS_FINAL __has_builtin(__is_final)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_AGGREGATE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_AGGREGATE __has_builtin(__is_aggregate)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR)
|
||||||
|
#define ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR __has_builtin(__has_virtual_destructor)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS)
|
||||||
|
#define ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS __has_builtin(__has_unique_object_representations)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
|
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
|
||||||
#define ETL_USING_BUILTIN_UNDERLYING_TYPE __has_builtin(__underlying_type)
|
#define ETL_USING_BUILTIN_UNDERLYING_TYPE __has_builtin(__underlying_type)
|
||||||
#endif
|
#endif
|
||||||
@ -183,6 +279,46 @@ SOFTWARE.
|
|||||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE 1
|
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_STANDARD_LAYOUT)
|
||||||
|
#define ETL_USING_BUILTIN_IS_STANDARD_LAYOUT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_TRIVIAL)
|
||||||
|
#define ETL_USING_BUILTIN_IS_TRIVIAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_UNION)
|
||||||
|
#define ETL_USING_BUILTIN_IS_UNION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_EMPTY)
|
||||||
|
#define ETL_USING_BUILTIN_IS_EMPTY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_POLYMORPHIC)
|
||||||
|
#define ETL_USING_BUILTIN_IS_POLYMORPHIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_ABSTRACT)
|
||||||
|
#define ETL_USING_BUILTIN_IS_ABSTRACT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_FINAL)
|
||||||
|
#define ETL_USING_BUILTIN_IS_FINAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_AGGREGATE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_AGGREGATE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR)
|
||||||
|
#define ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS)
|
||||||
|
#define ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
// MSVC has supported __builtin_bit_cast since VS2019 16.6. __has_builtin is not
|
// MSVC has supported __builtin_bit_cast since VS2019 16.6. __has_builtin is not
|
||||||
// used for Microsoft (see above) to avoid a VS2022 intellisense issue, so the
|
// used for Microsoft (see above) to avoid a VS2022 intellisense issue, so the
|
||||||
// intrinsic is enabled here directly for the no-STL configuration.
|
// intrinsic is enabled here directly for the no-STL configuration.
|
||||||
@ -216,10 +352,58 @@ SOFTWARE.
|
|||||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 0
|
#define ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_DESTRUCTIBLE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_DESTRUCTIBLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_NOTHROW_DESTRUCTIBLE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_NOTHROW_DESTRUCTIBLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE)
|
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE)
|
||||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE 0
|
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_STANDARD_LAYOUT)
|
||||||
|
#define ETL_USING_BUILTIN_IS_STANDARD_LAYOUT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_TRIVIAL)
|
||||||
|
#define ETL_USING_BUILTIN_IS_TRIVIAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_UNION)
|
||||||
|
#define ETL_USING_BUILTIN_IS_UNION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_EMPTY)
|
||||||
|
#define ETL_USING_BUILTIN_IS_EMPTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_POLYMORPHIC)
|
||||||
|
#define ETL_USING_BUILTIN_IS_POLYMORPHIC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_ABSTRACT)
|
||||||
|
#define ETL_USING_BUILTIN_IS_ABSTRACT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_FINAL)
|
||||||
|
#define ETL_USING_BUILTIN_IS_FINAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_IS_AGGREGATE)
|
||||||
|
#define ETL_USING_BUILTIN_IS_AGGREGATE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR)
|
||||||
|
#define ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS)
|
||||||
|
#define ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
|
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
|
||||||
#define ETL_USING_BUILTIN_UNDERLYING_TYPE 0
|
#define ETL_USING_BUILTIN_UNDERLYING_TYPE 0
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -47,6 +47,12 @@ SOFTWARE.
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Required for std::swap, which etl::is_swappable must consider in any
|
||||||
|
// configuration that does not define etl::swap.
|
||||||
|
#if ETL_USING_CPP11 && (ETL_USING_STL || defined(ETL_IN_UNIT_TEST))
|
||||||
|
#include <utility>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace etl
|
namespace etl
|
||||||
{
|
{
|
||||||
#if ETL_USING_CPP11
|
#if ETL_USING_CPP11
|
||||||
@ -741,6 +747,38 @@ namespace etl
|
|||||||
inline constexpr bool is_array_v = is_array<T>::value;
|
inline constexpr bool is_array_v = is_array<T>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_bounded_array
|
||||||
|
template <typename T>
|
||||||
|
struct is_bounded_array : false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
struct is_bounded_array<T[Size]> : true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_bounded_array_v = is_bounded_array<T>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_unbounded_array
|
||||||
|
template <typename T>
|
||||||
|
struct is_unbounded_array : false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct is_unbounded_array<T[]> : true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
/// is_pointer
|
/// is_pointer
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -846,6 +884,38 @@ namespace etl
|
|||||||
inline constexpr bool is_pod_v = etl::is_pod<T>::value;
|
inline constexpr bool is_pod_v = etl::is_pod<T>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_standard_layout
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a type is standard layout, so the trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_STANDARD_LAYOUT
|
||||||
|
template <typename T>
|
||||||
|
struct is_standard_layout : etl::bool_constant<__is_standard_layout(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_standard_layout_v = etl::is_standard_layout<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_trivial
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a type is trivial, so the trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_TRIVIAL
|
||||||
|
template <typename T>
|
||||||
|
struct is_trivial : etl::bool_constant<__is_trivial(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_trivial_v = etl::is_trivial<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
/// conditional
|
/// conditional
|
||||||
template <bool BValue, typename T, typename F>
|
template <bool BValue, typename T, typename F>
|
||||||
@ -1144,6 +1214,137 @@ namespace etl
|
|||||||
inline constexpr bool is_class_v = is_class<T>::value;
|
inline constexpr bool is_class_v = is_class<T>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_union
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// distinguish a union from a class, so the trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_UNION
|
||||||
|
template <typename T>
|
||||||
|
struct is_union : etl::bool_constant<__is_union(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_union_v = is_union<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_empty
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a class type is empty, so the trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_EMPTY
|
||||||
|
template <typename T>
|
||||||
|
struct is_empty : etl::bool_constant<__is_empty(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_empty_v = is_empty<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_polymorphic
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a class type is polymorphic, so the trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_POLYMORPHIC
|
||||||
|
template <typename T>
|
||||||
|
struct is_polymorphic : etl::bool_constant<__is_polymorphic(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_polymorphic_v = is_polymorphic<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_abstract
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a class type is abstract, so the trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_ABSTRACT
|
||||||
|
template <typename T>
|
||||||
|
struct is_abstract : etl::bool_constant<__is_abstract(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_abstract_v = is_abstract<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_final
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a class type is final, so the trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_FINAL
|
||||||
|
template <typename T>
|
||||||
|
struct is_final : etl::bool_constant<__is_final(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_final_v = is_final<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_aggregate
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a type is an aggregate, so the trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_AGGREGATE
|
||||||
|
template <typename T>
|
||||||
|
struct is_aggregate : etl::bool_constant<__is_aggregate(typename etl::remove_cv<T>::type)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_aggregate_v = is_aggregate<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// has_virtual_destructor
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a class type has a virtual destructor, so the trait is
|
||||||
|
/// not defined.
|
||||||
|
#if ETL_USING_BUILTIN_HAS_VIRTUAL_DESTRUCTOR
|
||||||
|
template <typename T>
|
||||||
|
struct has_virtual_destructor : etl::bool_constant<__has_virtual_destructor(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// has_unique_object_representations
|
||||||
|
/// Requires compiler support. Without it there is no portable way to
|
||||||
|
/// determine whether a type has a unique object representation, so the trait
|
||||||
|
/// is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS
|
||||||
|
template <typename T>
|
||||||
|
struct has_unique_object_representations
|
||||||
|
: etl::bool_constant<__has_unique_object_representations(typename etl::remove_cv<typename etl::remove_all_extents<T>::type>::type)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<T>::value;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
/// is_base_of
|
/// is_base_of
|
||||||
#if ETL_USING_CPP11
|
#if ETL_USING_CPP11
|
||||||
@ -1464,6 +1665,132 @@ namespace etl
|
|||||||
|
|
||||||
template <typename TFrom, typename TTo >
|
template <typename TFrom, typename TTo >
|
||||||
inline constexpr bool is_nothrow_convertible_v = etl::is_nothrow_convertible<TFrom, TTo>::value;
|
inline constexpr bool is_nothrow_convertible_v = etl::is_nothrow_convertible<TFrom, TTo>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_destructible
|
||||||
|
/// Requires either compiler support or C++11. Without them there is no
|
||||||
|
/// portable way to determine whether a type is destructible, so the trait
|
||||||
|
/// is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_DESTRUCTIBLE
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible : etl::bool_constant<__is_destructible(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#elif ETL_USING_CPP11
|
||||||
|
namespace private_type_traits
|
||||||
|
{
|
||||||
|
// Selected only if 'declval<T&>().~T()' is a valid expression.
|
||||||
|
// Void types, function types and types with an inaccessible or deleted
|
||||||
|
// destructor all fail substitution and select the fallback.
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible_impl
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename U, typename = decltype(etl::declval<U&>().~U())>
|
||||||
|
static etl::true_type test(int);
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
static etl::false_type test(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static ETL_CONSTANT bool value = decltype(test<T>(0))::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible_helper : etl::bool_constant<is_destructible_impl<typename etl::remove_all_extents<T>::type>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reference types are always destructible.
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible_helper<T&> : etl::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible_helper<T&&> : etl::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// Arrays of unknown bound are incomplete types.
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible_helper<T[]> : etl::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
} // namespace private_type_traits
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible : etl::bool_constant<private_type_traits::is_destructible_helper<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// C++17 implies C++11, so the trait is always defined when the alias is.
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_destructible_v = etl::is_destructible<T>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_nothrow_destructible
|
||||||
|
/// Requires either compiler support or C++11. Without them there is no
|
||||||
|
/// portable way to determine whether a type is nothrow destructible, so the
|
||||||
|
/// trait is not defined.
|
||||||
|
#if ETL_USING_BUILTIN_IS_NOTHROW_DESTRUCTIBLE
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible : etl::bool_constant<__is_nothrow_destructible(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#elif ETL_USING_CPP11
|
||||||
|
namespace private_type_traits
|
||||||
|
{
|
||||||
|
// Only instantiated for destructible types, so 'declval<T&>().~T()' is a valid expression.
|
||||||
|
template <typename T, bool IsDestructible = etl::is_destructible<T>::value>
|
||||||
|
struct is_nothrow_destructible_impl : etl::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible_impl<T, true> : etl::bool_constant<noexcept(etl::declval<T&>().~T())>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible_helper : etl::bool_constant<is_nothrow_destructible_impl<typename etl::remove_all_extents<T>::type>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reference types are always nothrow destructible.
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible_helper<T&> : etl::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible_helper<T&&> : etl::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// Arrays of unknown bound are incomplete types.
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible_helper<T[]> : etl::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
} // namespace private_type_traits
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible : etl::bool_constant<private_type_traits::is_nothrow_destructible_helper<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// C++17 implies C++11, so the trait is always defined when the alias is.
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_nothrow_destructible_v = etl::is_nothrow_destructible<T>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
@ -1849,6 +2176,56 @@ namespace etl
|
|||||||
#if ETL_USING_CPP17
|
#if ETL_USING_CPP17
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr bool is_array_v = std::is_array_v<T>;
|
inline constexpr bool is_array_v = std::is_array_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_bounded_array
|
||||||
|
///\ingroup type_traits
|
||||||
|
#if ETL_USING_CPP20 && defined(__cpp_lib_bounded_array_traits)
|
||||||
|
template <typename T>
|
||||||
|
struct is_bounded_array : std::is_bounded_array<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
struct is_bounded_array : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
struct is_bounded_array<T[Size]> : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_bounded_array_v = etl::is_bounded_array<T>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_unbounded_array
|
||||||
|
///\ingroup type_traits
|
||||||
|
#if ETL_USING_CPP20 && defined(__cpp_lib_bounded_array_traits)
|
||||||
|
template <typename T>
|
||||||
|
struct is_unbounded_array : std::is_unbounded_array<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
struct is_unbounded_array : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_unbounded_array<T[]> : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_unbounded_array_v = etl::is_unbounded_array<T>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
@ -1920,6 +2297,72 @@ namespace etl
|
|||||||
inline constexpr bool is_pod_v = std::is_standard_layout_v<T> && std::is_trivially_default_constructible_v<T> && std::is_trivially_copyable_v<T>;
|
inline constexpr bool is_pod_v = std::is_standard_layout_v<T> && std::is_trivially_default_constructible_v<T> && std::is_trivially_copyable_v<T>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_standard_layout
|
||||||
|
///\ingroup type_traits
|
||||||
|
template <typename T>
|
||||||
|
struct is_standard_layout : std::is_standard_layout<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_standard_layout_v = std::is_standard_layout_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_trivial
|
||||||
|
///\ingroup type_traits
|
||||||
|
#if ETL_USING_CPP26
|
||||||
|
// std::is_trivial is deprecated in C++26 and later; avoid using it and
|
||||||
|
// compose the trait from is_trivially_copyable && is_trivially_default_constructible instead.
|
||||||
|
template <typename T>
|
||||||
|
struct is_trivial : etl::bool_constant<std::is_trivially_copyable<T>::value && std::is_trivially_default_constructible<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_trivial_v = std::is_trivially_copyable_v<T> && std::is_trivially_default_constructible_v<T>;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
struct is_trivial : std::is_trivial<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_trivial_v = std::is_trivial_v<T>;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_destructible
|
||||||
|
///\ingroup type_traits
|
||||||
|
template <typename T>
|
||||||
|
struct is_destructible : std::is_destructible<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_destructible_v = std::is_destructible_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_nothrow_destructible
|
||||||
|
///\ingroup type_traits
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_destructible : std::is_nothrow_destructible<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_nothrow_destructible_v = std::is_nothrow_destructible_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(ETL_COMPILER_GCC)
|
#if defined(ETL_COMPILER_GCC)
|
||||||
#if ETL_COMPILER_VERSION >= 5
|
#if ETL_COMPILER_VERSION >= 5
|
||||||
#define ETL_GCC_V5_TYPE_TRAITS_SUPPORTED
|
#define ETL_GCC_V5_TYPE_TRAITS_SUPPORTED
|
||||||
@ -2100,6 +2543,127 @@ namespace etl
|
|||||||
inline constexpr bool is_class_v = is_class<T>::value;
|
inline constexpr bool is_class_v = is_class<T>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_union
|
||||||
|
template <typename T>
|
||||||
|
struct is_union : std::is_union<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_union_v = std::is_union_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_empty
|
||||||
|
template <typename T>
|
||||||
|
struct is_empty : std::is_empty<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_empty_v = std::is_empty_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_polymorphic
|
||||||
|
template <typename T>
|
||||||
|
struct is_polymorphic : std::is_polymorphic<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_polymorphic_v = std::is_polymorphic_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_abstract
|
||||||
|
template <typename T>
|
||||||
|
struct is_abstract : std::is_abstract<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_abstract_v = std::is_abstract_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_final
|
||||||
|
/// std::is_final is only available from C++14, so for C++11 the compiler
|
||||||
|
/// builtin is used, if available. Otherwise the trait is not defined.
|
||||||
|
#if ETL_USING_CPP14
|
||||||
|
template <typename T>
|
||||||
|
struct is_final : std::is_final<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_final_v = std::is_final_v<T>;
|
||||||
|
#endif
|
||||||
|
#elif ETL_USING_BUILTIN_IS_FINAL
|
||||||
|
template <typename T>
|
||||||
|
struct is_final : etl::bool_constant<__is_final(T)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_aggregate
|
||||||
|
/// std::is_aggregate is only available from C++17, so for C++11 and C++14 the
|
||||||
|
/// compiler builtin is used, if available. Otherwise the trait is not defined.
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
struct is_aggregate : std::is_aggregate<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_aggregate_v = std::is_aggregate_v<T>;
|
||||||
|
#elif ETL_USING_BUILTIN_IS_AGGREGATE
|
||||||
|
template <typename T>
|
||||||
|
struct is_aggregate : etl::bool_constant<__is_aggregate(typename etl::remove_cv<T>::type)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// has_virtual_destructor
|
||||||
|
template <typename T>
|
||||||
|
struct has_virtual_destructor : std::has_virtual_destructor<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool has_virtual_destructor_v = std::has_virtual_destructor_v<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// has_unique_object_representations
|
||||||
|
/// std::has_unique_object_representations is only available from C++17, so for
|
||||||
|
/// C++11 and C++14 the compiler builtin is used, if available. Otherwise the
|
||||||
|
/// trait is not defined.
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
struct has_unique_object_representations : std::has_unique_object_representations<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool has_unique_object_representations_v = std::has_unique_object_representations_v<T>;
|
||||||
|
#elif ETL_USING_BUILTIN_HAS_UNIQUE_OBJECT_REPRESENTATIONS
|
||||||
|
template <typename T>
|
||||||
|
struct has_unique_object_representations
|
||||||
|
: etl::bool_constant<__has_unique_object_representations(typename etl::remove_cv<typename etl::remove_all_extents<T>::type>::type)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
/// add_lvalue_reference
|
/// add_lvalue_reference
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -2253,6 +2817,19 @@ namespace etl
|
|||||||
|
|
||||||
#endif // Condition = ETL_USING_STL && ETL_USING_CPP11
|
#endif // Condition = ETL_USING_STL && ETL_USING_CPP11
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_null_pointer
|
||||||
|
///\ingroup type_traits
|
||||||
|
template <typename T>
|
||||||
|
struct is_null_pointer : etl::is_same<typename etl::remove_cv<T>::type, etl::nullptr_t>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
// ETL extended type traits.
|
// ETL extended type traits.
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
@ -3996,6 +4573,23 @@ namespace etl
|
|||||||
inline constexpr bool is_member_pointer_v = etl::is_member_pointer<T>::value;
|
inline constexpr bool is_member_pointer_v = etl::is_member_pointer<T>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_scalar
|
||||||
|
/// An arithmetic, enumeration, pointer, pointer to member or
|
||||||
|
/// etl::nullptr_t type, optionally cv-qualified.
|
||||||
|
//***************************************************************************
|
||||||
|
template <typename T>
|
||||||
|
struct is_scalar
|
||||||
|
: etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_enum<T>::value || etl::is_pointer<T>::value || etl::is_member_pointer<T>::value
|
||||||
|
|| etl::is_null_pointer<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_scalar_v = etl::is_scalar<T>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ETL_USING_CPP11
|
#if ETL_USING_CPP11
|
||||||
//*********************************
|
//*********************************
|
||||||
/// Check if T is a function type
|
/// Check if T is a function type
|
||||||
@ -4130,6 +4724,235 @@ namespace etl
|
|||||||
inline constexpr bool is_object_pointer_v = etl::is_object_pointer<T>::value;
|
inline constexpr bool is_object_pointer_v = etl::is_object_pointer<T>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// swap
|
||||||
|
/// Declared here, and defined in utility.h, so that etl::is_swappable below
|
||||||
|
/// finds it by ordinary unqualified lookup.
|
||||||
|
/// We can't have std::swap and etl::swap templates coexisting in the unit
|
||||||
|
/// tests as the compiler will be unable to decide which one to use, due to
|
||||||
|
/// ADL.
|
||||||
|
//***************************************************************************
|
||||||
|
#if ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)
|
||||||
|
#if ETL_USING_CPP11
|
||||||
|
namespace private_type_traits
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct is_swappable_helper;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_swappable_helper;
|
||||||
|
} // namespace private_type_traits
|
||||||
|
|
||||||
|
// Constrained, as the standard requires, so that an attempt to swap a type
|
||||||
|
// that cannot be moved is a substitution failure rather than a hard error.
|
||||||
|
// This is what allows etl::is_swappable to be implemented.
|
||||||
|
// The exception specification is conditional, as the standard requires, so
|
||||||
|
// that etl::is_nothrow_swappable can be implemented.
|
||||||
|
template <typename T>
|
||||||
|
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_move_constructible<T>::value && etl::is_move_assignable<T>::value>::type swap(T& a, T& b)
|
||||||
|
ETL_NOEXCEPT_IF(etl::is_nothrow_move_constructible<T>::value&& etl::is_nothrow_move_assignable<T>::value);
|
||||||
|
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
ETL_CONSTEXPR14 typename etl::enable_if<private_type_traits::is_swappable_helper<T>::value>::type swap(T (&a)[Size], T (&b)[Size])
|
||||||
|
ETL_NOEXCEPT_IF(private_type_traits::is_nothrow_swappable_helper<T>::value);
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
ETL_CONSTEXPR14 void swap(T& a, T& b) ETL_NOEXCEPT;
|
||||||
|
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
ETL_CONSTEXPR14 void swap(T (&a)[Size], T (&b)[Size]) ETL_NOEXCEPT;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_swappable
|
||||||
|
/// Determines whether lvalues of type T can be swapped by an unqualified
|
||||||
|
/// call to swap.
|
||||||
|
/// Requires C++11. Without it there is no way of detecting the validity of
|
||||||
|
/// an expression, so the trait is not defined.
|
||||||
|
//***************************************************************************
|
||||||
|
#if ETL_USING_STL && ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
struct is_swappable : std::is_swappable<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_swappable_with
|
||||||
|
//***************************************************************************
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_swappable_with : std::is_swappable_with<T, U>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#elif ETL_USING_CPP11
|
||||||
|
namespace private_type_traits
|
||||||
|
{
|
||||||
|
namespace swap_detect
|
||||||
|
{
|
||||||
|
// Bring std::swap into scope, if it is available, so that the unqualified
|
||||||
|
// call below finds it in those configurations that do not define etl::swap.
|
||||||
|
// Otherwise etl::swap is found by ordinary lookup in the enclosing
|
||||||
|
// namespace. Either way, a swap found by argument dependent lookup takes
|
||||||
|
// part in overload resolution.
|
||||||
|
#if ETL_USING_STL || defined(ETL_IN_UNIT_TEST)
|
||||||
|
using std::swap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Selected only if 'swap(declval<T&>(), declval<T&>())' is a valid expression.
|
||||||
|
template <typename T>
|
||||||
|
struct is_swappable_test
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename U, typename = decltype(swap(etl::declval<U&>(), etl::declval<U&>()))>
|
||||||
|
static etl::true_type test(int);
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
static etl::false_type test(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static ETL_CONSTANT bool value = decltype(test<T>(0))::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Selected only if both 'swap(declval<T>(), declval<U>())' and
|
||||||
|
// 'swap(declval<U>(), declval<T>())' are valid expressions.
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_swappable_with_test
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename T1, typename U1, typename = decltype(swap(etl::declval<T1>(), etl::declval<U1>())),
|
||||||
|
typename = decltype(swap(etl::declval<U1>(), etl::declval<T1>()))>
|
||||||
|
static etl::true_type test(int);
|
||||||
|
|
||||||
|
template <typename, typename>
|
||||||
|
static etl::false_type test(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static ETL_CONSTANT bool value = decltype(test<T, U>(0))::value;
|
||||||
|
};
|
||||||
|
} // namespace swap_detect
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_swappable_helper : etl::bool_constant<swap_detect::is_swappable_test<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_swappable_with_helper : etl::bool_constant<swap_detect::is_swappable_with_test<T, U>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
} // namespace private_type_traits
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_swappable : etl::bool_constant<private_type_traits::is_swappable_helper<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_swappable_with
|
||||||
|
//***************************************************************************
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_swappable_with : etl::bool_constant<private_type_traits::is_swappable_with_helper<T, U>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_nothrow_swappable
|
||||||
|
/// Determines whether lvalues of type T can be swapped by an unqualified
|
||||||
|
/// call to swap, and that the swap cannot throw.
|
||||||
|
/// Requires C++11. Without it there is no way of detecting the validity of
|
||||||
|
/// an expression, so the trait is not defined.
|
||||||
|
//***************************************************************************
|
||||||
|
#if ETL_USING_STL && ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_swappable : std::is_nothrow_swappable<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_nothrow_swappable_with
|
||||||
|
//***************************************************************************
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_nothrow_swappable_with : std::is_nothrow_swappable_with<T, U>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#elif ETL_USING_CPP11
|
||||||
|
namespace private_type_traits
|
||||||
|
{
|
||||||
|
namespace swap_detect
|
||||||
|
{
|
||||||
|
// Only 'true' if the type is swappable and the swap expression is noexcept.
|
||||||
|
template <typename T, bool Is_Swappable = is_swappable_test<T>::value>
|
||||||
|
struct is_nothrow_swappable_test
|
||||||
|
{
|
||||||
|
static ETL_CONSTANT bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_swappable_test<T, true>
|
||||||
|
{
|
||||||
|
static ETL_CONSTANT bool value = noexcept(swap(etl::declval<T&>(), etl::declval<T&>()));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only 'true' if the types are swappable with each other and both of the
|
||||||
|
// swap expressions are noexcept.
|
||||||
|
template <typename T, typename U, bool Is_Swappable_With = is_swappable_with_test<T, U>::value>
|
||||||
|
struct is_nothrow_swappable_with_test
|
||||||
|
{
|
||||||
|
static ETL_CONSTANT bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_nothrow_swappable_with_test<T, U, true>
|
||||||
|
{
|
||||||
|
static ETL_CONSTANT bool value = noexcept(swap(etl::declval<T>(), etl::declval<U>())) && noexcept(swap(etl::declval<U>(), etl::declval<T>()));
|
||||||
|
};
|
||||||
|
} // namespace swap_detect
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_swappable_helper : etl::bool_constant<swap_detect::is_nothrow_swappable_test<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_nothrow_swappable_with_helper : etl::bool_constant<swap_detect::is_nothrow_swappable_with_test<T, U>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
} // namespace private_type_traits
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_nothrow_swappable : etl::bool_constant<private_type_traits::is_nothrow_swappable_helper<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// is_nothrow_swappable_with
|
||||||
|
//***************************************************************************
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_nothrow_swappable_with : etl::bool_constant<private_type_traits::is_nothrow_swappable_with_helper<T, U>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// C++17 implies C++11, so the trait is always defined when the alias is.
|
||||||
|
#if ETL_USING_CPP17
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_swappable_v = etl::is_swappable<T>::value;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline constexpr bool is_swappable_with_v = etl::is_swappable_with<T, U>::value;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_nothrow_swappable_v = etl::is_nothrow_swappable<T>::value;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline constexpr bool is_nothrow_swappable_with_v = etl::is_nothrow_swappable_with<T, U>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ETL_USING_CPP11
|
#if ETL_USING_CPP11
|
||||||
//*********************************
|
//*********************************
|
||||||
/// Check for the presence of operator()
|
/// Check for the presence of operator()
|
||||||
|
|||||||
@ -340,7 +340,31 @@ namespace etl
|
|||||||
// We can't have std::swap and etl::swap templates coexisting in the unit
|
// We can't have std::swap and etl::swap templates coexisting in the unit
|
||||||
// tests as the compiler will be unable to decide which one to use, due to
|
// tests as the compiler will be unable to decide which one to use, due to
|
||||||
// ADL.
|
// ADL.
|
||||||
|
// These are declared in type_traits.h, so that etl::is_swappable can find
|
||||||
|
// them, and defined here.
|
||||||
#if ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)
|
#if ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)
|
||||||
|
#if ETL_USING_CPP11
|
||||||
|
//***************************************************************************
|
||||||
|
// swap
|
||||||
|
template <typename T>
|
||||||
|
ETL_CONSTEXPR14 typename etl::enable_if<etl::is_move_constructible<T>::value && etl::is_move_assignable<T>::value>::type swap(T& a, T& b)
|
||||||
|
ETL_NOEXCEPT_IF(etl::is_nothrow_move_constructible<T>::value&& etl::is_nothrow_move_assignable<T>::value)
|
||||||
|
{
|
||||||
|
T temp(ETL_MOVE(a));
|
||||||
|
a = ETL_MOVE(b);
|
||||||
|
b = ETL_MOVE(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
ETL_CONSTEXPR14 typename etl::enable_if<private_type_traits::is_swappable_helper<T>::value>::type swap(T (&a)[Size], T (&b)[Size])
|
||||||
|
ETL_NOEXCEPT_IF(private_type_traits::is_nothrow_swappable_helper<T>::value)
|
||||||
|
{
|
||||||
|
for (size_t i = 0UL; i < Size; ++i)
|
||||||
|
{
|
||||||
|
swap(a[i], b[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
// swap
|
// swap
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -351,7 +375,7 @@ namespace etl
|
|||||||
b = ETL_MOVE(temp);
|
b = ETL_MOVE(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, size_t Size >
|
template <typename T, size_t Size>
|
||||||
ETL_CONSTEXPR14 void swap(T (&a)[Size], T (&b)[Size]) ETL_NOEXCEPT
|
ETL_CONSTEXPR14 void swap(T (&a)[Size], T (&b)[Size]) ETL_NOEXCEPT
|
||||||
{
|
{
|
||||||
for (size_t i = 0UL; i < Size; ++i)
|
for (size_t i = 0UL; i < Size; ++i)
|
||||||
@ -359,6 +383,7 @@ namespace etl
|
|||||||
swap(a[i], b[i]);
|
swap(a[i], b[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user