C++20 comes with a handy is_constant_evaluated which can be used to detect evaluation context.
Essentially, it can allow gcem to be a complete wrapper around stdlib operations (where stdlib is being replaced for compile-time context) and better runtime performance.
Moreover, without depending on C++ version, __cpp_lib_is_constant_evaluated can be used to check if the compiler provides the function (from header <type_traits>)
Before:
template<typename T>
constexpr
return_t<T>
ceil(const T x)
noexcept
{
return internal::ceil_check( static_cast<return_t<T>>(x) );
}
After:
template<typename T>
constexpr
return_t<T>
ceil(const T x)
noexcept
{
#ifdef __cpp_lib_is_constant_evaluated
if (!std::is_constant_evaluated()) return std::ceil(static_cast<return_t<T>>(x));
#endif
return internal::ceil_check( static_cast<return_t<T>>(x) );
}
Benefits:
- GCEM still remains C++11 compliant, but provides functionality if the compiler can via extensions
- We can use GCEM without incurring a penalty if a run-time context is used where compile-time was expected
Cons: Slight more code
C++20 comes with a handy
is_constant_evaluatedwhich can be used to detect evaluation context.Essentially, it can allow gcem to be a complete wrapper around stdlib operations (where stdlib is being replaced for compile-time context) and better runtime performance.
Moreover, without depending on C++ version,
__cpp_lib_is_constant_evaluatedcan be used to check if the compiler provides the function (from header<type_traits>)Before:
After:
Benefits:
Cons: Slight more code