diff --git a/include/etl/generators/type_traits_generator.h b/include/etl/generators/type_traits_generator.h index d47c14dc..eef30bd4 100644 --- a/include/etl/generators/type_traits_generator.h +++ b/include/etl/generators/type_traits_generator.h @@ -742,11 +742,11 @@ namespace etl ///\ingroup type_traits /// Implemented by checking if type is convertible to an integer through static_cast - namespace private_type_traits + namespace private_type_traits { // Base case template - struct is_convertible_to_int + struct is_convertible_to_int : false_type { }; @@ -755,7 +755,7 @@ namespace etl // 2nd template argument of base case defaults to int to ensure that this partial specialization is always tried first template struct is_convertible_to_int(declval()))> - : true_type + : true_type { }; } @@ -765,7 +765,7 @@ namespace etl : integral_constant::value && !is_class::value && !is_arithmetic::value && - !is_reference::value> + !is_reference::value> { }; @@ -1577,7 +1577,7 @@ typedef integral_constant true_type; //*************************************************************************** /// Get the Nth base of a recursively inherited type. /// Requires that the class has defined 'base_type'. - //*************************************************************************** + //*************************************************************************** // Recursive definition of the type. template struct nth_base @@ -1837,142 +1837,7 @@ typedef integral_constant true_type; using is_trivially_copyable = etl::bool_constant::value || etl::is_pointer::value>; #endif -#elif defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) - - //********************************************* - // Use the compiler's builtins. - //********************************************* - - //********************************************* - // is_assignable - template - struct is_assignable - { - static ETL_CONSTANT bool value = __is_assignable(T1, T2); - }; - -#if ETL_USING_CPP11 - //********************************************* - // is_constructible - template - struct is_constructible - { - static ETL_CONSTANT bool value = __is_constructible(T, TArgs...); - }; -#else - //********************************************* - // is_constructible - template - struct is_constructible - { - static ETL_CONSTANT bool value = __is_constructible(T, TArgs); - }; - - //********************************************* - // is_constructible - template - struct is_constructible - { - static ETL_CONSTANT bool value = __is_constructible(T); - }; -#endif - - //********************************************* - // is_copy_constructible - template - struct is_copy_constructible : public etl::is_constructible::type> - { - }; - - //********************************************* - // is_move_constructible - template - struct is_move_constructible : public etl::is_constructible - { - }; - -#if ETL_USING_CPP11 - //********************************************* - // is_trivially_constructible - template - struct is_trivially_constructible - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_constructor(T); -#else - static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs...); -#endif - }; -#else - //********************************************* - // is_trivially_constructible - template - struct is_trivially_constructible - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_constructor(T); -#else - static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs); -#endif - }; - - //********************************************* - // is_trivially_constructible - template - struct is_trivially_constructible - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_constructor(T); -#else - static ETL_CONSTANT bool value = __is_trivially_constructible(T); -#endif - }; -#endif - - //********************************************* - // is_trivially_copy_constructible - template - struct is_trivially_copy_constructible : public is_trivially_constructible::type> - { - }; - - //********************************************* - // is_trivially_destructible - template - struct is_trivially_destructible - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_destructor(T); -#else - static ETL_CONSTANT bool value = __is_trivially_destructible(T); -#endif - }; - - //********************************************* - // is_trivially_copy_assignable - template - struct is_trivially_copy_assignable - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_copy(T); -#else - static ETL_CONSTANT bool value = __is_trivially_copyable(T); -#endif - }; - - //********************************************* - // is_trivially_copyable - template - struct is_trivially_copyable - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_copy(T); -#else - static ETL_CONSTANT bool value = __is_trivially_copyable(T); -#endif - }; - -#elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) +#elif defined(ETL_USER_DEFINED_TYPE_TRAITS) //********************************************* // Force the user to provide specialisations for @@ -2108,21 +1973,38 @@ typedef integral_constant true_type; #else //********************************************* - // Assume that anything other than arithmetics - // and pointers return false for the traits. + // Deduce traits based on if builtins exist. //********************************************* //********************************************* // is_assignable +#if ETL_USING_BUILTIN_IS_ASSIGNABLE + template + struct is_assignable + { + static ETL_CONSTANT bool value = __is_assignable(T1, T2); + }; +#else template struct is_assignable : public etl::bool_constant<(etl::is_arithmetic::value || etl::is_pointer::value) && (etl::is_arithmetic::value || etl::is_pointer::value)> { }; +#endif #if ETL_USING_CPP11 +#if ETL_USING_BUILTIN_IS_CONSTRUCTIBLE + //********************************************* + // is_constructible + template + struct is_constructible + { + static ETL_CONSTANT bool value = __is_constructible(T, TArgs...); + }; + +#else //*************************************************************************** - /// is_constructible - namespace private_type_traits + /// is_constructible_ + namespace private_type_traits { template struct is_constructible_ : etl::false_type {}; @@ -2135,6 +2017,7 @@ typedef integral_constant true_type; // is_constructible template using is_constructible = private_type_traits::is_constructible_, T, Args...>; +#endif //********************************************* // is_copy_constructible @@ -2153,7 +2036,31 @@ typedef integral_constant true_type; template <> struct is_move_constructible : public false_type{}; #else +#if ETL_USING_BUILTIN_IS_CONSTRUCTIBLE + //********************************************* + // is_constructible + template + struct is_constructible + { + static ETL_CONSTANT bool value = __is_constructible(T, TArgs); + }; + //********************************************* + // is_constructible + template + struct is_constructible + { + static ETL_CONSTANT bool value = __is_constructible(T); + }; + + //********************************************* + // is_copy_constructible + template struct is_copy_constructible : public is_constructible::type>::type>{}; + + //********************************************* + // is_move_constructible + template struct is_move_constructible : public is_constructible{}; +#else //********************************************* // is_copy_constructible template @@ -2168,7 +2075,53 @@ typedef integral_constant true_type; { }; #endif +#endif +#if ETL_USING_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE +#if ETL_USING_CPP11 + //********************************************* + // is_trivially_constructible + template + struct is_trivially_constructible + { +#if defined(ETL_COMPILER_GCC) + static ETL_CONSTANT bool value = __has_trivial_constructor(T); +#else + static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs...); +#endif + }; +#else + //********************************************* + // is_trivially_constructible + template + struct is_trivially_constructible + { +#if defined(ETL_COMPILER_GCC) + static ETL_CONSTANT bool value = __has_trivial_constructor(T); +#else + static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs); +#endif + }; + + //********************************************* + // is_trivially_constructible + template + struct is_trivially_constructible + { +#if defined(ETL_COMPILER_GCC) + static ETL_CONSTANT bool value = __has_trivial_constructor(T); +#else + static ETL_CONSTANT bool value = __is_trivially_constructible(T); +#endif + }; +#endif + //********************************************* + // is_trivially_copy_constructible + template + struct is_trivially_copy_constructible : public is_trivially_constructible::type> + { + }; +#else //********************************************* // is_trivially_constructible template @@ -2182,28 +2135,70 @@ typedef integral_constant true_type; struct is_trivially_copy_constructible : public etl::bool_constant::value || etl::is_pointer::value> { }; +#endif +#if ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE + //********************************************* + // is_trivially_destructible + template + struct is_trivially_destructible + { +#if defined(ETL_COMPILER_GCC) + static ETL_CONSTANT bool value = __has_trivial_destructor(T); +#else + static ETL_CONSTANT bool value = __is_trivially_destructible(T); +#endif + }; +#else //********************************************* // is_trivially_destructible template struct is_trivially_destructible : public etl::bool_constant::value || etl::is_pointer::value> { }; +#endif +#if ETL_USING_BUILTIN_IS_TRIVIALLY_ASSIGNABLE + //********************************************* + // is_trivially_copy_assignable + template + struct is_trivially_copy_assignable + { +#if defined(ETL_COMPILER_GCC) + static ETL_CONSTANT bool value = __has_trivial_assign(T); +#else + static ETL_CONSTANT bool value = __is_trivially_assignable(typename add_lvalue_reference::type, + typename add_lvalue_reference::type); +#endif + }; +#else //********************************************* // is_trivially_copy_assignable template struct is_trivially_copy_assignable : public etl::bool_constant::value || etl::is_pointer::value> { }; +#endif +#if ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE + //********************************************* + // is_trivially_copyable + template + struct is_trivially_copyable + { +#if defined(ETL_COMPILER_GCC) + static ETL_CONSTANT bool value = __has_trivial_copy(T); +#else + static ETL_CONSTANT bool value = __is_trivially_copyable(T); +#endif + }; +#else //********************************************* // is_trivially_copyable template struct is_trivially_copyable : public etl::bool_constant::value || etl::is_pointer::value> { }; - #endif template @@ -2238,8 +2233,8 @@ typedef integral_constant true_type; template inline constexpr bool is_constructible_v = etl::is_constructible::value; - template - inline constexpr bool is_default_constructible_v = etl::is_default_constructible::value; + template + inline constexpr bool is_default_constructible_v = etl::is_default_constructible::value; template inline constexpr bool is_copy_constructible_v = etl::is_copy_constructible::value; @@ -2247,8 +2242,8 @@ typedef integral_constant true_type; template inline constexpr bool is_move_constructible_v = etl::is_move_constructible::value; - template - inline constexpr bool is_trivially_constructible_v = etl::is_trivially_constructible::value; + template + inline constexpr bool is_trivially_constructible_v = etl::is_trivially_constructible::value; template inline constexpr bool is_trivially_copy_constructible_v = etl::is_trivially_copy_constructible::value; @@ -2263,6 +2258,7 @@ typedef integral_constant true_type; inline constexpr bool is_trivially_copyable_v = etl::is_trivially_copyable::value; #endif +#endif // ETL_USING_STL && ETL_USING_CPP11 && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) #if ETL_USING_CPP11 //********************************************* @@ -2301,7 +2297,7 @@ typedef integral_constant true_type; }; template - struct common_type_2_impl + struct common_type_2_impl : decay_conditional_result { }; @@ -2319,8 +2315,8 @@ typedef integral_constant true_type; struct common_type : etl::conditional::type>::value&& etl::is_same::type>::value, private_common_type::common_type_2_impl, - common_type::type, - typename etl::decay::type>>::type + common_type::type, + typename etl::decay::type>>::type { }; @@ -2489,6 +2485,28 @@ typedef integral_constant true_type; template class Template> inline constexpr bool is_specialization_v = etl::is_specialization::value; #endif + + //********************************************* + // is_constant_evaluated + ETL_CONSTEXPR inline bool is_constant_evaluated() ETL_NOEXCEPT + { +#if ETL_USING_CPP23 + if consteval + { + return true; + } + else + { + return false; + } +#elif ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED == 1 + // fallback for C++20 on supported compilers + return __builtin_is_constant_evaluated(); +#else + // default if unsupported + return false; +#endif + } } // Helper macros diff --git a/include/etl/profiles/determine_builtin_support.h b/include/etl/profiles/determine_builtin_support.h index b45b23f7..82bf4dae 100644 --- a/include/etl/profiles/determine_builtin_support.h +++ b/include/etl/profiles/determine_builtin_support.h @@ -98,6 +98,10 @@ SOFTWARE. #define ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE (__has_builtin(__has_trivial_destructor) || __has_builtin(__is_trivially_destructible)) #endif + #if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_ASSIGNABLE) + #define ETL_USING_BUILTIN_IS_TRIVIALLY_ASSIGNABLE (__has_builtin(__has_trivial_assign) || __has_builtin(__is_trivially_assignable)) + #endif + #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)) #endif diff --git a/include/etl/type_traits.h b/include/etl/type_traits.h index a30efc76..de030470 100644 --- a/include/etl/type_traits.h +++ b/include/etl/type_traits.h @@ -730,11 +730,11 @@ namespace etl ///\ingroup type_traits /// Implemented by checking if type is convertible to an integer through static_cast - namespace private_type_traits + namespace private_type_traits { // Base case template - struct is_convertible_to_int + struct is_convertible_to_int : false_type { }; @@ -743,7 +743,7 @@ namespace etl // 2nd template argument of base case defaults to int to ensure that this partial specialization is always tried first template struct is_convertible_to_int(declval()))> - : true_type + : true_type { }; } @@ -753,7 +753,7 @@ namespace etl : integral_constant::value && !is_class::value && !is_arithmetic::value && - !is_reference::value> + !is_reference::value> { }; @@ -1570,7 +1570,7 @@ typedef integral_constant true_type; //*************************************************************************** /// Get the Nth base of a recursively inherited type. /// Requires that the class has defined 'base_type'. - //*************************************************************************** + //*************************************************************************** // Recursive definition of the type. template struct nth_base @@ -1997,7 +1997,7 @@ typedef integral_constant true_type; #else //*************************************************************************** /// is_constructible_ - namespace private_type_traits + namespace private_type_traits { template struct is_constructible_ : etl::false_type {}; @@ -2052,11 +2052,7 @@ typedef integral_constant true_type; //********************************************* // is_move_constructible -#if ETL_USING_CPP11 - template struct is_move_constructible : public is_constructible::type>{}; -#else template struct is_move_constructible : public is_constructible{}; -#endif #else //********************************************* // is_copy_constructible @@ -2155,19 +2151,29 @@ typedef integral_constant true_type; }; #endif -#if ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE +#if ETL_USING_BUILTIN_IS_TRIVIALLY_ASSIGNABLE //********************************************* // is_trivially_copy_assignable template struct is_trivially_copy_assignable { #if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_copy(T); + static ETL_CONSTANT bool value = __has_trivial_assign(T); #else - static ETL_CONSTANT bool value = __is_trivially_copyable(T); + static ETL_CONSTANT bool value = __is_trivially_assignable(typename add_lvalue_reference::type, + typename add_lvalue_reference::type); #endif }; +#else + //********************************************* + // is_trivially_copy_assignable + template + struct is_trivially_copy_assignable : public etl::bool_constant::value || etl::is_pointer::value> + { + }; +#endif +#if ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE //********************************************* // is_trivially_copyable template @@ -2180,21 +2186,12 @@ typedef integral_constant true_type; #endif }; #else - //********************************************* - // is_trivially_copy_assignable - template - struct is_trivially_copy_assignable : public etl::bool_constant::value || etl::is_pointer::value> - { - }; - //********************************************* // is_trivially_copyable template struct is_trivially_copyable : public etl::bool_constant::value || etl::is_pointer::value> { }; -#endif - #endif template @@ -2229,8 +2226,8 @@ typedef integral_constant true_type; template inline constexpr bool is_constructible_v = etl::is_constructible::value; - template - inline constexpr bool is_default_constructible_v = etl::is_default_constructible::value; + template + inline constexpr bool is_default_constructible_v = etl::is_default_constructible::value; template inline constexpr bool is_copy_constructible_v = etl::is_copy_constructible::value; @@ -2238,8 +2235,8 @@ typedef integral_constant true_type; template inline constexpr bool is_move_constructible_v = etl::is_move_constructible::value; - template - inline constexpr bool is_trivially_constructible_v = etl::is_trivially_constructible::value; + template + inline constexpr bool is_trivially_constructible_v = etl::is_trivially_constructible::value; template inline constexpr bool is_trivially_copy_constructible_v = etl::is_trivially_copy_constructible::value; @@ -2254,6 +2251,7 @@ typedef integral_constant true_type; inline constexpr bool is_trivially_copyable_v = etl::is_trivially_copyable::value; #endif +#endif // ETL_USING_STL && ETL_USING_CPP11 && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) #if ETL_USING_CPP11 //********************************************* @@ -2292,7 +2290,7 @@ typedef integral_constant true_type; }; template - struct common_type_2_impl + struct common_type_2_impl : decay_conditional_result { }; @@ -2310,8 +2308,8 @@ typedef integral_constant true_type; struct common_type : etl::conditional::type>::value&& etl::is_same::type>::value, private_common_type::common_type_2_impl, - common_type::type, - typename etl::decay::type>>::type + common_type::type, + typename etl::decay::type>>::type { };