mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Detect builtins (#1581)
Even without ETL_USE_TYPE_TRAITS_BUILTINS in the profile, we get compiler builtins detected. Makes detection more consistent now. Previously, some type trait builtins were detected automatically, and some others needed to be activated via ETL_USE_TYPE_TRAITS_BUILTINS in the profile explicitly. Replaces: #1174 Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
parent
452b6269f3
commit
ed5219283b
@ -53,6 +53,44 @@ SOFTWARE.
|
||||
|
||||
namespace etl
|
||||
{
|
||||
namespace private_memory
|
||||
{
|
||||
//*************************************************************************
|
||||
/// Checks whether a type can be copied to uninitialised storage by using
|
||||
/// assignment instead of placement new.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
struct is_trivially_copy_assignable_to_uninitialised_storage
|
||||
: etl::bool_constant<etl::is_trivially_copyable<T>::value && etl::is_trivially_copy_constructible<T>::value
|
||||
&& etl::is_trivially_copy_assignable<T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// Checks whether a type can be moved to uninitialised storage by using
|
||||
/// assignment instead of placement new.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
struct is_trivially_move_assignable_to_uninitialised_storage
|
||||
: etl::bool_constant<etl::is_trivially_copyable<T>::value && etl::is_trivially_move_constructible<T>::value
|
||||
&& etl::is_trivially_move_assignable<T>::value>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks whether a value-initialised type can be copied to uninitialised
|
||||
/// storage by using assignment instead of placement new.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
struct is_trivially_value_assignable_to_uninitialised_storage
|
||||
: etl::bool_constant<etl::is_trivially_constructible<T>::value && etl::is_trivially_copyable<T>::value
|
||||
&& etl::is_trivially_copy_assignable<T>::value>
|
||||
{
|
||||
};
|
||||
} // namespace private_memory
|
||||
|
||||
//*****************************************************************************
|
||||
/// Obtain the address represented by p without forming a reference to the
|
||||
/// object pointed to by p. Defined when not using the STL or C++20
|
||||
@ -428,7 +466,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TOutputIterator, typename T>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_copy_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
|
||||
{
|
||||
etl::fill(o_begin, o_end, value);
|
||||
@ -442,8 +482,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TOutputIterator, typename T>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_copy_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
|
||||
{
|
||||
typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
|
||||
@ -464,7 +505,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TOutputIterator, typename T, typename TCounter>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_copy_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
|
||||
{
|
||||
count += static_cast<TCounter>(etl::distance(o_begin, o_end));
|
||||
@ -481,8 +524,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TOutputIterator, typename T, typename TCounter>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_copy_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
|
||||
{
|
||||
count += static_cast<TCounter>(etl::distance(o_begin, o_end));
|
||||
@ -577,7 +621,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_copy_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
|
||||
{
|
||||
return etl::copy(i_begin, i_end, o_begin);
|
||||
@ -589,8 +635,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_copy_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
|
||||
{
|
||||
typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
|
||||
@ -614,7 +661,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator, typename TCounter>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_copy_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
|
||||
{
|
||||
TOutputIterator o_end = etl::copy(i_begin, i_end, o_begin);
|
||||
@ -630,8 +679,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator, typename TCounter>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_copy_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
|
||||
{
|
||||
TOutputIterator o_end = etl::uninitialized_copy(i_begin, i_end, o_begin);
|
||||
@ -910,7 +960,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_move_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
|
||||
{
|
||||
return etl::move(i_begin, i_end, o_begin);
|
||||
@ -922,8 +974,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_move_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
|
||||
{
|
||||
typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
|
||||
@ -947,7 +1000,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator, typename TCounter>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_move_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
|
||||
{
|
||||
TOutputIterator o_end = etl::move(i_begin, i_end, o_begin);
|
||||
@ -963,8 +1018,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator, typename TCounter>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_move_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
|
||||
{
|
||||
TOutputIterator o_end = etl::uninitialized_move(i_begin, i_end, o_begin);
|
||||
@ -1037,7 +1093,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TSize, typename TOutputIterator>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_move_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
|
||||
{
|
||||
return etl::move(i_begin, i_begin + n, o_begin);
|
||||
@ -1049,8 +1107,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TSize, typename TOutputIterator>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_move_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
|
||||
{
|
||||
typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
|
||||
@ -1074,7 +1133,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_move_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
|
||||
{
|
||||
TOutputIterator o_end = etl::move(i_begin, i_begin + n, o_begin);
|
||||
@ -1090,8 +1151,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_move_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
TOutputIterator>::type
|
||||
uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
|
||||
{
|
||||
TOutputIterator o_end = etl::uninitialized_move(i_begin, i_begin + n, o_begin);
|
||||
@ -1527,7 +1589,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TOutputIterator>
|
||||
typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
|
||||
typename etl::enable_if<
|
||||
etl::private_memory::is_trivially_value_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
void>::type
|
||||
uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
|
||||
{
|
||||
typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
|
||||
@ -1541,7 +1605,9 @@ namespace etl
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <typename TOutputIterator>
|
||||
typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
|
||||
typename etl::enable_if<
|
||||
!etl::private_memory::is_trivially_value_assignable_to_uninitialised_storage<typename etl::iterator_traits<TOutputIterator>::value_type>::value,
|
||||
void>::type
|
||||
uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
|
||||
{
|
||||
typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
|
||||
|
||||
@ -53,6 +53,10 @@ SOFTWARE.
|
||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 1
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_USING_BUILTIN_HAS_TRIVIAL_CONSTRUCTOR)
|
||||
#define ETL_USING_BUILTIN_HAS_TRIVIAL_CONSTRUCTOR 1
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_ASSIGNABLE)
|
||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_ASSIGNABLE 1
|
||||
#endif
|
||||
@ -61,6 +65,10 @@ SOFTWARE.
|
||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 1
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_USING_BUILTIN_HAS_TRIVIAL_DESTRUCTOR)
|
||||
#define ETL_USING_BUILTIN_HAS_TRIVIAL_DESTRUCTOR 1
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_USING_BUILTIN_IS_DESTRUCTIBLE)
|
||||
#define ETL_USING_BUILTIN_IS_DESTRUCTIBLE 1
|
||||
#endif
|
||||
@ -177,7 +185,14 @@ SOFTWARE.
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE)
|
||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE (__has_builtin(__has_trivial_constructor) || __has_builtin(__is_trivially_constructible))
|
||||
#define ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE __has_builtin(__is_trivially_constructible)
|
||||
#endif
|
||||
|
||||
// The legacy __has_trivial_constructor builtin. Deprecated by GCC 12 and
|
||||
// removed by GCC 15, so it must be detected separately from the standard
|
||||
// __is_trivially_constructible builtin.
|
||||
#if !defined(ETL_USING_BUILTIN_HAS_TRIVIAL_CONSTRUCTOR)
|
||||
#define ETL_USING_BUILTIN_HAS_TRIVIAL_CONSTRUCTOR __has_builtin(__has_trivial_constructor)
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_ASSIGNABLE)
|
||||
@ -185,7 +200,14 @@ SOFTWARE.
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE)
|
||||
#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(__is_trivially_destructible)
|
||||
#endif
|
||||
|
||||
// The legacy __has_trivial_destructor builtin. Deprecated by GCC 12 and
|
||||
// removed by GCC 15, so it must be detected separately from the standard
|
||||
// __is_trivially_destructible builtin.
|
||||
#if !defined(ETL_USING_BUILTIN_HAS_TRIVIAL_DESTRUCTOR)
|
||||
#define ETL_USING_BUILTIN_HAS_TRIVIAL_DESTRUCTOR __has_builtin(__has_trivial_destructor)
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_USING_BUILTIN_IS_DESTRUCTIBLE)
|
||||
|
||||
@ -4193,8 +4193,9 @@ namespace etl
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// is_constructible
|
||||
//***************************************************************************
|
||||
/// is_constructible
|
||||
#if !ETL_USING_BUILTIN_IS_CONSTRUCTIBLE
|
||||
namespace private_type_traits
|
||||
{
|
||||
template <class, class T, class... TArgs>
|
||||
@ -4207,11 +4208,19 @@ namespace etl
|
||||
{
|
||||
};
|
||||
} // namespace private_type_traits
|
||||
#endif
|
||||
|
||||
//*********************************************
|
||||
// is_constructible
|
||||
//*********************************************
|
||||
// is_constructible
|
||||
#if ETL_USING_BUILTIN_IS_CONSTRUCTIBLE
|
||||
template <class T, class... TArgs>
|
||||
struct is_constructible : public etl::bool_constant<__is_constructible(T, TArgs...)>
|
||||
{
|
||||
};
|
||||
#else
|
||||
template <class T, class... TArgs>
|
||||
using is_constructible = private_type_traits::is_constructible_<void_t<>, T, TArgs...>;
|
||||
#endif
|
||||
|
||||
//*********************************************
|
||||
// is_copy_constructible
|
||||
@ -4304,49 +4313,79 @@ namespace etl
|
||||
//*********************************************
|
||||
// is_nothrow_constructible
|
||||
template <typename T, typename... TArgs>
|
||||
#if ETL_USING_BUILTIN_IS_NOTHROW_CONSTRUCTIBLE
|
||||
struct is_nothrow_constructible : public etl::bool_constant<__is_nothrow_constructible(T, TArgs...)>
|
||||
#else
|
||||
struct is_nothrow_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_nothrow_default_constructible
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_NOTHROW_CONSTRUCTIBLE
|
||||
struct is_nothrow_default_constructible : public etl::is_nothrow_constructible<T>
|
||||
#else
|
||||
struct is_nothrow_default_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_nothrow_copy_constructible
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_NOTHROW_CONSTRUCTIBLE
|
||||
struct is_nothrow_copy_constructible : public etl::is_nothrow_constructible<T, typename etl::add_lvalue_reference<const T>::type>
|
||||
#else
|
||||
struct is_nothrow_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_nothrow_move_constructible
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_NOTHROW_CONSTRUCTIBLE
|
||||
struct is_nothrow_move_constructible : public etl::is_nothrow_constructible<T, typename etl::add_rvalue_reference<T>::type>
|
||||
#else
|
||||
struct is_nothrow_move_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_nothrow_assignable
|
||||
template <typename T, typename U>
|
||||
#if ETL_USING_BUILTIN_IS_NOTHROW_ASSIGNABLE
|
||||
struct is_nothrow_assignable : public etl::bool_constant<__is_nothrow_assignable(T, U)>
|
||||
#else
|
||||
struct is_nothrow_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_nothrow_copy_assignable
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_NOTHROW_ASSIGNABLE
|
||||
struct is_nothrow_copy_assignable
|
||||
: public etl::is_nothrow_assignable<typename etl::add_lvalue_reference<T>::type, typename etl::add_lvalue_reference<const T>::type>
|
||||
#else
|
||||
struct is_nothrow_copy_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_nothrow_move_assignable
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_NOTHROW_ASSIGNABLE
|
||||
struct is_nothrow_move_assignable
|
||||
: public etl::is_nothrow_assignable<typename etl::add_lvalue_reference<T>::type, typename etl::add_rvalue_reference<T>::type>
|
||||
#else
|
||||
struct is_nothrow_move_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
#endif
|
||||
@ -4354,35 +4393,68 @@ namespace etl
|
||||
//*********************************************
|
||||
// is_trivially_constructible
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE
|
||||
struct is_trivially_constructible : public etl::bool_constant<__is_trivially_constructible(T)>
|
||||
#elif ETL_USING_CPP11 && ETL_USING_BUILTIN_HAS_TRIVIAL_CONSTRUCTOR
|
||||
struct is_trivially_constructible : public etl::bool_constant<__has_trivial_constructor(T) && etl::is_constructible<T>::value>
|
||||
#else
|
||||
struct is_trivially_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_trivially_copy_constructible
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE
|
||||
struct is_trivially_copy_constructible
|
||||
: public etl::bool_constant<__is_trivially_constructible(T, typename etl::add_lvalue_reference<const T>::type)>
|
||||
#elif ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE
|
||||
// A trivially copyable type may still have a deleted copy constructor, so the
|
||||
// copy constructor must be checked for as well.
|
||||
struct is_trivially_copy_constructible : public etl::bool_constant<__is_trivially_copyable(T) && etl::is_copy_constructible<T>::value>
|
||||
#else
|
||||
struct is_trivially_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_trivially_default_constructible
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE || ETL_USING_BUILTIN_HAS_TRIVIAL_CONSTRUCTOR
|
||||
struct is_trivially_default_constructible : public etl::is_trivially_constructible<T>
|
||||
#else
|
||||
struct is_trivially_default_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_trivially_move_constructible
|
||||
template <typename T>
|
||||
#if ETL_USING_CPP11 && ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE
|
||||
struct is_trivially_move_constructible : public etl::bool_constant<__is_trivially_constructible(T, typename etl::add_rvalue_reference<T>::type)>
|
||||
#elif ETL_USING_CPP11 && ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE
|
||||
// A trivially copyable type may still have a deleted move constructor, so the
|
||||
// move constructor must be checked for as well.
|
||||
struct is_trivially_move_constructible : public etl::bool_constant<__is_trivially_copyable(T) && etl::is_move_constructible<T>::value>
|
||||
#else
|
||||
struct is_trivially_move_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
//*********************************************
|
||||
// is_trivially_destructible
|
||||
template <typename T>
|
||||
#if ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE
|
||||
struct is_trivially_destructible : public etl::bool_constant<__is_trivially_destructible(T)>
|
||||
#elif ETL_USING_CPP11 && ETL_USING_BUILTIN_HAS_TRIVIAL_DESTRUCTOR
|
||||
struct is_trivially_destructible : public etl::bool_constant<__has_trivial_destructor(T) && etl::is_destructible<T>::value>
|
||||
#else
|
||||
struct is_trivially_destructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@ -138,6 +138,33 @@ namespace
|
||||
}
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
// A trivially copyable type that can be copy constructed but not copy
|
||||
// assigned. It must use the placement-new uninitialized algorithm path.
|
||||
struct CopyConstructOnly
|
||||
{
|
||||
int value;
|
||||
|
||||
CopyConstructOnly() = default;
|
||||
|
||||
CopyConstructOnly(const CopyConstructOnly&) = default;
|
||||
CopyConstructOnly& operator=(const CopyConstructOnly&) = delete;
|
||||
};
|
||||
|
||||
// A trivially copyable type that can be move constructed but not move
|
||||
// assigned. It must use the placement-new uninitialized algorithm path.
|
||||
struct MoveConstructOnly
|
||||
{
|
||||
int value;
|
||||
|
||||
MoveConstructOnly() = default;
|
||||
|
||||
MoveConstructOnly(const MoveConstructOnly&) = delete;
|
||||
MoveConstructOnly(MoveConstructOnly&&) = default;
|
||||
MoveConstructOnly& operator=(MoveConstructOnly&&) = delete;
|
||||
};
|
||||
#endif
|
||||
|
||||
//***********************************
|
||||
template <typename T>
|
||||
struct NoDelete
|
||||
@ -546,6 +573,59 @@ namespace
|
||||
CHECK_EQUAL(0U, count);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
TEST(test_uninitialized_algorithms_use_construction_when_assignment_is_deleted)
|
||||
{
|
||||
CopyConstructOnly copy_source[2];
|
||||
copy_source[0].value = 1;
|
||||
copy_source[1].value = 2;
|
||||
|
||||
alignas(CopyConstructOnly) unsigned char copy_storage[sizeof(CopyConstructOnly) * 2U];
|
||||
CopyConstructOnly* copy_destination = reinterpret_cast<CopyConstructOnly*>(copy_storage);
|
||||
|
||||
etl::uninitialized_copy(copy_source, copy_source + 2, copy_destination);
|
||||
CHECK_EQUAL(1, copy_destination[0].value);
|
||||
CHECK_EQUAL(2, copy_destination[1].value);
|
||||
|
||||
alignas(CopyConstructOnly) unsigned char fill_storage[sizeof(CopyConstructOnly) * 2U];
|
||||
CopyConstructOnly* fill_destination = reinterpret_cast<CopyConstructOnly*>(fill_storage);
|
||||
|
||||
etl::uninitialized_fill(fill_destination, fill_destination + 2, copy_source[0]);
|
||||
CHECK_EQUAL(1, fill_destination[0].value);
|
||||
CHECK_EQUAL(1, fill_destination[1].value);
|
||||
|
||||
alignas(CopyConstructOnly) unsigned char value_storage[sizeof(CopyConstructOnly) * 2U];
|
||||
CopyConstructOnly* value_destination = reinterpret_cast<CopyConstructOnly*>(value_storage);
|
||||
|
||||
etl::uninitialized_value_construct(value_destination, value_destination + 2);
|
||||
CHECK_EQUAL(0, value_destination[0].value);
|
||||
CHECK_EQUAL(0, value_destination[1].value);
|
||||
|
||||
MoveConstructOnly move_source[2];
|
||||
move_source[0].value = 3;
|
||||
move_source[1].value = 4;
|
||||
|
||||
alignas(MoveConstructOnly) unsigned char move_storage[sizeof(MoveConstructOnly) * 2U];
|
||||
MoveConstructOnly* move_destination = reinterpret_cast<MoveConstructOnly*>(move_storage);
|
||||
|
||||
etl::uninitialized_move(move_source, move_source + 2, move_destination);
|
||||
CHECK_EQUAL(3, move_destination[0].value);
|
||||
CHECK_EQUAL(4, move_destination[1].value);
|
||||
|
||||
MoveConstructOnly move_n_source[2];
|
||||
move_n_source[0].value = 5;
|
||||
move_n_source[1].value = 6;
|
||||
|
||||
alignas(MoveConstructOnly) unsigned char move_n_storage[sizeof(MoveConstructOnly) * 2U];
|
||||
MoveConstructOnly* move_n_destination = reinterpret_cast<MoveConstructOnly*>(move_n_storage);
|
||||
|
||||
etl::uninitialized_move_n(move_n_source, 2U, move_n_destination);
|
||||
CHECK_EQUAL(5, move_n_destination[0].value);
|
||||
CHECK_EQUAL(6, move_n_destination[1].value);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_uninitialized_default_construct_n_trivial)
|
||||
{
|
||||
|
||||
@ -150,6 +150,29 @@ namespace
|
||||
NotDefaultConstructible& operator=(NotDefaultConstructible&&) = delete;
|
||||
};
|
||||
|
||||
// The legacy compiler builtin for trivial construction does not test
|
||||
// accessibility, unlike is_trivially_constructible.
|
||||
struct PrivateTrivialDefaultConstructor
|
||||
{
|
||||
private:
|
||||
|
||||
PrivateTrivialDefaultConstructor() = default;
|
||||
};
|
||||
|
||||
// The legacy compiler builtin for trivial destruction does not test
|
||||
// accessibility or deletion, unlike is_trivially_destructible.
|
||||
struct PrivateTrivialDestructor
|
||||
{
|
||||
private:
|
||||
|
||||
~PrivateTrivialDestructor() = default;
|
||||
};
|
||||
|
||||
struct DeletedTrivialDestructor
|
||||
{
|
||||
~DeletedTrivialDestructor() = delete;
|
||||
};
|
||||
|
||||
// A function to test etl::type_identity.
|
||||
template <typename T>
|
||||
T type_identity_test_add(T first, typename etl::type_identity<T>::type second)
|
||||
@ -2851,7 +2874,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST(test_is_trivially_constructible)
|
||||
{
|
||||
#if ETL_USING_STL || defined(ETL_USE_TYPE_TRAITS_BUILTINS) || defined(ETL_USER_DEFINED_TYPE_TRAITS)
|
||||
#if ETL_USING_STL || defined(ETL_USE_TYPE_TRAITS_BUILTINS) || defined(ETL_USER_DEFINED_TYPE_TRAITS) || ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE \
|
||||
|| ETL_USING_BUILTIN_HAS_TRIVIAL_CONSTRUCTOR
|
||||
#if ETL_USING_CPP17
|
||||
CHECK((etl::is_trivially_constructible_v<Copyable>) == (std::is_trivially_constructible_v<Copyable>));
|
||||
CHECK((etl::is_trivially_constructible_v<Moveable>) == (std::is_trivially_constructible_v<Moveable>));
|
||||
@ -2861,6 +2885,11 @@ namespace
|
||||
CHECK((etl::is_trivially_constructible<Moveable>::value) == (std::is_trivially_constructible<Moveable>::value));
|
||||
CHECK((etl::is_trivially_constructible<MoveableCopyable>::value) == (std::is_trivially_constructible<MoveableCopyable>::value));
|
||||
#endif
|
||||
#if ETL_USING_CPP11
|
||||
CHECK(!etl::is_trivially_constructible<PrivateTrivialDefaultConstructor>::value);
|
||||
CHECK((etl::is_trivially_constructible<PrivateTrivialDefaultConstructor>::value)
|
||||
== (std::is_trivially_constructible<PrivateTrivialDefaultConstructor>::value));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2919,7 +2948,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST(test_is_trivially_destructible)
|
||||
{
|
||||
#if ETL_USING_STL || defined(ETL_USE_TYPE_TRAITS_BUILTINS) || defined(ETL_USER_DEFINED_TYPE_TRAITS)
|
||||
#if ETL_USING_STL || defined(ETL_USE_TYPE_TRAITS_BUILTINS) || defined(ETL_USER_DEFINED_TYPE_TRAITS) || ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE \
|
||||
|| ETL_USING_BUILTIN_HAS_TRIVIAL_DESTRUCTOR
|
||||
#if ETL_USING_CPP17
|
||||
CHECK((etl::is_trivially_destructible_v<Copyable>) == (std::is_trivially_destructible_v<Copyable>));
|
||||
CHECK((etl::is_trivially_destructible_v<Moveable>) == (std::is_trivially_destructible_v<Moveable>));
|
||||
@ -2929,6 +2959,12 @@ namespace
|
||||
CHECK((etl::is_trivially_destructible<Moveable>::value) == (std::is_trivially_destructible<Moveable>::value));
|
||||
CHECK((etl::is_trivially_destructible<MoveableCopyable>::value) == (std::is_trivially_destructible<MoveableCopyable>::value));
|
||||
#endif
|
||||
#if ETL_USING_CPP11
|
||||
CHECK(!etl::is_trivially_destructible<PrivateTrivialDestructor>::value);
|
||||
CHECK(!etl::is_trivially_destructible<DeletedTrivialDestructor>::value);
|
||||
CHECK((etl::is_trivially_destructible<PrivateTrivialDestructor>::value) == (std::is_trivially_destructible<PrivateTrivialDestructor>::value));
|
||||
CHECK((etl::is_trivially_destructible<DeletedTrivialDestructor>::value) == (std::is_trivially_destructible<DeletedTrivialDestructor>::value));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user