diff --git a/include/boost/leaf/all.hpp b/include/boost/leaf/all.hpp index 50cad66..0d10b98 100644 --- a/include/boost/leaf/all.hpp +++ b/include/boost/leaf/all.hpp @@ -2905,16 +2905,6 @@ namespace boost { namespace leaf { template decltype(std::declval()()) try_catch_( TryBlock &&, H && ... ); - - template - BOOST_LEAF_CONSTEXPR - typename std::decay()().value())>::type - try_handle_all( TryBlock &&, H && ... h ); - - template - BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR - typename std::decay()())>::type - try_handle_some( TryBlock &&, H && ... ); }; //////////////////////////////////////// @@ -3020,24 +3010,6 @@ namespace boost { namespace leaf { # pragma warning(push,1) #endif -// >>> #include -#line 1 "boost/leaf/detail/handle.hpp" -#ifndef BOOST_LEAF_DETAIL_HANDLE_HPP_INCLUDED -#define BOOST_LEAF_DETAIL_HANDLE_HPP_INCLUDED - -// Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc. - -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if defined(__clang__) -# pragma clang system_header -#elif (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma GCC system_header -#elif defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma warning(push,1) -#endif - // >>> #include #line 1 "boost/leaf/detail/demangle.hpp" #ifndef BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED @@ -3170,7 +3142,9 @@ namespace boost { namespace leaf { #endif // <<< #include -#line 19 "boost/leaf/detail/handle.hpp" +#line 19 "boost/leaf/handle_errors.hpp" +#ifndef BOOST_LEAF_NO_EXCEPTIONS +#endif namespace boost { namespace leaf { @@ -3572,6 +3546,15 @@ namespace boost { namespace leaf { return peek::type>(tup, ei); } + template + BOOST_LEAF_CONSTEXPR inline + std::exception const * + handler_argument_traits:: + check( Tup const &, error_info const & ei ) noexcept + { + return ei.exception(); + } + template struct check_arguments; @@ -3746,156 +3729,63 @@ namespace boost { namespace leaf { //////////////////////////////////////// +#ifdef BOOST_LEAF_NO_EXCEPTIONS + template BOOST_LEAF_CONSTEXPR inline typename std::decay()().value())>::type try_handle_all( TryBlock && try_block, H && ... h ) { - // Creating a named temp on purpose, to avoid C++11 and C++14 zero-initializing the context. - context_type_from_handlers c; - return c.try_handle_all( std::forward(try_block), std::forward(h)... ); + using namespace leaf_detail; + context_type_from_handlers ctx; + static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_all function must be registered with leaf::is_result_type"); + auto active_context = activate_context(ctx); + if( auto r = std::forward(try_block)() ) + return r.value(); + else + { + error_id id = r.error(); + ctx.deactivate(); + using R = typename std::decay()().value())>::type; + return ctx.template handle_error(std::move(id), std::forward(h)...); + } } template BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR inline typename std::decay()())>::type try_handle_some( TryBlock && try_block, H && ... h ) - { - // Creating a named temp on purpose, to avoid C++11 and C++14 zero-initializing the context. - context_type_from_handlers c; - return c.try_handle_some( std::forward(try_block), std::forward(h)... ); - } - -} } - -#endif -// <<< #include -#line 18 "boost/leaf/handle_errors.hpp" - -#ifdef BOOST_LEAF_NO_EXCEPTIONS -// >>> # include -#line 1 "boost/leaf/detail/ctx_nocatch.hpp" -#ifndef BOOST_LEAF_DETAIL_CTX_NOCATCH_HPP_INCLUDED -#define BOOST_LEAF_DETAIL_CTX_NOCATCH_HPP_INCLUDED - -// Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc. - -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if defined(__clang__) -# pragma clang system_header -#elif (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma GCC system_header -#elif defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma warning(push,1) -#endif - -#ifndef BOOST_LEAF_NO_EXCEPTIONS -# error This header requires exception handling to be disabled -#endif - -namespace boost { namespace leaf { - - template - template - BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE - typename std::decay()().value())>::type - context:: - try_handle_all( TryBlock && try_block, H && ... h ) - { - using namespace leaf_detail; - static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_all function must be registered with leaf::is_result_type"); - auto active_context = activate_context(*this); - if( auto r = std::forward(try_block)() ) - return r.value(); - else - { - error_id id = r.error(); - this->deactivate(); - using R = typename std::decay()().value())>::type; - return this->template handle_error(std::move(id), std::forward(h)...); - } - } - - template - template - BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE - typename std::decay()())>::type - context:: - try_handle_some( TryBlock && try_block, H && ... h ) { using namespace leaf_detail; + context_type_from_handlers ctx; static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_some function must be registered with leaf::is_result_type"); - auto active_context = activate_context(*this); + auto active_context = activate_context(ctx); if( auto r = std::forward(try_block)() ) return r; else { error_id id = r.error(); - this->deactivate(); + ctx.deactivate(); using R = typename std::decay()())>::type; - auto rr = this->template handle_error(std::move(id), std::forward(h)..., [&r]()->R { return std::move(r); }); + auto rr = ctx.template handle_error(std::move(id), std::forward(h)..., [&r]()->R { return std::move(r); }); if( !rr ) - this->propagate(); + ctx.propagate(); return rr; } } -} } - -#endif -// <<< # include -#line 21 "boost/leaf/handle_errors.hpp" #else -// >>> # include -#line 1 "boost/leaf/detail/ctx_catch.hpp" -#ifndef BOOST_LEAF_DETAIL_CTX_CATCH_HPP_INCLUDED -#define BOOST_LEAF_DETAIL_CTX_CATCH_HPP_INCLUDED -// Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc. - -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if defined(__clang__) -# pragma clang system_header -#elif (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma GCC system_header -#elif defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma warning(push,1) -#endif - -#ifdef BOOST_LEAF_NO_EXCEPTIONS -# error This header requires exception handling -#endif - - -namespace boost { namespace leaf { - - namespace leaf_detail - { - template - BOOST_LEAF_CONSTEXPR inline - std::exception const * - handler_argument_traits:: - check( Tup const &, error_info const & ei ) noexcept - { - return ei.exception(); - } - } - - template template BOOST_LEAF_CONSTEXPR inline typename std::decay()().value())>::type - context:: try_handle_all( TryBlock && try_block, H && ... h ) { using namespace leaf_detail; + context_type_from_handlers ctx; static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_all function must be registered with leaf::is_result_type"); - auto active_context = activate_context(*this); - if( auto r = this->try_catch_( + auto active_context = activate_context(ctx); + if( auto r = ctx.try_catch_( [&] { return std::forward(try_block)(); @@ -3905,24 +3795,23 @@ namespace boost { namespace leaf { else { error_id id = r.error(); - if( this->is_active() ) - this->deactivate(); + if( ctx.is_active() ) + ctx.deactivate(); using R = typename std::decay()().value())>::type; - return this->template handle_error(std::move(id), std::forward(h)...); + return ctx.template handle_error(std::move(id), std::forward(h)...); } } - template template BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR inline typename std::decay()())>::type - context:: try_handle_some( TryBlock && try_block, H && ... h ) { using namespace leaf_detail; + context_type_from_handlers ctx; static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_some function must be registered with leaf::is_result_type"); - auto active_context = activate_context(*this); - if( auto r = this->try_catch_( + auto active_context = activate_context(ctx); + if( auto r = ctx.try_catch_( [&] { return std::forward(try_block)(); @@ -3932,12 +3821,12 @@ namespace boost { namespace leaf { else { error_id id = r.error(); - if( this->is_active() ) - this->deactivate(); + if( ctx.is_active() ) + ctx.deactivate(); using R = typename std::decay()())>::type; - auto rr = this->template handle_error(std::move(id), std::forward(h)..., [&r]()->R { return std::move(r); }); + auto rr = ctx.template handle_error(std::move(id), std::forward(h)..., [&r]()->R { return std::move(r); }); if( !rr ) - this->propagate(); + ctx.propagate(); return rr; } } @@ -3989,8 +3878,6 @@ namespace boost { namespace leaf { } } - //////////////////////////////////////// - template BOOST_LEAF_CONSTEXPR inline decltype(std::declval()()) @@ -4007,8 +3894,12 @@ namespace boost { namespace leaf { std::forward(h)...); } +#endif + } } +#ifndef BOOST_LEAF_NO_EXCEPTIONS + // Boost Exception Integration namespace boost { class exception; } @@ -4071,9 +3962,6 @@ namespace boost { namespace leaf { } } -#endif -// <<< # include -#line 23 "boost/leaf/handle_errors.hpp" #endif #endif diff --git a/include/boost/leaf/context.hpp b/include/boost/leaf/context.hpp index 6b04c63..e43a5a8 100644 --- a/include/boost/leaf/context.hpp +++ b/include/boost/leaf/context.hpp @@ -251,16 +251,6 @@ namespace boost { namespace leaf { template decltype(std::declval()()) try_catch_( TryBlock &&, H && ... ); - - template - BOOST_LEAF_CONSTEXPR - typename std::decay()().value())>::type - try_handle_all( TryBlock &&, H && ... h ); - - template - BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR - typename std::decay()())>::type - try_handle_some( TryBlock &&, H && ... ); }; //////////////////////////////////////// diff --git a/include/boost/leaf/detail/ctx_catch.hpp b/include/boost/leaf/detail/ctx_catch.hpp deleted file mode 100644 index 8fa3adf..0000000 --- a/include/boost/leaf/detail/ctx_catch.hpp +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef BOOST_LEAF_DETAIL_CTX_CATCH_HPP_INCLUDED -#define BOOST_LEAF_DETAIL_CTX_CATCH_HPP_INCLUDED - -// Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc. - -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if defined(__clang__) -# pragma clang system_header -#elif (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma GCC system_header -#elif defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma warning(push,1) -#endif - -#ifdef BOOST_LEAF_NO_EXCEPTIONS -# error This header requires exception handling -#endif - -#include - -namespace boost { namespace leaf { - - namespace leaf_detail - { - template - BOOST_LEAF_CONSTEXPR inline - std::exception const * - handler_argument_traits:: - check( Tup const &, error_info const & ei ) noexcept - { - return ei.exception(); - } - } - - template - template - BOOST_LEAF_CONSTEXPR inline - typename std::decay()().value())>::type - context:: - try_handle_all( TryBlock && try_block, H && ... h ) - { - using namespace leaf_detail; - static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_all function must be registered with leaf::is_result_type"); - auto active_context = activate_context(*this); - if( auto r = this->try_catch_( - [&] - { - return std::forward(try_block)(); - }, - std::forward(h)...) ) - return r.value(); - else - { - error_id id = r.error(); - if( this->is_active() ) - this->deactivate(); - using R = typename std::decay()().value())>::type; - return this->template handle_error(std::move(id), std::forward(h)...); - } - } - - template - template - BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR inline - typename std::decay()())>::type - context:: - try_handle_some( TryBlock && try_block, H && ... h ) - { - using namespace leaf_detail; - static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_some function must be registered with leaf::is_result_type"); - auto active_context = activate_context(*this); - if( auto r = this->try_catch_( - [&] - { - return std::forward(try_block)(); - }, - std::forward(h)...) ) - return r; - else - { - error_id id = r.error(); - if( this->is_active() ) - this->deactivate(); - using R = typename std::decay()())>::type; - auto rr = this->template handle_error(std::move(id), std::forward(h)..., [&r]()->R { return std::move(r); }); - if( !rr ) - this->propagate(); - return rr; - } - } - - template - template - inline - decltype(std::declval()()) - context:: - try_catch_( TryBlock && try_block, H && ... h ) - { - using namespace leaf_detail; - BOOST_LEAF_ASSERT(is_active()); - using R = decltype(std::declval()()); - try - { - return std::forward(try_block)(); - } - catch( capturing_exception const & cap ) - { - try - { - cap.unload_and_rethrow_original_exception(); - } - catch( std::exception & ex ) - { - deactivate(); - return handle_error_(this->tup(), error_info(&ex), std::forward(h)..., - []() -> R { throw; } ); - } - catch(...) - { - deactivate(); - return handle_error_(this->tup(), error_info(nullptr), std::forward(h)..., - []() -> R { throw; } ); - } - } - catch( std::exception & ex ) - { - deactivate(); - return handle_error_(this->tup(), error_info(&ex), std::forward(h)..., - []() -> R { throw; } ); - } - catch(...) - { - deactivate(); - return handle_error_(this->tup(), error_info(nullptr), std::forward(h)..., - []() -> R { throw; } ); - } - } - - //////////////////////////////////////// - - template - BOOST_LEAF_CONSTEXPR inline - decltype(std::declval()()) - try_catch( TryBlock && try_block, H && ... h ) - { - using namespace leaf_detail; - context_type_from_handlers ctx; - auto active_context = activate_context(ctx); - return ctx.try_catch_( - [&] - { - return std::forward(try_block)(); - }, - std::forward(h)...); - } - -} } - -// Boost Exception Integration - -namespace boost { class exception; } -namespace boost { template class error_info; } -namespace boost { namespace exception_detail { template struct get_info; } } - -namespace boost { namespace leaf { - - namespace leaf_detail - { - template - struct match_enum_type; - - template - struct match_enum_type> - { - using type = T; - }; - - template - BOOST_LEAF_CONSTEXPR inline Ex * get_exception( error_info const & ei ) - { - return dynamic_cast(ei.exception()); - } - - template - struct dependent_type { using type = T; }; - - template - using dependent_type_t = typename dependent_type::type; - - template - struct handler_argument_traits> - { - using error_type = void; - constexpr static bool always_available = false; - - template - BOOST_LEAF_CONSTEXPR static T * check( Tup & tup, error_info const & ei ) noexcept - { - using boost_exception = dependent_type_t; - if( auto * be = get_exception(ei) ) - return exception_detail::get_info>::get(*be); - else - return 0; - } - - template - BOOST_LEAF_CONSTEXPR static boost::error_info get( Tup const & tup, error_info const & ei ) noexcept - { - return boost::error_info(*check(tup, ei)); - } - }; - - template struct handler_argument_traits const &>: handler_argument_traits_require_by_value> { }; - template struct handler_argument_traits const *>: handler_argument_traits_require_by_value> { }; - template struct handler_argument_traits &>: handler_argument_traits_require_by_value> { }; - template struct handler_argument_traits *>: handler_argument_traits_require_by_value> { }; - } - -} } - -#endif diff --git a/include/boost/leaf/detail/ctx_nocatch.hpp b/include/boost/leaf/detail/ctx_nocatch.hpp deleted file mode 100644 index 70f538e..0000000 --- a/include/boost/leaf/detail/ctx_nocatch.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef BOOST_LEAF_DETAIL_CTX_NOCATCH_HPP_INCLUDED -#define BOOST_LEAF_DETAIL_CTX_NOCATCH_HPP_INCLUDED - -// Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc. - -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if defined(__clang__) -# pragma clang system_header -#elif (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma GCC system_header -#elif defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma warning(push,1) -#endif - -#ifndef BOOST_LEAF_NO_EXCEPTIONS -# error This header requires exception handling to be disabled -#endif - -namespace boost { namespace leaf { - - template - template - BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE - typename std::decay()().value())>::type - context:: - try_handle_all( TryBlock && try_block, H && ... h ) - { - using namespace leaf_detail; - static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_all function must be registered with leaf::is_result_type"); - auto active_context = activate_context(*this); - if( auto r = std::forward(try_block)() ) - return r.value(); - else - { - error_id id = r.error(); - this->deactivate(); - using R = typename std::decay()().value())>::type; - return this->template handle_error(std::move(id), std::forward(h)...); - } - } - - template - template - BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE - typename std::decay()())>::type - context:: - try_handle_some( TryBlock && try_block, H && ... h ) - { - using namespace leaf_detail; - static_assert(is_result_type()())>::value, "The return type of the try_block passed to a try_handle_some function must be registered with leaf::is_result_type"); - auto active_context = activate_context(*this); - if( auto r = std::forward(try_block)() ) - return r; - else - { - error_id id = r.error(); - this->deactivate(); - using R = typename std::decay()())>::type; - auto rr = this->template handle_error(std::move(id), std::forward(h)..., [&r]()->R { return std::move(r); }); - if( !rr ) - this->propagate(); - return rr; - } - } - -} } - -#endif diff --git a/include/boost/leaf/detail/handle.hpp b/include/boost/leaf/detail/handle.hpp deleted file mode 100644 index 60face8..0000000 --- a/include/boost/leaf/detail/handle.hpp +++ /dev/null @@ -1,616 +0,0 @@ -#ifndef BOOST_LEAF_DETAIL_HANDLE_HPP_INCLUDED -#define BOOST_LEAF_DETAIL_HANDLE_HPP_INCLUDED - -// Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc. - -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if defined(__clang__) -# pragma clang system_header -#elif (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma GCC system_header -#elif defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) -# pragma warning(push,1) -#endif - -#include -#include - -namespace boost { namespace leaf { - - class error_info - { - error_info & operator=( error_info const & ) = delete; - - std::exception * const ex_; - error_id const err_id_; - - static error_id unpack_error_id( std::exception const * ex ) noexcept - { - if( std::system_error const * se = dynamic_cast(ex) ) - return error_id(se->code()); - else if( std::error_code const * ec = dynamic_cast(ex) ) - return error_id(*ec); - else if( error_id const * err_id = dynamic_cast(ex) ) - return *err_id; - else - return current_error(); - } - - protected: - - error_info( error_info const & ) noexcept = default; - - void print( std::ostream & os ) const - { - os << "Error ID = " << err_id_.value(); - if( ex_ ) - { - os << - "\nException dynamic type: " << leaf_detail::demangle(typeid(*ex_).name()) << - "\nstd::exception::what(): " << ex_->what(); - } - } - - public: - - BOOST_LEAF_CONSTEXPR explicit error_info( error_id id ) noexcept: - ex_(0), - err_id_(id) - { - } - - explicit error_info( std::exception * ex ) noexcept: - ex_(ex), - err_id_(unpack_error_id(ex_)) - { - } - - BOOST_LEAF_CONSTEXPR error_id error() const noexcept - { - return err_id_; - } - - BOOST_LEAF_CONSTEXPR std::exception * exception() const noexcept - { - return ex_; - } - - friend std::ostream & operator<<( std::ostream & os, error_info const & x ) - { - os << "leaf::error_info: "; - x.print(os); - return os << '\n'; - } - }; - - //////////////////////////////////////// - -#if BOOST_LEAF_DIAGNOSTICS - - class diagnostic_info: public error_info - { - leaf_detail::e_unexpected_count const * e_uc_; - void const * tup_; - void (*print_)( std::ostream &, void const * tup, int key_to_print ); - - protected: - - diagnostic_info( diagnostic_info const & ) noexcept = default; - - template - BOOST_LEAF_CONSTEXPR diagnostic_info( error_info const & ei, leaf_detail::e_unexpected_count const * e_uc, Tup const & tup ) noexcept: - error_info(ei), - e_uc_(e_uc), - tup_(&tup), - print_(&leaf_detail::tuple_for_each::value, Tup>::print) - { - } - - public: - - friend std::ostream & operator<<( std::ostream & os, diagnostic_info const & x ) - { - os << "leaf::diagnostic_info for "; - x.print(os); - os << ":\n"; - x.print_(os, x.tup_, x.error().value()); - if( x.e_uc_ ) - x.e_uc_->print(os); - return os; - } - }; - - namespace leaf_detail - { - struct diagnostic_info_: diagnostic_info - { - template - BOOST_LEAF_CONSTEXPR diagnostic_info_( error_info const & ei, leaf_detail::e_unexpected_count const * e_uc, Tup const & tup ) noexcept: - diagnostic_info(ei, e_uc, tup) - { - } - }; - - template <> - struct handler_argument_traits: handler_argument_always_available - { - template - BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept - { - return diagnostic_info_(ei, handler_argument_traits_defaults::check(tup, ei), tup); - } - }; - } - -#else - - class diagnostic_info: public error_info - { - protected: - - diagnostic_info( diagnostic_info const & ) noexcept = default; - - BOOST_LEAF_CONSTEXPR diagnostic_info( error_info const & ei ) noexcept: - error_info(ei) - { - } - - public: - - friend std::ostream & operator<<( std::ostream & os, diagnostic_info const & x ) - { - os << - "leaf::diagnostic_info requires #define BOOST_LEAF_DIAGNOSTICS 1\n" - "leaf::error_info: "; - x.print(os); - return os << '\n'; - } - }; - - namespace leaf_detail - { - struct diagnostic_info_: diagnostic_info - { - BOOST_LEAF_CONSTEXPR diagnostic_info_( error_info const & ei ) noexcept: - diagnostic_info(ei) - { - } - }; - - template <> - struct handler_argument_traits: handler_argument_always_available - { - template - BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept - { - return diagnostic_info_(ei); - } - }; - } - -#endif - - //////////////////////////////////////// - -#if BOOST_LEAF_DIAGNOSTICS - - class verbose_diagnostic_info: public error_info - { - leaf_detail::e_unexpected_info const * e_ui_; - void const * tup_; - void (*print_)( std::ostream &, void const * tup, int key_to_print ); - - protected: - - verbose_diagnostic_info( verbose_diagnostic_info const & ) noexcept = default; - - template - BOOST_LEAF_CONSTEXPR verbose_diagnostic_info( error_info const & ei, leaf_detail::e_unexpected_info const * e_ui, Tup const & tup ) noexcept: - error_info(ei), - e_ui_(e_ui), - tup_(&tup), - print_(&leaf_detail::tuple_for_each::value, Tup>::print) - { - } - - public: - - friend std::ostream & operator<<( std::ostream & os, verbose_diagnostic_info const & x ) - { - os << "leaf::verbose_diagnostic_info for "; - x.print(os); - os << ":\n"; - x.print_(os, x.tup_, x.error().value()); - if( x.e_ui_ ) - x.e_ui_->print(os); - return os; - } - }; - - namespace leaf_detail - { - struct verbose_diagnostic_info_: verbose_diagnostic_info - { - template - BOOST_LEAF_CONSTEXPR verbose_diagnostic_info_( error_info const & ei, leaf_detail::e_unexpected_info const * e_ui, Tup const & tup ) noexcept: - verbose_diagnostic_info(ei, e_ui, tup) - { - } - }; - - template <> - struct handler_argument_traits: handler_argument_always_available - { - template - BOOST_LEAF_CONSTEXPR static verbose_diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept - { - return verbose_diagnostic_info_(ei, handler_argument_traits_defaults::check(tup, ei), tup); - } - }; - } - -#else - - class verbose_diagnostic_info: public error_info - { - protected: - - verbose_diagnostic_info( verbose_diagnostic_info const & ) noexcept = default; - - BOOST_LEAF_CONSTEXPR verbose_diagnostic_info( error_info const & ei ) noexcept: - error_info(ei) - { - } - - public: - - friend std::ostream & operator<<( std::ostream & os, verbose_diagnostic_info const & x ) - { - os << - "leaf::verbose_diagnostic_info requires #define BOOST_LEAF_DIAGNOSTICS 1\n" - "leaf::error_info: "; - x.print(os); - return os << '\n'; - } - }; - - namespace leaf_detail - { - struct verbose_diagnostic_info_: verbose_diagnostic_info - { - BOOST_LEAF_CONSTEXPR verbose_diagnostic_info_( error_info const & ei ) noexcept: - verbose_diagnostic_info(ei) - { - } - }; - - - template <> - struct handler_argument_traits: handler_argument_always_available - { - template - BOOST_LEAF_CONSTEXPR static verbose_diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept - { - return verbose_diagnostic_info_(ei); - } - }; - } - -#endif - - //////////////////////////////////////// - - namespace leaf_detail - { - template - struct type_index; - - template - struct type_index - { - constexpr static int value = 0; - }; - - template - struct type_index - { - constexpr static int value = 1 + type_index::value; - }; - - template - struct tuple_type_index; - - template - struct tuple_type_index> - { - constexpr static int value = type_index::value; - }; - -#ifndef BOOST_LEAF_NO_EXCEPTIONS - - template ::value> - struct peek_exception; - - template <> - struct peek_exception - { - BOOST_LEAF_CONSTEXPR static std::exception * peek( error_info const & ei ) noexcept - { - return ei.exception(); - } - }; - - template - struct peek_exception - { - BOOST_LEAF_CONSTEXPR static E * peek( error_info const & ei ) noexcept - { - return dynamic_cast(ei.exception()); - } - }; - - template - struct peek_exception - { - BOOST_LEAF_CONSTEXPR static E * peek( error_info const & ) noexcept - { - return 0; - } - }; - -#endif - - template - BOOST_LEAF_CONSTEXPR inline - E const * - peek( SlotsTuple const & tup, error_info const & ei ) noexcept - { - if( error_id err = ei.error() ) - if( E const * e = std::get,SlotsTuple>::value>(tup).has_value(err.value()) ) - return e; -#ifndef BOOST_LEAF_NO_EXCEPTIONS - else - return peek_exception::peek(ei); -#endif - return 0; - } - - template - BOOST_LEAF_CONSTEXPR inline - E * - peek( SlotsTuple & tup, error_info const & ei ) noexcept - { - if( error_id err = ei.error() ) - if( E * e = std::get,SlotsTuple>::value>(tup).has_value(err.value()) ) - return e; -#ifndef BOOST_LEAF_NO_EXCEPTIONS - else - return peek_exception::peek(ei); -#endif - return 0; - } - } - - //////////////////////////////////////// - - namespace leaf_detail - { - template - template - BOOST_LEAF_CONSTEXPR inline - typename handler_argument_traits_defaults::error_type const * - handler_argument_traits_defaults:: - check( Tup const & tup, error_info const & ei ) noexcept - { - return peek::type>(tup, ei); - } - - template - template - BOOST_LEAF_CONSTEXPR inline - typename handler_argument_traits_defaults::error_type * - handler_argument_traits_defaults:: - check( Tup & tup, error_info const & ei ) noexcept - { - return peek::type>(tup, ei); - } - - template - struct check_arguments; - - template - struct check_arguments - { - BOOST_LEAF_CONSTEXPR static bool check( Tup const &, error_info const & ) - { - return true; - } - }; - - template - struct check_arguments - { - BOOST_LEAF_CONSTEXPR static bool check( Tup & tup, error_info const & ei ) noexcept - { - return handler_argument_traits::check(tup, ei) && check_arguments::check(tup, ei); - } - }; - } - - //////////////////////////////////////// - - namespace leaf_detail - { - template - struct handler_matches_any_error: std::false_type - { - }; - - template class L> - struct handler_matches_any_error>: std::true_type - { - }; - - template class L, class Car, class... Cdr> - struct handler_matches_any_error> - { - constexpr static bool value = handler_argument_traits::always_available && handler_matches_any_error>::value; - }; - } - - //////////////////////////////////////// - - namespace leaf_detail - { - template - BOOST_LEAF_CONSTEXPR inline bool check_handler_( Tup & tup, error_info const & ei, leaf_detail_mp11::mp_list ) noexcept - { - return check_arguments::check(tup, ei); - } - - template ::value, class FReturnType = fn_return_type> - struct handler_caller - { - template - BOOST_LEAF_CONSTEXPR static R call( Tup & tup, error_info const & ei, F && f, leaf_detail_mp11::mp_list ) - { - return std::forward(f)( handler_argument_traits::get(tup, ei)... ); - } - }; - - template