BareMetalLib (BML) is an experimental, modern C++, header-only support library for bare-metal programming (e.g. OS kernels, embedded software). It is intended for use in environments where exceptions are disabled and the C++ standard library cannot be used - BML aims to provide functionality similar to that of the C++ standard library, but in a form more suited to bare-metal programming. Namely, it eschews the use of:
- Headers from the C and C++ standard libraries, except for C11 freestanding headers
- Exceptions (BML is
noexcept
throughout) - RTTI
- Thread-local storage
- Non-
constexpr
static objects (BML does not require any initialization at runtime) - Dynamic allocation via global
operator new
oroperator new[]
- Floating point operations
Apart from these bare-metal-related constraints, the following additional constraints are imposed on BML code:
- Unsigned types cannot be used, except for bitfields. For example, sizes and indices are
represented using
ptrdiff_t
(instead ofsize_t
, which is what the C++ standard library does). This brings BML more in line with the arithmetic section of the C++ core guidelines.
Due to these constraints, BML is not a drop-in replacement for the C++ standard library. However, other than being exception-free, user code is not expected to conform to the same constraints.
BML is based on libc++. This is a learning project, so please be patient!
BML requires a C++17 conforming compiler. It is tested on the following platforms:
Architecture | OS | Compiler |
---|---|---|
x86_64 | Debian Buster (amd64) | Clang 6.0.1 |
x86_64 | Debian Buster (amd64) | GCC 8.3.0 |
i386 | Debian Buster (i386) | Clang 6.0.1 |
i386 | Debian Buster (i386) | GCC 8.3.0 |
aarch64 | Debian Buster (arm64) | Clang 6.0.1 |
aarch64 | Debian Buster (arm64) | GCC 8.3.0 |
armv7l | Debian Buster (armhf) | Clang 6.0.1 |
armv7l | Debian Buster (armhf) | GCC 8.3.0 |
armv5l | Debian Buster (armel) | Clang 6.0.1 |
armv5l | Debian Buster (armel) | GCC 8.3.0 |
Copy include/bml
into your project's include path and include a BML header to get started. Some
usage examples:
This example finds the minimum and maximum of 4 integers and returns them in a tuple.
#include <bml/containers.hpp> #include <bml/utilities.hpp> auto find_minmax(int i1, int i2, int i3, int i4) noexcept -> bml::tuple<int, int> { auto min = bml::min(i1, i2, i3, i4); auto max = bml::max(i1, i2, i3, i4); return bml::tuple(min, max); }
This example defines a do_foo
function which calls its argument's member foo
function if that
argument's type defines such a function. Otherwise, it performs a generic foo
action on its
argument.
#include <bml/type_traits/is_detected.hpp> #include <bml/type_traits/enable_if.hpp> #include <bml/utilities/declval.hpp> template <typename T> using has_foo = decltype(bml::declval<T>().foo()); template <typename T> auto do_foo(T&& arg) noexcept -> bml::enable_if_ty<bml::is_detected_v<has_foo, T>> { arg.foo(); } template <typename T> auto do_foo(T&& arg) noexcept -> bml::enable_if_ty<!bml::is_detected_v<has_foo, T>> { // Do some generic foo action on arg. This is called for argument types that do not have a // custom foo() member function. }
BML's documentation can be found in the docs/
directory, or online.
BML relies on CMake for testing. Whether tests are built or not is controlled by a single CMake
option - BML_BUILD_TESTS
.
To run BML's tests on your own platform, run the following command (this assumes that
../BareMetalLib
is where the root of this repository is stored on your system):
cmake -DBML_BUILD_TESTS=ON ../BareMetalLib && make && ctest
BML's code is licensed under the Apache 2.0 License with LLVM exceptions. BML's documentation,
which encompasses all content in the docs/
directory, is licensed under CC BY-SA 4.0.
For more details, see LICENSE.md.