Skip to content

Commit 07d43b7

Browse files
committed
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.).
1 parent 04f929e commit 07d43b7

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

platform/cxxsupport/mstd_type_traits

+24
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
* - mstd::is_invocable, mbed::is_invocable_r, etc
4848
* - mstd::invoke_result
4949
* - logical operator traits (mstd::conjunction, mstd::disjunction, mstd::negation)
50+
* - mstd::is_constant_evaluated
5051
*/
5152

5253
#include <mstd_cstddef>
@@ -1361,6 +1362,29 @@ struct is_nothrow_invocable_r : impl::is_invocable_r<R, invoke_result<F, Args...
13611362

13621363
#endif // __cpp_lib_is_invocable
13631364

1365+
/* C++20 is_constant_evaluated */
1366+
constexpr bool is_constant_evaluated() noexcept
1367+
{
1368+
#ifdef __clang__
1369+
#if __has_builtin(__builtin_is_constant_evaluated)
1370+
#define MSTD_HAS_IS_CONSTANT_EVALUATED 1
1371+
return __builtin_is_constant_evaluated();
1372+
#else
1373+
return false;
1374+
#endif
1375+
#elif __GNUC__ >= 9
1376+
#define MSTD_HAS_IS_CONSTANT_EVALUATED 1
1377+
return __builtin_is_constant_evaluated();
1378+
#else
1379+
return false;
1380+
#endif
1381+
}
1382+
1383+
#if MSTD_HAS_IS_CONSTANT_EVALUATED
1384+
#define MSTD_CONSTEXPR_IF_HAS_IS_CONSTANT_EVALUATED constexpr
1385+
#else
1386+
#define MSTD_CONSTEXPR_IF_HAS_IS_CONSTANT_EVALUATED
1387+
#endif
13641388

13651389
} // namespace mstd
13661390

0 commit comments

Comments
 (0)