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.).
|
||
|---|---|---|
| .. | ||
| TOOLCHAIN_ARMC5 | ||
| README.md | ||
| mstd_algorithm | ||
| mstd_atomic | ||
| mstd_cstddef | ||
| mstd_functional | ||
| mstd_iterator | ||
| mstd_memory | ||
| mstd_mutex | ||
| mstd_mutex.cpp | ||
| mstd_tuple | ||
| mstd_type_traits | ||
| mstd_utility | ||
README.md
C++ support
Mbed OS supports a number of toolchains, and the files here provide support to smooth over C++ library differences.
The current baseline version is C++14, so we hope for full C++14 library support.
Omissions are:
- areas like chrono and threads, which depend on OS support, where retargeting is not complete.
- atomics and shared pointers, as atomic implementations for ARMv6-M are not provided by all toolchains, and the ARMv7-M implementations include DMB instructions we do not want/need for non-SMP.
User code should normally be able to include C++14 headers and get most expected functionality. (But bear in mind that many C++ library features like streams and STL containers are quite heavy and may not be appropriate for small embedded use).
However, ARM C 5 has only C++11 language support (at least a large subset), and
no C++11/14 library. For the headers that are totally new in C++11,
they are provided here in TOOLCHAIN_ARMC5 under their standard C++11 name.
(Eg <array>, <cinttypes>, <initializer_list>, <type_traits>).
But for headers that already exist in C++03, extensions are required.
So, to support ARM C 5, use #include <mstd_utility>, rather than
#include <utility> if you need C++11 or later features from that header.
Each mstd_ file includes the toolchain's corresponding header file,
which will provide its facilities in namespace std. Any missing
C++11/C++14 facilities for ARM C 5 are also provided in namespace std.
Then APIs from namespace std are added to namespace mstd, with adjustment
if necessary, and APIs being omitted if not suitable for embedded use.
For example:
std::size_t(<cstddef>) - toolchain'sstd::size_tmstd::size_t(<mstd_cstddef>) - alias forstd::size_tstd::swap(<utility>) - toolchain'sstd::swap(not move-capable for ARM C 5)mstd::swap(<mstd_utility>) - alias forstd::swapor move-capable ARM C 5 replacement.std::atomic(<atomic>) - toolchain'sstd::atomic(not implemented for IAR ARMv6)mstd::atomic(<mstd_atomic>) - custommstd::atomicfor all toolchainsstd::void_t(<type_traits>) - toolchain'sstd::void_tif available (it's C++17 so likely not)mstd::void_t(<mstd_type_traits>) - alias forstd::void_tif available, else local implementationstd::thread(<thread>) - toolchain'sstd::thread- not available or portedmstd::thread- doesn't exist -mstdAPIs only exist if available on all toolchains
Using std::xxx will generally work, but may suffer from toolchain variance. mstd::xxx should always be better - it will either be an alias to std::xxx, or work better for Mbed OS.
In portable code, when compiling for non-Mbed OS, the directive namespace mstd == std can be used
to cover the difference:
// my_code.c
#if TARGET_LIKE_MBED
#include <mstd_atomic>
#else
#include <atomic>
namespace mstd = std;
#endif
mstd::atomic my_atomic;