This repository implements std::optional
extensions targeting C++26. The Beman.Optional26
library aims to evaluate the stability, the usability, and the performance of these proposed changes before they are officially adopted by WG21 into the C++ Working Draft. Additionally, it allows developers to use these new features before they are implemented in major standard library compilers.
Implements:
Source is licensed with the Apache 2.0 license with LLVM exceptions
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Documentation and associated papers are licensed with the Creative Commons Attribution 4.0 International license.
// SPDX-License-Identifier: CC-BY-4.0
The intent is that the source and documentation are available for use by people implementing their own optional types as well as people using the optional presented here as-is.
The README itself is licesed with CC0 1.0 Universal. Copy the contents and incorporate in your own work as you see fit.
// SPDX-License-Identifier: CC0-1.0
Full runable examples can be found in examples/
- please check ./examples/README.md.
The next code snippet shows optional range support added in Give std::optional Range Support (P3168R2):
#include <Beman/Optional26/optional.hpp>
...
// Example from P3168R2: basic range loop over C++26 optional.
beman::optional26::optional<int> empty_opt{};
for ([[maybe_unused]] const auto& i : empty_opt) {
// Should not see this in console.
std::cout << "\"for each loop\" over C++26 optional: empty_opt\n";
}
beman::optional26::optional<int> opt{26};
for (const auto& i : opt) {
// Should see this in console.
std::cout << "\"for each loop\" over C++26 optional: opt = " << i << "\n";
}
Full code can be found in ./examples/range_loop.cpp. Build and run instructions in ./examples/README.md. Or try it on Compiler Explorer.
The next code snippet shows optional reference support added in std::optional<T&>
(P2988R5):
#include <Beman/Optional26/optional.hpp>
...
{
// Empty optional example.
std::optional<int> std_empty_opt;
beman::optional26::optional<int> beman_empty_opt;
assert(!std_empty_opt.has_value() &&
!beman_empty_opt.has_value()); // or assert(!std_empty_opt && !beman_empty_opt);
std::cout << "std_vs_beman: .has_value() matches?: "
<< (std_empty_opt.has_value() == beman_empty_opt.has_value() ? "yes" : "no") << "\n";
}
{
// Optional with value example.
std::optional<int> std_opt = 26;
beman::optional26::optional<int> beman_opt = 26;
assert(std_opt.has_value() && beman_opt.has_value()); // or assert(std_opt && beman_opt);
assert(std_opt.value() == beman_opt.value()); // or assert(*std_opt == *beman_opt);
std::cout << "std_vs_beman: .value() matches?: " << (std_opt.value() == beman_opt.value() ? "yes" : "no")
<< "\n";
}
Full code can be found in ./examples/optional_ref.cpp. Build and run instructions in ./examples/README.md.
This is a modern C++ project which can be compiled with the latest C++ standards (C++20 or later).
Default build: C++23
. Please check etc/${compiler}-flags.cmake
.
This project is mainly tested on Ubuntu 22.04
and Ubuntu 24.04
, but it should be as portable as CMake is. This project has no C or C++ dependencies.
Build-time dependencies:
cmake
ninja
, make
, or another CMake-supported build system
Example of installation on Ubuntu 24.04
:
# Install tools:
apt-get install -y cmake make ninja-build
# Example of toolchains:
apt-get install \
g++-14 gcc-14 gcc-13 g++-14 \
clang-18 clang++-18 clang-17 clang++-17
Full set of supported toolchains can be found in .github/workflows/ci.yml.
This project strives to be as normal and simple a CMake project as possible. This build workflow in particular will work, producing a static beman_optional26
library, ready to package:
# List available preset configurations:
$ cmake --workflow --list-presets
Available workflow presets:
"system"
"gcc-14"
"gcc-13"
"clang-18"
"clang-17"
# Run examples:
$ cmake --workflow --preset gcc-14
cmake --workflow --preset gcc-14
Executing workflow step 1 of 3: configure preset "gcc-14"
...
-- Build files have been written to: /path/to/repo/.build/gcc-14
Executing workflow step 2 of 3: build preset "gcc-14"
ninja: no work to do.
Executing workflow step 3 of 3: test preset "gcc-14"
Test project /path/to/repo/.build/gcc-14
Start 1: OptionalTest.TestGTest
1/... Test #1: OptionalTest.TestGTest ........................... Passed 0.00 sec
...
Start x: RangeSupportTest.RangeConcepts
.../... Test #x: RangeSupportTest.RangeConcepts ................... Passed 0.00 sec
Start x+1: RangeSupportTest.IteratorConcepts
.../... Test #x+1: RangeSupportTest.IteratorConcepts ................ Passed 0.00 sec
...
100% tests passed, 0 tests failed out of ...
Total Test time (real) = 0.09 sec
This should build and run the tests with GCC 14 with the address and undefined behavior sanitizers enabled.
The CMake preset system suffers from combinitorial explosion. There is a makefile in the root of the repository to aid in running more configurations.
make -k TOOLCHAIN=clang-18 CONFIG=Tsan VERBOSE=1
The makefile will use your system compiler, c++
, if no toolchain name is provided, otherwise it will use the toolchain in the etc/ directory to perform the build. The Ninja multi config generator is used, with configurations for RelWithDebugInfo
, Debug
, Tsan
, and Asan
configured by default.
Latest revision(s) of the papers can be built / found at:
Give *std::optional* Range Support (P3168)
std::optional<T&> (P2988)
.