mirror of https://github.com/ARMmbed/mbed-os.git
Add mstd::is_constant_evaluated
GCC 9 and sufficiently-new Clang (including ARM Compiler 6.13) give us
access to the C++20 (draft) `is_constant_evaluated` test. Allows us to
restrict code to compile-time only.
This is particularly useful when using assembler intrinsics, which the
compiler cannot optimise or compile-time evaluate. It allows us to write
something like
constexpr uint32_t reverse_bits(uint32_t x)
{
if (is_constant_evaluated(x)) {
// C code to do calculation here
return x;
} else {
// an assembler intrinsic that cannot be optimised
return __RBIT(x);
}
}
This can then be totally compile-time given a constant input.
(In this example, ultimately it would be a good idea to include this
functionality in CMSIS's GCC `__RBIT`, which needs it because GCC
requires use of assembler. Clang implements `__RBIT` as a built-in,
meaning it can already compute it at compile-time, so does not benefit.).
pull/11897/head
parent
04f929e85f
commit
07d43b72d2
|
|
@ -47,6 +47,7 @@
|
||||||
* - mstd::is_invocable, mbed::is_invocable_r, etc
|
* - mstd::is_invocable, mbed::is_invocable_r, etc
|
||||||
* - mstd::invoke_result
|
* - mstd::invoke_result
|
||||||
* - logical operator traits (mstd::conjunction, mstd::disjunction, mstd::negation)
|
* - logical operator traits (mstd::conjunction, mstd::disjunction, mstd::negation)
|
||||||
|
* - mstd::is_constant_evaluated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mstd_cstddef>
|
#include <mstd_cstddef>
|
||||||
|
|
@ -1361,6 +1362,29 @@ struct is_nothrow_invocable_r : impl::is_invocable_r<R, invoke_result<F, Args...
|
||||||
|
|
||||||
#endif // __cpp_lib_is_invocable
|
#endif // __cpp_lib_is_invocable
|
||||||
|
|
||||||
|
/* C++20 is_constant_evaluated */
|
||||||
|
constexpr bool is_constant_evaluated() noexcept
|
||||||
|
{
|
||||||
|
#ifdef __clang__
|
||||||
|
#if __has_builtin(__builtin_is_constant_evaluated)
|
||||||
|
#define MSTD_HAS_IS_CONSTANT_EVALUATED 1
|
||||||
|
return __builtin_is_constant_evaluated();
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
#elif __GNUC__ >= 9
|
||||||
|
#define MSTD_HAS_IS_CONSTANT_EVALUATED 1
|
||||||
|
return __builtin_is_constant_evaluated();
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MSTD_HAS_IS_CONSTANT_EVALUATED
|
||||||
|
#define MSTD_CONSTEXPR_IF_HAS_IS_CONSTANT_EVALUATED constexpr
|
||||||
|
#else
|
||||||
|
#define MSTD_CONSTEXPR_IF_HAS_IS_CONSTANT_EVALUATED
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace mstd
|
} // namespace mstd
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue