C++ boost::leaf examples
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
chodak166 3c47a629be Add initial boost::leaf examples within cmake/vcpkg project 1 month ago
scripts Add initial boost::leaf examples within cmake/vcpkg project 1 month ago
src Add initial boost::leaf examples within cmake/vcpkg project 1 month ago
.dockerignore Add initial boost::leaf examples within cmake/vcpkg project 1 month ago
CMakeLists.txt Add initial boost::leaf examples within cmake/vcpkg project 1 month ago
Dockerfile Add initial boost::leaf examples within cmake/vcpkg project 1 month ago
README.md Add initial boost::leaf examples within cmake/vcpkg project 1 month ago
docker-compose.yml Add initial boost::leaf examples within cmake/vcpkg project 1 month ago
vcpkg.json Add initial boost::leaf examples within cmake/vcpkg project 1 month ago

README.md

Boost.LEAF Diagnostic Propagation Examples

Three small C++ programs demonstrating how Boost.LEAF propagates rich diagnostic information together with an error code, without throwing exceptions and without exceptions needing to be enabled in the codebase.

  • src/leaf_on_error_example.cpp — distinct context structs attached per scope with leaf::on_error; handlers matched by the exact set of available types.
  • src/leaf_mutable_block.cpp — a single mutable diagnostic_context struct, re-registered with leaf::on_error as the operation progresses, so the handler receives the latest snapshot of all fields.
  • src/leaf_universal_handler.cpp — handler selection: specific handlers first, generic "universal" handlers later, plus a final fallback. Shows how LEAF picks the best match.

Core idea

LEAF returns errors as values of type leaf::result<T> instead of throwing exceptions. At each point where an error can occur, arbitrary diagnostic values (file names, user info, chunk numbers, timestamps, ...) are registered with leaf::on_error(value). If leaf::new_error(...) is returned, all registered values are captured into the current error context, and the top level uses leaf::try_handle_all(try_block, handlers...) to let the handlers inspect whichever context types were active when the error was created.

Handler matching is done purely on types: a handler requesting (write_error const&, file_context const&, user_context const&) will only run if the error carries exactly those registered values; a more general handler is used otherwise. This gives exception-like separation between "raising" a failure and "dealing with" it, but with explicit result values, no exceptions, and no RTTI dependency.

The examples intentionally return distinct exit codes from the handlers so each one reports which handler actually matched.

Local build

Requirements: CMake >= 3.21, a C++17 compiler, and vcpkg (git clone + bootstrap). The dependency is header-only boost-leaf.

git clone https://github.com/microsoft/vcpkg.git
./vcpkg/bootstrap-vcpkg.sh

cmake -S . -B build \
  -DCMAKE_TOOLCHAIN_FILE=$PWD/vcpkg/scripts/buildsystems/vcpkg.cmake \
  -DCMAKE_BUILD_TYPE=Release
cmake --build build

Run one of the examples:

./build/leaf_on_error_example

If you already have Boost (>= 1.75) installed at the system level, plain cmake -S . -B build also works; the CMake project picks Boost::leaf from a vcpkg toolchain when available and falls back to the system header target otherwise.

Docker

docker build -t leaf-examples .
docker run --rm leaf-examples

The first (build) stage installs the toolchain, clones vcpkg, downloads boost-leaf through the vcpkg.json manifest and builds all three examples. The second (run) stage copies the binaries into a slim image and executes them one after another, printing the exit code of each.

Docker Compose (v2)

docker compose up --build

runs the same build and then starts a container that executes all three examples. docker compose build builds without running; docker compose run --rm leaf-examples works too.