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.).
The retarget code allocates an array of FileHandle* for console and file
handling (filehandles). A tiny target only needs a console (putc/getc).
There is no need for file handling.
The POSIX layer and the array of FileHandle* is not required for small
targets that only need a console ; this code is optionally compiled
out if the configuration parameter platform.stdio-minimal-console-only is
set to `"true"`.
tuples will be useful for things like `mbed::Event` and
`mbed::Callback` - storing parameter packs from variadic templates.
Create a C++14(ish) `<tuple>` for ARMC5, and a `<mstd_tuple>` that
adds `apply` and `make_from_tuple` from C++17.
Add add-standard-as-possible version of C++11 <mutex>.
A lot of the stuff in there is generic, but the actual mutex classes and
call_once need to interface with the OS.
For those, they're not available in ARMC5 or IAR; retargetting would be
necessary for ARMC6 and GCC, and I've yet to investigate how whether
that's possible. So for now I'm using local implementations.
Although `Mutex` in principle could support `timed_mutex` and
`recursive_timed_mutex`, we don't have `chrono` for the time parameters,
so hold off for now.
For the generic stuff like mstd::unique_lock, they are aliased to
std::unique_lock where possible.
Regularise the C++ support glue, adding `<mstd_type_traits>` etc.
These include the base toolchain file, backfill `namespace std` as much
as possible for ARM C 5, and then arrange to create unified
`namespace mstd`, which can incorporate toolchain bypasses
(eg `mstd::swap` for ARM C 5, or `mstd::atomic`), and include local
implementations of post-ARM C++14 stuff.
All APIs in `namespace mstd` are intended to function as their
`namespace std` equivalent, and their presence there indicates they
are functional on all toolchains, and should be safe to use in
an Mbed OS build (including not unreasonable memory footprint).
See README.md for more info.