diff --git a/include/etl/profiles/determine_builtin_support.h b/include/etl/profiles/determine_builtin_support.h index d9838227..8aab897b 100644 --- a/include/etl/profiles/determine_builtin_support.h +++ b/include/etl/profiles/determine_builtin_support.h @@ -55,6 +55,10 @@ SOFTWARE. #if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE) #define ETL_USING_BUILTIN_UNDERLYING_TYPE 1 #endif + + #if !defined(ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED) + #define ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED 1 + #endif #endif #if defined(__has_builtin) && !defined(ETL_COMPILER_MICROSOFT) // Use __has_builtin to check for existence of builtin functions? Fix VS2022 intellisense issue. @@ -82,6 +86,10 @@ SOFTWARE. #define ETL_USING_BUILTIN_UNDERLYING_TYPE __has_builtin(__underlying_type) #endif + #if !defined(ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED) + #define ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED __has_builtin(__builtin_is_constant_evaluated) + #endif + #if !defined(ETL_USING_BUILTIN_MEMCPY) #define ETL_USING_BUILTIN_MEMCPY __has_builtin(__builtin_memcpy) #endif @@ -128,6 +136,10 @@ SOFTWARE. #define ETL_USING_BUILTIN_UNDERLYING_TYPE 0 #endif +#if !defined(ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED) + #define ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED 0 +#endif + #if !defined(ETL_USING_BUILTIN_MEMCPY) #define ETL_USING_BUILTIN_MEMCPY 0 #endif @@ -160,6 +172,7 @@ namespace etl static ETL_CONSTANT bool using_builtin_is_trivially_destructible = (ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE == 1); static ETL_CONSTANT bool using_builtin_is_trivially_copyable = (ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE == 1); static ETL_CONSTANT bool using_builtin_underlying_type = (ETL_USING_BUILTIN_UNDERLYING_TYPE == 1); + static ETL_CONSTANT bool using_builtin_is_constant_evaluated = (ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED == 1); static ETL_CONSTANT bool using_builtin_memcpy = (ETL_USING_BUILTIN_MEMCPY == 1); static ETL_CONSTANT bool using_builtin_memmove = (ETL_USING_BUILTIN_MEMMOVE == 1); static ETL_CONSTANT bool using_builtin_memset = (ETL_USING_BUILTIN_MEMSET == 1); diff --git a/include/etl/type_traits.h b/include/etl/type_traits.h index a9222820..3c9ac66b 100644 --- a/include/etl/type_traits.h +++ b/include/etl/type_traits.h @@ -2482,6 +2482,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/test/test_type_traits.cpp b/test/test_type_traits.cpp index 15f9b8a4..48aa9a31 100644 --- a/test/test_type_traits.cpp +++ b/test/test_type_traits.cpp @@ -1472,4 +1472,22 @@ namespace CHECK_FALSE((etl::is_specialization, specialized>::value)); #endif } + +#if ETL_USING_CPP11 + //************************************************************************* + TEST(test_is_constant_evaluated) + { + const bool c0 = etl::is_constant_evaluated(); +#if !ETL_USING_CPP23 && defined(ETL_COMPILER_MICROSOFT) + // Not supported on MSVC via __has_builtin, see determine_builtin_support.h + CHECK_FALSE(c0); +#else + CHECK_TRUE(c0); +#endif + + volatile int i = 1; + const bool c1 = (((i == 1) && etl::is_constant_evaluated()) ? true : false); + CHECK_FALSE(c1); + } +#endif }