├── .drone.jsonnet ├── .drone ├── drone.bat └── drone.sh ├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── gh-pages.yml ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── CMakeLists.txt ├── LICENSE_1_0.txt ├── README.md ├── build.jam ├── conanfile.py ├── doc ├── Jamfile ├── docinfo.html ├── leaf-theme.yml ├── leaf.adoc ├── rouge-github.css ├── skin.png ├── whitepaper.md ├── zajo-dark.css └── zajo-light.css ├── example ├── error_log.cpp ├── error_trace.cpp ├── exception_to_result.cpp ├── lua_callback_exceptions.cpp ├── lua_callback_result.cpp ├── print_file │ ├── print_file_exceptions.cpp │ ├── print_file_leaf_result.cpp │ ├── print_file_system_result.cpp │ └── readme.md ├── print_half.cpp ├── readme.md ├── try_capture_all_exceptions.cpp └── try_capture_all_result.cpp ├── gen └── generate_single_header.py ├── include └── boost │ ├── leaf.hpp │ └── leaf │ ├── common.hpp │ ├── config.hpp │ ├── config │ ├── tls.hpp │ ├── tls_array.hpp │ ├── tls_cpp11.hpp │ ├── tls_freertos.hpp │ └── tls_globals.hpp │ ├── context.hpp │ ├── detail │ ├── all.hpp │ ├── capture_list.hpp │ ├── demangle.hpp │ ├── function_traits.hpp │ ├── mp11.hpp │ ├── optional.hpp │ └── print.hpp │ ├── diagnostics.hpp │ ├── error.hpp │ ├── exception.hpp │ ├── handle_errors.hpp │ ├── on_error.hpp │ ├── pred.hpp │ ├── result.hpp │ └── to_variant.hpp ├── index.html ├── meson.build ├── meson_options.txt ├── meta └── libraries.json ├── subprojects ├── lua.wrap └── tl_expected.wrap ├── test ├── BOOST_LEAF_ASSIGN_test.cpp ├── BOOST_LEAF_AUTO_test.cpp ├── BOOST_LEAF_CHECK_test.cpp ├── Jamfile.v2 ├── _compile-fail-BOOST_LEAF_ASSIGN.cpp ├── _compile-fail-BOOST_LEAF_AUTO.cpp ├── _compile-fail-arg_boost_error_info_1.cpp ├── _compile-fail-arg_boost_error_info_2.cpp ├── _compile-fail-arg_catch_1.cpp ├── _compile-fail-arg_catch_2.cpp ├── _compile-fail-arg_match_1.cpp ├── _compile-fail-arg_match_2.cpp ├── _compile-fail-arg_rvalue_ref.cpp ├── _compile-fail-diagnostic_details.cpp ├── _compile-fail-diagnostic_info.cpp ├── _compile-fail-error_info.cpp ├── _compile-fail-exception_1.cpp ├── _compile-fail-exception_2.cpp ├── _compile-fail-new_error.cpp ├── _compile-fail-result_1.cpp ├── _compile-fail-result_2.cpp ├── _compile-fail-result_3.cpp ├── _compile-fail-result_4.cpp ├── _hpp_capture_test.cpp ├── _hpp_common_test.cpp ├── _hpp_config_test.cpp ├── _hpp_context_test.cpp ├── _hpp_diagnostics_test.cpp ├── _hpp_error_test.cpp ├── _hpp_exception_test.cpp ├── _hpp_handle_errors_test.cpp ├── _hpp_leaf_test.cpp ├── _hpp_on_error_test.cpp ├── _hpp_pred_test.cpp ├── _hpp_result_test.cpp ├── _hpp_to_variant_test.cpp ├── _test_ec.hpp ├── _test_res.hpp ├── boost │ └── core │ │ ├── current_function.hpp │ │ └── lightweight_test.hpp ├── boost_exception_test.cpp ├── capture_exception_async_test.cpp ├── capture_exception_result_async_test.cpp ├── capture_exception_result_unload_test.cpp ├── capture_exception_state_test.cpp ├── capture_exception_unload_test.cpp ├── capture_result_async_test.cpp ├── capture_result_state_test.cpp ├── capture_result_unload_test.cpp ├── context_activator_test.cpp ├── context_deduction_test.cpp ├── ctx_handle_all_test.cpp ├── ctx_handle_some_test.cpp ├── ctx_remote_handle_all_test.cpp ├── ctx_remote_handle_some_test.cpp ├── diagnostics_test1.cpp ├── diagnostics_test2.cpp ├── diagnostics_test3.cpp ├── diagnostics_test4.cpp ├── diagnostics_test5.cpp ├── diagnostics_test6.cpp ├── e_LastError_test.cpp ├── e_errno_test.cpp ├── error_code_test.cpp ├── error_id_test.cpp ├── exception_test.cpp ├── exception_to_result_test.cpp ├── function_traits_test.cpp ├── github_issue53_test.cpp ├── github_issue53x_test.cpp ├── handle_all_other_result_test.cpp ├── handle_all_test.cpp ├── handle_basic_test.cpp ├── handle_some_other_result_test.cpp ├── handle_some_test.cpp ├── lightweight_test.hpp ├── match_member_test.cpp ├── match_test.cpp ├── match_value_test.cpp ├── multiple_errors_test.cpp ├── on_error_accumulate_basic_test.cpp ├── on_error_accumulate_nested_error_exception_test.cpp ├── on_error_accumulate_nested_error_result_test.cpp ├── on_error_accumulate_nested_new_error_exception_test.cpp ├── on_error_accumulate_nested_new_error_result_test.cpp ├── on_error_accumulate_nested_success_exception_test.cpp ├── on_error_accumulate_nested_success_result_test.cpp ├── on_error_defer_basic_test.cpp ├── on_error_defer_nested_error_exception_test.cpp ├── on_error_defer_nested_error_result_test.cpp ├── on_error_defer_nested_new_error_exception_test.cpp ├── on_error_defer_nested_new_error_result_test.cpp ├── on_error_defer_nested_success_exception_test.cpp ├── on_error_defer_nested_success_result_test.cpp ├── on_error_preload_basic_test.cpp ├── on_error_preload_exception_test.cpp ├── on_error_preload_nested_error_exception_test.cpp ├── on_error_preload_nested_error_result_test.cpp ├── on_error_preload_nested_new_error_exception_test.cpp ├── on_error_preload_nested_new_error_result_test.cpp ├── on_error_preload_nested_success_exception_test.cpp ├── on_error_preload_nested_success_result_test.cpp ├── optional_test.cpp ├── parse_name_test.cpp ├── print_test.cpp ├── result_bad_result_test.cpp ├── result_implicit_conversion_test.cpp ├── result_load_test.cpp ├── result_print_test.cpp ├── result_ref_test.cpp ├── result_state_test.cpp ├── tls_array_alloc_test1.cpp ├── tls_array_alloc_test2.cpp ├── tls_array_alloc_test3.cpp ├── tls_array_test.cpp ├── to_variant_test.cpp ├── try_capture_all_test.cpp ├── try_catch_error_id_test.cpp ├── try_catch_system_error_test.cpp ├── try_catch_test.cpp ├── try_exception_and_result_test.cpp ├── visibility_test.cpp ├── visibility_test_lib.cpp └── visibility_test_lib.hpp └── wasm.txt /.drone/drone.bat: -------------------------------------------------------------------------------- 1 | @REM Copyright 2022 Peter Dimov 2 | @REM Distributed under the Boost Software License, Version 1.0. 3 | @REM https://www.boost.org/LICENSE_1_0.txt 4 | 5 | @ECHO ON 6 | 7 | set LIBRARY=%1 8 | set DRONE_BUILD_DIR=%CD% 9 | 10 | set BOOST_BRANCH=develop 11 | if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master 12 | cd .. 13 | git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root 14 | cd boost-root 15 | git submodule update --init tools/boostdep 16 | xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\ 17 | python tools/boostdep/depinst/depinst.py %LIBRARY% 18 | cmd /c bootstrap 19 | b2 -d0 headers 20 | 21 | echo "Generating single header" 22 | cd libs/%LIBRARY% 23 | python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf 24 | 25 | echo "Testing" 26 | if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% 27 | if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD% 28 | ..\..\b2 -j3 test toolset=%TOOLSET% %CXXSTD% %ADDRMD% embed-manifest-via=linker link=shared,static variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_single_header,leaf_release_single_header 29 | -------------------------------------------------------------------------------- /.drone/drone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Peter Dimov 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # https://www.boost.org/LICENSE_1_0.txt 6 | 7 | set -ex 8 | 9 | DRONE_BUILD_DIR=$(pwd) 10 | export PATH=~/.local/bin:/usr/local/bin:$PATH 11 | 12 | BOOST_BRANCH=develop 13 | if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi 14 | 15 | cd .. 16 | git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root 17 | cd boost-root 18 | git submodule update --init tools/boostdep 19 | cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY 20 | python tools/boostdep/depinst/depinst.py $LIBRARY 21 | ./bootstrap.sh 22 | ./b2 -d0 headers 23 | 24 | echo "Generating single header" 25 | cd libs/$LIBRARY 26 | python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf 27 | 28 | echo "Testing" 29 | echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam 30 | ../../b2 -j3 test $LINKFLAGS toolset=$TOOLSET cxxstd=$CXXSTD ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} link=shared,static variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_single_header,leaf_release_single_header 31 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: documentation 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - feature/gha_fixes 8 | 9 | jobs: 10 | publish: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | 15 | - name: Install packages 16 | run: | 17 | sudo gem install asciidoctor asciidoctor-pdf rouge 18 | 19 | - name: Setup Boost 20 | run: | 21 | REF=${GITHUB_BASE_REF:-$GITHUB_REF} 22 | BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true 23 | cd .. 24 | git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root 25 | cd boost-root 26 | cp -r $GITHUB_WORKSPACE/* libs/leaf 27 | git submodule update --init tools/build 28 | git submodule update --init tools/boost_install 29 | git submodule update --init libs/config 30 | ./bootstrap.sh 31 | 32 | - name: Create user-config.jam 33 | run: | 34 | echo "using asciidoctor ;" > ~/user-config.jam 35 | 36 | - name: Build documentation 37 | run: | 38 | cd ../boost-root/libs/leaf/doc 39 | ../../../b2 40 | 41 | - name: Generate single header 42 | run: | 43 | REF=$(git show-ref $GITHUB_REF --hash) 44 | cd ../boost-root/libs/leaf 45 | python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o doc/html/leaf.hpp boost/leaf --hash "$REF" 46 | 47 | - name: Deploy to GitHub Pages 48 | uses: JamesIves/github-pages-deploy-action@4.0.0 49 | with: 50 | token: ${{ secrets.GITHUB_TOKEN }} 51 | branch: gh-pages 52 | folder: ../boost-root/libs/leaf/doc/html 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .Trashes 3 | *.suo 4 | *.user 5 | *.log 6 | *.sdf 7 | *.opensdf 8 | *.db 9 | *.opendb 10 | _bld/* 11 | doc/html/* 12 | snippets/* 13 | subprojects/*/ 14 | .vscode/ipch/* 15 | .vscode/settings.json 16 | .vscode/c_cpp_properties.json 17 | test/leaf.hpp 18 | doc/leaf.html 19 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(Windows) Launch", 9 | "type": "cppvsdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/_bld/debug/capture_exception_result_async_test", 12 | "args": [], 13 | "cwd": "${fileDirname}", 14 | "stopAtEntry": false, 15 | "externalConsole": false 16 | }, 17 | 18 | { 19 | "name": "(lldb) Launch", 20 | "type": "cppdbg", 21 | "request": "launch", 22 | "program": "${workspaceFolder}/_bld/debug/capture_exception_result_async_test", 23 | "args": [], 24 | "cwd": "${workspaceFolder}", 25 | "stopAtEntry": false, 26 | "externalConsole": false, 27 | "MIMode": "lldb" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Generated by `boostdep --cmake leaf` 2 | # Copyright 2020 Peter Dimov 3 | # Distributed under the Boost Software License, Version 1.0. 4 | # https://www.boost.org/LICENSE_1_0.txt 5 | 6 | cmake_minimum_required(VERSION 3.5...3.16) 7 | 8 | project(boost_leaf VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) 9 | 10 | add_library(boost_leaf INTERFACE) 11 | add_library(Boost::leaf ALIAS boost_leaf) 12 | 13 | target_include_directories(boost_leaf INTERFACE include) 14 | 15 | if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") 16 | 17 | add_subdirectory(test) 18 | 19 | endif() 20 | 21 | -------------------------------------------------------------------------------- /LICENSE_1_0.txt: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LEAF 2 | 3 | > A lightweight error handling library for C++11. 4 | 5 | ## Documentation 6 | 7 | https://boostorg.github.io/leaf/ 8 | 9 | ## Features 10 | 11 | * Portable single-header format, no dependencies. 12 | * Tiny code size, configurable for embedded development. 13 | * No dynamic memory allocations, even with very large payloads. 14 | * Deterministic unbiased efficiency on the "happy" path and the "sad" path. 15 | * Error objects are handled in constant time, independent of call stack depth. 16 | * Can be used with or without exception handling. 17 | 18 | ## Support 19 | 20 | * [cpplang on Slack](https://Cpplang.slack.com) (use the `#boost` channel) 21 | * [Boost Users Mailing List](https://lists.boost.org/mailman/listinfo.cgi/boost-users) 22 | * [Boost Developers Mailing List](https://lists.boost.org/mailman/listinfo.cgi/boost) 23 | 24 | ## Distribution 25 | 26 | Besides GitHub, there are two other distribution channels: 27 | 28 | * LEAF is included in official [Boost](https://www.boost.org/) releases, starting with Boost 1.75. 29 | * For maximum portability, the library is also available in single-header format: [leaf.hpp](https://raw.githubusercontent.com/boostorg/leaf/gh-pages/leaf.hpp). 30 | 31 | Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. Distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0]. 32 | -------------------------------------------------------------------------------- /build.jam: -------------------------------------------------------------------------------- 1 | # Copyright René Ferdinand Rivera Morell 2023-2024 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at 4 | # http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | require-b2 5.2 ; 7 | 8 | project /boost/leaf 9 | ; 10 | 11 | explicit 12 | [ alias boost_leaf : : : : include ] 13 | [ alias all : boost_leaf test ] 14 | ; 15 | 16 | call-if : boost-library leaf 17 | ; 18 | -------------------------------------------------------------------------------- /conanfile.py: -------------------------------------------------------------------------------- 1 | from conan import ConanFile 2 | from conan.tools.files import copy 3 | from conan.tools.layout import basic_layout 4 | from conan.tools.build import check_min_cppstd 5 | from conan.errors import ConanInvalidConfiguration 6 | import os 7 | 8 | 9 | required_conan_version = ">=1.50.0" 10 | 11 | 12 | class BoostLEAFConan(ConanFile): 13 | name = "boost-leaf" 14 | version = "1.81.0" 15 | license = "BSL-1.0" 16 | url = "https://github.com/conan-io/conan-center-index" 17 | homepage = "https://github.com/boostorg/leaf" 18 | description = ("Lightweight Error Augmentation Framework") 19 | topics = ("multi-platform", "multi-threading", "cpp11", "error-handling", 20 | "header-only", "low-latency", "no-dependencies", "single-header") 21 | settings = "os", "compiler", "arch", "build_type" 22 | exports_sources = "include/*", "LICENSE_1_0.txt" 23 | no_copy_source = True 24 | 25 | def package_id(self): 26 | self.info.clear() 27 | 28 | @property 29 | def _min_cppstd(self): 30 | return "11" 31 | 32 | @property 33 | def _compilers_minimum_version(self): 34 | return { 35 | "gcc": "4.8", 36 | "Visual Studio": "17", 37 | "msvc": "141", 38 | "clang": "3.9", 39 | "apple-clang": "10.0.0" 40 | } 41 | 42 | def requirements(self): 43 | pass 44 | 45 | def validate(self): 46 | if self.settings.get_safe("compiler.cppstd"): 47 | check_min_cppstd(self, self._min_cppstd) 48 | 49 | def lazy_lt_semver(v1, v2): 50 | lv1 = [int(v) for v in v1.split(".")] 51 | lv2 = [int(v) for v in v2.split(".")] 52 | min_length = min(len(lv1), len(lv2)) 53 | return lv1[:min_length] < lv2[:min_length] 54 | 55 | compiler = str(self.settings.compiler) 56 | version = str(self.settings.compiler.version) 57 | minimum_version = self._compilers_minimum_version.get(compiler, False) 58 | 59 | if minimum_version and lazy_lt_semver(version, minimum_version): 60 | raise ConanInvalidConfiguration( 61 | f"{self.name} {self.version} requires C++{self._min_cppstd}, which your compiler ({compiler}-{version}) does not support") 62 | 63 | def layout(self): 64 | basic_layout(self) 65 | 66 | def package(self): 67 | copy(self, "LICENSE_1_0.txt", dst=os.path.join( 68 | self.package_folder, "licenses"), src=self.source_folder) 69 | copy(self, "*.h", dst=os.path.join(self.package_folder, "include"), 70 | src=os.path.join(self.source_folder, "include")) 71 | copy(self, "*.hpp", dst=os.path.join(self.package_folder, 72 | "include"), src=os.path.join(self.source_folder, "include")) 73 | 74 | def package_info(self): 75 | self.cpp_info.set_property("cmake_target_name", "boost::leaf") 76 | 77 | self.cpp_info.bindirs = [] 78 | self.cpp_info.frameworkdirs = [] 79 | self.cpp_info.libdirs = [] 80 | self.cpp_info.resdirs = [] 81 | -------------------------------------------------------------------------------- /doc/Jamfile: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Peter Dimov 2 | # Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 3 | # 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # (See accompanying file LICENSE_1_0.txt or copy at 6 | # http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | project doc/leaf ; 9 | using asciidoctor ; 10 | 11 | html index.html : leaf.adoc : stylesheet=zajo-dark.css linkcss ; 12 | install html_ : index.html skin.png zajo-dark.css zajo-light.css rouge-github.css : html ; 13 | 14 | pdf leaf.pdf : leaf.adoc : book pdf-themesdir=. pdf-theme=leaf ; 15 | install pdf_ : leaf.pdf : html ; 16 | 17 | alias boostdoc ; 18 | explicit boostdoc ; 19 | alias boostrelease : html_ ; 20 | explicit boostrelease ; 21 | -------------------------------------------------------------------------------- /doc/docinfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | -------------------------------------------------------------------------------- /doc/leaf-theme.yml: -------------------------------------------------------------------------------- 1 | extends: default 2 | base: 3 | font: 4 | color: #404040 5 | literal: 6 | font: 7 | family: Courier 8 | color: #000000 9 | admonition: 10 | icon: 11 | note: 12 | stroke-color: #000000 13 | tip: 14 | stroke-color: #000000 15 | warning: 16 | stroke-color: #FF5100 17 | important: 18 | stroke-color: #FF5100 19 | caution: 20 | stroke-color: #FF5100 21 | conum: 22 | font: 23 | glyphs: circled 24 | color: #000000 25 | link: 26 | text-decoration: underline 27 | text-decoration-width: 0.5 28 | font-color: #000000 29 | -------------------------------------------------------------------------------- /doc/rouge-github.css: -------------------------------------------------------------------------------- 1 | .highlight table td { padding: 5px; } 2 | .highlight table pre { margin: 0; } 3 | .highlight .cm { 4 | color: #999988; 5 | font-style: italic; 6 | } 7 | .highlight .cp { 8 | color: #999999; 9 | font-weight: bold; 10 | } 11 | .highlight .c1 { 12 | color: #999988; 13 | font-style: italic; 14 | } 15 | .highlight .cs { 16 | color: #999999; 17 | font-weight: bold; 18 | font-style: italic; 19 | } 20 | .highlight .c, .highlight .cd { 21 | color: #999988; 22 | font-style: italic; 23 | } 24 | .highlight .err { 25 | } 26 | .highlight .gd { 27 | color: #000000; 28 | background-color: #ffdddd; 29 | } 30 | .highlight .ge { 31 | color: #000000; 32 | font-style: italic; 33 | } 34 | .highlight .gr { 35 | color: #aa0000; 36 | } 37 | .highlight .gh { 38 | color: #999999; 39 | } 40 | .highlight .gi { 41 | color: #000000; 42 | background-color: #ddffdd; 43 | } 44 | .highlight .go { 45 | color: #888888; 46 | } 47 | .highlight .gp { 48 | color: #555555; 49 | } 50 | .highlight .gs { 51 | font-weight: bold; 52 | } 53 | .highlight .gu { 54 | color: #aaaaaa; 55 | } 56 | .highlight .gt { 57 | color: #aa0000; 58 | } 59 | .highlight .kc { 60 | font-weight: bold; 61 | } 62 | .highlight .kd { 63 | font-weight: bold; 64 | } 65 | .highlight .kn { 66 | font-weight: bold; 67 | } 68 | .highlight .kp { 69 | font-weight: bold; 70 | } 71 | .highlight .kr { 72 | font-weight: bold; 73 | } 74 | .highlight .kt { 75 | color: #445588; 76 | font-weight: bold; 77 | } 78 | .highlight .k, .highlight .kv { 79 | font-weight: bold; 80 | } 81 | .highlight .mf { 82 | color: #009999; 83 | } 84 | .highlight .mh { 85 | color: #009999; 86 | } 87 | .highlight .il { 88 | color: #009999; 89 | } 90 | .highlight .mi { 91 | color: #009999; 92 | } 93 | .highlight .mo { 94 | color: #009999; 95 | } 96 | .highlight .m, .highlight .mb, .highlight .mx { 97 | color: #009999; 98 | } 99 | .highlight .sb { 100 | color: #d14; 101 | } 102 | .highlight .sc { 103 | color: #d14; 104 | } 105 | .highlight .sd { 106 | color: #d14; 107 | } 108 | .highlight .s2 { 109 | color: #d14; 110 | } 111 | .highlight .se { 112 | color: #d14; 113 | } 114 | .highlight .sh { 115 | color: #d14; 116 | } 117 | .highlight .si { 118 | color: #d14; 119 | } 120 | .highlight .sx { 121 | color: #d14; 122 | } 123 | .highlight .sr { 124 | color: #009926; 125 | } 126 | .highlight .s1 { 127 | color: #d14; 128 | } 129 | .highlight .ss { 130 | color: #990073; 131 | } 132 | .highlight .s { 133 | color: #d14; 134 | } 135 | .highlight .na { 136 | color: #008080; 137 | } 138 | .highlight .bp { 139 | color: #999999; 140 | } 141 | .highlight .nb { 142 | color: #0086B3; 143 | } 144 | .highlight .nc { 145 | color: #445588; 146 | font-weight: bold; 147 | } 148 | .highlight .no { 149 | color: #008080; 150 | } 151 | .highlight .nd { 152 | color: #3c5d5d; 153 | font-weight: bold; 154 | } 155 | .highlight .ni { 156 | color: #800080; 157 | } 158 | .highlight .ne { 159 | color: #990000; 160 | font-weight: bold; 161 | } 162 | .highlight .nf { 163 | color: #990000; 164 | font-weight: bold; 165 | } 166 | .highlight .nl { 167 | color: #990000; 168 | font-weight: bold; 169 | } 170 | .highlight .nn { 171 | color: #555555; 172 | } 173 | .highlight .nt { 174 | color: #000080; 175 | } 176 | .highlight .vc { 177 | color: #008080; 178 | } 179 | .highlight .vg { 180 | color: #008080; 181 | } 182 | .highlight .vi { 183 | color: #008080; 184 | } 185 | .highlight .nv { 186 | color: #008080; 187 | } 188 | .highlight .ow { 189 | font-weight: bold; 190 | } 191 | .highlight .o { 192 | font-weight: bold; 193 | } 194 | .highlight .o { 195 | font-weight: bold; 196 | } 197 | .highlight .w { 198 | color: #bbbbbb; 199 | } 200 | -------------------------------------------------------------------------------- /doc/skin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/leaf/61e4b0db4e1934f91a06d6f0cbbe8d5f91f96383/doc/skin.png -------------------------------------------------------------------------------- /example/print_file/readme.md: -------------------------------------------------------------------------------- 1 | # Print File Example 2 | 3 | This directory contains several versions of a trivial program which takes a file name on the command line and prints it. Each version uses a different error handling implementation. 4 | 5 | * [print_file_leaf_result.cpp](./print_file_leaf_result.cpp) reports errors with 6 | `leaf::result`, using an error code `enum` for classification of failures. 7 | 8 | * [print_file_system_result.cpp](./print_file_system_result.cpp) is the same as 9 | above, but using `boost::system::result` instead of `leaf::result`. 10 | This demonstrates the ability of LEAF to transport arbitrary error objects using an 11 | external result type, rather than `boost::leaf::result`. 12 | 13 | * [print_file_exceptions.cpp](./print_file_exceptions.cpp) throws on error, using an error code 14 | `enum` for classification of failures. 15 | -------------------------------------------------------------------------------- /example/readme.md: -------------------------------------------------------------------------------- 1 | # Example Programs Using LEAF to Handle Errors 2 | 3 | * [print_file](./print_file): This directory contains several versions of a trivial program which takes a file name on the command line and prints it. Each version uses a different error handling implementation. 4 | 5 | * [try_capture_all_result.cpp](https://github.com/boostorg/leaf/blob/master/example/try_capture_all_result.cpp?ts=4): Shows how to transport error objects between threads in a `leaf::result` object without using exception handling. 6 | * [try_capture_all_exceptions.cpp](https://github.com/boostorg/leaf/blob/master/example/try_capture_all_exceptions.cpp?ts=4): Shows how to transport error objects between threads in a `leaf::result` object using exception handling. 7 | * [lua_callback_result.cpp](https://github.com/boostorg/leaf/blob/master/example/lua_callback_result.cpp?ts=4): Transporting arbitrary error objects through an uncooperative C API. 8 | * [lua_callback_exceptions.cpp](https://github.com/boostorg/leaf/blob/master/example/lua_callback_exceptions.cpp?ts=4): Transporting arbitrary error objects through an uncooperative API using exceptions. 9 | * [exception_to_result.cpp](https://github.com/boostorg/leaf/blob/master/example/exception_to_result.cpp?ts=4): Demonstrates how to transport exceptions through a `noexcept` layer in the program. 10 | * [exception_error_log.cpp](https://github.com/boostorg/leaf/blob/master/example/error_log.cpp?ts=4): Using `accumulate` to produce an error log. 11 | * [exception_error_trace.cpp](https://github.com/boostorg/leaf/blob/master/example/error_trace.cpp?ts=4): Same as above, but the log is recorded in a `std::deque` rather than just printed. 12 | * [print_half.cpp](https://github.com/boostorg/leaf/blob/master/example/print_half.cpp?ts=4): This is a Boost Outcome example adapted to LEAF, demonstrating the use of `try_handle_some` to handle some errors, forwarding any other error to the caller. 13 | -------------------------------------------------------------------------------- /example/try_capture_all_exceptions.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | // This is a simple program that demonstrates the use of LEAF to transport error 6 | // objects between threads, using exception handling. See capture_in_result.cpp 7 | // for the version that does not use exception handling. 8 | 9 | #include 10 | 11 | #if !BOOST_LEAF_CFG_CAPTURE || defined(BOOST_LEAF_NO_EXCEPTIONS) 12 | 13 | #include 14 | 15 | int main() 16 | { 17 | std::cout << "Unit test not applicable." << std::endl; 18 | return 0; 19 | } 20 | 21 | #else 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | namespace leaf = boost::leaf; 33 | 34 | // Define several error types. 35 | struct e_thread_id { std::thread::id value; }; 36 | struct e_failure_info1 { std::string value; }; 37 | struct e_failure_info2 { int value; }; 38 | 39 | // A type that represents a successfully returned result from a task. 40 | struct task_result { }; 41 | 42 | // This is our task function. It produces objects of type task_result, but it 43 | // may fail. 44 | task_result task() 45 | { 46 | bool succeed = (rand()%4) != 0; //...at random. 47 | if( succeed ) 48 | return { }; 49 | else 50 | leaf::throw_exception( 51 | e_thread_id{std::this_thread::get_id()}, 52 | e_failure_info1{"info"}, 53 | e_failure_info2{42} ); 54 | }; 55 | 56 | int main() 57 | { 58 | int const task_count = 42; 59 | 60 | // Container to collect the generated std::future objects. 61 | std::vector>> fut; 62 | 63 | // Launch the tasks, but rather than launching the task function directly, 64 | // we use try_capture_all: in case of a failure, the returned leaf::result<> 65 | // will capture all error objects. 66 | std::generate_n( std::back_inserter(fut), task_count, 67 | [&] 68 | { 69 | return std::async( 70 | std::launch::async, 71 | [&] 72 | { 73 | return leaf::try_capture_all(task); 74 | } ); 75 | } ); 76 | 77 | // Wait on the futures, get the task results, handle errors. 78 | for( auto & f : fut ) 79 | { 80 | f.wait(); 81 | 82 | leaf::try_catch( 83 | [&] 84 | { 85 | task_result r = f.get().value(); 86 | 87 | // Success! Use r to access task_result. 88 | std::cout << "Success!" << std::endl; 89 | (void) r; // Presumably we'll somehow use the task_result. 90 | }, 91 | []( e_failure_info1 const & v1, e_failure_info2 const & v2, e_thread_id const & tid ) 92 | { 93 | std::cerr << "Error in thread " << tid.value << "! failure_info1: " << v1.value << ", failure_info2: " << v2.value << std::endl; 94 | }, 95 | []( leaf::diagnostic_info const & unmatched ) 96 | { 97 | std::cerr << 98 | "Unknown failure detected" << std::endl << 99 | "Cryptic diagnostic information follows" << std::endl << 100 | unmatched; 101 | } ); 102 | } 103 | } 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /include/boost/leaf.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_HPP_INCLUDED 2 | #define BOOST_LEAF_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /include/boost/leaf/common.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_COMMON_HPP_INCLUDED 2 | #define BOOST_LEAF_COMMON_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #if BOOST_LEAF_CFG_STD_STRING 16 | # include 17 | #endif 18 | 19 | #if BOOST_LEAF_CFG_WIN32 20 | # include 21 | # include 22 | # ifdef min 23 | # undef min 24 | # endif 25 | # ifdef max 26 | # undef max 27 | # endif 28 | #endif 29 | 30 | namespace boost { namespace leaf { 31 | 32 | struct BOOST_LEAF_SYMBOL_VISIBLE e_api_function { char const * value; }; 33 | 34 | #if BOOST_LEAF_CFG_STD_STRING 35 | 36 | struct BOOST_LEAF_SYMBOL_VISIBLE e_file_name 37 | { 38 | std::string value; 39 | }; 40 | 41 | #else 42 | 43 | struct BOOST_LEAF_SYMBOL_VISIBLE e_file_name 44 | { 45 | char const * value = ""; 46 | BOOST_LEAF_CONSTEXPR explicit e_file_name( char const * ) { } 47 | }; 48 | 49 | #endif 50 | 51 | struct BOOST_LEAF_SYMBOL_VISIBLE e_errno 52 | { 53 | int value; 54 | 55 | explicit e_errno(int val=errno): value(val) { } 56 | 57 | template 58 | friend std::ostream & operator<<(std::basic_ostream & os, e_errno const & err) 59 | { 60 | return os << err.value << ", \"" << std::strerror(err.value) << '"'; 61 | } 62 | }; 63 | 64 | struct BOOST_LEAF_SYMBOL_VISIBLE e_type_info_name { char const * value; }; 65 | 66 | struct BOOST_LEAF_SYMBOL_VISIBLE e_at_line { int value; }; 67 | 68 | namespace windows 69 | { 70 | struct e_LastError 71 | { 72 | unsigned value; 73 | 74 | explicit e_LastError(unsigned val): value(val) { } 75 | 76 | #if BOOST_LEAF_CFG_WIN32 77 | e_LastError(): value(GetLastError()) { } 78 | 79 | template 80 | friend std::ostream & operator<<(std::basic_ostream & os, e_LastError const & err) 81 | { 82 | struct msg_buf 83 | { 84 | LPVOID * p; 85 | msg_buf(): p(nullptr) { } 86 | ~msg_buf() noexcept { if(p) LocalFree(p); } 87 | }; 88 | msg_buf mb; 89 | if( FormatMessageA( 90 | FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 91 | nullptr, 92 | err.value, 93 | MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), 94 | (LPSTR)&mb.p, 95 | 0, 96 | nullptr) ) 97 | { 98 | BOOST_LEAF_ASSERT(mb.p != nullptr); 99 | char * z = std::strchr((LPSTR)mb.p,0); 100 | if( z[-1] == '\n' ) 101 | *--z = 0; 102 | if( z[-1] == '\r' ) 103 | *--z = 0; 104 | return os << err.value << ", \"" << (LPCSTR)mb.p << '"'; 105 | } 106 | return os; 107 | } 108 | #endif 109 | }; 110 | } 111 | 112 | } } 113 | 114 | #endif // BOOST_LEAF_COMMON_HPP_INCLUDED 115 | -------------------------------------------------------------------------------- /include/boost/leaf/config/tls.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED 2 | #define BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #if defined(BOOST_LEAF_TLS_FREERTOS) 9 | # include 10 | #endif 11 | 12 | #ifndef BOOST_LEAF_USE_TLS_ARRAY 13 | # ifdef BOOST_LEAF_CFG_TLS_INDEX_TYPE 14 | # warning "BOOST_LEAF_CFG_TLS_INDEX_TYPE" is ignored if BOOST_LEAF_USE_TLS_ARRAY is not defined. 15 | # endif 16 | # ifdef BOOST_LEAF_CFG_TLS_ARRAY_SIZE 17 | # warning "BOOST_LEAF_CFG_TLS_ARRAY_SIZE" is ignored if BOOST_LEAF_USE_TLS_ARRAY is not defined. 18 | # endif 19 | # ifdef BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX 20 | # warning "BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX" is ignored if BOOST_LEAF_USE_TLS_ARRAY is not defined. 21 | # endif 22 | #endif 23 | 24 | #if defined BOOST_LEAF_USE_TLS_ARRAY 25 | # include 26 | #elif defined(BOOST_LEAF_NO_THREADS) 27 | # include 28 | #else 29 | # include 30 | #endif 31 | 32 | #endif // BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED 33 | -------------------------------------------------------------------------------- /include/boost/leaf/config/tls_cpp11.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED 2 | #define BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | // LEAF requires thread local storage support for pointers and for uin32_t values. 9 | 10 | // This header implements thread local storage for pointers and for unsigned int 11 | // values using the C++11 built-in thread_local storage class specifier. 12 | 13 | #include 14 | #include 15 | 16 | namespace boost { namespace leaf { 17 | 18 | namespace detail 19 | { 20 | using atomic_unsigned_int = std::atomic; 21 | } 22 | 23 | namespace tls 24 | { 25 | template 26 | struct BOOST_LEAF_SYMBOL_VISIBLE ptr 27 | { 28 | static thread_local T * p; 29 | }; 30 | 31 | template 32 | thread_local T * ptr::p; 33 | 34 | template 35 | T * read_ptr() noexcept 36 | { 37 | return ptr::p; 38 | } 39 | 40 | template 41 | void write_ptr( T * p ) noexcept 42 | { 43 | ptr::p = p; 44 | } 45 | 46 | //////////////////////////////////////// 47 | 48 | template 49 | struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint 50 | { 51 | static thread_local unsigned x; 52 | }; 53 | 54 | template 55 | thread_local unsigned tagged_uint::x; 56 | 57 | template 58 | unsigned read_uint() noexcept 59 | { 60 | return tagged_uint::x; 61 | } 62 | 63 | template 64 | void write_uint( unsigned x ) noexcept 65 | { 66 | tagged_uint::x = x; 67 | } 68 | } 69 | 70 | } } 71 | 72 | #endif // BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED 73 | -------------------------------------------------------------------------------- /include/boost/leaf/config/tls_freertos.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED 2 | #define BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | // Copyright (c) 2022 Khalil Estell 9 | 10 | // LEAF requires thread local storage support for pointers and for uin32_t values. 11 | 12 | // This header implements "thread local" storage via FreeTOS functions 13 | // pvTaskGetThreadLocalStoragePointer / pvTaskSetThreadLocalStoragePointer 14 | 15 | #include 16 | 17 | #ifndef BOOST_LEAF_USE_TLS_ARRAY 18 | # define BOOST_LEAF_USE_TLS_ARRAY 19 | #endif 20 | 21 | #ifndef BOOST_LEAF_CFG_TLS_ARRAY_SIZE 22 | # define BOOST_LEAF_CFG_TLS_ARRAY_SIZE configNUM_THREAD_LOCAL_STORAGE_POINTERS 23 | #endif 24 | 25 | static_assert((BOOST_LEAF_CFG_TLS_ARRAY_SIZE) <= configNUM_THREAD_LOCAL_STORAGE_POINTERS, 26 | "Bad BOOST_LEAF_CFG_TLS_ARRAY_SIZE"); 27 | 28 | namespace boost { namespace leaf { 29 | 30 | namespace tls 31 | { 32 | // See https://www.freertos.org/thread-local-storage-pointers.html. 33 | 34 | inline void * read_void_ptr( int tls_index ) noexcept 35 | { 36 | return pvTaskGetThreadLocalStoragePointer(0, tls_index); 37 | } 38 | 39 | inline void write_void_ptr( int tls_index, void * p ) noexcept 40 | { 41 | vTaskSetThreadLocalStoragePointer(0, tls_index, p); 42 | } 43 | } 44 | 45 | } } 46 | 47 | #endif // BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED 48 | -------------------------------------------------------------------------------- /include/boost/leaf/config/tls_globals.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED 2 | #define BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | // LEAF requires thread local storage support for pointers and for uin32_t values. 9 | 10 | // This header implements "thread local" storage for pointers and for unsigned int 11 | // values using globals, which is suitable for single thread environments. 12 | 13 | #include 14 | 15 | namespace boost { namespace leaf { 16 | 17 | namespace detail 18 | { 19 | using atomic_unsigned_int = unsigned int; 20 | } 21 | 22 | namespace tls 23 | { 24 | template 25 | struct BOOST_LEAF_SYMBOL_VISIBLE ptr 26 | { 27 | static T * p; 28 | }; 29 | 30 | template 31 | T * ptr::p; 32 | 33 | template 34 | T * read_ptr() noexcept 35 | { 36 | return ptr::p; 37 | } 38 | 39 | template 40 | void write_ptr( T * p ) noexcept 41 | { 42 | ptr::p = p; 43 | } 44 | 45 | //////////////////////////////////////// 46 | 47 | template 48 | struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint 49 | { 50 | static unsigned x; 51 | }; 52 | 53 | template 54 | unsigned tagged_uint::x; 55 | 56 | template 57 | unsigned read_uint() noexcept 58 | { 59 | return tagged_uint::x; 60 | } 61 | 62 | template 63 | void write_uint( unsigned x ) noexcept 64 | { 65 | tagged_uint::x = x; 66 | } 67 | } 68 | 69 | } } 70 | 71 | #endif // BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED 72 | -------------------------------------------------------------------------------- /include/boost/leaf/detail/all.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | -------------------------------------------------------------------------------- /include/boost/leaf/detail/capture_list.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED 2 | #define BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include 9 | #include 10 | 11 | #if BOOST_LEAF_CFG_CAPTURE 12 | 13 | #include 14 | 15 | namespace boost { namespace leaf { 16 | 17 | class error_id; 18 | 19 | namespace detail 20 | { 21 | struct BOOST_LEAF_SYMBOL_VISIBLE tls_tag_id_factory_current_id; 22 | 23 | class capture_list 24 | { 25 | capture_list( capture_list const & ) = delete; 26 | capture_list & operator=( capture_list const & ) = delete; 27 | 28 | protected: 29 | 30 | class node 31 | { 32 | friend class capture_list; 33 | 34 | virtual void unload( int err_id ) = 0; 35 | #if BOOST_LEAF_CFG_DIAGNOSTICS 36 | virtual void print(std::ostream &, error_id const & to_print, char const * & prefix) const = 0; 37 | #endif 38 | 39 | protected: 40 | 41 | virtual ~node() noexcept 42 | { 43 | }; 44 | 45 | node * next_; 46 | 47 | BOOST_LEAF_CONSTEXPR explicit node( node * * & last ) noexcept: 48 | next_(nullptr) 49 | { 50 | BOOST_LEAF_ASSERT(last != nullptr); 51 | *last = this; 52 | last = &next_; 53 | } 54 | } * first_; 55 | 56 | template 57 | BOOST_LEAF_CONSTEXPR void for_each( F f ) const 58 | { 59 | for( node * p=first_; p; p=p->next_ ) 60 | f(*p); 61 | } 62 | 63 | public: 64 | 65 | BOOST_LEAF_CONSTEXPR explicit capture_list( node * first ) noexcept: 66 | first_(first) 67 | { 68 | } 69 | 70 | BOOST_LEAF_CONSTEXPR capture_list( capture_list && other ) noexcept: 71 | first_(other.first_) 72 | { 73 | other.first_ = nullptr; 74 | } 75 | 76 | ~capture_list() noexcept 77 | { 78 | for( node const * p = first_; p; ) 79 | { 80 | node const * n = p -> next_; 81 | delete p; 82 | p = n; 83 | } 84 | } 85 | 86 | void unload( int const err_id ) 87 | { 88 | capture_list moved(first_); 89 | first_ = nullptr; 90 | tls::write_uint(unsigned(err_id)); 91 | moved.for_each( 92 | [err_id]( node & n ) 93 | { 94 | n.unload(err_id); // last node may throw 95 | } ); 96 | } 97 | 98 | template 99 | void print(std::basic_ostream & os, error_id const & to_print, char const * & prefix) const 100 | { 101 | #if BOOST_LEAF_CFG_DIAGNOSTICS 102 | if( first_ ) 103 | { 104 | for_each( 105 | [&os, &to_print, &prefix]( node const & n ) 106 | { 107 | n.print(os, to_print, prefix); 108 | } ); 109 | } 110 | #else 111 | (void) os; 112 | (void) prefix; 113 | (void) to_print; 114 | #endif 115 | } 116 | }; 117 | 118 | } 119 | 120 | } } 121 | 122 | #endif 123 | 124 | #endif // BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED 125 | -------------------------------------------------------------------------------- /include/boost/leaf/detail/function_traits.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED 2 | #define BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace boost { namespace leaf { 13 | 14 | namespace detail 15 | { 16 | template struct remove_noexcept { using type = T; }; 17 | template struct remove_noexcept { using type = R(*)(A...); }; 18 | template struct remove_noexcept { using type = R(C::*)(A...); }; 19 | template struct remove_noexcept { using type = R(C::*)(A...) const; }; 20 | 21 | template 22 | struct gcc49_workaround //Thanks Glen Fernandes 23 | { 24 | using type = void; 25 | }; 26 | 27 | template 28 | using void_t = typename gcc49_workaround::type; 29 | 30 | template 31 | struct function_traits_impl 32 | { 33 | constexpr static int arity = -1; 34 | }; 35 | 36 | template 37 | struct function_traits_impl> 38 | { 39 | private: 40 | 41 | using tr = function_traits_impl::type>; 42 | 43 | public: 44 | 45 | using return_type = typename tr::return_type; 46 | static constexpr int arity = tr::arity - 1; 47 | 48 | using mp_args = typename leaf_detail_mp11::mp_rest; 49 | 50 | template 51 | struct arg: 52 | tr::template arg 53 | { 54 | }; 55 | }; 56 | 57 | template 58 | struct function_traits_impl 59 | { 60 | using return_type = R; 61 | static constexpr int arity = sizeof...(A); 62 | 63 | using mp_args = leaf_detail_mp11::mp_list; 64 | 65 | template 66 | struct arg 67 | { 68 | static_assert(I < arity, "I out of range"); 69 | using type = typename std::tuple_element>::type; 70 | }; 71 | }; 72 | 73 | template struct function_traits_impl : function_traits_impl { }; 74 | template struct function_traits_impl : function_traits_impl { }; 75 | template struct function_traits_impl : function_traits_impl { }; 76 | template struct function_traits_impl : function_traits_impl { }; 77 | template struct function_traits_impl : function_traits_impl { }; 78 | template struct function_traits_impl : function_traits_impl { }; 79 | template struct function_traits_impl : function_traits_impl { }; 80 | template struct function_traits_impl : function_traits_impl { }; 81 | 82 | template 83 | struct function_traits: function_traits_impl::type> 84 | { 85 | }; 86 | 87 | template 88 | using fn_return_type = typename function_traits::return_type; 89 | 90 | template 91 | using fn_arg_type = typename function_traits::template arg::type; 92 | 93 | template 94 | using fn_mp_args = typename function_traits::mp_args; 95 | } 96 | 97 | } } 98 | 99 | #endif // BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED 100 | -------------------------------------------------------------------------------- /include/boost/leaf/to_variant.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_TO_VARIANT_HPP_INCLUDED 2 | #define BOOST_LEAF_TO_VARIANT_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #if __cplusplus >= 201703L 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace boost { namespace leaf { 18 | 19 | template 20 | std::variant()().value())>::type,std::tuple...>> 21 | to_variant( TryBlock && try_block ) 22 | { 23 | static_assert(is_result_type()())>::value, "The return type of the try_block passed to a to_variant function must be registered with leaf::is_result_type"); 24 | using T = typename std::decay()().value())>::type; 25 | using error_tuple_type = std::tuple...>; 26 | using variant_type = std::variant; 27 | return try_handle_all( 28 | [&]() -> result 29 | { 30 | if( auto r = std::forward(try_block)() ) 31 | return *std::move(r); 32 | else 33 | return r.error(); 34 | }, 35 | []( E const * ... e ) -> variant_type 36 | { 37 | return error_tuple_type { e ? std::optional(*e) : std::optional{}... }; 38 | }, 39 | []() -> variant_type 40 | { 41 | return error_tuple_type { }; 42 | } ); 43 | } 44 | 45 | } } 46 | 47 | #endif 48 | 49 | #endif // BOOST_LEAF_TO_VARIANT_HPP_INCLUDED 50 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Automatic redirection failed, please go to 7 | doc/html/index.html. 8 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('single_header',type:'boolean',value:false,description:'Unit tests #include "leaf.hpp" instead of individual headers') 2 | option('leaf_boost_examples',type:'boolean',value:false,description:'Builds the examples that use Boost') 3 | option('leaf_lua_examples',type:'boolean',value:false,description:'Enable or disable downloading of Lua and building the Lua examples') 4 | option('leaf_diagnostics',type:'integer',value:1,description:'BOOST_LEAF_CFG_DIAGNOSTICS value') 5 | option('leaf_capture',type:'integer',value:1,description:'BOOST_LEAF_CFG_CAPTURE value') 6 | option('leaf_embedded',type:'boolean',value:false,description:'Defines BOOST_LEAF_EMBEDDED') 7 | option('leaf_enable_unit_tests',type:'boolean',value:true,description:'Enable the building of unit test programs') 8 | option('leaf_enable_examples',type:'boolean',value:true,description:'Enable the building of example programs') 9 | -------------------------------------------------------------------------------- /meta/libraries.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "leaf", 3 | "name": "LEAF", 4 | "authors": [ 5 | "Emil Dotchevski" 6 | ], 7 | "maintainers": [ 8 | "Emil Dotchevski" 9 | ], 10 | "description": "A lightweight error handling library for C++11.", 11 | "category": [ 12 | "Error-handling" 13 | ], 14 | "cxxstd": "11" 15 | } 16 | -------------------------------------------------------------------------------- /subprojects/lua.wrap: -------------------------------------------------------------------------------- 1 | [wrap-file] 2 | directory=lua-5.1.5 3 | 4 | source_url = http://www.lua.org/ftp/lua-5.1.5.tar.gz 5 | source_filename = lua-5.1.5.tar.gz 6 | source_hash = 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333 7 | 8 | patch_url = https://github.com/zajo/meson_wraps/blob/master/lua/subprojects/lua.tar.gz?raw=true 9 | patch_filename = lua.tar.gz 10 | patch_hash = 51cd288c6ce32cd338e39cf9a1343dcb2ea9f05293055c96dcce87781d3b0afb -------------------------------------------------------------------------------- /subprojects/tl_expected.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/zajo/expected.git 3 | revision = head 4 | -------------------------------------------------------------------------------- /test/BOOST_LEAF_ASSIGN_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | #endif 11 | 12 | #include "lightweight_test.hpp" 13 | #ifdef BOOST_LEAF_BOOST_AVAILABLE 14 | # include 15 | #else 16 | # define BOOST_WORKAROUND(a,b) 0 17 | #endif 18 | 19 | namespace leaf = boost::leaf; 20 | 21 | struct value 22 | { 23 | int x; 24 | 25 | explicit value( int x_ ): x(x_) { }; 26 | 27 | #ifndef BOOST_LEAF_NO_CXX11_REF_QUALIFIERS 28 | value( value const & ) = delete; 29 | value( value && ) = default; 30 | #endif 31 | }; 32 | 33 | leaf::result f1() 34 | { 35 | return value { 21 }; 36 | } 37 | 38 | leaf::result f2() 39 | { 40 | BOOST_LEAF_ASSIGN(auto a, f1()); 41 | #if BOOST_WORKAROUND( BOOST_GCC, < 50000 ) || BOOST_WORKAROUND( BOOST_CLANG, <= 30800 ) 42 | return std::move(a); // Older compilers are confused, but... 43 | #else 44 | return a; // ...this doesn't need to be return std::move(a); 45 | #endif 46 | } 47 | 48 | leaf::result f3() 49 | { 50 | BOOST_LEAF_ASSIGN(auto a, f2()); 51 | BOOST_LEAF_ASSIGN(auto b, f2()); // Invoking the macro twice in the same scope, testing the temp name generation 52 | return value { a.x + b.x }; 53 | } 54 | 55 | int main() 56 | { 57 | BOOST_TEST_EQ(f3()->x, 42); 58 | 59 | { 60 | int r = leaf::try_handle_all( 61 | []() -> leaf::result 62 | { 63 | int x = 42; 64 | 65 | leaf::result r1(x); 66 | BOOST_LEAF_ASSIGN(auto && rx1, r1); 67 | BOOST_TEST_EQ(r1.value(), rx1); 68 | 69 | leaf::result r2(x); 70 | BOOST_LEAF_ASSIGN(auto && rx2, r2); 71 | BOOST_TEST_EQ(r2.value(), rx2); 72 | 73 | leaf::result r3(x); 74 | BOOST_LEAF_ASSIGN(auto & rx3, r3); 75 | BOOST_TEST_EQ(&r3.value(), &rx3); 76 | 77 | return 0; 78 | }, 79 | [] 80 | { 81 | return 1; 82 | } ); 83 | BOOST_TEST_EQ(r, 0); 84 | } 85 | 86 | return boost::report_errors(); 87 | } 88 | -------------------------------------------------------------------------------- /test/BOOST_LEAF_AUTO_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | #endif 11 | 12 | #include "lightweight_test.hpp" 13 | #ifdef BOOST_LEAF_BOOST_AVAILABLE 14 | # include 15 | #else 16 | # define BOOST_WORKAROUND(a,b) 0 17 | #endif 18 | 19 | namespace leaf = boost::leaf; 20 | 21 | struct value 22 | { 23 | int x; 24 | 25 | explicit value( int x_ ): x(x_) { }; 26 | 27 | #ifndef BOOST_LEAF_NO_CXX11_REF_QUALIFIERS 28 | value( value const & ) = delete; 29 | value( value && ) = default; 30 | #endif 31 | }; 32 | 33 | leaf::result f1() 34 | { 35 | return value { 21 }; 36 | } 37 | 38 | leaf::result f2() 39 | { 40 | BOOST_LEAF_AUTO(a, f1()); 41 | #if BOOST_WORKAROUND( BOOST_GCC, < 50000 ) || BOOST_WORKAROUND( BOOST_CLANG, <= 30800 ) 42 | return std::move(a); // Older compilers are confused, but... 43 | #else 44 | return a; // ...this doesn't need to be return std::move(a); 45 | #endif 46 | } 47 | 48 | template 49 | leaf::result f2_lambda( Lambda ) 50 | { 51 | BOOST_LEAF_AUTO(a, f1()); 52 | #if BOOST_WORKAROUND( BOOST_GCC, < 50000 ) || BOOST_WORKAROUND( BOOST_CLANG, <= 30800 ) 53 | return std::move(a); // Older compilers are confused, but... 54 | #else 55 | return a; // ...this doesn't need to be return std::move(a); 56 | #endif 57 | } 58 | 59 | leaf::result f3() 60 | { 61 | BOOST_LEAF_AUTO(a, f2()); 62 | 63 | // Invoking the macro twice in the same scope, testing the temp name 64 | // generation. Also making sure we can pass a lambda (See 65 | // https://github.com/boostorg/leaf/issues/16). 66 | BOOST_LEAF_AUTO(b, f2_lambda([]{})); 67 | 68 | return value { a.x + b.x }; 69 | } 70 | 71 | int main() 72 | { 73 | BOOST_TEST_EQ(f3()->x, 42); 74 | 75 | { 76 | int r = leaf::try_handle_all( 77 | []() -> leaf::result 78 | { 79 | int x = 42; 80 | 81 | leaf::result r1(x); 82 | BOOST_LEAF_AUTO(rx1, r1); 83 | BOOST_TEST_EQ(r1.value(), rx1); 84 | 85 | leaf::result r2(x); 86 | BOOST_LEAF_AUTO(rx2, r2); 87 | BOOST_TEST_EQ(r2.value(), rx2); 88 | 89 | return 0; 90 | }, 91 | [] 92 | { 93 | return 1; 94 | } ); 95 | BOOST_TEST_EQ(r, 0); 96 | } 97 | 98 | return boost::report_errors(); 99 | } 100 | -------------------------------------------------------------------------------- /test/BOOST_LEAF_CHECK_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | #endif 11 | 12 | #ifdef BOOST_LEAF_BOOST_AVAILABLE 13 | # include 14 | #else 15 | # define BOOST_WORKAROUND(a,b) 0 16 | #endif 17 | 18 | #include "lightweight_test.hpp" 19 | 20 | namespace leaf = boost::leaf; 21 | 22 | struct value 23 | { 24 | int x; 25 | 26 | explicit value( int x_ ): x(x_) { }; 27 | 28 | #ifndef BOOST_LEAF_NO_CXX11_REF_QUALIFIERS 29 | value( value const & ) = delete; 30 | value( value && ) = default; 31 | #endif 32 | }; 33 | 34 | leaf::result f1( bool success ) 35 | { 36 | if( success ) 37 | return value { 21 }; 38 | else 39 | return leaf::new_error(); 40 | } 41 | 42 | #if BOOST_LEAF_GNUC_STMTEXPR 43 | 44 | leaf::result f2( bool success ) 45 | { 46 | return value { BOOST_LEAF_CHECK(f1(success)).x + BOOST_LEAF_CHECK(f1(success)).x }; 47 | } 48 | 49 | #else 50 | 51 | leaf::result f2( bool success ) 52 | { 53 | BOOST_LEAF_AUTO(a, f1(success)); 54 | BOOST_LEAF_AUTO(b, f1(success)); 55 | return value { a.x + b.x }; 56 | } 57 | 58 | #endif 59 | 60 | leaf::result f3( bool success ) 61 | { 62 | BOOST_LEAF_CHECK(f2(success)); 63 | return { }; 64 | } 65 | 66 | int main() 67 | { 68 | BOOST_TEST_EQ(f2(true).value().x, 42); 69 | BOOST_TEST(!f2(false)); 70 | BOOST_TEST(f3(true)); 71 | BOOST_TEST(!f3(false)); 72 | 73 | return boost::report_errors(); 74 | } 75 | -------------------------------------------------------------------------------- /test/_compile-fail-BOOST_LEAF_ASSIGN.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | template 10 | struct my_result 11 | { 12 | my_result( T ); 13 | my_result( std::error_code ); 14 | T value() const; 15 | std::error_code error(); 16 | explicit operator bool() const; 17 | }; 18 | 19 | my_result f(); 20 | 21 | my_result g() 22 | { 23 | int a; 24 | BOOST_LEAF_ASSIGN(a, f()); 25 | return a; 26 | } 27 | -------------------------------------------------------------------------------- /test/_compile-fail-BOOST_LEAF_AUTO.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | template 10 | struct my_result 11 | { 12 | my_result( T ); 13 | my_result( std::error_code ); 14 | T value() const; 15 | std::error_code error(); 16 | explicit operator bool() const; 17 | }; 18 | 19 | my_result f(); 20 | 21 | my_result g() 22 | { 23 | BOOST_LEAF_AUTO(a, f()); 24 | return a; 25 | } 26 | -------------------------------------------------------------------------------- /test/_compile-fail-arg_boost_error_info_1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | 8 | namespace leaf = boost::leaf; 9 | 10 | struct test_ex: std::exception { }; 11 | 12 | typedef boost::error_info test_info; 13 | 14 | int main() 15 | { 16 | leaf::try_catch( 17 | [] 18 | { 19 | }, 20 | []( test_info const & x ) // boost::error_info must be taken by value 21 | { 22 | } ); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test/_compile-fail-arg_boost_error_info_2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | 8 | namespace leaf = boost::leaf; 9 | 10 | struct test_ex: std::exception { }; 11 | 12 | typedef boost::error_info test_info; 13 | 14 | int main() 15 | { 16 | leaf::try_catch( 17 | [] 18 | { 19 | }, 20 | []( test_info const & x ) // boost::error_info must be taken by value 21 | { 22 | } ); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test/_compile-fail-arg_catch_1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace leaf = boost::leaf; 10 | 11 | int main() 12 | { 13 | return leaf::try_handle_all( 14 | []() -> leaf::result 15 | { 16 | return 0; 17 | }, 18 | []( leaf::catch_ const & ) // leaf::catch_<> must be taken by value 19 | { 20 | return 1; 21 | }, 22 | [] 23 | { 24 | return 2; 25 | }); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test/_compile-fail-arg_catch_2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace leaf = boost::leaf; 10 | 11 | int main() 12 | { 13 | return leaf::try_handle_all( 14 | []() -> leaf::result 15 | { 16 | return 0; 17 | }, 18 | []( leaf::catch_ & ) // leaf::catch_<> must be taken by value 19 | { 20 | return 1; 21 | }, 22 | [] 23 | { 24 | return 2; 25 | }); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test/_compile-fail-arg_match_1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace leaf = boost::leaf; 10 | 11 | int main() 12 | { 13 | return leaf::try_handle_all( 14 | []() -> leaf::result 15 | { 16 | return 0; 17 | }, 18 | []( leaf::match const & ) // leaf::match<> must be taken by value 19 | { 20 | return 1; 21 | }, 22 | [] 23 | { 24 | return 2; 25 | }); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test/_compile-fail-arg_match_2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace leaf = boost::leaf; 10 | 11 | int main() 12 | { 13 | return leaf::try_handle_all( 14 | []() -> leaf::result 15 | { 16 | return 0; 17 | }, 18 | []( leaf::match & ) // leaf::match<> must be taken by value 19 | { 20 | return 1; 21 | }, 22 | [] 23 | { 24 | return 2; 25 | }); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test/_compile-fail-arg_rvalue_ref.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | 8 | namespace leaf = boost::leaf; 9 | 10 | int main() 11 | { 12 | return leaf::try_handle_all( 13 | []() -> leaf::result 14 | { 15 | return 0; 16 | }, 17 | []( int && ) // && arguments are not allowed 18 | { 19 | return 1; 20 | }, 21 | [] 22 | { 23 | return 2; 24 | }); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /test/_compile-fail-diagnostic_details.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | leaf::diagnostic_details f(); 10 | leaf::diagnostic_details a = f(); 11 | leaf::diagnostic_details b = a; 12 | -------------------------------------------------------------------------------- /test/_compile-fail-diagnostic_info.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | leaf::diagnostic_info f(); 10 | leaf::diagnostic_info a = f(); 11 | leaf::diagnostic_info b = a; 12 | -------------------------------------------------------------------------------- /test/_compile-fail-error_info.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | leaf::error_info f(); 10 | leaf::error_info a = f(); 11 | leaf::error_info b = a; 12 | -------------------------------------------------------------------------------- /test/_compile-fail-exception_1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | struct test: std::exception { }; 10 | 11 | auto e = leaf::exception(std::exception(), test()); 12 | -------------------------------------------------------------------------------- /test/_compile-fail-exception_2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | struct test: std::exception { }; 10 | 11 | auto e = leaf::exception(42, test()); 12 | -------------------------------------------------------------------------------- /test/_compile-fail-new_error.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | int a; 8 | auto x = boost::leaf::new_error(&a); // Pointer error objects not allowed 9 | -------------------------------------------------------------------------------- /test/_compile-fail-result_1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | leaf::result f(); 10 | 11 | leaf::result g() 12 | { 13 | return f(); // Types are incompatible 14 | } 15 | -------------------------------------------------------------------------------- /test/_compile-fail-result_2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Thanks @strager 3 | 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | size_t g() { 12 | return 42; 13 | } 14 | 15 | boost::leaf::result> f() { 16 | return g(); // vector constructor is explicit 17 | } 18 | -------------------------------------------------------------------------------- /test/_compile-fail-result_3.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Thanks @strager 3 | 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | boost::leaf::result g() { 12 | return 42; 13 | } 14 | 15 | boost::leaf::result> f() { 16 | return g(); // vector constructor is explicit 17 | } 18 | -------------------------------------------------------------------------------- /test/_compile-fail-result_4.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | namespace leaf = boost::leaf; 8 | 9 | leaf::result x; // Default constructor not available for references 10 | -------------------------------------------------------------------------------- /test/_hpp_capture_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_common_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_config_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_context_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_diagnostics_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_error_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_handle_errors_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_leaf_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_on_error_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_pred_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_hpp_to_variant_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /test/_test_res.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_LEAF_TEST_RES_HPP_INCLUDED 2 | #define BOOST_LEAF_TEST_RES_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include "_test_ec.hpp" 9 | 10 | template 11 | class test_res 12 | { 13 | enum class variant 14 | { 15 | value, 16 | error 17 | }; 18 | T value_; 19 | E error_; 20 | variant which_; 21 | public: 22 | test_res( T const & value ) noexcept: 23 | value_(value), 24 | error_(), 25 | which_(variant::value) 26 | { 27 | } 28 | test_res( E const & error ) noexcept: 29 | value_(), 30 | error_(error), 31 | which_(variant::error) 32 | { 33 | } 34 | template 35 | test_res( Enum e, typename std::enable_if::value, Enum>::type * = nullptr ): 36 | value_(), 37 | error_(make_error_code(e)), 38 | which_(variant::error) 39 | { 40 | } 41 | explicit operator bool() const noexcept 42 | { 43 | return which_ == variant::value; 44 | } 45 | T const & value() const 46 | { 47 | BOOST_LEAF_ASSERT(which_ == variant::value); 48 | return value_; 49 | } 50 | E const & error() const 51 | { 52 | BOOST_LEAF_ASSERT(which_ == variant::error); 53 | return error_; 54 | } 55 | }; 56 | 57 | template 58 | class test_res 59 | { 60 | enum class variant 61 | { 62 | value, 63 | error 64 | }; 65 | E error_; 66 | variant which_; 67 | public: 68 | test_res() noexcept: 69 | error_(), 70 | which_(variant::value) 71 | { 72 | } 73 | test_res( E const & error ) noexcept: 74 | error_(error), 75 | which_(variant::error) 76 | { 77 | } 78 | template 79 | test_res( Enum e, typename std::enable_if::value, Enum>::type * = nullptr ): 80 | error_(make_error_code(e)), 81 | which_(variant::error) 82 | { 83 | } 84 | explicit operator bool() const noexcept 85 | { 86 | return which_ == variant::value; 87 | } 88 | void value() const 89 | { 90 | BOOST_LEAF_ASSERT(which_ == variant::value); 91 | } 92 | E const & error() const 93 | { 94 | BOOST_LEAF_ASSERT(which_ == variant::error); 95 | return error_; 96 | } 97 | }; 98 | 99 | namespace boost { namespace leaf { 100 | 101 | template 102 | struct is_result_type; 103 | 104 | template 105 | struct is_result_type>: std::true_type 106 | { 107 | }; 108 | 109 | } } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /test/boost/core/current_function.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED 2 | #define BOOST_CURRENT_FUNCTION_HPP_INCLUDED 3 | 4 | // MS compatible compilers support #pragma once 5 | 6 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 7 | # pragma once 8 | #endif 9 | 10 | // 11 | // boost/current_function.hpp - BOOST_CURRENT_FUNCTION 12 | // 13 | // Copyright (c) 2002 Peter Dimov and Multi Media Ltd. 14 | // 15 | // Distributed under the Boost Software License, Version 1.0. 16 | // See accompanying file LICENSE_1_0.txt or copy at 17 | // http://www.boost.org/LICENSE_1_0.txt 18 | // 19 | // http://www.boost.org/libs/assert/current_function.html 20 | // 21 | 22 | namespace boost 23 | { 24 | 25 | namespace detail 26 | { 27 | 28 | inline void current_function_helper() 29 | { 30 | 31 | #if defined( BOOST_DISABLE_CURRENT_FUNCTION ) 32 | 33 | # define BOOST_CURRENT_FUNCTION "(unknown)" 34 | 35 | #elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) || defined(__clang__) 36 | 37 | # define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ 38 | 39 | #elif defined(__DMC__) && (__DMC__ >= 0x810) 40 | 41 | # define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ 42 | 43 | #elif defined(__FUNCSIG__) 44 | 45 | # define BOOST_CURRENT_FUNCTION __FUNCSIG__ 46 | 47 | #elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) 48 | 49 | # define BOOST_CURRENT_FUNCTION __FUNCTION__ 50 | 51 | #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) 52 | 53 | # define BOOST_CURRENT_FUNCTION __FUNC__ 54 | 55 | #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) 56 | 57 | # define BOOST_CURRENT_FUNCTION __func__ 58 | 59 | #elif defined(__cplusplus) && (__cplusplus >= 201103) 60 | 61 | # define BOOST_CURRENT_FUNCTION __func__ 62 | 63 | #else 64 | 65 | # define BOOST_CURRENT_FUNCTION "(unknown)" 66 | 67 | #endif 68 | 69 | } 70 | 71 | } // namespace detail 72 | 73 | } // namespace boost 74 | 75 | #endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED 76 | -------------------------------------------------------------------------------- /test/boost_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #if defined(BOOST_LEAF_NO_EXCEPTIONS) || !defined(BOOST_LEAF_BOOST_AVAILABLE) 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | #endif 25 | 26 | #include "lightweight_test.hpp" 27 | #include 28 | #include 29 | 30 | namespace leaf = boost::leaf; 31 | 32 | struct test_ex: std::exception { }; 33 | 34 | typedef boost::error_info test_info; 35 | 36 | int main() 37 | { 38 | static_assert(std::is_same>().matched)>::value, "handler_argument_traits deduction bug"); 39 | 40 | using tr = leaf::detail::handler_argument_traits>; 41 | static_assert(std::is_same, tr::context_types>::value, "handler_argument_traits deduction bug"); 42 | 43 | { 44 | int r = leaf::try_catch( 45 | [] 46 | { 47 | try 48 | { 49 | boost::throw_exception(test_ex()); 50 | } 51 | catch( boost::exception & ex ) 52 | { 53 | ex << test_info(42); 54 | throw; 55 | } 56 | return 0; 57 | }, 58 | []( test_info x ) 59 | { 60 | BOOST_TEST_EQ(x.value(), 42); 61 | return 1; 62 | }, 63 | [] 64 | { 65 | return 2; 66 | } ); 67 | BOOST_TEST_EQ(r, 1); 68 | } 69 | 70 | { 71 | int r = leaf::try_catch( 72 | [] 73 | { 74 | try 75 | { 76 | boost::throw_exception(test_ex()); 77 | } 78 | catch( boost::exception & ex ) 79 | { 80 | ex << test_info(42); 81 | throw; 82 | } 83 | return 0; 84 | }, 85 | []( leaf::match ) 86 | { 87 | return 1; 88 | }, 89 | [] 90 | { 91 | return 2; 92 | } ); 93 | BOOST_TEST_EQ(r, 1); 94 | } 95 | 96 | { 97 | int r = leaf::try_catch( 98 | [] 99 | { 100 | try 101 | { 102 | boost::throw_exception(test_ex()); 103 | } 104 | catch( boost::exception & ex ) 105 | { 106 | ex << test_info(42); 107 | throw; 108 | } 109 | return 0; 110 | }, 111 | []( leaf::match ) 112 | { 113 | return 1; 114 | }, 115 | [] 116 | { 117 | return 2; 118 | } ); 119 | BOOST_TEST_EQ(r, 2); 120 | } 121 | 122 | return boost::report_errors(); 123 | } 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /test/capture_exception_state_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #if defined(BOOST_LEAF_NO_EXCEPTIONS) || !BOOST_LEAF_CFG_CAPTURE 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #if BOOST_LEAF_CFG_STD_STRING 28 | # include 29 | # include 30 | #endif 31 | 32 | #include "lightweight_test.hpp" 33 | 34 | namespace leaf = boost::leaf; 35 | 36 | int count = 0; 37 | 38 | template 39 | struct info 40 | { 41 | info() noexcept 42 | { 43 | ++count; 44 | } 45 | 46 | info( info const & ) noexcept 47 | { 48 | ++count; 49 | } 50 | 51 | ~info() noexcept 52 | { 53 | --count; 54 | } 55 | 56 | template 57 | friend std::ostream & operator<<( std::basic_ostream & os, info const & ) 58 | { 59 | return os << "info<" << N << "> instance"; 60 | } 61 | }; 62 | 63 | int main() 64 | { 65 | { 66 | leaf::result r = leaf::try_capture_all( 67 | []() -> int 68 | { 69 | leaf::throw_exception(info<1>{}, info<3>{}); 70 | }); 71 | BOOST_TEST_EQ(count, 2); 72 | 73 | #if BOOST_LEAF_CFG_STD_STRING 74 | { 75 | std::ostringstream st; 76 | st << r; 77 | std::string s = st.str(); 78 | std::cout << s << std::endl; 79 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 80 | { 81 | BOOST_TEST_NE(s.find("info<1> instance"), s.npos); 82 | BOOST_TEST_NE(s.find("info<3> instance"), s.npos); 83 | } 84 | } 85 | #endif 86 | 87 | int ret = leaf::try_catch( 88 | [&] 89 | { 90 | return r.value(); 91 | }, 92 | []( info<1>, info<3> ) 93 | { 94 | return 42; 95 | }, 96 | [] 97 | { 98 | return -42; 99 | } ); 100 | BOOST_TEST_EQ(ret, 42); 101 | } 102 | BOOST_TEST_EQ(count, 0); 103 | 104 | return boost::report_errors(); 105 | } 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /test/capture_result_state_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #if !BOOST_LEAF_CFG_CAPTURE 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | #endif 25 | 26 | #if BOOST_LEAF_CFG_STD_STRING 27 | # include 28 | # include 29 | #endif 30 | 31 | #include "lightweight_test.hpp" 32 | 33 | namespace leaf = boost::leaf; 34 | 35 | int count = 0; 36 | 37 | template 38 | struct info 39 | { 40 | info() noexcept 41 | { 42 | ++count; 43 | } 44 | 45 | info( info const & ) noexcept 46 | { 47 | ++count; 48 | } 49 | 50 | ~info() noexcept 51 | { 52 | --count; 53 | } 54 | 55 | template 56 | friend std::ostream & operator<<( std::basic_ostream & os, info const & ) 57 | { 58 | return os << "info<" << N << "> instance"; 59 | } 60 | }; 61 | 62 | int main() 63 | { 64 | { 65 | leaf::result r = leaf::try_capture_all( 66 | []() -> leaf::result 67 | { 68 | return leaf::new_error( info<1>{}, info<3>{} ); 69 | } ); 70 | BOOST_TEST_EQ(count, 2); 71 | 72 | #if BOOST_LEAF_CFG_STD_STRING 73 | { 74 | std::ostringstream st; 75 | st << r; 76 | std::string s = st.str(); 77 | std::cout << s << std::endl; 78 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 79 | { 80 | BOOST_TEST_NE(s.find("info<1> instance"), s.npos); 81 | BOOST_TEST_NE(s.find("info<3> instance"), s.npos); 82 | } 83 | } 84 | #endif 85 | 86 | int ret = leaf::try_handle_all( 87 | [&] 88 | { 89 | return std::move(r); 90 | }, 91 | []( info<1>, info<3> ) 92 | { 93 | return 42; 94 | }, 95 | [] 96 | { 97 | return -42; 98 | } ); 99 | BOOST_TEST_EQ(ret, 42); 100 | } 101 | BOOST_TEST_EQ(count, 0); 102 | 103 | return boost::report_errors(); 104 | } 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /test/context_activator_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | }; 22 | 23 | template 24 | leaf::result f( Ctx & ctx ) 25 | { 26 | auto active_context = activate_context(ctx); 27 | return leaf::new_error( info<1>{1} ); 28 | } 29 | 30 | int main() 31 | { 32 | auto error_handlers = std::make_tuple( 33 | []( info<1> x ) 34 | { 35 | BOOST_TEST_EQ(x.value, 1); 36 | return 1; 37 | }, 38 | [] 39 | { 40 | return 2; 41 | } ); 42 | 43 | int r = leaf::try_handle_all( 44 | [&] 45 | { 46 | auto ctx = leaf::make_context(error_handlers); 47 | leaf::result r1; 48 | { 49 | auto active_context = activate_context(ctx); 50 | r1 = f(ctx); 51 | } 52 | ctx.unload(r1.error()); 53 | return r1; 54 | }, 55 | error_handlers ); 56 | BOOST_TEST_EQ(r, 1); 57 | 58 | return boost::report_errors(); 59 | } 60 | -------------------------------------------------------------------------------- /test/ctx_handle_all_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | #include 15 | 16 | namespace leaf = boost::leaf; 17 | 18 | template 19 | struct info 20 | { 21 | int value; 22 | }; 23 | 24 | template 25 | leaf::result f( Ctx & ctx ) 26 | { 27 | auto active_context = activate_context(ctx); 28 | return leaf::new_error( info<1>{1} ); 29 | } 30 | 31 | int main() 32 | { 33 | leaf::context, leaf::diagnostic_details const &> ctx; 34 | 35 | { 36 | leaf::result r1 = f(ctx); 37 | BOOST_TEST(!r1); 38 | 39 | int r2 = ctx.handle_error( 40 | r1.error(), 41 | []( info<1> x ) 42 | { 43 | BOOST_TEST_EQ(x.value, 1); 44 | return 1; 45 | }, 46 | []( leaf::diagnostic_details const & info ) 47 | { 48 | std::cout << info; 49 | return 2; 50 | } ); 51 | BOOST_TEST_EQ(r2, 1); 52 | } 53 | 54 | return boost::report_errors(); 55 | } 56 | -------------------------------------------------------------------------------- /test/ctx_handle_some_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | }; 22 | 23 | template 24 | leaf::result f( Ctx & ctx ) 25 | { 26 | auto active_context = activate_context(ctx); 27 | return leaf::new_error( info<1>{1} ); 28 | } 29 | 30 | int main() 31 | { 32 | leaf::context> ctx; 33 | 34 | { 35 | leaf::result r1 = f(ctx); 36 | BOOST_TEST(!r1); 37 | 38 | leaf::result r2 = ctx.handle_error>( 39 | r1.error(), 40 | []( info<1> x ) -> leaf::result 41 | { 42 | BOOST_TEST_EQ(x.value, 1); 43 | return 1; 44 | }, 45 | [&r1] 46 | { 47 | return std::move(r1); 48 | } ); 49 | BOOST_TEST_EQ(r2.value(), 1); 50 | } 51 | 52 | return boost::report_errors(); 53 | } 54 | -------------------------------------------------------------------------------- /test/ctx_remote_handle_all_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | #include 15 | 16 | namespace leaf = boost::leaf; 17 | 18 | template 19 | struct info 20 | { 21 | int value; 22 | }; 23 | 24 | template 25 | leaf::result f( Ctx & ctx ) 26 | { 27 | auto active_context = activate_context(ctx); 28 | return leaf::new_error( info<1>{1} ); 29 | } 30 | 31 | int main() 32 | { 33 | auto handlers = std::make_tuple( 34 | []( info<1> x ) 35 | { 36 | BOOST_TEST_EQ(x.value, 1); 37 | return 1; 38 | }, 39 | []( leaf::diagnostic_details const & info ) 40 | { 41 | std::cout << info; 42 | return 2; 43 | } ); 44 | 45 | auto ctx = leaf::make_context(handlers); 46 | 47 | { 48 | leaf::result r1 = f(ctx); 49 | BOOST_TEST(!r1); 50 | 51 | std::cout << "ctx contents:" << std::endl << ctx; 52 | 53 | int r2 = ctx.handle_error( 54 | r1.error(), 55 | std::move(handlers)); 56 | BOOST_TEST_EQ(r2, 1); 57 | } 58 | 59 | return boost::report_errors(); 60 | } 61 | -------------------------------------------------------------------------------- /test/ctx_remote_handle_some_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | }; 22 | 23 | template 24 | leaf::result f( Ctx & ctx ) 25 | { 26 | auto active_context = activate_context(ctx); 27 | return leaf::new_error( info<1>{1} ); 28 | } 29 | 30 | int main() 31 | { 32 | auto handle_error = std::make_tuple( 33 | []( info<1> x ) 34 | { 35 | BOOST_TEST_EQ(x.value, 1); 36 | return 1; 37 | }, 38 | []( leaf::error_info const & ei ) 39 | { 40 | return ei.error(); 41 | }); 42 | 43 | auto ctx = leaf::make_context(handle_error); 44 | 45 | { 46 | leaf::result r1 = f(ctx); 47 | BOOST_TEST(!r1); 48 | 49 | leaf::result r2 = ctx.handle_error>( 50 | r1.error(), 51 | handle_error ); 52 | BOOST_TEST_EQ(r2.value(), 1); 53 | } 54 | 55 | return boost::report_errors(); 56 | } 57 | -------------------------------------------------------------------------------- /test/diagnostics_test3.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | # include 12 | #endif 13 | 14 | #if BOOST_LEAF_CFG_STD_STRING 15 | # include 16 | # include 17 | #endif 18 | 19 | #include "lightweight_test.hpp" 20 | 21 | namespace leaf = boost::leaf; 22 | 23 | struct info { int value; }; 24 | 25 | leaf::result f1() 26 | { 27 | return leaf::new_error(info{41}); 28 | } 29 | 30 | leaf::result f2() 31 | { 32 | auto load = leaf::on_error(info{42}); 33 | return f1(); 34 | } 35 | 36 | int main() 37 | { 38 | leaf::try_handle_all( 39 | []() -> leaf::result 40 | { 41 | return f2(); 42 | }, 43 | []( leaf::diagnostic_details const & di ) 44 | { 45 | #if BOOST_LEAF_CFG_STD_STRING 46 | std::ostringstream st; 47 | st << di; 48 | std::string s = st.str(); 49 | std::cout << s << std::endl; 50 | if( BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_CAPTURE ) 51 | { 52 | BOOST_TEST_NE(s.find("41"), s.npos); 53 | BOOST_TEST_EQ(s.find("42"), s.npos); 54 | } 55 | #endif 56 | } ); 57 | 58 | return boost::report_errors(); 59 | } 60 | -------------------------------------------------------------------------------- /test/diagnostics_test4.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | # include 12 | #endif 13 | 14 | #if BOOST_LEAF_CFG_STD_STRING 15 | # include 16 | # include 17 | #endif 18 | 19 | #include 20 | 21 | #include "lightweight_test.hpp" 22 | 23 | namespace leaf = boost::leaf; 24 | 25 | struct my_error 26 | { 27 | std::vector vec; 28 | void append(int x) 29 | { 30 | vec.push_back(x); 31 | } 32 | friend std::ostream & operator<<( std::ostream & os, my_error const & x ) 33 | { 34 | for( auto const & e : x.vec ) 35 | os << "appended: " << e << std::endl; 36 | return os; 37 | } 38 | }; 39 | 40 | leaf::result f1() 41 | { 42 | auto ctx_ = leaf::on_error([](my_error & e) {e.append(42);}); 43 | return leaf::new_error("new_error"); 44 | } 45 | 46 | leaf::result f2() 47 | { 48 | auto ctx_ = leaf::on_error([](my_error & e) {e.append(43);}); 49 | return f1(); 50 | } 51 | 52 | int main() 53 | { 54 | leaf::try_handle_all([]() -> leaf::result 55 | { 56 | return f2(); 57 | }, 58 | [](leaf::diagnostic_details const & e) 59 | { 60 | #if BOOST_LEAF_CFG_STD_STRING 61 | std::ostringstream st; 62 | st << e; 63 | std::string s = st.str(); 64 | std::cout << s << std::endl; 65 | if( BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_CAPTURE ) 66 | { 67 | BOOST_TEST_NE(s.find("new_error"), s.npos); 68 | BOOST_TEST_NE(s.find("appended: 42"), s.npos); 69 | BOOST_TEST_NE(s.find("appended: 43"), s.npos); 70 | } 71 | #endif 72 | } ); 73 | 74 | return boost::report_errors(); 75 | } 76 | -------------------------------------------------------------------------------- /test/diagnostics_test5.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | # include 12 | #endif 13 | 14 | #if BOOST_LEAF_CFG_STD_STRING 15 | # include 16 | # include 17 | #endif 18 | 19 | #include "lightweight_test.hpp" 20 | 21 | namespace leaf = boost::leaf; 22 | 23 | namespace 24 | { 25 | int counter = 0; 26 | } 27 | 28 | template 29 | struct info 30 | { 31 | info(info const &) = delete; 32 | info & operator=(info const &) = delete; 33 | int acc = 0; 34 | info() 35 | { 36 | ++counter; 37 | } 38 | info( info && x ): 39 | acc(x.acc) 40 | { 41 | ++counter; 42 | } 43 | ~info() 44 | { 45 | --counter; 46 | } 47 | void accumulate() 48 | { 49 | ++acc; 50 | } 51 | friend std::ostream & operator<<( std::ostream & os, info const & x ) 52 | { 53 | return os << "info<" << N << ">: acc=" << x.acc; 54 | } 55 | }; 56 | 57 | leaf::result f1() 58 | { 59 | return leaf::new_error(info<1>(), [](info<4> & x){ x.accumulate(); }); 60 | } 61 | 62 | leaf::result f2() 63 | { 64 | auto load = leaf::on_error(info<2>{}, [](){ return info<3>(); }, [](info<4> & x){ x.accumulate(); }); 65 | return f1(); 66 | } 67 | 68 | leaf::result f3() 69 | { 70 | return leaf::try_handle_some( 71 | []() -> leaf::result 72 | { 73 | return f2(); 74 | }, 75 | []( leaf::diagnostic_details const & e ) 76 | { 77 | return e.error(); 78 | } ); 79 | } 80 | 81 | int main() 82 | { 83 | BOOST_TEST_EQ(counter, 0); 84 | leaf::try_handle_all( 85 | []() -> leaf::result 86 | { 87 | return f3(); 88 | }, 89 | []( info<1> const &, leaf::diagnostic_details const & di ) 90 | { 91 | #if BOOST_LEAF_CFG_STD_STRING 92 | std::ostringstream st; 93 | st << di; 94 | std::string s = st.str(); 95 | std::cout << s << std::endl; 96 | if( BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_CAPTURE ) 97 | { 98 | auto const n1 = s.find("info<1>: acc=0"); 99 | auto const n2 = s.find("info<2>: acc=0"); 100 | auto const n3 = s.find("info<3>: acc=0"); 101 | auto const n4 = s.find("info<4>: acc=2"); 102 | BOOST_TEST_NE(n1, s.npos); 103 | BOOST_TEST_NE(n2, s.npos); 104 | BOOST_TEST_NE(n3, s.npos); 105 | BOOST_TEST_NE(n4, s.npos); 106 | BOOST_TEST_EQ(counter, 4); 107 | } 108 | else 109 | BOOST_TEST_EQ(counter, 1); 110 | #endif 111 | }, 112 | [] 113 | { 114 | std::abort(); 115 | } ); 116 | BOOST_TEST_EQ(counter, 0); 117 | 118 | leaf::try_handle_all( 119 | []() -> leaf::result 120 | { 121 | return f2(); 122 | }, 123 | [] 124 | { 125 | BOOST_TEST_EQ(counter, 0); 126 | } ); 127 | 128 | return boost::report_errors(); 129 | } 130 | -------------------------------------------------------------------------------- /test/diagnostics_test6.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | # include 12 | #endif 13 | 14 | #if BOOST_LEAF_CFG_STD_STRING 15 | # include 16 | # include 17 | #endif 18 | 19 | #include 20 | 21 | #include "lightweight_test.hpp" 22 | 23 | namespace leaf = boost::leaf; 24 | 25 | template struct info { int value; }; 26 | 27 | leaf::result f1() 28 | { 29 | return leaf::new_error(info<1>{11}, info<2>{21}); 30 | } 31 | 32 | leaf::result f2() 33 | { 34 | return leaf::try_handle_some( 35 | [] 36 | { 37 | return f1(); 38 | }, 39 | [] 40 | { 41 | return leaf::new_error(info<1>{12}); 42 | } ); 43 | } 44 | 45 | leaf::result f3() 46 | { 47 | return leaf::try_handle_some( 48 | [] 49 | { 50 | return f1(); 51 | }, 52 | [](leaf::diagnostic_details const &) 53 | { 54 | return leaf::new_error(info<1>{13}); 55 | } ); 56 | } 57 | 58 | leaf::result f4() 59 | { 60 | return leaf::try_handle_some( 61 | [] 62 | { 63 | return f1(); 64 | }, 65 | [](leaf::diagnostic_details const & e) 66 | { 67 | return e.error().load(info<1>{14}); 68 | } ); 69 | } 70 | 71 | int main() 72 | { 73 | leaf::try_handle_all([]() -> leaf::result 74 | { 75 | return f2(); 76 | }, 77 | [](leaf::diagnostic_details const & e) 78 | { 79 | #if BOOST_LEAF_CFG_STD_STRING 80 | std::ostringstream st; 81 | st << e; 82 | std::string s = st.str(); 83 | std::cout << s << std::endl; 84 | if( BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_CAPTURE ) 85 | { 86 | BOOST_TEST_EQ(s.find(": 11"), s.npos); 87 | BOOST_TEST_NE(s.find(": 12"), s.npos); 88 | BOOST_TEST_EQ(s.find(": 21"), s.npos); 89 | } 90 | #endif 91 | } ); 92 | 93 | leaf::try_handle_all([]() -> leaf::result 94 | { 95 | return f3(); 96 | }, 97 | [](leaf::diagnostic_details const & e) 98 | { 99 | #if BOOST_LEAF_CFG_STD_STRING 100 | std::ostringstream st; 101 | st << e; 102 | std::string s = st.str(); 103 | std::cout << s << std::endl; 104 | if( BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_CAPTURE ) 105 | { 106 | BOOST_TEST_EQ(s.find(": 11"), s.npos); 107 | BOOST_TEST_NE(s.find(": 13"), s.npos); 108 | BOOST_TEST_EQ(s.find(": 21"), s.npos); 109 | } 110 | #endif 111 | } ); 112 | 113 | leaf::try_handle_all([]() -> leaf::result 114 | { 115 | return f4(); 116 | }, 117 | [](leaf::diagnostic_details const & e) 118 | { 119 | #if BOOST_LEAF_CFG_STD_STRING 120 | std::ostringstream st; 121 | st << e; 122 | std::string s = st.str(); 123 | std::cout << s << std::endl; 124 | if( BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_CAPTURE ) 125 | { 126 | BOOST_TEST_EQ(s.find(": 12"), s.npos); 127 | BOOST_TEST_NE(s.find(": 14"), s.npos); 128 | BOOST_TEST_NE(s.find(": 21"), s.npos); 129 | } 130 | #endif 131 | } ); 132 | 133 | return boost::report_errors(); 134 | } 135 | -------------------------------------------------------------------------------- /test/e_LastError_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifndef _WIN32 6 | 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << "This test requires Windows"; 12 | return 0; 13 | } 14 | 15 | #else 16 | 17 | #define BOOST_LEAF_CFG_WIN32 1 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #if BOOST_LEAF_CFG_STD_STRING 28 | # include 29 | # include 30 | #endif 31 | 32 | #include "lightweight_test.hpp" 33 | 34 | namespace leaf = boost::leaf; 35 | 36 | int main() 37 | { 38 | SetLastError(ERROR_FILE_NOT_FOUND); 39 | #if BOOST_LEAF_CFG_STD_STRING 40 | std::ostringstream ss; 41 | ss << leaf::windows::e_LastError{}; 42 | std::string s = ss.str(); 43 | std::cout << s << std::endl; 44 | #if BOOST_LEAF_CFG_DIAGNOSTICS 45 | BOOST_TEST_NE(ss.str().find("The system cannot find the file specified"), std::string::npos); 46 | #endif 47 | #endif 48 | 49 | int r = leaf::try_handle_all( 50 | []() -> leaf::result 51 | { 52 | SetLastError(ERROR_FILE_NOT_FOUND); 53 | struct reset_LastError { ~reset_LastError() {SetLastError(0); } } reset; 54 | return leaf::new_error( leaf::windows::e_LastError{} ); 55 | }, 56 | []( leaf::windows::e_LastError e ) 57 | { 58 | BOOST_TEST_EQ(GetLastError(), 0); 59 | BOOST_TEST_EQ(e.value, ERROR_FILE_NOT_FOUND); 60 | return 1; 61 | }, 62 | [] 63 | { 64 | return 2; 65 | } ); 66 | BOOST_TEST_EQ(r, 1); 67 | return boost::report_errors(); 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /test/e_errno_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #if BOOST_LEAF_CFG_STD_STRING 14 | # include 15 | # include 16 | #endif 17 | 18 | #include "lightweight_test.hpp" 19 | 20 | namespace leaf = boost::leaf; 21 | 22 | int main() 23 | { 24 | errno = ENOENT; 25 | #if BOOST_LEAF_CFG_STD_STRING 26 | std::ostringstream ss; 27 | ss << leaf::e_errno{}; 28 | std::string s = ss.str(); 29 | std::cout << s << std::endl; 30 | #if BOOST_LEAF_CFG_STD_DIAGNOSTICS 31 | BOOST_TEST_NE(s.find(std::strerror(ENOENT)), std::string::npos); 32 | #endif 33 | #endif 34 | 35 | int r = leaf::try_handle_all( 36 | []() -> leaf::result 37 | { 38 | struct reset_errno { ~reset_errno() { errno=0; } } reset; 39 | return leaf::new_error( leaf::e_errno{} ); 40 | }, 41 | []( leaf::e_errno e ) 42 | { 43 | BOOST_TEST_EQ(errno, 0); 44 | BOOST_TEST_EQ(e.value, ENOENT); 45 | return 1; 46 | }, 47 | [] 48 | { 49 | return 2; 50 | } ); 51 | BOOST_TEST_EQ(r, 1); 52 | return boost::report_errors(); 53 | } 54 | -------------------------------------------------------------------------------- /test/exception_to_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template struct my_exception: std::exception { }; 32 | 33 | int main() 34 | { 35 | { 36 | int r = leaf::try_handle_all( 37 | [] 38 | { 39 | return leaf::exception_to_result,my_exception<2>>( 40 | []() -> int 41 | { 42 | throw my_exception<1>(); 43 | } ); 44 | }, 45 | []( my_exception<1> const &, std::exception_ptr const & ep ) 46 | { 47 | try 48 | { 49 | std::rethrow_exception(ep); 50 | } 51 | catch( my_exception<1> const & ) 52 | { 53 | } 54 | return 1; 55 | }, 56 | []( my_exception<2> const & ) 57 | { 58 | return 2; 59 | }, 60 | [] 61 | { 62 | return 3; 63 | } ); 64 | BOOST_TEST_EQ(r, 1); 65 | } 66 | { 67 | int r = leaf::try_handle_all( 68 | [] 69 | { 70 | return leaf::exception_to_result,my_exception<2>>( 71 | []() -> int 72 | { 73 | throw my_exception<2>(); 74 | } ); 75 | }, 76 | []( my_exception<1> const & ) 77 | { 78 | return 1; 79 | }, 80 | []( my_exception<2> const &, std::exception_ptr const & ep ) 81 | { 82 | try 83 | { 84 | std::rethrow_exception(ep); 85 | } 86 | catch( my_exception<2> const & ) 87 | { 88 | } 89 | return 2; 90 | }, 91 | [] 92 | { 93 | return 3; 94 | } ); 95 | BOOST_TEST_EQ(r, 2); 96 | } 97 | { 98 | int r = leaf::try_handle_all( 99 | [] 100 | { 101 | return leaf::exception_to_result>( 102 | []() -> int 103 | { 104 | throw my_exception<1>(); 105 | } ); 106 | }, 107 | []( std::exception const &, std::exception_ptr const & ep ) 108 | { 109 | try 110 | { 111 | std::rethrow_exception(ep); 112 | } 113 | catch( my_exception<1> const & ) 114 | { 115 | } 116 | return 1; 117 | }, 118 | []( my_exception<1> const & ) 119 | { 120 | return 2; 121 | }, 122 | [] 123 | { 124 | return 3; 125 | } ); 126 | BOOST_TEST_EQ(r, 1); 127 | } 128 | return boost::report_errors(); 129 | } 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /test/function_traits_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | #endif 10 | 11 | #include 12 | 13 | namespace leaf = boost::leaf; 14 | 15 | template 16 | void check_traits( F ) 17 | { 18 | using namespace leaf::detail; 19 | using leaf::leaf_detail_mp11::mp_list; 20 | static_assert(function_traits::arity == 4,"arity"); 21 | static_assert(std::is_same,double>::value,"return_type"); 22 | static_assert(std::is_same,int>::value,"arg<0>"); 23 | static_assert(std::is_same,float>::value,"arg<1>"); 24 | static_assert(std::is_same,int const &>::value,"arg<2>"); 25 | static_assert(std::is_same,float &&>::value,"arg<3>"); 26 | static_assert(std::is_same,mp_list>::value,"mp_args"); 27 | } 28 | 29 | double f1( int, float, int const &, float && ) 30 | { 31 | return 42; 32 | } 33 | 34 | int main() 35 | { 36 | check_traits(&f1); 37 | check_traits(std::function(f1)); 38 | check_traits( []( int const volatile, float const, int const &, float && ) -> double 39 | { 40 | return 42; 41 | } ); 42 | check_traits( []( int const volatile, float const, int const &, float && ) noexcept -> double 43 | { 44 | return 42; 45 | } ); 46 | static_assert(leaf::detail::function_traits::arity == -1, "int arity"); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /test/github_issue53_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | enum class ErrorCode 18 | { 19 | E_GENERIC_UNEXPECTED, 20 | E_GENERIC_PARSE 21 | }; 22 | 23 | leaf::result test1( int a ) 24 | { 25 | if( a == 1 ) 26 | return leaf::new_error(ErrorCode::E_GENERIC_UNEXPECTED); 27 | return 32; 28 | } 29 | 30 | leaf::result test2(int a) 31 | { 32 | return leaf::try_handle_some( 33 | [&]() -> leaf::result 34 | { 35 | BOOST_LEAF_AUTO(val, test1(a)); 36 | (void) val; 37 | return 4.5; 38 | }, 39 | [](leaf::match) -> leaf::result 40 | { 41 | return leaf::new_error(ErrorCode::E_GENERIC_PARSE); 42 | } 43 | ); 44 | } 45 | 46 | void test3(int a) 47 | { 48 | int x = 0; 49 | leaf::try_handle_all( 50 | [&]() -> leaf::result 51 | { 52 | BOOST_LEAF_AUTO(val, test2(a)); 53 | (void) val; 54 | return {}; 55 | }, 56 | [&](leaf::match) 57 | { 58 | x = 1; 59 | }, 60 | [&](ErrorCode e) 61 | { 62 | x = 2; 63 | }, 64 | [&]() 65 | { 66 | x = 3; 67 | } 68 | ); 69 | BOOST_TEST_EQ(x, 1); 70 | } 71 | 72 | int main() 73 | { 74 | test3(1); 75 | return boost::report_errors(); 76 | } 77 | -------------------------------------------------------------------------------- /test/github_issue53x_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | 6 | #include 7 | 8 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 9 | 10 | #include 11 | 12 | int main() 13 | { 14 | std::cout << "Unit test not applicable." << std::endl; 15 | return 0; 16 | } 17 | 18 | #else 19 | 20 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 21 | # include "leaf.hpp" 22 | #else 23 | # include 24 | # include 25 | # include 26 | #endif 27 | 28 | #include "lightweight_test.hpp" 29 | 30 | namespace leaf = boost::leaf; 31 | 32 | enum class ErrorCode 33 | { 34 | E_GENERIC_UNEXPECTED, 35 | E_GENERIC_PARSE 36 | }; 37 | 38 | int test1( int a ) 39 | { 40 | if( a == 1 ) 41 | BOOST_LEAF_THROW_EXCEPTION(ErrorCode::E_GENERIC_UNEXPECTED); 42 | return 32; 43 | } 44 | 45 | float test2(int a) 46 | { 47 | return leaf::try_catch( 48 | [&] 49 | { 50 | auto val = test1(a); 51 | (void) val; 52 | return 4.5; 53 | }, 54 | [](leaf::match) 55 | { 56 | BOOST_LEAF_THROW_EXCEPTION(ErrorCode::E_GENERIC_PARSE); 57 | return 0; 58 | } 59 | ); 60 | } 61 | 62 | void test3(int a) 63 | { 64 | int x = 0; 65 | leaf::try_catch( 66 | [&] 67 | { 68 | auto val = test2(a); 69 | (void) val; 70 | }, 71 | [&](leaf::match) 72 | { 73 | x = 1; 74 | }, 75 | [&](ErrorCode e) 76 | { 77 | x = 2; 78 | }, 79 | [&]() 80 | { 81 | x = 3; 82 | } 83 | ); 84 | BOOST_TEST_EQ(x, 1); 85 | } 86 | 87 | int main() 88 | { 89 | test3(1); 90 | return boost::report_errors(); 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /test/handle_all_other_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #if !BOOST_LEAF_CFG_STD_SYSTEM_ERROR 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | #endif 24 | 25 | #include "_test_res.hpp" 26 | #include "lightweight_test.hpp" 27 | 28 | namespace leaf = boost::leaf; 29 | 30 | template struct info { int value; }; 31 | 32 | template 33 | ResType f( bool succeed ) 34 | { 35 | if( succeed ) 36 | return 42; 37 | else 38 | return make_error_code(std::errc::no_such_file_or_directory); 39 | } 40 | 41 | template 42 | ResType g( bool succeed ) 43 | { 44 | if( auto r = f(succeed) ) 45 | return r; 46 | else 47 | return leaf::error_id(r.error()).load(info<42>{42}); 48 | } 49 | 50 | template 51 | void test() 52 | { 53 | { 54 | int r = leaf::try_handle_all( 55 | [] 56 | { 57 | return g(true); 58 | }, 59 | [] 60 | { 61 | return -1; 62 | } ); 63 | BOOST_TEST_EQ(r, 42); 64 | } 65 | { 66 | int r = leaf::try_handle_all( 67 | [&] 68 | { 69 | auto r1 = g(false); 70 | BOOST_TEST(!r1); 71 | auto ec = r1.error(); 72 | BOOST_TEST_EQ(ec.message(), "LEAF error"); 73 | BOOST_TEST(!std::strcmp(ec.category().name(),"LEAF error")); 74 | return r1; 75 | }, 76 | []( info<42> const & x, std::error_code const & ec ) 77 | { 78 | BOOST_TEST_EQ(x.value, 42); 79 | BOOST_TEST_EQ(ec, make_error_code(std::errc::no_such_file_or_directory)); 80 | return 1; 81 | }, 82 | [] 83 | { 84 | return 2; 85 | } ); 86 | BOOST_TEST_EQ(r, 1); 87 | } 88 | } 89 | 90 | int main() 91 | { 92 | test>(); 93 | test>(); 94 | test const>(); 95 | test const>(); 96 | return boost::report_errors(); 97 | } 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /test/handle_some_other_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #if !BOOST_LEAF_CFG_STD_SYSTEM_ERROR 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | #endif 25 | 26 | #include "_test_res.hpp" 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template struct info { int value; }; 32 | 33 | template 34 | ResType f( bool succeed ) 35 | { 36 | if( succeed ) 37 | return 42; 38 | else 39 | return make_error_code(errc_a::a0); 40 | } 41 | 42 | template 43 | ResType g( bool succeed ) 44 | { 45 | if( auto r = f(succeed) ) 46 | return r; 47 | else 48 | return leaf::error_id(r.error()).load(info<42>{42}); 49 | } 50 | 51 | template 52 | void test() 53 | { 54 | { 55 | ResType r = leaf::try_handle_some( 56 | [] 57 | { 58 | return g(true); 59 | } ); 60 | BOOST_TEST(r); 61 | BOOST_TEST_EQ(r.value(), 42); 62 | } 63 | { 64 | int called = 0; 65 | ResType r = leaf::try_handle_some( 66 | [&] 67 | { 68 | auto r1 = g(false); 69 | BOOST_TEST(!r1); 70 | auto ec = r1.error(); 71 | BOOST_TEST_EQ(ec.message(), "LEAF error"); 72 | BOOST_TEST(!std::strcmp(ec.category().name(),"LEAF error")); 73 | return r1; 74 | }, 75 | [&]( info<42> const & x, leaf::match, cond_x::x00> ec ) 76 | { 77 | called = 1; 78 | BOOST_TEST_EQ(x.value, 42); 79 | return ec.matched; 80 | } ); 81 | BOOST_TEST(!r); 82 | BOOST_TEST_EQ(r.error(), make_error_code(errc_a::a0)); 83 | BOOST_TEST(called); 84 | } 85 | } 86 | 87 | int main() 88 | { 89 | test>(); 90 | test>(); 91 | test const>(); 92 | test const>(); 93 | return boost::report_errors(); 94 | } 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /test/lightweight_test.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include "boost/core/lightweight_test.hpp" 7 | #include 8 | 9 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 10 | namespace boost 11 | { 12 | [[noreturn]] void throw_exception( std::exception const & e ) 13 | { 14 | std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); 15 | std::terminate(); 16 | } 17 | 18 | struct source_location; 19 | [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) 20 | { 21 | throw_exception(e); 22 | } 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /test/match_member_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #if __cplusplus < 201703L 6 | 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << "Unit test not applicable." << std::endl; 12 | return 0; 13 | } 14 | 15 | #else 16 | 17 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 18 | # include "leaf.hpp" 19 | #else 20 | # include 21 | # include 22 | # include 23 | #endif 24 | 25 | #include "_test_ec.hpp" 26 | #include "lightweight_test.hpp" 27 | #include 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | enum class my_error { e1=1, e2, e3 }; 32 | 33 | struct e_my_error { my_error value; }; 34 | 35 | #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR 36 | struct e_error_code { std::error_code value; }; 37 | #endif 38 | 39 | struct my_exception: std::exception 40 | { 41 | int value; 42 | }; 43 | 44 | template 45 | bool test(E const & e ) 46 | { 47 | if( M::evaluate(e) ) 48 | { 49 | M m{e}; 50 | BOOST_TEST_EQ(&e, &m.matched); 51 | return true; 52 | } 53 | else 54 | return false; 55 | } 56 | 57 | int main() 58 | { 59 | { 60 | e_my_error e = { my_error::e1 }; 61 | 62 | BOOST_TEST(( test>(e) )); 63 | BOOST_TEST(( !test>(e) )); 64 | BOOST_TEST(( test>(e) )); 65 | } 66 | 67 | #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR 68 | { 69 | e_error_code e = { errc_a::a0 }; 70 | 71 | BOOST_TEST(( test>(e) )); 72 | BOOST_TEST(( !test>(e) )); 73 | BOOST_TEST(( test>(e) )); 74 | } 75 | #endif 76 | 77 | { 78 | int r = leaf::try_handle_all( 79 | []() -> leaf::result 80 | { 81 | return leaf::new_error(e_my_error{my_error::e1}); 82 | }, 83 | 84 | []( leaf::match_member<&e_my_error::value, my_error::e1> ) 85 | { 86 | return 1; 87 | }, 88 | 89 | [] 90 | { 91 | return 2; 92 | } ); 93 | BOOST_TEST_EQ(r, 1); 94 | } 95 | 96 | { 97 | int r = leaf::try_handle_all( 98 | []() -> leaf::result 99 | { 100 | return leaf::new_error(e_my_error{my_error::e1}); 101 | }, 102 | 103 | []( leaf::match_member<&e_my_error::value, my_error::e2> ) 104 | { 105 | return 1; 106 | }, 107 | 108 | [] 109 | { 110 | return 2; 111 | } ); 112 | BOOST_TEST_EQ(r, 2); 113 | } 114 | 115 | return boost::report_errors(); 116 | } 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /test/match_value_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "_test_ec.hpp" 14 | #include "lightweight_test.hpp" 15 | #include 16 | 17 | namespace leaf = boost::leaf; 18 | 19 | enum class my_error { e1=1, e2, e3 }; 20 | 21 | struct e_my_error { my_error value; }; 22 | 23 | #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR 24 | struct e_error_code { std::error_code value; }; 25 | #endif 26 | 27 | struct my_exception: std::exception 28 | { 29 | int value; 30 | }; 31 | 32 | template 33 | bool test(E const & e ) 34 | { 35 | if( M::evaluate(e) ) 36 | { 37 | M m{e}; 38 | BOOST_TEST_EQ(&e, &m.matched); 39 | return true; 40 | } 41 | else 42 | return false; 43 | } 44 | 45 | int main() 46 | { 47 | { 48 | e_my_error e = { my_error::e1 }; 49 | 50 | BOOST_TEST(( test>(e) )); 51 | BOOST_TEST(( !test>(e) )); 52 | BOOST_TEST(( test>(e) )); 53 | } 54 | 55 | #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR 56 | { 57 | e_error_code e = { errc_a::a0 }; 58 | 59 | BOOST_TEST(( test, cond_x::x00>>(e) )); 60 | BOOST_TEST(( !test, cond_x::x11>>(e) )); 61 | BOOST_TEST(( test, cond_x::x11, cond_x::x00>>(e) )); 62 | 63 | #if __cplusplus >= 201703L 64 | BOOST_TEST(( test>(e) )); 65 | BOOST_TEST(( !test>(e) )); 66 | BOOST_TEST(( test>(e) )); 67 | #endif 68 | } 69 | #endif 70 | 71 | { 72 | int r = leaf::try_handle_all( 73 | []() -> leaf::result 74 | { 75 | return leaf::new_error(e_my_error{my_error::e1}); 76 | }, 77 | 78 | []( leaf::match_value ) 79 | { 80 | return 1; 81 | }, 82 | 83 | [] 84 | { 85 | return 2; 86 | } ); 87 | BOOST_TEST_EQ(r, 1); 88 | } 89 | 90 | { 91 | int r = leaf::try_handle_all( 92 | []() -> leaf::result 93 | { 94 | return leaf::new_error(e_my_error{my_error::e1}); 95 | }, 96 | 97 | []( leaf::match_value ) 98 | { 99 | return 1; 100 | }, 101 | 102 | [] 103 | { 104 | return 2; 105 | } ); 106 | BOOST_TEST_EQ(r, 2); 107 | } 108 | 109 | return boost::report_errors(); 110 | } 111 | -------------------------------------------------------------------------------- /test/multiple_errors_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 10 | # include "leaf.hpp" 11 | #else 12 | # include 13 | #endif 14 | 15 | #include "lightweight_test.hpp" 16 | #include 17 | 18 | namespace leaf = boost::leaf; 19 | 20 | template 21 | struct info 22 | { 23 | int value; 24 | }; 25 | 26 | leaf::result f12() 27 | { 28 | return leaf::new_error( info<1>{1}, info<2>{2} ); 29 | } 30 | 31 | leaf::result f23() 32 | { 33 | return leaf::new_error( info<2>{2}, info<3>{3} ); 34 | } 35 | 36 | int main() 37 | { 38 | { 39 | int r = leaf::try_handle_all( 40 | []() -> leaf::result 41 | { 42 | leaf::result r1 = f12(); 43 | (void) r1; 44 | leaf::result r2 = f23(); 45 | return r2.error(); 46 | }, 47 | []( info<1> ) 48 | { 49 | return 1; 50 | }, 51 | []( info<2> const & x, info<3> const & y ) 52 | { 53 | BOOST_TEST_EQ(x.value, 2); 54 | BOOST_TEST_EQ(y.value, 3); 55 | return 2; 56 | }, 57 | [] 58 | { 59 | return 3; 60 | } ); 61 | BOOST_TEST_EQ(r, 2); 62 | } 63 | 64 | #ifndef BOOST_LEAF_NO_EXCEPTIONS 65 | { 66 | int r = leaf::try_catch( 67 | []() -> int 68 | { 69 | try 70 | { 71 | leaf::throw_exception(info<4>{4}); 72 | } 73 | catch(...) 74 | { 75 | } 76 | throw std::exception{}; 77 | }, 78 | []( std::exception const &, info<4> ) 79 | { 80 | return 1; 81 | }, 82 | []( std::exception const & ) 83 | { 84 | return 2; 85 | } ); 86 | BOOST_TEST_EQ(r, 2); 87 | } 88 | { 89 | int r = leaf::try_catch( 90 | []() -> int 91 | { 92 | try 93 | { 94 | auto load = leaf::on_error(info<4>{4}); 95 | throw std::exception(); 96 | } 97 | catch(...) 98 | { 99 | } 100 | leaf::throw_exception(); 101 | }, 102 | []( std::exception const &, info<4> ) 103 | { 104 | return 1; 105 | }, 106 | []( std::exception const & ) 107 | { 108 | return 2; 109 | } ); 110 | BOOST_TEST_EQ(r, 2); 111 | } 112 | #endif 113 | 114 | return boost::report_errors(); 115 | } 116 | -------------------------------------------------------------------------------- /test/on_error_accumulate_basic_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value = 0; 21 | }; 22 | 23 | leaf::error_id g() 24 | { 25 | auto load = leaf::on_error( [](info<1> & x) {++x.value;} ); 26 | return leaf::new_error(); 27 | } 28 | 29 | leaf::error_id f() 30 | { 31 | auto load = leaf::on_error( [](info<1> & x) {++x.value;}, [](info<2> & x) {++x.value;} ); 32 | return g(); 33 | } 34 | 35 | int main() 36 | { 37 | int r = leaf::try_handle_all( 38 | []() -> leaf::result 39 | { 40 | return f(); 41 | }, 42 | []( info<1> const & a, info<2> const & b ) 43 | { 44 | BOOST_TEST_EQ(a.value, 2); 45 | BOOST_TEST_EQ(b.value, 1); 46 | return 1; 47 | }, 48 | [] 49 | { 50 | return 2; 51 | } ); 52 | BOOST_TEST_EQ(r, 1); 53 | return boost::report_errors(); 54 | } 55 | -------------------------------------------------------------------------------- /test/on_error_accumulate_nested_error_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template 32 | struct info 33 | { 34 | int value; 35 | }; 36 | 37 | void f0() 38 | { 39 | auto load = leaf::on_error( []( info<0> & ) { } ); 40 | leaf::throw_exception(info<2>{2}); 41 | } 42 | 43 | void f1() 44 | { 45 | auto load = leaf::on_error( info<0>{-1}, info<2>{-1}, []( info<1> & x ) {++x.value;} ); 46 | f0(); 47 | } 48 | 49 | void f2() 50 | { 51 | try 52 | { 53 | f1(); 54 | } 55 | catch( leaf::error_id const & err ) 56 | { 57 | err.load( info<3>{3} ); 58 | throw; 59 | } 60 | } 61 | 62 | int main() 63 | { 64 | int r = leaf::try_catch( 65 | [] 66 | { 67 | f2(); 68 | return 0; 69 | }, 70 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 71 | { 72 | BOOST_TEST_EQ(i0.value, 0); 73 | BOOST_TEST_EQ(i1.value, 1); 74 | BOOST_TEST_EQ(i2.value, 2); 75 | BOOST_TEST_EQ(i3.value, 3); 76 | return 1; 77 | }, 78 | [] 79 | { 80 | return 2; 81 | } ); 82 | BOOST_TEST_EQ(r, 1); 83 | 84 | return boost::report_errors(); 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /test/on_error_accumulate_nested_error_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | info(): 22 | value(0) 23 | { 24 | } 25 | explicit info(int value): 26 | value(value) 27 | { 28 | } 29 | }; 30 | 31 | leaf::error_id f0() 32 | { 33 | auto load = leaf::on_error( []( info<0> & ) { } ); 34 | return leaf::new_error( info<2>(2) ); 35 | } 36 | 37 | leaf::error_id f1() 38 | { 39 | auto load = leaf::on_error( info<0>(-1), info<2>(-1), []( info<1> & x ) {++x.value;} ); 40 | return f0(); 41 | } 42 | 43 | leaf::error_id f2() 44 | { 45 | return f1().load( info<3>(3) ); 46 | } 47 | 48 | int main() 49 | { 50 | int r = leaf::try_handle_all( 51 | []() -> leaf::result 52 | { 53 | return f2(); 54 | }, 55 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 56 | { 57 | BOOST_TEST_EQ(i0.value, 0); 58 | BOOST_TEST_EQ(i1.value, 1); 59 | BOOST_TEST_EQ(i2.value, 2); 60 | BOOST_TEST_EQ(i3.value, 3); 61 | return 1; 62 | }, 63 | [] 64 | { 65 | return 2; 66 | } ); 67 | BOOST_TEST_EQ(r, 1); 68 | 69 | return boost::report_errors(); 70 | } 71 | -------------------------------------------------------------------------------- /test/on_error_accumulate_nested_new_error_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template 32 | struct info 33 | { 34 | int value; 35 | info(): 36 | value(0) 37 | { 38 | } 39 | explicit info(int value): 40 | value(value) 41 | { 42 | } 43 | }; 44 | 45 | void f0() 46 | { 47 | auto load = leaf::on_error( info<0>(-1) ); 48 | leaf::throw_exception(info<1>(-1)); 49 | } 50 | 51 | void f1() 52 | { 53 | auto load = leaf::on_error( []( info<0> & ) { }, []( info<1> & x ) { ++x.value; }, []( info<2> & x ) { ++x.value; } ); 54 | try { f0(); } catch(...) { } 55 | leaf::throw_exception(); 56 | } 57 | 58 | leaf::error_id f2() 59 | { 60 | try 61 | { 62 | f1(); 63 | BOOST_TEST(false); 64 | } 65 | catch( leaf::error_id const & err ) 66 | { 67 | err.load( info<3>(3) ); 68 | throw; 69 | } 70 | catch(...) 71 | { 72 | BOOST_TEST(false); 73 | } 74 | return leaf::new_error(); 75 | } 76 | 77 | int main() 78 | { 79 | int r = leaf::try_catch( 80 | [] 81 | { 82 | f2(); 83 | return 0; 84 | }, 85 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 86 | { 87 | BOOST_TEST_EQ(i0.value, 0); 88 | BOOST_TEST_EQ(i1.value, 1); 89 | BOOST_TEST_EQ(i2.value, 1); 90 | BOOST_TEST_EQ(i3.value, 3); 91 | return 1; 92 | }, 93 | [] 94 | { 95 | return 2; 96 | } ); 97 | BOOST_TEST_EQ(r, 1); 98 | 99 | return boost::report_errors(); 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /test/on_error_accumulate_nested_new_error_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | info(): 22 | value(0) 23 | { 24 | } 25 | explicit info(int value): 26 | value(value) 27 | { 28 | } 29 | }; 30 | 31 | leaf::error_id f0() 32 | { 33 | auto load = leaf::on_error( info<0>(-1) ); 34 | return leaf::new_error( info<1>(-1) ); 35 | } 36 | 37 | leaf::error_id f1() 38 | { 39 | auto load = leaf::on_error( []( info<0> & ) { }, []( info<1> & x ) { ++x.value; }, []( info<2> & x ) { ++x.value; } ); 40 | (void) f0(); 41 | return leaf::new_error(); 42 | } 43 | 44 | leaf::error_id f2() 45 | { 46 | return f1().load( info<3>(3) ); 47 | } 48 | 49 | int main() 50 | { 51 | int r = leaf::try_handle_all( 52 | []() -> leaf::result 53 | { 54 | return f2(); 55 | }, 56 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 57 | { 58 | BOOST_TEST_EQ(i0.value, 0); 59 | BOOST_TEST_EQ(i1.value, 1); 60 | BOOST_TEST_EQ(i2.value, 1); 61 | BOOST_TEST_EQ(i3.value, 3); 62 | return 1; 63 | }, 64 | [] 65 | { 66 | return 2; 67 | } ); 68 | BOOST_TEST_EQ(r, 1); 69 | 70 | return boost::report_errors(); 71 | } 72 | -------------------------------------------------------------------------------- /test/on_error_accumulate_nested_success_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | #endif 25 | 26 | #include "lightweight_test.hpp" 27 | 28 | namespace leaf = boost::leaf; 29 | 30 | struct info { int value; }; 31 | 32 | void g1() 33 | { 34 | auto load = leaf::on_error( []( info & x ) { ++x.value; } ); 35 | } 36 | 37 | void g2() 38 | { 39 | throw std::exception(); 40 | } 41 | 42 | void f() 43 | { 44 | auto load = leaf::on_error( info{42} ); 45 | g1(); 46 | g2(); 47 | } 48 | 49 | int main() 50 | { 51 | int r = leaf::try_catch( 52 | [] 53 | { 54 | f(); 55 | return 0; 56 | }, 57 | []( info x ) 58 | { 59 | BOOST_TEST_EQ(x.value, 42); 60 | return 1; 61 | }, 62 | [] 63 | { 64 | return 2; 65 | } ); 66 | BOOST_TEST_EQ(r, 1); 67 | 68 | return boost::report_errors(); 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /test/on_error_accumulate_nested_success_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | struct info { int value; }; 18 | 19 | leaf::result g1() 20 | { 21 | auto load = leaf::on_error( []( info & x ) { ++x.value; } ); 22 | return { }; 23 | } 24 | 25 | leaf::result g2() 26 | { 27 | return leaf::new_error(); 28 | } 29 | 30 | leaf::result f() 31 | { 32 | auto load = leaf::on_error( info{2} ); 33 | BOOST_LEAF_CHECK(g1()); 34 | return g2(); 35 | } 36 | 37 | int main() 38 | { 39 | int r = leaf::try_handle_all( 40 | []() -> leaf::result 41 | { 42 | BOOST_LEAF_CHECK(f()); 43 | return 1; 44 | }, 45 | []( info x ) 46 | { 47 | BOOST_TEST_EQ(x.value, 2); 48 | return 2; 49 | }, 50 | [] 51 | { 52 | return 3; 53 | } ); 54 | BOOST_TEST_EQ(r, 2); 55 | 56 | return boost::report_errors(); 57 | } 58 | -------------------------------------------------------------------------------- /test/on_error_defer_basic_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #if BOOST_LEAF_CFG_STD_STRING 14 | # include 15 | # include 16 | #endif 17 | 18 | #include "lightweight_test.hpp" 19 | 20 | namespace leaf = boost::leaf; 21 | 22 | int cleanup_count; 23 | 24 | int global; 25 | 26 | int get_global() noexcept 27 | { 28 | return global; 29 | } 30 | 31 | template 32 | struct info 33 | { 34 | int value; 35 | }; 36 | 37 | leaf::error_id g() 38 | { 39 | global = 0; 40 | auto load = leaf::on_error( []{++cleanup_count;}, []{ return info<42>{get_global()}; }, []{ return info<-42>{-42}; } ); 41 | global = 42; 42 | return leaf::new_error(); 43 | } 44 | 45 | leaf::error_id f() 46 | { 47 | auto load = leaf::on_error([]{++cleanup_count;}); 48 | return g(); 49 | } 50 | 51 | int main() 52 | { 53 | int r = leaf::try_handle_all( 54 | []() -> leaf::result 55 | { 56 | return f(); 57 | }, 58 | []( info<42> const & i42, leaf::diagnostic_info const & di ) 59 | { 60 | BOOST_TEST_EQ(i42.value, 42); 61 | #if BOOST_LEAF_CFG_STD_STRING 62 | std::ostringstream ss; 63 | ss << di; 64 | std::string s = ss.str(); 65 | std::cout << s << std::endl; 66 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 67 | BOOST_TEST_NE(s.find("info<42>"), s.npos); 68 | #endif 69 | return 1; 70 | }, 71 | [] 72 | { 73 | return 2; 74 | } ); 75 | BOOST_TEST_EQ(r, 1); 76 | BOOST_TEST_EQ(cleanup_count, 2); 77 | return boost::report_errors(); 78 | } 79 | -------------------------------------------------------------------------------- /test/on_error_defer_nested_error_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template 32 | struct info 33 | { 34 | int value; 35 | }; 36 | 37 | void f0() 38 | { 39 | auto load = leaf::on_error( [] { return info<0>{0}; } ); 40 | leaf::throw_exception(info<2>{2}); 41 | } 42 | 43 | void f1() 44 | { 45 | auto load = leaf::on_error( [] { return info<0>{-1}; }, [] { return info<1>{1}; }, [] { return info<2>{-1}; } ); 46 | f0(); 47 | } 48 | 49 | void f2() 50 | { 51 | try 52 | { 53 | f1(); 54 | } 55 | catch( leaf::error_id const & err ) 56 | { 57 | err.load( info<3>{3} ); 58 | throw; 59 | } 60 | } 61 | 62 | int main() 63 | { 64 | int r = leaf::try_catch( 65 | [] 66 | { 67 | f2(); 68 | return 0; 69 | }, 70 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 71 | { 72 | BOOST_TEST_EQ(i0.value, 0); 73 | BOOST_TEST_EQ(i1.value, 1); 74 | BOOST_TEST_EQ(i2.value, 2); 75 | BOOST_TEST_EQ(i3.value, 3); 76 | return 1; 77 | }, 78 | [] 79 | { 80 | return 2; 81 | } ); 82 | BOOST_TEST_EQ(r, 1); 83 | 84 | return boost::report_errors(); 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /test/on_error_defer_nested_error_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | }; 22 | 23 | leaf::error_id f0() 24 | { 25 | auto load = leaf::on_error( [] { return info<0>{0}; } ); 26 | return leaf::new_error( info<2>{2} ); 27 | } 28 | 29 | leaf::error_id f1() 30 | { 31 | auto load = leaf::on_error( [] { return info<0>{-1}; }, [] { return info<1>{1}; }, [] { return info<2>{-1}; } ); 32 | return f0(); 33 | } 34 | 35 | leaf::error_id f2() 36 | { 37 | return f1().load( info<3>{3} ); 38 | } 39 | 40 | int main() 41 | { 42 | int r = leaf::try_handle_all( 43 | []() -> leaf::result 44 | { 45 | return f2(); 46 | }, 47 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 48 | { 49 | BOOST_TEST_EQ(i0.value, 0); 50 | BOOST_TEST_EQ(i1.value, 1); 51 | BOOST_TEST_EQ(i2.value, 2); 52 | BOOST_TEST_EQ(i3.value, 3); 53 | return 1; 54 | }, 55 | [] 56 | { 57 | return 2; 58 | } ); 59 | BOOST_TEST_EQ(r, 1); 60 | 61 | return boost::report_errors(); 62 | } 63 | -------------------------------------------------------------------------------- /test/on_error_defer_nested_new_error_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template 32 | struct info 33 | { 34 | int value; 35 | }; 36 | 37 | void f0() 38 | { 39 | auto load = leaf::on_error( [] { return info<0>{-1}; } ); 40 | leaf::throw_exception(info<1>{-1}); 41 | } 42 | 43 | void f1() 44 | { 45 | auto load = leaf::on_error( [] { return info<0>{0}; }, [] { return info<1>{1}; }, [] { return info<2>{2}; } ); 46 | try { f0(); } catch(...) { } 47 | leaf::throw_exception(); 48 | } 49 | 50 | leaf::error_id f2() 51 | { 52 | try 53 | { 54 | f1(); 55 | BOOST_TEST(false); 56 | } 57 | catch( leaf::error_id const & err ) 58 | { 59 | err.load( info<3>{3} ); 60 | throw; 61 | } 62 | catch(...) 63 | { 64 | BOOST_TEST(false); 65 | } 66 | return leaf::new_error(); 67 | } 68 | 69 | int main() 70 | { 71 | int r = leaf::try_catch( 72 | [] 73 | { 74 | f2(); 75 | return 0; 76 | }, 77 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 78 | { 79 | BOOST_TEST_EQ(i0.value, 0); 80 | BOOST_TEST_EQ(i1.value, 1); 81 | BOOST_TEST_EQ(i2.value, 2); 82 | BOOST_TEST_EQ(i3.value, 3); 83 | return 1; 84 | }, 85 | [] 86 | { 87 | return 2; 88 | } ); 89 | BOOST_TEST_EQ(r, 1); 90 | 91 | return boost::report_errors(); 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /test/on_error_defer_nested_new_error_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | }; 22 | 23 | leaf::error_id f0() 24 | { 25 | auto load = leaf::on_error( [] { return info<0>{-1}; } ); 26 | return leaf::new_error( info<1>{-1} ); 27 | } 28 | 29 | leaf::error_id f1() 30 | { 31 | auto load = leaf::on_error( [] { return info<0>{0}; }, [] { return info<1>{1}; }, [] { return info<2>{2}; } ); 32 | (void) f0(); 33 | return leaf::new_error(); 34 | } 35 | 36 | leaf::error_id f2() 37 | { 38 | return f1().load( info<3>{3} ); 39 | } 40 | 41 | int main() 42 | { 43 | int r = leaf::try_handle_all( 44 | []() -> leaf::result 45 | { 46 | return f2(); 47 | }, 48 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 49 | { 50 | BOOST_TEST_EQ(i0.value, 0); 51 | BOOST_TEST_EQ(i1.value, 1); 52 | BOOST_TEST_EQ(i2.value, 2); 53 | BOOST_TEST_EQ(i3.value, 3); 54 | return 1; 55 | }, 56 | [] 57 | { 58 | return 2; 59 | } ); 60 | BOOST_TEST_EQ(r, 1); 61 | 62 | return boost::report_errors(); 63 | } 64 | -------------------------------------------------------------------------------- /test/on_error_defer_nested_success_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | #endif 25 | 26 | #include "lightweight_test.hpp" 27 | 28 | namespace leaf = boost::leaf; 29 | 30 | struct info { int value; }; 31 | 32 | void g1() 33 | { 34 | auto load = leaf::on_error( [] { return info{1}; } ); 35 | } 36 | 37 | void g2() 38 | { 39 | throw std::exception(); 40 | } 41 | 42 | void f() 43 | { 44 | auto load = leaf::on_error( [] { return info{2}; } ); 45 | g1(); 46 | g2(); 47 | } 48 | 49 | int main() 50 | { 51 | int r = leaf::try_catch( 52 | [] 53 | { 54 | f(); 55 | return 0; 56 | }, 57 | []( info x ) 58 | { 59 | BOOST_TEST_EQ(x.value, 2); 60 | return 1; 61 | }, 62 | [] 63 | { 64 | return 2; 65 | } ); 66 | BOOST_TEST_EQ(r, 1); 67 | 68 | return boost::report_errors(); 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /test/on_error_defer_nested_success_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | struct info { int value; }; 18 | 19 | leaf::result g1() 20 | { 21 | auto load = leaf::on_error( [] { return info{1}; } ); 22 | return { }; 23 | } 24 | 25 | leaf::result g2() 26 | { 27 | return leaf::new_error(); 28 | } 29 | 30 | leaf::result f() 31 | { 32 | auto load = leaf::on_error( [] { return info{2}; } ); 33 | BOOST_LEAF_CHECK(g1()); 34 | return g2(); 35 | } 36 | 37 | int main() 38 | { 39 | int r = leaf::try_handle_all( 40 | []() -> leaf::result 41 | { 42 | BOOST_LEAF_CHECK(f()); 43 | return 1; 44 | }, 45 | []( info x ) 46 | { 47 | BOOST_TEST_EQ(x.value, 2); 48 | return 2; 49 | }, 50 | [] 51 | { 52 | return 3; 53 | } ); 54 | BOOST_TEST_EQ(r, 2); 55 | 56 | return boost::report_errors(); 57 | } 58 | -------------------------------------------------------------------------------- /test/on_error_preload_basic_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | }; 22 | 23 | template 24 | leaf::error_id f( G && g ) 25 | { 26 | return std::forward(g)(); 27 | } 28 | 29 | template 30 | void test( G && g ) 31 | { 32 | int r = leaf::try_handle_all( 33 | [&]() -> leaf::result 34 | { 35 | return f(std::move(g)); 36 | }, 37 | []( info<42> const & i42, leaf::diagnostic_info const & di ) 38 | { 39 | BOOST_TEST_EQ(i42.value, 42); 40 | return 1; 41 | }, 42 | [] 43 | { 44 | return 2; 45 | } ); 46 | BOOST_TEST_EQ(r, 1); 47 | } 48 | 49 | int main() 50 | { 51 | test( 52 | [] 53 | { 54 | auto load = leaf::on_error( info<42>{42}, info<-42>{-42} ); 55 | return leaf::new_error(); 56 | }); 57 | test( 58 | [] 59 | { 60 | info<42> inf1{42}; 61 | info<-42> const inf2{-42}; 62 | auto load = leaf::on_error( inf1, inf2 ); 63 | return leaf::new_error(); 64 | }); 65 | test( 66 | [] 67 | { 68 | info<42> inf1{42}; 69 | auto load = leaf::on_error( inf1, info<-42>{-42} ); 70 | return leaf::new_error(); 71 | }); 72 | return boost::report_errors(); 73 | } 74 | -------------------------------------------------------------------------------- /test/on_error_preload_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #if defined(BOOST_LEAF_NO_EXCEPTIONS) || defined(BOOST_LEAF_NO_THREADS) 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template 32 | struct info 33 | { 34 | int value; 35 | }; 36 | 37 | template 38 | void g1( Thrower th ) 39 | { 40 | auto load = leaf::on_error( info<1>{} ); 41 | th(); 42 | } 43 | 44 | template 45 | void g2( Thrower th ) 46 | { 47 | auto load = leaf::on_error(info<3>{}, info<2>{} ); 48 | th(); 49 | } 50 | 51 | template 52 | void f1( Thrower th ) 53 | { 54 | return g1(th); 55 | } 56 | 57 | template 58 | void f2( Thrower th ) 59 | { 60 | return g2(th); 61 | } 62 | 63 | int main() 64 | { 65 | BOOST_TEST_EQ(1, 66 | leaf::try_catch( 67 | [] 68 | { 69 | f1( [] { leaf::throw_exception(); } ); 70 | return 0; 71 | }, 72 | []( leaf::error_info const & err, info<1> ) 73 | { 74 | BOOST_TEST_EQ(err.error().value(), 5); 75 | return 1; 76 | }, 77 | []( info<2> ) 78 | { 79 | return 2; 80 | }, 81 | []( info<1>, info<2> ) 82 | { 83 | return 3; 84 | } )); 85 | 86 | BOOST_TEST_EQ(2, 87 | leaf::try_catch( 88 | [] 89 | { 90 | f2( [] { leaf::throw_exception(); } ); 91 | return 0; 92 | }, 93 | []( info<1> ) 94 | { 95 | return 1; 96 | }, 97 | []( leaf::error_info const & err, info<2>, info<3> ) 98 | { 99 | BOOST_TEST_EQ(err.error().value(), 9); 100 | return 2; 101 | }, 102 | []( info<1>, info<2> ) 103 | { 104 | return 3; 105 | } )); 106 | 107 | BOOST_TEST_EQ(1, 108 | leaf::try_catch( 109 | [] 110 | { 111 | f1( [] { throw std::exception(); } ); 112 | return 0; 113 | }, 114 | []( leaf::error_info const & err, info<1> ) 115 | { 116 | BOOST_TEST_EQ(err.error().value(), 13); 117 | return 1; 118 | }, 119 | []( info<2> ) 120 | { 121 | return 2; 122 | }, 123 | []( info<1>, info<2> ) 124 | { 125 | return 3; 126 | } ) ); 127 | 128 | BOOST_TEST_EQ(2, 129 | leaf::try_catch( 130 | [] 131 | { 132 | f2( [] { throw std::exception(); } ); 133 | return 0; 134 | }, 135 | []( info<1> ) 136 | { 137 | return 1; 138 | }, 139 | []( leaf::error_info const & err, info<2>, info<3> ) 140 | { 141 | BOOST_TEST_EQ(err.error().value(), 17); 142 | return 2; 143 | }, 144 | []( info<1>, info<2> ) 145 | { 146 | return 3; 147 | } )); 148 | 149 | return boost::report_errors(); 150 | } 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /test/on_error_preload_nested_error_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template 32 | struct info 33 | { 34 | int value; 35 | }; 36 | 37 | void f0() 38 | { 39 | auto load = leaf::on_error( info<0>{0} ); 40 | leaf::throw_exception(info<2>{2}); 41 | } 42 | 43 | void f1() 44 | { 45 | auto load = leaf::on_error( info<0>{-1}, info<1>{1}, info<2>{-1} ); 46 | f0(); 47 | } 48 | 49 | void f2() 50 | { 51 | try 52 | { 53 | f1(); 54 | } 55 | catch( leaf::error_id const & err ) 56 | { 57 | err.load( info<3>{3} ); 58 | throw; 59 | } 60 | } 61 | 62 | int main() 63 | { 64 | int r = leaf::try_catch( 65 | [] 66 | { 67 | f2(); 68 | return 0; 69 | }, 70 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 71 | { 72 | BOOST_TEST_EQ(i0.value, 0); 73 | BOOST_TEST_EQ(i1.value, 1); 74 | BOOST_TEST_EQ(i2.value, 2); 75 | BOOST_TEST_EQ(i3.value, 3); 76 | return 1; 77 | }, 78 | [] 79 | { 80 | return 2; 81 | } ); 82 | BOOST_TEST_EQ(r, 1); 83 | 84 | return boost::report_errors(); 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /test/on_error_preload_nested_error_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | }; 22 | 23 | leaf::error_id f0() 24 | { 25 | auto load = leaf::on_error(info<0>{}); 26 | return leaf::new_error( info<2>{2} ); 27 | } 28 | 29 | leaf::error_id f1() 30 | { 31 | auto load = leaf::on_error( info<0>{-1}, info<1>{1}, info<2>{-1} ); 32 | return f0(); 33 | } 34 | 35 | leaf::error_id f2() 36 | { 37 | return f1().load( info<3>{3} ); 38 | } 39 | 40 | int main() 41 | { 42 | int r = leaf::try_handle_all( 43 | []() -> leaf::result 44 | { 45 | return f2(); 46 | }, 47 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 48 | { 49 | BOOST_TEST_EQ(i0.value, 0); 50 | BOOST_TEST_EQ(i1.value, 1); 51 | BOOST_TEST_EQ(i2.value, 2); 52 | BOOST_TEST_EQ(i3.value, 3); 53 | return 1; 54 | }, 55 | [] 56 | { 57 | return 2; 58 | } ); 59 | BOOST_TEST_EQ(r, 1); 60 | 61 | return boost::report_errors(); 62 | } 63 | -------------------------------------------------------------------------------- /test/on_error_preload_nested_new_error_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | template 32 | struct info 33 | { 34 | int value; 35 | }; 36 | 37 | void f0() 38 | { 39 | auto load = leaf::on_error( info<0>{-1} ); 40 | leaf::throw_exception(info<1>{-1}); 41 | } 42 | 43 | void f1() 44 | { 45 | auto load = leaf::on_error( info<0>{}, info<1>{1}, info<2>{2} ); 46 | try { f0(); } catch(...) { } 47 | leaf::throw_exception(); 48 | } 49 | 50 | leaf::error_id f2() 51 | { 52 | try 53 | { 54 | f1(); 55 | BOOST_TEST(false); 56 | } 57 | catch( leaf::error_id const & err ) 58 | { 59 | err.load( info<3>{3} ); 60 | throw; 61 | } 62 | catch(...) 63 | { 64 | BOOST_TEST(false); 65 | } 66 | return leaf::new_error(); 67 | } 68 | 69 | int main() 70 | { 71 | int r = leaf::try_catch( 72 | [] 73 | { 74 | f2(); 75 | return 0; 76 | }, 77 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 78 | { 79 | BOOST_TEST_EQ(i0.value, 0); 80 | BOOST_TEST_EQ(i1.value, 1); 81 | BOOST_TEST_EQ(i2.value, 2); 82 | BOOST_TEST_EQ(i3.value, 3); 83 | return 1; 84 | }, 85 | [] 86 | { 87 | return 2; 88 | } ); 89 | BOOST_TEST_EQ(r, 1); 90 | 91 | return boost::report_errors(); 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /test/on_error_preload_nested_new_error_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template 18 | struct info 19 | { 20 | int value; 21 | }; 22 | 23 | leaf::error_id f0() 24 | { 25 | auto load = leaf::on_error( info<0>{-1} ); 26 | return leaf::new_error( info<1>{-1} ); 27 | } 28 | 29 | leaf::error_id f1() 30 | { 31 | auto load = leaf::on_error(info<0>{}, info<1>{1}, info<2>{2} ); 32 | (void) f0(); 33 | return leaf::new_error(); 34 | } 35 | 36 | leaf::error_id f2() 37 | { 38 | return f1().load( info<3>{3} ); 39 | } 40 | 41 | int main() 42 | { 43 | int r = leaf::try_handle_all( 44 | []() -> leaf::result 45 | { 46 | return f2(); 47 | }, 48 | []( info<0> i0, info<1> i1, info<2> i2, info<3> i3 ) 49 | { 50 | BOOST_TEST_EQ(i0.value, 0); 51 | BOOST_TEST_EQ(i1.value, 1); 52 | BOOST_TEST_EQ(i2.value, 2); 53 | BOOST_TEST_EQ(i3.value, 3); 54 | return 1; 55 | }, 56 | [] 57 | { 58 | return 2; 59 | } ); 60 | BOOST_TEST_EQ(r, 1); 61 | 62 | return boost::report_errors(); 63 | } 64 | -------------------------------------------------------------------------------- /test/on_error_preload_nested_success_exception_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | #endif 25 | 26 | #include "lightweight_test.hpp" 27 | 28 | namespace leaf = boost::leaf; 29 | 30 | struct info { int value; }; 31 | 32 | void g1() 33 | { 34 | auto load = leaf::on_error( info{1} ); 35 | } 36 | 37 | void g2() 38 | { 39 | throw std::exception(); 40 | } 41 | 42 | void f() 43 | { 44 | auto load = leaf::on_error( info{2} ); 45 | g1(); 46 | g2(); 47 | } 48 | 49 | int main() 50 | { 51 | int r = leaf::try_catch( 52 | [] 53 | { 54 | f(); 55 | return 0; 56 | }, 57 | []( info x ) 58 | { 59 | BOOST_TEST_EQ(x.value, 2); 60 | return 1; 61 | }, 62 | [] 63 | { 64 | return 2; 65 | } ); 66 | BOOST_TEST_EQ(r, 1); 67 | 68 | return boost::report_errors(); 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /test/on_error_preload_nested_success_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | struct info { int value; }; 18 | 19 | leaf::result g1() 20 | { 21 | auto load = leaf::on_error( info{1} ); 22 | return { }; 23 | } 24 | 25 | leaf::result g2() 26 | { 27 | return leaf::new_error(); 28 | } 29 | 30 | leaf::result f() 31 | { 32 | auto load = leaf::on_error( info{2} ); 33 | BOOST_LEAF_CHECK(g1()); 34 | return g2(); 35 | } 36 | 37 | int main() 38 | { 39 | int r = leaf::try_handle_all( 40 | []() -> leaf::result 41 | { 42 | BOOST_LEAF_CHECK(f()); 43 | return 1; 44 | }, 45 | []( info x ) 46 | { 47 | BOOST_TEST_EQ(x.value, 2); 48 | return 2; 49 | }, 50 | [] 51 | { 52 | return 3; 53 | } ); 54 | BOOST_TEST_EQ(r, 2); 55 | 56 | return boost::report_errors(); 57 | } 58 | -------------------------------------------------------------------------------- /test/parse_name_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | #endif 10 | 11 | #include 12 | #include 13 | 14 | namespace leaf = boost::leaf; 15 | 16 | #include "lightweight_test.hpp" 17 | 18 | namespace leaf_test 19 | { 20 | class class_ { }; 21 | struct struct_ { }; 22 | enum enum_ { }; 23 | template class class_template1 { }; 24 | template struct struct_template1 { }; 25 | template class class_template2 { }; 26 | template struct struct_template2 { }; 27 | } 28 | 29 | namespace boost { namespace leaf { 30 | struct in_namespace_boost_leaf { }; 31 | } } 32 | 33 | class class_ { }; 34 | struct struct_ { }; 35 | enum enum_ { }; 36 | template class class_template1 { }; 37 | template struct struct_template1 { }; 38 | template class class_template2 { }; 39 | template struct struct_template2 { }; 40 | 41 | bool test(leaf::parsed const & pn, char const * correct) 42 | { 43 | return 44 | std::strlen(correct) == pn.len && 45 | std::memcmp(correct, pn.name, pn.len) == 0; 46 | } 47 | 48 | int main() 49 | { 50 | using leaf::parse; 51 | 52 | BOOST_TEST(test(parse(), "boost::leaf::in_namespace_boost_leaf")); 53 | 54 | BOOST_TEST(test(parse(), "int")); 55 | 56 | BOOST_TEST(test(parse(), "leaf_test::class_")); 57 | BOOST_TEST(test(parse(), "leaf_test::struct_")); 58 | BOOST_TEST(test(parse(), "leaf_test::enum_")); 59 | BOOST_TEST(test(parse>(), "leaf_test::class_template1<42>")); 60 | BOOST_TEST(test(parse>(), "leaf_test::struct_template1<42>")); 61 | BOOST_TEST(test(parse>(), "leaf_test::class_template2")); 62 | BOOST_TEST(test(parse>(), "leaf_test::struct_template2")); 63 | 64 | BOOST_TEST(test(parse(), "class_")); 65 | BOOST_TEST(test(parse(), "struct_")); 66 | BOOST_TEST(test(parse(), "enum_")); 67 | BOOST_TEST(test(parse>(), "class_template1<42>")); 68 | BOOST_TEST(test(parse>(), "struct_template1<42>")); 69 | BOOST_TEST(test(parse>(), "class_template2")); 70 | BOOST_TEST(test(parse>(), "struct_template2")); 71 | 72 | return boost::report_errors(); 73 | } 74 | -------------------------------------------------------------------------------- /test/print_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #if !BOOST_LEAF_CFG_DIAGNOSTICS || !BOOST_LEAF_CFG_STD_STRING 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | #endif 24 | 25 | #include 26 | #include 27 | 28 | #include "lightweight_test.hpp" 29 | 30 | namespace leaf = boost::leaf; 31 | 32 | struct c0 33 | { 34 | friend std::ostream & operator<<( std::ostream & os, c0 const & ) 35 | { 36 | return os << "info"; 37 | } 38 | }; 39 | 40 | struct c1 41 | { 42 | int value; 43 | 44 | friend std::ostream & operator<<( std::ostream & os, c1 const & x ) 45 | { 46 | return os << "value " << x.value; 47 | } 48 | }; 49 | 50 | struct c2 51 | { 52 | int value; 53 | }; 54 | 55 | std::ostream & operator<<( std::ostream & os, c2 const & x ) 56 | { 57 | return os << "value " << x.value; 58 | } 59 | 60 | struct c3 61 | { 62 | int value; 63 | }; 64 | 65 | struct c4 66 | { 67 | struct unprintable { }; 68 | unprintable value;; 69 | }; 70 | 71 | template 72 | std::string print(T const & x, char const * prefix, char const * delimiter) 73 | { 74 | using namespace leaf::detail; 75 | std::ostringstream s; 76 | diagnostic::print(s, prefix, delimiter, x); 77 | diagnostic::print(s, prefix, delimiter, x); 78 | std::string q = s.str(); 79 | std::cout << "[LINE " << Line << "] " << q << '\n'; 80 | return q; 81 | } 82 | 83 | struct my_exception: std::exception 84 | { 85 | char const * what() const noexcept override { return "my_exception what"; } 86 | }; 87 | 88 | int main() 89 | { 90 | { 91 | std::string out = print<__LINE__>(c0{}, "Title " , ", "); 92 | BOOST_TEST_EQ(out, "Title c0: info, c0: info"); 93 | } 94 | { 95 | std::string out = print<__LINE__>(c1{42}, "Title ", ", "); 96 | BOOST_TEST_EQ(out, "Title c1: value 42, c1: value 42"); 97 | } 98 | { 99 | std::string out = print<__LINE__>(c2{42}, "Title ", ", "); 100 | BOOST_TEST_EQ(out, "Title c2: value 42, c2: value 42"); 101 | } 102 | { 103 | std::string out = print<__LINE__>(c3{42}, "Title ", ", "); 104 | BOOST_TEST_EQ(out, "Title c3: 42, c3: 42"); 105 | } 106 | { 107 | std::string out = print<__LINE__>(c4{}, "Title ", ", "); 108 | BOOST_TEST_EQ(out, "Title c4, c4"); 109 | } 110 | { 111 | std::string out = print<__LINE__>(my_exception{}, "Title ", ", "); 112 | BOOST_TEST_EQ(out, "Title my_exception: \"my_exception what\", my_exception: \"my_exception what\""); 113 | } 114 | return boost::report_errors(); 115 | } 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /test/result_bad_result_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | #ifdef BOOST_LEAF_BOOST_AVAILABLE 29 | # include 30 | #else 31 | # define BOOST_WORKAROUND(a,b) 0 32 | #endif 33 | 34 | namespace leaf = boost::leaf; 35 | 36 | struct e_test { int value; }; 37 | 38 | int check( leaf::bad_result const &, leaf::match_value ) 39 | { 40 | return 1; 41 | } 42 | 43 | struct res { int val; }; 44 | 45 | int main() 46 | { 47 | { 48 | int r = leaf::try_catch( 49 | [] 50 | { 51 | leaf::result r1 = leaf::new_error(e_test{42}); 52 | (void) r1.value(); 53 | return 0; 54 | }, 55 | check ); 56 | BOOST_TEST_EQ(r, 1); 57 | } 58 | #if !BOOST_WORKAROUND( BOOST_GCC, < 50000 ) 59 | { 60 | int r = leaf::try_catch( 61 | [] 62 | { 63 | leaf::result const r1 = leaf::new_error(e_test{42}); 64 | (void) r1.value(); 65 | return 0; 66 | }, 67 | check ); 68 | BOOST_TEST_EQ(r, 1); 69 | } 70 | #endif 71 | { 72 | leaf::result r1 = leaf::new_error(e_test{42}); 73 | BOOST_TEST(!r1.operator->()); 74 | } 75 | #if !BOOST_WORKAROUND( BOOST_GCC, < 50000 ) 76 | { 77 | leaf::result const r1 = leaf::new_error(e_test{42}); 78 | BOOST_TEST(!r1.operator->()); 79 | } 80 | #endif 81 | { 82 | int r = leaf::try_catch( 83 | [] 84 | { 85 | leaf::result r1 = leaf::new_error(e_test{42}); 86 | (void) r1.value(); 87 | return 0; 88 | }, 89 | check ); 90 | BOOST_TEST_EQ(r, 1); 91 | } 92 | #if !BOOST_WORKAROUND( BOOST_GCC, < 50000 ) 93 | { 94 | int r = leaf::try_catch( 95 | [] 96 | { 97 | leaf::result const r1 = leaf::new_error(e_test{42}); 98 | (void) r1.value(); 99 | return 0; 100 | }, 101 | check ); 102 | BOOST_TEST_EQ(r, 1); 103 | } 104 | #endif 105 | 106 | return boost::report_errors(); 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /test/result_implicit_conversion_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | #endif 10 | 11 | #include "lightweight_test.hpp" 12 | 13 | namespace leaf = boost::leaf; 14 | 15 | struct A 16 | { 17 | int x; 18 | A() noexcept: 19 | x(0) 20 | { 21 | } 22 | 23 | A( int x_ ) noexcept: 24 | x(x_) 25 | { 26 | } 27 | }; 28 | 29 | leaf::result f() 30 | { 31 | return 42; 32 | } 33 | 34 | leaf::result g() 35 | { 36 | return f(); 37 | } 38 | 39 | int main() 40 | { 41 | BOOST_TEST_EQ(g().value().x, 42); 42 | { 43 | leaf::result r1(42); 44 | leaf::result r2(std::move(r1)); 45 | BOOST_TEST_EQ(r2.value().x, 42); 46 | } 47 | { 48 | leaf::result r1(42); 49 | leaf::result r2; 50 | r2 = std::move(r1); 51 | BOOST_TEST_EQ(r2.value().x, 42); 52 | } 53 | return boost::report_errors(); 54 | } 55 | -------------------------------------------------------------------------------- /test/result_load_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | # include 11 | #endif 12 | 13 | #include "lightweight_test.hpp" 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | template struct info { int value; }; 18 | 19 | template 20 | leaf::result test() 21 | { 22 | leaf::result r1 = leaf::new_error(info<42>{40}); 23 | leaf::result r2 = r1.load(info<1>{}); 24 | leaf::result r3 = r2.load(info<2>{2}, []{ return info<3>{3}; }); 25 | leaf::result r4 = r3.load([](info<42> & x){ ++x.value; }); 26 | leaf::result r5 = r4.load([](info<42> & x){ ++x.value; }, [](info<1> & x){ ++x.value; }); 27 | return r5; 28 | } 29 | 30 | int main() 31 | { 32 | { 33 | int r = leaf::try_handle_all( 34 | [] 35 | { 36 | return test(); 37 | }, 38 | []( leaf::match_value, 42>, leaf::match_value, 1>, leaf::match_value, 2>, leaf::match_value, 3> ) 39 | { 40 | return 1; 41 | }, 42 | [] 43 | { 44 | return 2; 45 | } ); 46 | BOOST_TEST_EQ(r, 1); 47 | } 48 | { 49 | int r = leaf::try_handle_all( 50 | []() -> leaf::result 51 | { 52 | BOOST_LEAF_CHECK(test()); 53 | return 0; 54 | }, 55 | []( leaf::match_value, 42>, leaf::match_value, 1>, leaf::match_value, 2>, leaf::match_value, 3> ) 56 | { 57 | return 1; 58 | }, 59 | [] 60 | { 61 | return 2; 62 | } ); 63 | BOOST_TEST_EQ(r, 1); 64 | } 65 | return boost::report_errors(); 66 | } 67 | -------------------------------------------------------------------------------- /test/result_print_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | #endif 11 | 12 | #if BOOST_LEAF_CFG_STD_STRING 13 | # include 14 | # include 15 | #endif 16 | 17 | #include "lightweight_test.hpp" 18 | 19 | namespace leaf = boost::leaf; 20 | 21 | struct non_printable_value 22 | { 23 | }; 24 | 25 | struct e_err 26 | { 27 | template 28 | friend std::ostream & operator<<( std::basic_ostream & os, e_err const & ) 29 | { 30 | return os << "e_err"; 31 | } 32 | }; 33 | 34 | int main() 35 | { 36 | { 37 | leaf::result r = 42; 38 | BOOST_TEST(r); 39 | #if BOOST_LEAF_CFG_STD_STRING 40 | std::ostringstream ss; 41 | ss << r; 42 | std::string s = ss.str(); 43 | std::cout << s << std::endl; 44 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 45 | BOOST_TEST_EQ(s, "42"); 46 | #endif 47 | } 48 | 49 | { 50 | leaf::result r; 51 | BOOST_TEST(r); 52 | #if BOOST_LEAF_CFG_STD_STRING 53 | std::ostringstream ss; 54 | ss << r; 55 | std::string s = ss.str(); 56 | std::cout << s << std::endl; 57 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 58 | BOOST_TEST_EQ(s, "{not printable}"); 59 | #endif 60 | } 61 | 62 | { 63 | leaf::result r; 64 | BOOST_TEST(r); 65 | #if BOOST_LEAF_CFG_STD_STRING 66 | std::ostringstream ss; 67 | ss << r; 68 | std::string s = ss.str(); 69 | std::cout << s << std::endl; 70 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 71 | BOOST_TEST_EQ(s, "No error"); 72 | #endif 73 | } 74 | 75 | { 76 | leaf::result r = leaf::new_error(e_err{ }); 77 | BOOST_TEST(!r); 78 | #if BOOST_LEAF_CFG_STD_STRING 79 | std::ostringstream ss; 80 | ss << r; 81 | std::string s = ss.str(); 82 | std::cout << s << std::endl; 83 | leaf::error_id err = r.error(); 84 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 85 | BOOST_TEST_EQ(s, "Error serial #" + std::to_string(err.value()/4)); 86 | #endif 87 | } 88 | 89 | #if BOOST_LEAF_CFG_CAPTURE 90 | { 91 | leaf::result r = leaf::try_capture_all( 92 | []() -> leaf::result 93 | { 94 | return leaf::new_error(e_err{ }); 95 | } ); 96 | #if BOOST_LEAF_CFG_STD_STRING 97 | std::ostringstream ss; 98 | ss << r; 99 | std::string s = ss.str(); 100 | std::cout << s << std::endl; 101 | leaf::error_id err = r.error(); 102 | BOOST_TEST_NE(s.find("Error serial #" + std::to_string(err.value()/4)), s.npos); 103 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 104 | { 105 | BOOST_TEST_NE(s.find("Captured:"), s.npos); 106 | BOOST_TEST_NE(s.find("e_err: e_err"), s.npos); 107 | } 108 | #endif 109 | } 110 | #endif 111 | 112 | return boost::report_errors(); 113 | } 114 | -------------------------------------------------------------------------------- /test/tls_array_alloc_test1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifndef BOOST_LEAF_NO_EXCEPTIONS 6 | # define BOOST_LEAF_NO_EXCEPTIONS 7 | #endif 8 | 9 | #ifdef BOOST_LEAF_CFG_STD_SYSTEM_ERROR 10 | # undef BOOST_LEAF_CFG_STD_SYSTEM_ERROR 11 | #endif 12 | #define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 0 13 | 14 | #ifdef BOOST_LEAF_CFG_DIAGNOSTICS 15 | # undef BOOST_LEAF_CFG_DIAGNOSTICS 16 | #endif 17 | #define BOOST_LEAF_CFG_DIAGNOSTICS 0 18 | 19 | #ifdef BOOST_LEAF_CFG_CAPTURE 20 | # undef BOOST_LEAF_CFG_CAPTURE 21 | #endif 22 | #define BOOST_LEAF_CFG_CAPTURE 0 23 | 24 | #define BOOST_LEAF_USE_TLS_ARRAY 25 | #define BOOST_LEAF_CFG_TLS_ARRAY_SIZE 64 26 | #define BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX 10 27 | 28 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 29 | # include "leaf.hpp" 30 | #else 31 | # include 32 | # include 33 | #endif 34 | 35 | #include 36 | #include 37 | #include 38 | #include "lightweight_test.hpp" 39 | 40 | namespace leaf = boost::leaf; 41 | 42 | static void * tls_storage[BOOST_LEAF_CFG_TLS_ARRAY_SIZE]; 43 | static int min_tls_index = std::numeric_limits::max(); 44 | static int max_tls_index = std::numeric_limits::min(); 45 | 46 | namespace boost { namespace leaf { 47 | 48 | namespace tls 49 | { 50 | void * read_void_ptr( int tls_index ) noexcept 51 | { 52 | BOOST_TEST_GE(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 53 | BOOST_TEST_LT(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 54 | min_tls_index = std::min(min_tls_index, tls_index); 55 | max_tls_index = std::max(max_tls_index, tls_index); 56 | return tls_storage[tls_index]; 57 | } 58 | 59 | void write_void_ptr( int tls_index, void * p ) noexcept 60 | { 61 | BOOST_TEST_GE(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 62 | BOOST_TEST_LT(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 63 | min_tls_index = std::min(min_tls_index, tls_index); 64 | max_tls_index = std::max(max_tls_index, tls_index); 65 | tls_storage[tls_index] = p; 66 | } 67 | } 68 | 69 | } } 70 | 71 | template 72 | struct my_error_info 73 | { 74 | }; 75 | 76 | int main() 77 | { 78 | std::vector used_ptrs; 79 | int r = leaf::try_handle_all( 80 | [&]() -> leaf::result 81 | { 82 | return leaf::new_error( my_error_info<1>{}, my_error_info<2>{} ); 83 | }, 84 | [] 85 | { 86 | return 1; 87 | } ); 88 | BOOST_TEST_EQ(r, 1); 89 | BOOST_TEST_EQ(min_tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 90 | BOOST_TEST_EQ(max_tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 91 | return boost::report_errors(); 92 | } 93 | -------------------------------------------------------------------------------- /test/tls_array_alloc_test2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifndef BOOST_LEAF_NO_EXCEPTIONS 6 | # define BOOST_LEAF_NO_EXCEPTIONS 7 | #endif 8 | 9 | #ifdef BOOST_LEAF_CFG_STD_SYSTEM_ERROR 10 | # undef BOOST_LEAF_CFG_STD_SYSTEM_ERROR 11 | #endif 12 | #define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 0 13 | 14 | #ifdef BOOST_LEAF_CFG_DIAGNOSTICS 15 | # undef BOOST_LEAF_CFG_DIAGNOSTICS 16 | #endif 17 | #define BOOST_LEAF_CFG_DIAGNOSTICS 0 18 | 19 | #ifdef BOOST_LEAF_CFG_CAPTURE 20 | # undef BOOST_LEAF_CFG_CAPTURE 21 | #endif 22 | #define BOOST_LEAF_CFG_CAPTURE 0 23 | 24 | #define BOOST_LEAF_USE_TLS_ARRAY 25 | #define BOOST_LEAF_CFG_TLS_ARRAY_SIZE 64 26 | #define BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX 10 27 | 28 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 29 | # include "leaf.hpp" 30 | #else 31 | # include 32 | # include 33 | #endif 34 | 35 | #include 36 | #include 37 | #include 38 | #include "lightweight_test.hpp" 39 | 40 | namespace leaf = boost::leaf; 41 | 42 | static void * tls_storage[BOOST_LEAF_CFG_TLS_ARRAY_SIZE]; 43 | static int min_tls_index = std::numeric_limits::max(); 44 | static int max_tls_index = std::numeric_limits::min(); 45 | 46 | namespace boost { namespace leaf { 47 | 48 | namespace tls 49 | { 50 | void * read_void_ptr( int tls_index ) noexcept 51 | { 52 | BOOST_TEST_GE(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 53 | BOOST_TEST_LT(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 54 | min_tls_index = std::min(min_tls_index, tls_index); 55 | max_tls_index = std::max(max_tls_index, tls_index); 56 | return tls_storage[tls_index]; 57 | } 58 | 59 | void write_void_ptr( int tls_index, void * p ) noexcept 60 | { 61 | BOOST_TEST_GE(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 62 | BOOST_TEST_LT(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 63 | min_tls_index = std::min(min_tls_index, tls_index); 64 | max_tls_index = std::max(max_tls_index, tls_index); 65 | tls_storage[tls_index] = p; 66 | } 67 | } 68 | 69 | } } 70 | 71 | template 72 | struct my_error_info 73 | { 74 | }; 75 | 76 | int main() 77 | { 78 | std::vector used_ptrs; 79 | int r = leaf::try_handle_all( 80 | [&]() -> leaf::result 81 | { 82 | return leaf::new_error( my_error_info<1>{}, my_error_info<2>{} ); 83 | }, 84 | []( my_error_info<2> ) 85 | { 86 | return 1; 87 | }, 88 | [] 89 | { 90 | return 2; 91 | } ); 92 | BOOST_TEST_EQ(r, 1); 93 | BOOST_TEST_EQ(min_tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 94 | BOOST_TEST_EQ(max_tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)+1); 95 | return boost::report_errors(); 96 | } 97 | -------------------------------------------------------------------------------- /test/tls_array_alloc_test3.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifndef BOOST_LEAF_NO_EXCEPTIONS 6 | # define BOOST_LEAF_NO_EXCEPTIONS 7 | #endif 8 | 9 | #ifdef BOOST_LEAF_CFG_STD_SYSTEM_ERROR 10 | # undef BOOST_LEAF_CFG_STD_SYSTEM_ERROR 11 | #endif 12 | #define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 0 13 | 14 | #ifdef BOOST_LEAF_CFG_DIAGNOSTICS 15 | # undef BOOST_LEAF_CFG_DIAGNOSTICS 16 | #endif 17 | #define BOOST_LEAF_CFG_DIAGNOSTICS 0 18 | 19 | #ifdef BOOST_LEAF_CFG_CAPTURE 20 | # undef BOOST_LEAF_CFG_CAPTURE 21 | #endif 22 | #define BOOST_LEAF_CFG_CAPTURE 0 23 | 24 | #define BOOST_LEAF_USE_TLS_ARRAY 25 | #define BOOST_LEAF_CFG_TLS_ARRAY_SIZE 64 26 | #define BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX 10 27 | 28 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 29 | # include "leaf.hpp" 30 | #else 31 | # include 32 | # include 33 | #endif 34 | 35 | #include 36 | #include 37 | #include 38 | #include "lightweight_test.hpp" 39 | 40 | namespace leaf = boost::leaf; 41 | 42 | static void * tls_storage[BOOST_LEAF_CFG_TLS_ARRAY_SIZE]; 43 | static int min_tls_index = std::numeric_limits::max(); 44 | static int max_tls_index = std::numeric_limits::min(); 45 | 46 | namespace boost { namespace leaf { 47 | 48 | namespace tls 49 | { 50 | void * read_void_ptr( int tls_index ) noexcept 51 | { 52 | BOOST_TEST_GE(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 53 | BOOST_TEST_LT(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 54 | min_tls_index = std::min(min_tls_index, tls_index); 55 | max_tls_index = std::max(max_tls_index, tls_index); 56 | return tls_storage[tls_index]; 57 | } 58 | 59 | void write_void_ptr( int tls_index, void * p ) noexcept 60 | { 61 | BOOST_TEST_GE(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 62 | BOOST_TEST_LT(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 63 | min_tls_index = std::min(min_tls_index, tls_index); 64 | max_tls_index = std::max(max_tls_index, tls_index); 65 | tls_storage[tls_index] = p; 66 | } 67 | } 68 | 69 | } } 70 | 71 | template 72 | struct my_error_info 73 | { 74 | }; 75 | 76 | int main() 77 | { 78 | std::vector used_ptrs; 79 | int r = leaf::try_handle_all( 80 | [&]() -> leaf::result 81 | { 82 | return leaf::new_error( my_error_info<1>{}, my_error_info<2>{}, my_error_info<3>{}, my_error_info<4>{} ); 83 | }, 84 | []( my_error_info<2> ) 85 | { 86 | return 1; 87 | }, 88 | []( my_error_info<4> ) 89 | { 90 | return 2; 91 | }, 92 | [] 93 | { 94 | return 3; 95 | } ); 96 | BOOST_TEST_EQ(r, 1); 97 | BOOST_TEST_EQ(min_tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 98 | BOOST_TEST_EQ(max_tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)+2); 99 | return boost::report_errors(); 100 | } 101 | -------------------------------------------------------------------------------- /test/tls_array_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #define BOOST_LEAF_NO_EXCEPTIONS 6 | #define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 0 7 | #define BOOST_LEAF_CFG_STD_STRING 0 8 | #ifdef BOOST_LEAF_CFG_DIAGNOSTICS 9 | # undef BOOST_LEAF_CFG_DIAGNOSTICS 10 | #endif 11 | #define BOOST_LEAF_CFG_DIAGNOSTICS 0 12 | #define BOOST_LEAF_USE_TLS_ARRAY 13 | #define BOOST_LEAF_CFG_TLS_ARRAY_SIZE 64 14 | #define BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX 10 15 | 16 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 17 | # include "leaf.hpp" 18 | #else 19 | # include 20 | # include 21 | #endif 22 | 23 | #include 24 | #include 25 | #include 26 | #include "lightweight_test.hpp" 27 | 28 | namespace leaf = boost::leaf; 29 | 30 | static void * tls_storage[BOOST_LEAF_CFG_TLS_ARRAY_SIZE]; 31 | static int min_tls_index = std::numeric_limits::max(); 32 | static int max_tls_index = std::numeric_limits::min(); 33 | 34 | namespace boost { namespace leaf { 35 | 36 | namespace tls 37 | { 38 | void * read_void_ptr( int tls_index ) noexcept 39 | { 40 | BOOST_TEST_GE(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 41 | BOOST_TEST_LT(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 42 | min_tls_index = std::min(min_tls_index, tls_index); 43 | max_tls_index = std::max(max_tls_index, tls_index); 44 | return tls_storage[tls_index]; 45 | } 46 | 47 | void write_void_ptr( int tls_index, void * p ) noexcept 48 | { 49 | BOOST_TEST_GE(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 50 | BOOST_TEST_LT(tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 51 | min_tls_index = std::min(min_tls_index, tls_index); 52 | max_tls_index = std::max(max_tls_index, tls_index); 53 | tls_storage[tls_index] = p; 54 | } 55 | } 56 | 57 | } } 58 | 59 | template 60 | struct my_error_info 61 | { 62 | }; 63 | 64 | // Mirroring boost::leaf::detail::optional, to verify correctness of TLS pointers 65 | template 66 | struct optional 67 | { 68 | int key_; 69 | union { T value_; }; 70 | }; 71 | int const offset = offsetof(optional>, value_); 72 | 73 | int main() 74 | { 75 | std::vector used_ptrs; 76 | int r = leaf::try_handle_all( 77 | [&]() -> leaf::result 78 | { 79 | BOOST_TEST_GE(min_tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); 80 | BOOST_TEST_GT(max_tls_index, min_tls_index); 81 | BOOST_TEST_LT(max_tls_index, (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); 82 | for( int i=min_tls_index; i<=max_tls_index; ++i ) 83 | used_ptrs.push_back((char const *)tls_storage[i] + offset); 84 | return leaf::new_error( my_error_info<1>{}, my_error_info<2>{} ); 85 | }, 86 | 87 | [&]( my_error_info<1> const & a, my_error_info<2> const & b ) 88 | { 89 | BOOST_TEST(std::find(used_ptrs.begin(), used_ptrs.end(), &a) != used_ptrs.end()); 90 | BOOST_TEST(std::find(used_ptrs.begin(), used_ptrs.end(), &b) != used_ptrs.end()); 91 | return 1; 92 | }, 93 | 94 | [] 95 | { 96 | return 2; 97 | } ); 98 | BOOST_TEST_EQ(r, 1); 99 | return boost::report_errors(); 100 | } 101 | -------------------------------------------------------------------------------- /test/to_variant_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #if __cplusplus < 201703L 6 | 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << "Unit test not applicable." << std::endl; 12 | return 0; 13 | } 14 | 15 | #else 16 | 17 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 18 | # include "leaf.hpp" 19 | #else 20 | # include 21 | #endif 22 | 23 | #include "_test_ec.hpp" 24 | #include "lightweight_test.hpp" 25 | 26 | namespace leaf = boost::leaf; 27 | 28 | enum class E1 { e11, e12, e13 }; 29 | enum class E2 { e21, e22, e23 }; 30 | enum class E3 { e31, e32, e33 }; 31 | 32 | int main() 33 | { 34 | #if !defined(__clang__) || __clang_major__ < 5 || __clang_major__ > 7 // See https://github.com/llvm/llvm-project/issues/32569 35 | { 36 | auto v = leaf::to_variant( 37 | []() -> leaf::result 38 | { 39 | return 42; 40 | } ); 41 | BOOST_TEST_EQ(v.index(), 0); 42 | BOOST_TEST_EQ(std::get<0>(v), 42); 43 | } 44 | 45 | { 46 | auto v = leaf::to_variant( 47 | []() -> leaf::result 48 | { 49 | return leaf::new_error(E1::e12, E3::e31); 50 | } ); 51 | BOOST_TEST(v.index() == 1); 52 | auto t = std::get<1>(v); 53 | 54 | BOOST_TEST(std::get<0>(t).has_value()); 55 | BOOST_TEST(!std::get<1>(t).has_value()); 56 | BOOST_TEST(std::get<2>(t).has_value()); 57 | 58 | BOOST_TEST(std::get<0>(t).value() == E1::e12); 59 | BOOST_TEST(std::get<2>(t).value() == E3::e31); 60 | } 61 | #endif 62 | 63 | return boost::report_errors(); 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /test/try_capture_all_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #if BOOST_LEAF_CFG_STD_STRING 8 | # include 9 | # include 10 | #endif 11 | 12 | #if !BOOST_LEAF_CFG_CAPTURE 13 | 14 | #include 15 | 16 | int main() 17 | { 18 | std::cout << "Unit test not applicable." << std::endl; 19 | return 0; 20 | } 21 | 22 | #else 23 | 24 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 25 | # include "leaf.hpp" 26 | #else 27 | # include 28 | # include 29 | #endif 30 | 31 | #include "lightweight_test.hpp" 32 | 33 | namespace leaf = boost::leaf; 34 | 35 | namespace 36 | { 37 | template 38 | struct err 39 | { 40 | static int count; 41 | static int move_count; 42 | 43 | err() 44 | { 45 | ++count; 46 | } 47 | 48 | err( err const & ) 49 | { 50 | ++count; 51 | } 52 | 53 | err( err && ) 54 | { 55 | ++count; 56 | ++move_count; 57 | } 58 | 59 | ~err() 60 | { 61 | --count; 62 | } 63 | }; 64 | template int err::count = 0; 65 | template int err::move_count = 0; 66 | } 67 | 68 | int main() 69 | { 70 | #ifndef BOOST_LEAF_NO_EXCEPTIONS 71 | { 72 | leaf::result r = leaf::try_capture_all([]() { throw std::runtime_error("x"); }); 73 | BOOST_TEST(!r); 74 | int r1 = leaf::try_handle_all( 75 | [&]() -> leaf::result 76 | { 77 | BOOST_LEAF_CHECK(r); 78 | return 0; 79 | }, 80 | [](std::runtime_error const &) 81 | { 82 | return 1; 83 | }, 84 | [] 85 | { 86 | return 2; 87 | } ); 88 | BOOST_TEST_EQ(r1, 1); 89 | } 90 | #endif 91 | { 92 | leaf::result r = leaf::try_capture_all( 93 | []() -> leaf::result 94 | { 95 | return leaf::new_error(err<1>{}, err<2>{}); 96 | }); 97 | BOOST_TEST_EQ(err<1>::count, 1); 98 | BOOST_TEST_EQ(err<2>::count, 1); 99 | BOOST_TEST(!r); 100 | int r1 = leaf::try_handle_all( 101 | [&]() -> leaf::result 102 | { 103 | BOOST_LEAF_CHECK(r); 104 | return 0; 105 | }, 106 | [](err<1>, err<2>) 107 | { 108 | return 1; 109 | }, 110 | [] 111 | { 112 | return 2; 113 | } ); 114 | BOOST_TEST_EQ(r1, 1); 115 | } 116 | BOOST_TEST_EQ(err<1>::count, 0); 117 | BOOST_TEST_EQ(err<2>::count, 0); 118 | 119 | { 120 | leaf::result r = leaf::try_capture_all( 121 | []() -> leaf::result 122 | { 123 | return leaf::new_error(err<1>{}, err<2>{}); 124 | }); 125 | BOOST_TEST(!r); 126 | BOOST_TEST_EQ(err<1>::count, 1); 127 | BOOST_TEST_EQ(err<2>::count, 1); 128 | int r1 = leaf::try_handle_all( 129 | [&]() -> leaf::result 130 | { 131 | BOOST_LEAF_CHECK(r); 132 | return 0; 133 | }, 134 | [](err<1>, err<2>) 135 | { 136 | return 1; 137 | }, 138 | [] 139 | { 140 | return 2; 141 | } ); 142 | BOOST_TEST_EQ(r1, 1); 143 | } 144 | BOOST_TEST_EQ(err<1>::count, 0); 145 | BOOST_TEST_EQ(err<2>::count, 0); 146 | 147 | return boost::report_errors(); 148 | } 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /test/try_catch_error_id_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | 7 | #ifdef BOOST_LEAF_NO_EXCEPTIONS 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | std::cout << "Unit test not applicable." << std::endl; 14 | return 0; 15 | } 16 | 17 | #else 18 | 19 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 20 | # include "leaf.hpp" 21 | #else 22 | # include 23 | # include 24 | # include 25 | #endif 26 | 27 | #include "lightweight_test.hpp" 28 | 29 | namespace leaf = boost::leaf; 30 | 31 | struct info { int value; }; 32 | 33 | struct my_error: std::exception { }; 34 | 35 | int main() 36 | { 37 | int r = leaf::try_catch( 38 | []() -> int 39 | { 40 | leaf::throw_exception( my_error(), info{42} ); 41 | }, 42 | []( my_error const &, leaf::catch_ id ) 43 | { 44 | BOOST_TEST(dynamic_cast(&id.matched) != 0 && dynamic_cast(&id.matched)->value() == 5); 45 | return 1; 46 | }, 47 | [] 48 | { 49 | return 2; 50 | } ); 51 | BOOST_TEST_EQ(r, 1); 52 | return boost::report_errors(); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /test/visibility_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 6 | # include "leaf.hpp" 7 | #else 8 | # include 9 | # include 10 | #endif 11 | 12 | #include "visibility_test_lib.hpp" 13 | 14 | #if BOOST_LEAF_CFG_STD_STRING 15 | # include 16 | # include 17 | #endif 18 | 19 | #include "lightweight_test.hpp" 20 | 21 | namespace leaf = boost::leaf; 22 | 23 | leaf::result hidden_result(); 24 | void hidden_throw(); 25 | 26 | int main() 27 | { 28 | { 29 | int r = leaf::try_handle_all( 30 | []() -> leaf::result 31 | { 32 | BOOST_LEAF_CHECK(hidden_result()); 33 | return 0; 34 | }, 35 | []( my_info<1> x1, my_info<2> x2, leaf::diagnostic_details const & info, leaf::diagnostic_details const & vinfo ) 36 | { 37 | BOOST_TEST_EQ(x1.value, 1); 38 | BOOST_TEST_EQ(x2.value, 2); 39 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 40 | { 41 | #if BOOST_LEAF_CFG_STD_STRING 42 | std::ostringstream ss; ss << vinfo; 43 | std::string s = ss.str(); 44 | std::cout << s << std::endl; 45 | if( BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_CAPTURE ) 46 | BOOST_TEST_NE(s.find("Test my_info<3>::value = 3"), std::string::npos); 47 | #endif 48 | } 49 | return 1; 50 | }, 51 | [](leaf::diagnostic_details const & vinfo) 52 | { 53 | std::cout << "Test is failing\n" << vinfo; 54 | return 2; 55 | } ); 56 | BOOST_TEST_EQ(r, 1); 57 | } 58 | 59 | #ifndef BOOST_LEAF_NO_EXCEPTIONS 60 | { 61 | int r = leaf::try_catch( 62 | [] 63 | { 64 | hidden_throw(); 65 | return 0; 66 | }, 67 | []( my_info<1> x1, my_info<2> x2, leaf::diagnostic_details const & info, leaf::diagnostic_details const & vinfo ) 68 | { 69 | BOOST_TEST_EQ(x1.value, 1); 70 | BOOST_TEST_EQ(x2.value, 2); 71 | if( BOOST_LEAF_CFG_DIAGNOSTICS ) 72 | { 73 | #if BOOST_LEAF_CFG_STD_STRING 74 | std::ostringstream ss; ss << vinfo; 75 | std::string s = ss.str(); 76 | std::cout << s << std::endl; 77 | if( BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_CAPTURE ) 78 | BOOST_TEST_NE(s.find("Test my_info<3>::value = 3"), std::string::npos); 79 | #endif 80 | } 81 | return 1; 82 | }, 83 | [](leaf::diagnostic_details const & vinfo) 84 | { 85 | std::cout << "Test is failing\n" << vinfo; 86 | return 2; 87 | } ); 88 | BOOST_TEST_EQ(r, 1); 89 | } 90 | { 91 | try 92 | { 93 | hidden_throw(); 94 | BOOST_ERROR("hidden_throw() failed to throw"); 95 | } 96 | catch( leaf::error_id const & ) 97 | { 98 | } 99 | catch(...) 100 | { 101 | BOOST_ERROR("Failed to catch leaf::error_id"); 102 | } 103 | } 104 | #endif 105 | 106 | return boost::report_errors(); 107 | } 108 | -------------------------------------------------------------------------------- /test/visibility_test_lib.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include "visibility_test_lib.hpp" 6 | 7 | #ifdef BOOST_LEAF_TEST_SINGLE_HEADER 8 | # include "leaf.hpp" 9 | #else 10 | # include 11 | # include 12 | # include 13 | #endif 14 | 15 | namespace leaf = boost::leaf; 16 | 17 | leaf::result BOOST_SYMBOL_VISIBLE hidden_result() 18 | { 19 | auto load = leaf::on_error( my_info<1>{1}, my_info<3>{3} ); 20 | return leaf::new_error( my_info<2>{2} ); 21 | } 22 | 23 | #ifndef BOOST_NO_EXCEPTIONS 24 | 25 | void BOOST_SYMBOL_VISIBLE hidden_throw() 26 | { 27 | auto load = leaf::on_error( my_info<1>{1}, my_info<3>{3} ); 28 | leaf::throw_exception( my_info<2>{2} ); 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /test/visibility_test_lib.hpp: -------------------------------------------------------------------------------- 1 | #ifndef VISIBILITY_TEST_LIB_HPP_INCLUDED 2 | #define VISIBILITY_TEST_LIB_HPP_INCLUDED 3 | 4 | // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include 9 | #include 10 | 11 | template 12 | struct BOOST_SYMBOL_VISIBLE my_info 13 | { 14 | int value; 15 | 16 | template 17 | friend std::ostream & operator<<( std::basic_ostream & os, my_info const & x ) 18 | { 19 | return os << "Test my_info<" << Tag << ">::value = " << x.value; 20 | } 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /wasm.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc. 2 | 3 | # Distributed under the Boost Software License, Version 1.0. (See accompanying 4 | # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | # Crossfile for Meson / emscripten 7 | 8 | [binaries] 9 | c = 'emcc' 10 | cpp = 'em++' 11 | ar = 'emar' 12 | # exe_wrapper = ['node', '--experimental-wasm-threads', '--experimental-wasm-bulk-memory', '--max-old-space-size=4096'] 13 | 14 | [host_machine] 15 | system = 'emscripten' 16 | cpu_family = 'wasm32' 17 | cpu = 'wasm32' 18 | endian = 'little' 19 | --------------------------------------------------------------------------------