### C++ Exception Handling Example (Conceptual) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This is a conceptual example demonstrating how C++ exception handling might look with specific error types and arguments. It is not valid C++ syntax but illustrates the desired pattern for error matching. ```cpp try { auto r = process_file(); //Success, use r: .... } catch(file_read_error &, e_file_name const & fn, e_errno const & err) { std::cerr << "Could not read " << fn << ", errno=" << err << std::endl; } catch(file_read_error &, e_errno const & err) { std::cerr << "File read error, errno=" << err << std::endl; } catch(file_read_error &) { std::cerr << "File read error!" << std::endl; } ``` -------------------------------- ### try_handle_some Example: Handling e_file_name with pointer (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This example shows how to use `try_handle_some` with a handler that accepts `leaf::e_file_name` as a pointer. This allows the handler to gracefully manage cases where the error object might not be present. The handler checks for a valid pointer before dereferencing. ```cpp try_handle_some( []() -> leaf::result { return f(); }, [](leaf::e_file_name const * fn) { if( fn ) std::cerr << "File Name: \"" << fn->value << '"' << std::endl; return 1; } ); ``` -------------------------------- ### Handle Any Error with leaf::diagnostic_info Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This example shows how to handle any error using a lambda that takes a leaf::diagnostic_info object. It prints diagnostic information and returns the original error. This handler provides more details than leaf::error_info. ```C++ try_handle_some( [] { return f(); // throws }, [](leaf::diagnostic_info const & info) { std::cerr << "leaf::diagnostic_information:\n" << info; return info.error(); } ); ``` -------------------------------- ### try_handle_some Example: Handling e_file_name with reference (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index An example demonstrating how to use `try_handle_some` to handle a specific error type, `leaf::e_file_name`, when it's passed by const reference. The handler returns an int and prints the file name if available. If the error is not handled, the original result from the try_block is returned. ```cpp auto r = leaf::try_handle_some( []() -> leaf::result { return f(); }, [](leaf::e_file_name const & fn) { std::cerr << "File Name: \"" << fn.value << '"' << std::endl; return 1; } ); ``` -------------------------------- ### Handling Errors with leaf::diagnostic_info Source: https://www.boost.org/doc/libs/latest/libs/leaf/index This example shows `try_handle_some` used with a lambda accepting `leaf::diagnostic_info`. It prints diagnostic information and returns the original error. This handler also matches any error. ```C++ try_handle_some( [] { return f(); // throws }, [](leaf::diagnostic_info const & info) { std::cerr << "leaf::diagnostic_information:\n" << info; return info.error(); } ); ``` -------------------------------- ### LEAF Macros for Error Handling Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Provides examples of common macros provided by LEAF for simplifying error handling operations. These macros abstract away boilerplate code, making error management more concise. ```C++ #include // Example using BOOST_LEAF_CHECK macro // boost::leaf::result res = potentially_failing_operation(); // BOOST_LEAF_CHECK(res); // int value = *res; // Example using BOOST_LEAF_NEW_ERROR macro // BOOST_LEAF_NEW_ERROR(error_id, "An error occurred"); ``` -------------------------------- ### Create Context using make_context Source: https://www.boost.org/doc/libs/latest/libs/leaf/index The `make_context` function creates a context object, which is essential for managing error handling scopes in Boost Leaf. It can be called with or without arguments, and its return type `context_type_from_handlers` is determined by the types of the handlers provided. This allows for flexible setup of error handling contexts based on the expected exception types. ```cpp #include namespace boost { namespace leaf { template context_type_from_handlers make_context() noexcept { return { }; } template context_type_from_handlers make_context( H && ... ) noexcept { return { }; } } } ``` ```cpp auto ctx = leaf::make_context( []( e_this ) { .... }, []( e_that ) { .... } ); // decltype(ctx) is leaf::context ``` -------------------------------- ### LEAF: Handling Custom Result Types with try_handle_some Source: https://www.boost.org/doc/libs/latest/libs/leaf/index This example demonstrates using `leaf::try_handle_some` when the primary function returns a custom result type (`lib3::result`) that has been made compatible with LEAF via `is_result_type` specialization. It shows how to handle errors from `lib1::error_code` and `lib2::error_code` within this context. ```cpp lib3::result r = leaf::try_handle_some( []() -> lib3::result { return f(); }, []( lib1::error_code ec ) -> lib3::result { // Handle lib1::error_code }, []( lib2::error_code ec ) -> lib3::result { // Handle lib2::error_code } ); ``` -------------------------------- ### Using `catch_` to Handle Multiple Exception Types (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index An example demonstrating the usage of the `boost::leaf::catch_` predicate within `leaf::try_catch`. This snippet shows how to define a handler that is selected if the `f()` function throws an exception of either `ex1` or `ex2` type, accessing the matched exception via `c.matched`. ```cpp struct ex1: std::exception { }; struct ex2: std::exception { }; leaf::try_catch( [] { return f(); // throws }, [](leaf::catch_ c) { assert(dynamic_cast(&c.matched) || dynamic_cast(&c.matched)); .... } ); ``` -------------------------------- ### LEAF: Handling Multiple External Error Types with try_handle_some Source: https://www.boost.org/doc/libs/latest/libs/leaf/index This example demonstrates using `leaf::try_handle_some` to manage errors originating from different external result types. It allows specifying distinct handlers for `lib1::error_code` and `lib2::error_code`, enabling centralized error processing. ```cpp leaf::result r = leaf::try_handle_some( []() -> leaf::result { return f(); }, []( lib1::error_code ec ) -> leaf::result { // Handle lib1::error_code }, []( lib2::error_code ec ) -> leaf::result { // Handle lib2::error_code } ); ``` -------------------------------- ### Integrate Boost Exception Handling with LEAF try_catch Source: https://www.boost.org/doc/libs/latest/libs/leaf/index This example shows how to replace the traditional Boost Exception `try-catch` block with LEAF's `try_catch` mechanism. It demonstrates capturing a custom exception type (`my_info_`) defined using Boost Exception, and accessing its value within a LEAF error handler. ```cpp #include #include #include typedef boost::error_info my_info; void f(); // Assume this function throws a boost::exception with my_info void g() { leaf::try_catch( [] { f(); }, []( my_info x ) { // Access the value associated with my_info std::cerr << "Got my_info with value = " << x.value(); } ); } ``` -------------------------------- ### Invert Predicate with if_not in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Demonstrates the if_not predicate wrapper which inverts the logic of another predicate. Creates a handler that requires an error object of type E to be available and the wrapped predicate to evaluate to false. Example shows if_not> requiring object e to NOT match any of the specified values V. ```cpp if_not> ``` -------------------------------- ### Run LEAF Unit Tests with Meson Build Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Instructions for running the LEAF library's unit tests using the Meson Build system. This involves cloning the LEAF repository, configuring a debug build, navigating to the build directory, and executing the test command. ```bash cd leaf meson bld/debug cd bld/debug meson test ``` -------------------------------- ### Run LEAF Unit Tests with Boost Build Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Instructions for running the LEAF library's unit tests using the Boost Build system (b2). This command should be executed from the `/libs/leaf` directory. ```bash ../../b2 test ``` -------------------------------- ### Example: Throwing a custom exception with `throw_exception` Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This C++ example demonstrates how to use `leaf::throw_exception` to throw a custom exception type that derives from `std::exception`. The `throw_exception` overload selected is the one that takes an exception object and optionally other arguments to construct a new `error_id`. ```cpp struct my_exception: std::exception { }; leaf::throw_exception(my_exception{}); ``` -------------------------------- ### Example: Throwing an enum value with `throw_exception` Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This C++ example shows how to use `leaf::throw_exception` with an enum value. When the first argument is not derived from `std::exception`, `throw_exception` creates an exception that derives from `std::exception` and `error_id`, using the provided enum value to initialize the `error_id`. ```cpp enum class my_error { e1=1, e2, e3 }; leaf::throw_exception(my_error::e1); ``` -------------------------------- ### Obtain Arbitrary Info at Catch Point: Boost Exception vs. LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Explains how to retrieve arbitrary error information within a catch block, comparing Boost Exception's 'get_error_info' with LEAF's 'try_catch' lambda. ```cpp try { f(); } catch( my_exception & e ) { if( T * v = get_error_info(e) ) { //my_info is available in e. } } boost::get_error_info ``` ```cpp leaf::try_catch( [] { f(); // throws } [](my_exception &, my_info const & x) { //my_info is available with //the caught exception. } ); try_catch ``` -------------------------------- ### Get Current Error ID - Boost LEAF current_error Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Function that retrieves the error_id value most recently created by new_error in the calling thread. Returns the current error context for the thread without modifying it. ```cpp namespace boost { namespace leaf { error_id current_error() noexcept; } } ``` -------------------------------- ### Initialize Lua interpreter and register C callback in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Creates a new Lua state with automatic cleanup using std::shared_ptr, registers a C++ function as a Lua callback, and initializes a Lua function that wraps the callback. The lua_register call makes the C++ do_work function available to Lua programs. ```cpp std::shared_ptr init_lua_state() noexcept { std::shared_ptr L(lua_open(), &lua_close); lua_register(&*L, "do_work", &do_work); luaL_dostring(&*L, "\ \n function call_do_work()\ \n return do_work()\ \n end"); return L; } ``` -------------------------------- ### Boost.Leaf context Constructors (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Provides the default and move constructors for the Boost.Leaf `context` class. The default constructor creates an empty context, while the move constructor transfers ownership of error objects from one context to another. ```cpp namespace boost { namespace leaf { template context::context() noexcept; template context::context( context && x ) noexcept; } } ``` -------------------------------- ### Get Value Type Alias with result::value_type Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index The `value_type` is a member type defined within `boost::leaf::result` that serves as a synonym for the template parameter `T`. It indicates the type of the value stored within the result. ```cpp A member type of `result`, defined as a synonim for `T`. ``` -------------------------------- ### Handling `std::error_code` with Enum Values (C++17) (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Shows how to handle `std::error_code` values that correspond to specific enum members. This example requires C++17 and utilizes `std::is_error_code_enum` specialization for the custom enum. ```cpp enum class my_enum { e1=1, e2, e3 }; namespace std { template <> struct is_error_code_enum: std::true_type { }; } leaf::try_handle_some( [] { return f(); // returns leaf::result }, []( leaf::match m ) { static_assert(std::is_same::value); assert(m.matched == my_enum::e1 || m.matched == my_enum::e2); // ... } ); ``` -------------------------------- ### Boost.Leaf context Constructors (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Provides the default and move constructors for the `context` class. The default constructor creates an empty context, while the move constructor transfers ownership of error objects from one context to another. Moving an active context is undefined behavior. ```cpp namespace boost { namespace leaf { template context::context() noexcept; template context::context( context && x ) noexcept; } } ``` -------------------------------- ### Reuse Error Handlers with try_handle_all in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Demonstrates the initial pattern of using try_handle_all with error handlers for a single operation. Shows how the same handlers can be repeated for different operations, which leads to code duplication. ```cpp leaf::try_handle_all( [&] { return f(); // returns leaf::result }, [](my_error_enum x) { ... }, [](read_file_error_enum y, e_file_name const & fn) { ... }, [] { ... }); ``` -------------------------------- ### Custom Predicate Function for Error Handling (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Demonstrates using a custom predicate function with `leaf::match` for more complex error condition checking. This example defines a handler that triggers if an error's `severity` value exceeds a threshold. ```cpp struct severity { int value; } template constexpr bool severity_greater_than( severity const & e ) noexcept { return e.value > S; } leaf::try_handle_some( // ... handler logic using severity_greater_than ... ``` -------------------------------- ### Pass Arbitrary Info at Throw: Boost Exception vs. LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Illustrates how to pass arbitrary error information when throwing an exception, contrasting Boost Exception's operator<< chaining with LEAF's 'throw_exception' function. ```cpp throw my_exception() << my_info(x) << my_info(y); operator<< ``` ```cpp leaf::throw_exception( my_exception(), my_info{x}, my_info{y} ); throw_exception ``` -------------------------------- ### LEAF Error Handling with try_handle_all and Diagnostic Details in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Demonstrates LEAF's try_handle_all pattern for error handling with specific and catch-all handlers. The snippet shows how to create errors with multiple error objects (error_code and e_file_name), handle them with matching handlers, and use diagnostic_details to capture unhandled errors. The diagnostic_details handler is required and receives all error information available on the stack. ```cpp enum class error_code { read_error, write_error }; leaf::try_handle_all( []() -> leaf::result { ... return leaf::new_error( error_code::write_error, leaf::e_file_name{ "file.txt" } ); }, []( leaf::match ) { std::cerr << "Read error!" << std::endl; }, []( leaf::diagnostic_details const & info ) { std::cerr << "Unrecognized error detected\n" << info; } ); ``` -------------------------------- ### Handling `std::error_code` Categories (C++17) (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Illustrates handling `std::error_code` based on its category and specific values. This example requires C++17 and uses `leaf::category` to match error codes belonging to a particular enum's category. ```cpp enum class enum_a { a1=1, a2, a3 }; enum class enum_b { b1=1, b2, b3 }; namespace std { template <> struct is_error_code_enum: std::true_type { }; template <> struct is_error_code_enum: std::true_type { }; } leaf::try_handle_some( [] { return f(); // returns leaf::result }, []( leaf::match, enum_b::b2> m ) { static_assert(std::is_same::value); assert(&m.matched.category() == &std::error_code(enum_{}).category() || m.matched == enum_b::b2); // ... } ); ``` -------------------------------- ### Print Answer or Forward Error with result (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index A function `print_answer` that attempts to get an answer using `compute_answer`. It uses `BOOST_LEAF_AUTO` to unwrap the result. If `compute_answer` returns a successful value, it's printed; otherwise, the error is implicitly forwarded to the caller. ```cpp leaf::result print_answer() noexcept { BOOST_LEAF_AUTO(answer, compute_answer()); std::cout << "Answer: " << answer << std::endl; return { }; } ``` -------------------------------- ### Handle Lua callback results with try_handle_all in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Main function that repeatedly calls the Lua callback and handles different error types using try_handle_all. Demonstrates handling do_work_error_code, lua_pcall errors with messages, and unmatched errors with proper error information output. ```cpp int main() noexcept { std::shared_ptr L=init_lua_state(); for( int i=0; i!=10; ++i ) { leaf::try_handle_all( [&]() -> leaf::result { BOOST_LEAF_AUTO(answer, call_lua(&*L)); std::cout << "do_work succeeded, answer=" << answer << '\n'; return { }; }, [](do_work_error_code e) { std::cout << "Got do_work_error_code = " << e << "!\n"; }, [](e_lua_pcall_error const & err, e_lua_error_message const & msg) { std::cout << "Got e_lua_pcall_error, Lua error code = " << err.value << ", " << msg.value << "\n"; }, [](leaf::error_info const & unmatched) { std::cerr << "Unknown failure detected\n" << unmatched; } ); } } ``` -------------------------------- ### Obtain Arbitrary Info at Catch (Boost Exception vs. LEAF) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Explains how to retrieve custom error data when catching exceptions. Boost Exception uses `get_error_info`, and LEAF employs `try_catch` with a handler lambda. ```C++ #include try { f(); } catch( my_exception & e ) { if( T * v = boost::get_error_info(e) ) { //my_info is available in e. } } ``` ```C++ #include leaf::try_catch( [] { f(); // throws } [](my_exception &, my_info const & x) // handler { //my_info is available with //the caught exception. } ); ``` -------------------------------- ### Print Error Objects for Diagnostics: Boost Exception vs. LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Compares how error objects are converted to strings for diagnostic messages, noting Boost Exception's automatic inclusion of all error_info vs. LEAF's selective inclusion and optional 'diagnostic_details'. ```cpp `boost::error_info` types may define conversion to `std::string` by providing `to_string` overloads **or** by overloading `operator<<` for `std::ostream`. `boost::diagnostic_information` ``` ```cpp Error types may define `operator<<` overloads for `std::ostream`. `leaf::<`, `leaf::diagnostic_details` ``` -------------------------------- ### Match Specific Boost Exception Info Value with LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This example illustrates using `leaf::match_value` to create a LEAF error handler that triggers only when a caught exception carries a specific type of error information (`my_info`) and that information has a particular value (42). ```c++ void g() { leaf::try_catch( [] { f(); }, []( leaf::match_value ) { std::cerr << "Got my_info with value = 42"; } ); } ``` -------------------------------- ### Boost Leaf Context Activator RAII Class Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index The `context_activator` class in Boost Leaf implements RAII for activating and deactivating contexts. Its constructor calls `ctx.activate()` if the context is not already active, and its destructor calls `ctx.deactivate()` if the context was activated by the constructor. This ensures proper context management. ```cpp #include namespace boost { namespace leaf { template class context_activator { context_activator( context_activator const & ) = delete; context_activator & operator=( context_activator const & ) = delete; public: explicit context_activator( Ctx & ctx ) noexcept; context_activator( context_activator && ) noexcept; ~context_activator() noexcept; }; } } ``` -------------------------------- ### Define Error Code Enum in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Defines a simple enum class representing different error codes (e1, e2, e3). This enum is used throughout the documentation as the basis for demonstrating error handling with predicates. Enum values are sequential integers starting from 1. ```cpp enum class my_error { e1=1, e2, e3 }; ``` -------------------------------- ### Reporting Errors with LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Demonstrates how to report errors using the LEAF framework. This typically involves creating an error object and associating it with diagnostic information. No specific input/output is detailed, but it's fundamental to LEAF's error management. ```C++ #include // Example of creating and reporting an error void report_my_error() { // Assuming an error_id or similar mechanism exists // boost::leaf::new_error(some_error_id, "Error message", ...); } ``` -------------------------------- ### Match my_error_condition::c1 with std::error_code using LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This example shows how to use the `leaf::match` predicate within a LEAF error handler to specifically match a `std::error_code` against `my_error_condition::c1`. This allows for targeted handling of specific error conditions reported as `std::error_code`. ```c++ leaf::try_handle_some( [] { return f(); // returns leaf::result }, []( leaf::match m ) { assert(m.matched == my_error_condition::c1); .... } ); ``` -------------------------------- ### Throwing an error_id enum with boost::leaf::throw_exception Source: https://www.boost.org/doc/libs/latest/libs/leaf/index This C++ example demonstrates throwing an enum value that represents an error using `leaf::throw_exception`. The `throw_exception` function will wrap this enum in an exception type that derives from `std::exception` and `error_id`. ```cpp enum class my_error { e1=1, e2, e3 }; leaf::throw_exception(my_error::e1); ``` -------------------------------- ### Pass Arbitrary Info at Throw (Boost Exception vs. LEAF) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Illustrates passing arbitrary data with exceptions. Boost Exception uses an overloaded `operator<<`, whereas LEAF utilizes a `throw_exception` function. ```C++ #include bool ThrowMyException = true; throw my_exception() << my_info(x) << my_info(y); ``` ```C++ #include leaf::throw_exception( my_exception(), my_info{x}, my_info{y} ); ``` -------------------------------- ### Boost Leaf match_member Predicate Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index The `match_member` predicate binds to any accessible data member of an error type `E`. It requires C++17 and is functionally similar to `match_value` but operates on data members instead of a 'value' field. Example usage involves specifying the data member pointer and desired values. ```cpp namespace boost { namespace leaf { template struct match_member; template struct match_member { E const & matched; // Other members not specified }; template struct is_predicate>: std::true_type {}; } // namespace leaf } // namespace boost ``` -------------------------------- ### Initialize Lua State and Register C++ Callback Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Initializes a Lua interpreter, registers a C++ function 'do_work' as a Lua callback, and creates a Lua function 'call_do_work' to invoke the registered C++ function. Uses std::shared_ptr for automatic Lua state cleanup. ```cpp std::shared_ptr init_lua_state() noexcept { std::shared_ptr L(lua_open(), &lua_close); __**(1)** lua_register(&*L, "do_work", &do_work); __**(2)** luaL_dostring(&*L, " __**(3)** function call_do_work() return do_work() end"); return L; } ``` -------------------------------- ### Boost Leaf error_monitor Class Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index The error_monitor class assists in obtaining an error_id for error objects when working with APIs that do not natively support Boost.Leaf. It provides methods to check the current error state and to associate specific error objects with an error_id. The example demonstrates its usage in augmenting failures from uncooperative APIs. ```cpp #include namespace boost { namespace leaf { class error_monitor { public: error_monitor() noexcept; error_id check() const noexcept; error_id assigned_error_id( E && ... e ) const noexcept; }; } } ``` ```cpp leaf::error augmenter() noexcept { leaf::error_monitor cur_err; int val; auto ec = compute_value(&val); if( failure(ec) ) return cur_err.assigned_error_id().load(e1, e2, ...); else return val; } ``` -------------------------------- ### Custom Comparison Function with `leaf::match` (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Demonstrates using pointers to custom comparison functions within `leaf::match` for advanced error handling. This example uses a `severity_greater_than` function to handle errors where the `severity` value exceeds a specified threshold. ```cpp struct severity { int value; } template constexpr bool severity_greater_than( severity const & e ) noexcept { return e.value > S; } leaf::try_handle_some( // ... error handling code ... ); ``` -------------------------------- ### Handle All Errors with try_handle_all (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index The `try_handle_all` function is similar to `try_handle_some` but guarantees that all errors are handled. It requires at least one handler capable of managing any error. If the try block returns a `result`, `try_handle_all` unwraps it and returns `r.value()`. Initialization of T must be possible from the handlers. ```cpp #include namespace boost { namespace leaf { template typename std::decay()().value())>::type try_handle_all( TryBlock && try_block, H && ... h ); } } ``` -------------------------------- ### Get error_id value in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/index The `error_id::value()` method returns an integer representing a program-wide unique failure identifier. Returns 0 if the error_id was default-initialized, otherwise returns a non-zero unique identifier guaranteeing the failure's identity across the program. ```cpp namespace boost { namespace leaf { int error_id::value() const noexcept; } } ``` -------------------------------- ### Handle Any Error with leaf::error_info Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This snippet demonstrates handling any error using a lambda function that accepts a leaf::error_info object. It prints the error information and returns the original error. This is useful for general error logging and propagation. ```C++ try_handle_some( [] { return f(); // returns leaf::result }, [](leaf::error_info const & info) { std::cerr << "leaf::error_info:\n" << info; return info.error(); } ); ``` -------------------------------- ### Boost Leaf Error Handling with if_not Predicate (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Demonstrates using the `if_not` predicate with `leaf::try_handle_some` to conditionally handle errors. This example shows a handler that is invoked when an error of type `my_enum` is present, but it is *not* equal to `my_enum::e1` or `my_enum::e2`. The `matched` object can be accessed within the handler. ```cpp enum class my_enum { e1, e2, e3 }; leaf::try_handle_some( [] { return f(); // returns leaf::result }, []( leaf::if_not> ) { /* handler code */ } ); ``` -------------------------------- ### Handle Errors with try_handle_all in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Demonstrates comprehensive error handling using Boost.Leaf's try_handle_all function, which matches error handlers to specific exception types or provides a default fallback. This handles both exceptions converted from result and unknown errors uniformly. ```cpp leaf::try_handle_all( []() -> leaf::result { BOOST_LEAF_CHECK(print_answer()); return { }; }, [](error_a const & e) { std::cerr << "Error A!" << std::endl; }, [](error_b const & e) { std::cerr << "Error B!" << std::endl; }, [] { std::cerr << "Unknown error!" << std::endl; } ); ``` -------------------------------- ### Handle Any Error with leaf::diagnostic_details Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index This snippet illustrates handling any error with a lambda accepting leaf::diagnostic_details. It prints verbose diagnostic information, including dropped error object values, and returns the original error. This offers the most detailed error reporting. ```C++ try_handle_some( [] { return f(); // throws }, [](leaf::diagnostic_details const & info) { std::cerr << "leaf::diagnostic_details\n" << info; return info.error(); } ); ``` -------------------------------- ### Create Multiple Error Objects with leaf::new_error Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Demonstrates how to return multiple error objects simultaneously using leaf::new_error function. This allows associating an error code with related contextual information like file names, enabling richer error reporting. ```cpp enum class io_error { open_error, read_error, write_error }; struct e_file_name { std::string value; } leaf::result open_file( char const * name ) { .... if( open_failed ) return leaf::new_error(io_error::open_error, e_file_name {name}); .... } ``` -------------------------------- ### C++11 Compatible `std::error_code` Handling with `leaf::condition` (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Provides a C++11 compatible workaround for handling `std::error_code` enum values using `leaf::condition` within `leaf::match`. This achieves the same functionality as Example 2 but avoids C++17-specific features like template argument deduction for `leaf::category`. ```cpp enum class my_enum { e1=1, e2, e3 }; namespace std { template <> struct is_error_code_enum: std::true_type { }; } leaf::try_handle_some( [] { return f(); }, []( leaf::match, my_enum::e1, my_enum::e2> m ) { static_assert(std::is_same::value); assert(m.matched == my_enum::e1 || m.matched == my_enum::e2); .... } ); ``` -------------------------------- ### Define Custom Error Info Type: Boost Exception vs. LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Demonstrates how to define a custom type for transporting values, comparing the syntax for Boost Exception's 'error_info' and LEAF's custom struct. ```cpp typedef error_info my_info; boost::error_info ``` ```cpp struct my_info { T value; }; ``` -------------------------------- ### Boost.Leaf: Embedded Platform Configuration Equivalence Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Illustrates the equivalent macro definitions when `BOOST_LEAF_EMBEDDED` is defined. This configuration aims to minimize dependencies and resource usage, making Leaf suitable for embedded systems by disabling diagnostics, standard error code and string support, and dynamic memory allocation for captures. ```cpp #ifndef BOOST_LEAF_CFG_DIAGNOSTICS # define BOOST_LEAF_CFG_DIAGNOSTICS 0 #endif #ifndef BOOST_LEAF_CFG_STD_SYSTEM_ERROR # define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 0 #endif #ifndef BOOST_LEAF_CFG_STD_STRING # define BOOST_LEAF_CFG_STD_STRING 0 #endif #ifndef BOOST_LEAF_CFG_CAPTURE ``` -------------------------------- ### Monitor errors from uncooperative APIs in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/index The `error_monitor` class helps associate error objects with failures from third-party APIs that don't use LEAF. It provides `check()` to get a default error_id and `assigned_error_id()` to retrieve the last error_id from `new_error` calls or create a new one if none exists. This enables error augmentation in callbacks invoked by non-LEAF APIs. ```cpp namespace boost { namespace leaf { class error_monitor { public: error_monitor() noexcept; error_id check() const noexcept; error_id assigned_error_id( E && ... e ) const noexcept; }; } } ``` ```cpp error_code compute_value( int * out_value ) noexcept; leaf::error augmenter() noexcept { leaf::error_monitor cur_err; int val; auto ec = compute_value(&val); if( failure(ec) ) return cur_err.assigned_error_id().load(e1, e2, ...); else return val; } ``` -------------------------------- ### Augment Exceptions in Error-Neutral Contexts: Boost Exception vs. LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Shows how to augment exceptions in contexts where the specific exception type is not directly handled, comparing Boost Exception's 'try-catch' with LEAF's 'on_error'. ```cpp try { f(); } catch( boost::exception & e ) { e << my_info(x); throw; } boost::exception ``` ```cpp auto load = leaf::on_error( my_info{x} ); f(); on_error ``` -------------------------------- ### Handling Errors with leaf::diagnostic_details Source: https://www.boost.org/doc/libs/latest/libs/leaf/index This snippet illustrates `try_handle_some` with a lambda that takes `leaf::diagnostic_details`. It prints verbose diagnostic information and returns the original error. This handler matches any error. ```C++ try_handle_some( [] { return f(); // throws }, [](leaf::diagnostic_details const & info) { std::cerr << "leaf::diagnostic_details\n" << info; return info.error(); } ); ``` -------------------------------- ### BOOST_LEAF_THROW_EXCEPTION Macro for Error Handling Source: https://www.boost.org/doc/libs/latest/libs/leaf/index The BOOST_LEAF_THROW_EXCEPTION macro provides a convenient way to throw exceptions while automatically including the current source location information. It wraps the `leaf::throw_exception` function, ensuring that exception data is enriched with context, aiding in debugging and error tracing. This macro requires the Boost.Leaf library. ```cpp #include #define BOOST_LEAF_THROW_EXCEPTION <> ``` -------------------------------- ### Boost Leaf Error Handling Functions (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Provides functions for handling errors in Boost Leaf. Includes try_handle_all, try_handle_some, try_catch, and try_capture_all for different error handling strategies. The error_info class provides details about caught errors. ```cpp #include namespace boost { namespace leaf { template typename std::decay()().value())>::type try_handle_all( TryBlock && try_block, H && ... h ); template typename std::decay()())>::type try_handle_some( TryBlock && try_block, H && ... h ); template typename std::decay()())>::type try_catch( TryBlock && try_block, H && ... h ); #if BOOST_LEAF_CFG_CAPTURE template result // T deduced depending on TryBlock return type try_capture_all( TryBlock && try_block ); #endif class error_info { //No public constructors public: error_id error() const noexcept; bool exception_caught() const noexcept; std::exception const * exception() const noexcept; template friend std::ostream & operator<<( std::basic_ostream &, error_info const & ); }; } } // namespace boost::leaf ``` -------------------------------- ### e_source_location Structure in C++ Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index The e_source_location structure captures file, line, and function information, typically used by macros like BOOST_LEAF_NEW_ERROR and BOOST_LEAF_THROW_EXCEPTION. ```C++ #include namespace boost { namespace leaf { struct e_source_location { char const * file; int line; char const * function; template friend std::ostream & operator<<( std::basic_ostream &, e_source_location const & ); }; } } ``` -------------------------------- ### Augmenting Errors with LEAF Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Details how to augment existing errors with additional information using LEAF. This allows for richer error reporting and easier debugging by adding context or details to an error object. ```C++ #include // Example of augmenting an error with additional info // boost::leaf::error_info info; // info.add("additional_key", "additional_value"); // boost::leaf::new_error(existing_error, info); ``` -------------------------------- ### Main Function with Error Handling for Lua Calls Source: https://www.boost.org/doc/libs/latest/libs/leaf/index The main function initializes the Lua state and then enters a loop to repeatedly call 'call_lua'. It uses leaf::try_handle_all to catch and process different types of errors that may arise from the Lua execution, including specific do_work errors, Lua call errors, and any other unexpected failures. ```cpp int main() noexcept { std::shared_ptr L=init_lua_state(); for( int i=0; i!=10; ++i ) { leaf::try_handle_all( [&]() -> leaf::result { BOOST_LEAF_AUTO(answer, call_lua(&*L)); std::cout << "do_work succeeded, answer=" << answer << '\n'; __**(1)** return { }; }, [](do_work_error_code e) __**(2)** { std::cout << "Got do_work_error_code = " << e << "!\n"; }, [](e_lua_pcall_error const & err, e_lua_error_message const & msg) __**(3)** { std::cout << "Got e_lua_pcall_error, Lua error code = " << err.value << ", " << msg.value << "\n"; }, [](leaf::error_info const & unmatched) { std::cerr << "Unknown failure detected\n" << unmatched; } ); } } ``` -------------------------------- ### Boost.Leaf On-Error Callback (C++) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Defines utilities for handling errors when they occur within the Boost.Leaf error handling system. `on_error` allows registering callbacks that are executed when an error is encountered. `error_monitor` provides a mechanism to check for assigned error IDs and monitor error states. ```cpp #include namespace boost { namespace leaf { template <> on_error( Item && ... e ) noexcept; class error_monitor { public: error_monitor() noexcept; error_id check() const noexcept; error_id assigned_error_id() const noexcept; }; } } ``` -------------------------------- ### Handle Multiple Error Objects with try_handle_some Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Shows how error handlers can accept multiple error objects as parameters. Handlers are evaluated in order, and the first handler matching the available error objects is invoked. Supports optional error objects via pointer parameters. ```cpp leaf::result r = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(f, open_file(fn)); .... }, []( io_error ec, e_file_name fn ) -> leaf::result { // Handle I/O errors when a file name is also available. }, []( io_error ec ) -> leaf::result { // Handle I/O errors when no file name is available. } ); ``` -------------------------------- ### Printing Error Objects (Boost Exception vs. LEAF) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Covers how error objects are represented as strings for diagnostic messages. Boost Exception can provide comprehensive info by default, while LEAF requires `diagnostic_details` for full output, potentially involving dynamic allocation. ```C++ #include std::cout << boost::diagnostic_information(e); ``` ```C++ #include #include // For potentially incomplete diagnostic info (no dynamic allocation): // std::cout << leaf::diagnostic_info(e); // For complete diagnostic info (may involve dynamic allocation): std::cout << leaf::diagnostic_details(e); ``` -------------------------------- ### Handle Augmented Errors with Multiple Error Types Source: https://www.boost.org/doc/libs/latest/libs/leaf/doc/html/index Demonstrates handling errors that have been augmented with additional context. Multiple handlers can be defined to handle different error type combinations, with handlers receiving both the error code and the augmented context objects. ```cpp leaf::result r = leaf::try_handle_some( [&]() -> leaf::result { BOOST_LEAF_CHECK( process_file(f) ); }, []( parse_error e, e_line current_line ) { std::cerr << "Parse error at line " << current_line.value << std::endl; }, []( io_error e, e_line current_line ) { std::cerr << "I/O error at line " << current_line.value << std::endl; }, []( io_error e ) { std::cerr << "I/O error" << std::endl; } ); ``` -------------------------------- ### Handling Errors with leaf::error_info Source: https://www.boost.org/doc/libs/latest/libs/leaf/index This snippet demonstrates how to use `try_handle_some` with a lambda function that accepts `leaf::error_info`. It prints the error information and returns the original error. This handler matches any error. ```C++ try_handle_some( [] { return f(); // returns leaf::result }, [](leaf::error_info const & info) { std::cerr << "leaf::error_info:\n" << info; return info.error(); } ); ``` -------------------------------- ### Define Custom Error Info Type (Boost Exception vs. LEAF) Source: https://www.boost.org/doc/libs/latest/libs/leaf/index Demonstrates how to define a custom type for transporting error information. Boost Exception uses `boost::error_info` with a tag, while LEAF uses a simple struct. ```C++ #include typedef boost::error_info my_info; ``` ```C++ struct my_info { T value; }; ```