#ifndef BOOST_LEAF_HPP_INCLUDED #define BOOST_LEAF_HPP_INCLUDED // Boost LEAF single header distribution. Do not edit. // Generated on Feb 24, 2025 from https://github.com/boostorg/leaf/tree/aff38b5. // Latest published version of this file: https://raw.githubusercontent.com/boostorg/leaf/gh-pages/leaf.hpp. // Copyright 2018-2024 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) // >>> #include #ifndef BOOST_LEAF_CONFIG_HPP_INCLUDED #define BOOST_LEAF_CONFIG_HPP_INCLUDED // #line 8 "boost/leaf/config.hpp" #ifdef BOOST_LEAF_TLS_FREERTOS # ifndef BOOST_LEAF_EMBEDDED # define BOOST_LEAF_EMBEDDED # endif #endif #ifdef BOOST_LEAF_EMBEDDED # ifndef BOOST_LEAF_CFG_DIAGNOSTICS # define BOOST_LEAF_CFG_DIAGNOSTICS 0 # endif # ifndef BOOST_LEAF_CFG_STD_SYSTEM_ERROR # define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 0 # endif # ifndef BOOST_LEAF_CFG_STD_STRING # define BOOST_LEAF_CFG_STD_STRING 0 # endif # ifndef BOOST_LEAF_CFG_CAPTURE # define BOOST_LEAF_CFG_CAPTURE 0 # endif #endif //////////////////////////////////////// #ifndef BOOST_LEAF_ASSERT # include # define BOOST_LEAF_ASSERT assert #endif //////////////////////////////////////// #ifndef BOOST_LEAF_CFG_DIAGNOSTICS # define BOOST_LEAF_CFG_DIAGNOSTICS 1 #endif #ifndef BOOST_LEAF_CFG_STD_SYSTEM_ERROR # define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 1 #endif #ifndef BOOST_LEAF_CFG_STD_STRING # define BOOST_LEAF_CFG_STD_STRING 1 #endif #ifndef BOOST_LEAF_CFG_CAPTURE # define BOOST_LEAF_CFG_CAPTURE 1 #endif #ifndef BOOST_LEAF_CFG_WIN32 # define BOOST_LEAF_CFG_WIN32 0 #endif #ifndef BOOST_LEAF_CFG_GNUC_STMTEXPR # ifdef __GNUC__ # define BOOST_LEAF_CFG_GNUC_STMTEXPR 1 # else # define BOOST_LEAF_CFG_GNUC_STMTEXPR 0 # endif #endif #ifndef BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER # define BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER "\n " #endif #ifndef BOOST_LEAF_CFG_DIAGNOSTICS_DELIMITER # define BOOST_LEAF_CFG_DIAGNOSTICS_DELIMITER "\n " #endif #if BOOST_LEAF_CFG_DIAGNOSTICS != 0 && BOOST_LEAF_CFG_DIAGNOSTICS != 1 # error BOOST_LEAF_CFG_DIAGNOSTICS must be 0 or 1. #endif #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR != 0 && BOOST_LEAF_CFG_STD_SYSTEM_ERROR != 1 # error BOOST_LEAF_CFG_STD_SYSTEM_ERROR must be 0 or 1. #endif #if BOOST_LEAF_CFG_STD_STRING != 0 && BOOST_LEAF_CFG_STD_STRING != 1 # error BOOST_LEAF_CFG_STD_STRING must be 0 or 1. #endif #if BOOST_LEAF_CFG_CAPTURE != 0 && BOOST_LEAF_CFG_CAPTURE != 1 # error BOOST_LEAF_CFG_CAPTURE must be 0 or 1. #endif #if BOOST_LEAF_CFG_WIN32 != 0 && BOOST_LEAF_CFG_WIN32 != 1 # error BOOST_LEAF_CFG_WIN32 must be 0 or 1. #endif #if BOOST_LEAF_CFG_GNUC_STMTEXPR != 0 && BOOST_LEAF_CFG_GNUC_STMTEXPR != 1 # error BOOST_LEAF_CFG_GNUC_STMTEXPR must be 0 or 1. #endif #if BOOST_LEAF_CFG_DIAGNOSTICS && !BOOST_LEAF_CFG_STD_STRING # error BOOST_LEAF_CFG_DIAGNOSTICS requires BOOST_LEAF_CFG_STD_STRING, which has been disabled. #endif #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR && !BOOST_LEAF_CFG_STD_STRING # error BOOST_LEAF_CFG_STD_SYSTEM_ERROR requires BOOST_LEAF_CFG_STD_STRING, which has been disabled. #endif //////////////////////////////////////// #ifndef BOOST_LEAF_PRETTY_FUNCTION # if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) # define BOOST_LEAF_PRETTY_FUNCTION __FUNCSIG__ # else # define BOOST_LEAF_PRETTY_FUNCTION __PRETTY_FUNCTION__ # endif #endif //////////////////////////////////////// #ifndef BOOST_LEAF_NO_EXCEPTIONS // The following is based in part on Boost Config. // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Martin Wille 2003. // (C) Copyright Guillaume Melquiond 2003. # if defined(__clang__) && !defined(__ibmxl__) // Clang C++ emulates GCC, so it has to appear early. # if !__has_feature(cxx_exceptions) # define BOOST_LEAF_NO_EXCEPTIONS # endif # elif defined(__GNUC__) && !defined(__ibmxl__) // GNU C++: # if !defined(__EXCEPTIONS) # define BOOST_LEAF_NO_EXCEPTIONS # endif # elif defined(__CODEGEARC__) // CodeGear - must be checked for before Borland # if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS) # define BOOST_LEAF_NO_EXCEPTIONS # endif # elif defined(__IBMCPP__) && defined(__COMPILER_VER__) && defined(__MVS__) // IBM z/OS XL C/C++ # if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS) # define BOOST_LEAF_NO_EXCEPTIONS # endif # elif defined(__ibmxl__) // IBM XL C/C++ for Linux (Little Endian) # if !__has_feature(cxx_exceptions) # define BOOST_LEAF_NO_EXCEPTIONS # endif # elif defined(_MSC_VER) // Microsoft Visual C++ // Must remain the last #elif since some other vendors (Metrowerks, for // example) also #define _MSC_VER # if !_CPPUNWIND # define BOOST_LEAF_NO_EXCEPTIONS # endif # endif #endif //////////////////////////////////////// #ifdef _MSC_VER # define BOOST_LEAF_ALWAYS_INLINE __forceinline #else # define BOOST_LEAF_ALWAYS_INLINE __attribute__((always_inline)) inline #endif //////////////////////////////////////// #if defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) # if __has_attribute(nodiscard) # define BOOST_LEAF_ATTRIBUTE_NODISCARD [[nodiscard]] # endif #elif defined(__has_cpp_attribute) // require c++17 regardless of compiler # if __has_cpp_attribute(nodiscard) && __cplusplus >= 201703L # define BOOST_LEAF_ATTRIBUTE_NODISCARD [[nodiscard]] # endif #endif #ifndef BOOST_LEAF_ATTRIBUTE_NODISCARD # define BOOST_LEAF_ATTRIBUTE_NODISCARD #endif //////////////////////////////////////// #ifndef BOOST_LEAF_CONSTEXPR # if __cplusplus > 201402L # define BOOST_LEAF_CONSTEXPR constexpr # else # define BOOST_LEAF_CONSTEXPR # endif #endif //////////////////////////////////////// #ifndef BOOST_LEAF_DEPRECATED # if __cplusplus > 201402L # define BOOST_LEAF_DEPRECATED(msg) [[deprecated(msg)]] # else # define BOOST_LEAF_DEPRECATED(msg) # endif #endif //////////////////////////////////////// #ifndef BOOST_LEAF_NO_EXCEPTIONS # include # if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L) || (defined(_MSC_VER) && _MSC_VER >= 1900) # define BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS 1 # else # define BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS 0 # endif #endif //////////////////////////////////////// #ifdef __GNUC__ # define BOOST_LEAF_SYMBOL_VISIBLE [[gnu::visibility("default")]] #else # define BOOST_LEAF_SYMBOL_VISIBLE #endif //////////////////////////////////////// #if defined(__GNUC__) && !(defined(__clang__) || defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) < 409 # ifndef BOOST_LEAF_NO_CXX11_REF_QUALIFIERS # define BOOST_LEAF_NO_CXX11_REF_QUALIFIERS # endif #endif //////////////////////////////////////// // Configure TLS access // >>> #include #ifndef BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED // #line 8 "boost/leaf/config/tls.hpp" #if defined(BOOST_LEAF_TLS_FREERTOS) // >>> # include #ifndef BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED // #line 8 "boost/leaf/config/tls_freertos.hpp" // Copyright (c) 2022 Khalil Estell // LEAF requires thread local storage support for pointers and for uin32_t values. // This header implements "thread local" storage via FreeTOS functions // pvTaskGetThreadLocalStoragePointer / pvTaskSetThreadLocalStoragePointer #include #ifndef BOOST_LEAF_USE_TLS_ARRAY # define BOOST_LEAF_USE_TLS_ARRAY #endif #ifndef BOOST_LEAF_CFG_TLS_ARRAY_SIZE # define BOOST_LEAF_CFG_TLS_ARRAY_SIZE configNUM_THREAD_LOCAL_STORAGE_POINTERS #endif static_assert((BOOST_LEAF_CFG_TLS_ARRAY_SIZE) <= configNUM_THREAD_LOCAL_STORAGE_POINTERS, "Bad BOOST_LEAF_CFG_TLS_ARRAY_SIZE"); namespace boost { namespace leaf { namespace tls { // See https://www.freertos.org/thread-local-storage-pointers.html. inline void * read_void_ptr( int tls_index ) noexcept { return pvTaskGetThreadLocalStoragePointer(0, tls_index); } inline void write_void_ptr( int tls_index, void * p ) noexcept { vTaskSetThreadLocalStoragePointer(0, tls_index, p); } } } } #endif // BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED // <<< # include // #line 10 "boost/leaf/config/tls.hpp" #endif #ifndef BOOST_LEAF_USE_TLS_ARRAY # ifdef BOOST_LEAF_CFG_TLS_INDEX_TYPE # warning "BOOST_LEAF_CFG_TLS_INDEX_TYPE" is ignored if BOOST_LEAF_USE_TLS_ARRAY is not defined. # endif # ifdef BOOST_LEAF_CFG_TLS_ARRAY_SIZE # warning "BOOST_LEAF_CFG_TLS_ARRAY_SIZE" is ignored if BOOST_LEAF_USE_TLS_ARRAY is not defined. # endif # ifdef BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX # warning "BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX" is ignored if BOOST_LEAF_USE_TLS_ARRAY is not defined. # endif #endif #if defined BOOST_LEAF_USE_TLS_ARRAY // >>> # include #ifndef BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED // #line 8 "boost/leaf/config/tls_array.hpp" // Copyright (c) 2022 Khalil Estell // LEAF requires thread local storage support for pointers and for uin32_t values. // This header implements thread local storage for pointers and for unsigned int // values for platforms that support thread local pointers by index. namespace boost { namespace leaf { namespace tls { // The TLS support defined in this header requires the following two // functions to be defined elsewhere: void * read_void_ptr( int tls_index ) noexcept; void write_void_ptr( int tls_index, void * ) noexcept; } } } //////////////////////////////////////// #include #include #include #include #ifndef BOOST_LEAF_CFG_TLS_INDEX_TYPE # define BOOST_LEAF_CFG_TLS_INDEX_TYPE unsigned char #endif #ifndef BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX # define BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX 0 #endif static_assert((BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX) >= 0, "Bad BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX"); #ifdef BOOST_LEAF_CFG_TLS_ARRAY_SIZE static_assert((BOOST_LEAF_CFG_TLS_ARRAY_SIZE) > (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX), "Bad BOOST_LEAF_CFG_TLS_ARRAY_SIZE"); static_assert((BOOST_LEAF_CFG_TLS_ARRAY_SIZE) - 1 <= std::numeric_limits::max(), "Bad BOOST_LEAF_CFG_TLS_ARRAY_SIZE"); #endif //////////////////////////////////////// namespace boost { namespace leaf { namespace detail { using atomic_unsigned_int = std::atomic; } namespace tls { template class BOOST_LEAF_SYMBOL_VISIBLE index_counter { static int c_; static BOOST_LEAF_CFG_TLS_INDEX_TYPE next_() noexcept { int idx = ++c_; BOOST_LEAF_ASSERT(idx > (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); BOOST_LEAF_ASSERT(idx < (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); return idx; } public: template static BOOST_LEAF_CFG_TLS_INDEX_TYPE next() noexcept { return next_(); // Set breakpoint here to monitor TLS index allocation for T. } }; template struct BOOST_LEAF_SYMBOL_VISIBLE tls_index { static BOOST_LEAF_CFG_TLS_INDEX_TYPE idx; }; template struct BOOST_LEAF_SYMBOL_VISIBLE alloc_tls_index { static BOOST_LEAF_CFG_TLS_INDEX_TYPE const idx; }; template int index_counter::c_ = BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX; template BOOST_LEAF_CFG_TLS_INDEX_TYPE tls_index::idx = BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX; template BOOST_LEAF_CFG_TLS_INDEX_TYPE const alloc_tls_index::idx = tls_index::idx = index_counter<>::next(); //////////////////////////////////////// template T * read_ptr() noexcept { int tls_idx = tls_index::idx; if( tls_idx == (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX) ) return nullptr; --tls_idx; return reinterpret_cast(read_void_ptr(tls_idx)); } template void write_ptr( T * p ) noexcept { int tls_idx = alloc_tls_index::idx; --tls_idx; write_void_ptr(tls_idx, p); BOOST_LEAF_ASSERT(read_void_ptr(tls_idx) == p); } //////////////////////////////////////// template unsigned read_uint() noexcept { static_assert(sizeof(std::intptr_t) >= sizeof(unsigned), "Incompatible tls_array implementation"); return (unsigned) (std::intptr_t) (void *) read_ptr(); } template void write_uint( unsigned x ) noexcept { static_assert(sizeof(std::intptr_t) >= sizeof(unsigned), "Incompatible tls_array implementation"); write_ptr((Tag *) (void *) (std::intptr_t) x); } } } } #endif // BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED // <<< # include // #line 26 "boost/leaf/config/tls.hpp" #elif defined(BOOST_LEAF_NO_THREADS) // >>> # include #ifndef BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED // #line 8 "boost/leaf/config/tls_globals.hpp" // LEAF requires thread local storage support for pointers and for uin32_t values. // This header implements "thread local" storage for pointers and for unsigned int // values using globals, which is suitable for single thread environments. #include namespace boost { namespace leaf { namespace detail { using atomic_unsigned_int = unsigned int; } namespace tls { template struct BOOST_LEAF_SYMBOL_VISIBLE ptr { static T * p; }; template T * ptr::p; template T * read_ptr() noexcept { return ptr::p; } template void write_ptr( T * p ) noexcept { ptr::p = p; } //////////////////////////////////////// template struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint { static unsigned x; }; template unsigned tagged_uint::x; template unsigned read_uint() noexcept { return tagged_uint::x; } template void write_uint( unsigned x ) noexcept { tagged_uint::x = x; } } } } #endif // BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED // <<< # include // #line 28 "boost/leaf/config/tls.hpp" #else // >>> # include #ifndef BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED // #line 8 "boost/leaf/config/tls_cpp11.hpp" // LEAF requires thread local storage support for pointers and for uin32_t values. // This header implements thread local storage for pointers and for unsigned int // values using the C++11 built-in thread_local storage class specifier. #include #include namespace boost { namespace leaf { namespace detail { using atomic_unsigned_int = std::atomic; } namespace tls { template struct BOOST_LEAF_SYMBOL_VISIBLE ptr { static thread_local T * p; }; template thread_local T * ptr::p; template T * read_ptr() noexcept { return ptr::p; } template void write_ptr( T * p ) noexcept { ptr::p = p; } //////////////////////////////////////// template struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint { static thread_local unsigned x; }; template thread_local unsigned tagged_uint::x; template unsigned read_uint() noexcept { return tagged_uint::x; } template void write_uint( unsigned x ) noexcept { tagged_uint::x = x; } } } } #endif // BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED // <<< # include // #line 30 "boost/leaf/config/tls.hpp" #endif #endif // BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED // <<< #include // #line 234 "boost/leaf/config.hpp" #endif // BOOST_LEAF_CONFIG_HPP_INCLUDED // >>> #include #ifndef BOOST_LEAF_COMMON_HPP_INCLUDED #define BOOST_LEAF_COMMON_HPP_INCLUDED // #line 8 "boost/leaf/common.hpp" // #include // Expanded at line 14 // >>> #include #ifndef BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED #define BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED // #line 8 "boost/leaf/detail/demangle.hpp" // This file is based on boost::core::demangle // // Copyright 2014 Peter Dimov // Copyright 2014 Andrey Semashev // // 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 // #include // Expanded at line 14 #include #include #if BOOST_LEAF_CFG_DIAGNOSTICS // __has_include is currently supported by GCC and Clang. However GCC 4.9 may have issues and // returns 1 for 'defined( __has_include )', while '__has_include' is actually not supported: // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63662 #if defined(__has_include) && (!defined(__GNUC__) || defined(__clang__) || (__GNUC__ + 0) >= 5) # if __has_include() # define BOOST_LEAF_HAS_CXXABI_H # endif #elif defined(__GLIBCXX__) || defined(__GLIBCPP__) # define BOOST_LEAF_HAS_CXXABI_H #endif #if defined(BOOST_LEAF_HAS_CXXABI_H) # include // For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library // (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement // abi::__cxa_demangle(). We detect this implementation by checking the include guard here. # if defined(__GABIXX_CXXABI_H__) # undef BOOST_LEAF_HAS_CXXABI_H # endif #endif #endif namespace boost { namespace leaf { namespace detail { // The functions below are C++11 constexpr, but we use BOOST_LEAF_ALWAYS_INLINE to control object file // section count / template bleat. Evidently this makes a difference on gcc / windows at least. template = S2> struct cpp11_prefix { BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&)[S1], char const (&)[S2]) noexcept { return false; } }; template struct cpp11_prefix { BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&prefix)[S2]) noexcept { return str[I] == prefix[I] && cpp11_prefix::check(str, prefix); } }; template struct cpp11_prefix { BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&prefix)[S2]) noexcept { return str[0] == prefix[0]; } }; template BOOST_LEAF_ALWAYS_INLINE constexpr int check_prefix(char const (&str)[S1], char const (&prefix)[S2]) noexcept { return cpp11_prefix::check(str, prefix) ? S2 - 1 : 0; } //////////////////////////////////////// template = S2> struct cpp11_suffix { BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&)[S1], char const (&)[S2]) noexcept { return false; } }; template struct cpp11_suffix { BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&suffix)[S2]) noexcept { return str[I1] == suffix[I2] && cpp11_suffix::check(str, suffix); } }; template struct cpp11_suffix { BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&suffix)[S2]) noexcept { return str[I1] == suffix[0]; } }; template BOOST_LEAF_ALWAYS_INLINE constexpr int check_suffix(char const (&str)[S1], char const (&suffix)[S2]) noexcept { return cpp11_suffix::check(str, suffix) ? S1 - S2 : 0; } } namespace n { struct r { char const * name; int len; r(char const * name, int len) noexcept: name(name), len(len) { } template friend std::ostream & operator<<(std::basic_ostream & os, r const & pn) { return os.write(pn.name, pn.len); } }; template BOOST_LEAF_ALWAYS_INLINE r p() { // C++11 compile-time parsing of __PRETTY_FUNCTION__/__FUNCSIG__. The sizeof hacks are a // workaround for older GCC versions, where __PRETTY_FUNCTION__ is not constexpr, which triggers // compile errors when used in constexpr expressinos, yet evaluating a sizeof exrpession works. // We don't try to recognize the compiler based on compiler-specific macros. Any compiler/version // is supported as long as it uses one of the formats we recognize. // Unrecognized __PRETTY_FUNCTION__/__FUNCSIG__ formats will result in compiler diagnostics. // In that case, please file an issue on https://github.com/boostorg/leaf. #define BOOST_LEAF_P(P) (sizeof(char[1 + detail::check_prefix(BOOST_LEAF_PRETTY_FUNCTION, P)]) - 1) // clang style: int const p01 = BOOST_LEAF_P("r boost::leaf::n::p() [T = "); int const p02 = BOOST_LEAF_P("r __cdecl boost::leaf::n::p(void) [T = "); int const p03 = BOOST_LEAF_P("r __stdcall boost::leaf::n::p(void) [T = "); int const p04 = BOOST_LEAF_P("r __fastcall boost::leaf::n::p(void) [T = "); // old clang style: int const p05 = BOOST_LEAF_P("boost::leaf::n::r boost::leaf::n::p() [T = "); int const p06 = BOOST_LEAF_P("boost::leaf::n::r __cdecl boost::leaf::n::p(void) [T = "); int const p07 = BOOST_LEAF_P("boost::leaf::n::r __stdcall boost::leaf::n::p(void) [T = "); int const p08 = BOOST_LEAF_P("boost::leaf::n::r __fastcall boost::leaf::n::p(void) [T = "); // gcc style: int const p09 = BOOST_LEAF_P("boost::leaf::n::r boost::leaf::n::p() [with T = "); int const p10 = BOOST_LEAF_P("boost::leaf::n::r __cdecl boost::leaf::n::p() [with T = "); int const p11 = BOOST_LEAF_P("boost::leaf::n::r __stdcall boost::leaf::n::p() [with T = "); int const p12 = BOOST_LEAF_P("boost::leaf::n::r __fastcall boost::leaf::n::p() [with T = "); // msvc style, struct: int const p13 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p(void)"); #undef BOOST_LEAF_S char static_assert_unrecognized_pretty_function_format_please_file_github_issue[sizeof( char[ (s01 && (1 == (!!p01 + !!p02 + !!p03 + !!p04 + !!p05 + !!p06 + !!p07 + !!p08 + !!p09 + !!p10 + !!p11 + !!p12))) || (s02 && (1 == (!!p13 + !!p14 + !!p15 + !!p16 + !!p17 + !!p18 + !!p19 + !!p20 + !!p21))) || (s02 && (1 == (!!p22 + !!p23 + !!p24))) ] ) * 2 - 1]; (void) static_assert_unrecognized_pretty_function_format_please_file_github_issue; if( int const p = sizeof(char[1 + !!s01 * (p01 + p02 + p03 + p04 + p05 + p06 + p07 + p08 + p09 + p10 + p11 + p12)]) - 1 ) return { BOOST_LEAF_PRETTY_FUNCTION + p, s01 - p }; if( int const p = sizeof(char[1 + !!s02 * (p13 + p14 + p15 + p16 + p17 + p18 + p19 + p20 + p21)]) - 1 ) return { BOOST_LEAF_PRETTY_FUNCTION + p, s02 - p }; int const p = sizeof(char[1 + !!s02 * (p22 + p23 + p24)]) - 1; // p is not zero, we've static asserted the hell out of it return { BOOST_LEAF_PRETTY_FUNCTION + p, s02 - p }; } } using parsed = n::r; template parsed parse() { return n::p(); } } } //////////////////////////////////////// namespace boost { namespace leaf { namespace detail { template std::ostream & demangle_and_print(std::basic_ostream & os, char const * mangled_name) { BOOST_LEAF_ASSERT(mangled_name); #if defined(BOOST_LEAF_CFG_DIAGNOSTICS) && defined(BOOST_LEAF_HAS_CXXABI_H) struct raii { char * demangled_name; raii(char const * mangled_name) noexcept { int status = 0; demangled_name = abi::__cxa_demangle(mangled_name, nullptr, nullptr, &status); } ~raii() noexcept { std::free(demangled_name); } } d(mangled_name); if( d.demangled_name ) return os << d.demangled_name; #endif return os << mangled_name; } } } } #endif // BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED // <<< #include // #line 10 "boost/leaf/common.hpp" #include #include #include #if BOOST_LEAF_CFG_STD_STRING # include #endif #if BOOST_LEAF_CFG_WIN32 # include # include # ifdef min # undef min # endif # ifdef max # undef max # endif #endif namespace boost { namespace leaf { struct BOOST_LEAF_SYMBOL_VISIBLE e_api_function { char const * value; }; #if BOOST_LEAF_CFG_STD_STRING struct BOOST_LEAF_SYMBOL_VISIBLE e_file_name { std::string value; }; #else struct BOOST_LEAF_SYMBOL_VISIBLE e_file_name { char const * value = ""; BOOST_LEAF_CONSTEXPR explicit e_file_name( char const * ) { } }; #endif struct BOOST_LEAF_SYMBOL_VISIBLE e_errno { int value; explicit e_errno(int val=errno): value(val) { } template friend std::ostream & operator<<(std::basic_ostream & os, e_errno const & err) { return os << err.value << ", \"" << std::strerror(err.value) << '"'; } }; struct BOOST_LEAF_SYMBOL_VISIBLE e_type_info_name { char const * value; }; struct BOOST_LEAF_SYMBOL_VISIBLE e_at_line { int value; }; namespace windows { struct e_LastError { unsigned value; explicit e_LastError(unsigned val): value(val) { } #if BOOST_LEAF_CFG_WIN32 e_LastError(): value(GetLastError()) { } template friend std::ostream & operator<<(std::basic_ostream & os, e_LastError const & err) { struct msg_buf { LPVOID * p; msg_buf(): p(nullptr) { } ~msg_buf() noexcept { if(p) LocalFree(p); } }; msg_buf mb; if( FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, err.value, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPSTR)&mb.p, 0, nullptr) ) { BOOST_LEAF_ASSERT(mb.p != nullptr); char * z = std::strchr((LPSTR)mb.p,0); if( z[-1] == '\n' ) *--z = 0; if( z[-1] == '\r' ) *--z = 0; return os << err.value << ", \"" << (LPCSTR)mb.p << '"'; } return os; } #endif }; } } } #endif // BOOST_LEAF_COMMON_HPP_INCLUDED // >>> #include #ifndef BOOST_LEAF_CONTEXT_HPP_INCLUDED #define BOOST_LEAF_CONTEXT_HPP_INCLUDED // #line 8 "boost/leaf/context.hpp" // #include // Expanded at line 14 // >>> #include #ifndef BOOST_LEAF_ERROR_HPP_INCLUDED #define BOOST_LEAF_ERROR_HPP_INCLUDED // #line 8 "boost/leaf/error.hpp" // #include // Expanded at line 14 // >>> #include #ifndef BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED #define BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED // #line 8 "boost/leaf/detail/optional.hpp" // #include // Expanded at line 14 #include #include namespace boost { namespace leaf { namespace detail { template class optional { int key_; union { T value_; }; public: typedef T value_type; BOOST_LEAF_CONSTEXPR optional() noexcept: key_(0) { } BOOST_LEAF_CONSTEXPR optional( optional const & x ): key_(x.key_) { if( x.key_ ) (void) new (&value_) T( x.value_ ); } BOOST_LEAF_CONSTEXPR optional( optional && x ) noexcept: key_(x.key_) { if( x.key_ ) { (void) new (&value_) T( std::move(x.value_) ); x.reset(); } } BOOST_LEAF_CONSTEXPR optional( int key, T const & v ): key_(key), value_(v) { BOOST_LEAF_ASSERT(!empty()); } BOOST_LEAF_CONSTEXPR optional( int key, T && v ) noexcept: key_(key), value_(std::move(v)) { BOOST_LEAF_ASSERT(!empty()); } BOOST_LEAF_CONSTEXPR optional & operator=( optional const & x ) { reset(); if( int key = x.key() ) { load(key, x.value_); key_ = key; } return *this; } BOOST_LEAF_CONSTEXPR optional & operator=( optional && x ) noexcept { reset(); if( int key = x.key() ) { load(key, std::move(x.value_)); x.reset(); } return *this; } ~optional() noexcept { reset(); } BOOST_LEAF_CONSTEXPR bool empty() const noexcept { return key_ == 0; } BOOST_LEAF_CONSTEXPR int key() const noexcept { return key_; } BOOST_LEAF_CONSTEXPR void reset() noexcept { if( key_ ) { value_.~T(); key_=0; } } BOOST_LEAF_CONSTEXPR T & load( int key ) { BOOST_LEAF_ASSERT(key); reset(); (void) new(&value_) T; key_=key; return value_; } BOOST_LEAF_CONSTEXPR T & load( int key, T const & v ) { BOOST_LEAF_ASSERT(key); reset(); (void) new(&value_) T(v); key_=key; return value_; } BOOST_LEAF_CONSTEXPR T & load( int key, T && v ) noexcept { BOOST_LEAF_ASSERT(key); reset(); (void) new(&value_) T(std::move(v)); key_=key; return value_; } BOOST_LEAF_CONSTEXPR T const * has_value_any_key() const noexcept { return key_ ? &value_ : nullptr; } BOOST_LEAF_CONSTEXPR T * has_value_any_key() noexcept { return key_ ? &value_ : nullptr; } BOOST_LEAF_CONSTEXPR T const * has_value(int key) const noexcept { BOOST_LEAF_ASSERT(key); return key_ == key ? &value_ : nullptr; } BOOST_LEAF_CONSTEXPR T * has_value(int key) noexcept { BOOST_LEAF_ASSERT(key); return key_ == key ? &value_ : nullptr; } BOOST_LEAF_CONSTEXPR T const & value(int key) const & noexcept { BOOST_LEAF_ASSERT(has_value(key) != 0); (void) key; return value_; } BOOST_LEAF_CONSTEXPR T & value(int key) & noexcept { BOOST_LEAF_ASSERT(has_value(key) != 0); (void) key; return value_; } BOOST_LEAF_CONSTEXPR T const && value(int key) const && noexcept { BOOST_LEAF_ASSERT(has_value(key) != 0); (void) key; return value_; } BOOST_LEAF_CONSTEXPR T value(int key) && noexcept { BOOST_LEAF_ASSERT(has_value(key) != 0); (void) key; T tmp(std::move(value_)); reset(); return tmp; } BOOST_LEAF_CONSTEXPR T & value_or_default(int key) noexcept { if( T * v = has_value(key) ) return *v; else return load(key); } }; } } } #endif // BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED // <<< #include // #line 10 "boost/leaf/error.hpp" // >>> #include #ifndef BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED #define BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED // #line 8 "boost/leaf/detail/function_traits.hpp" // >>> #include #ifndef BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED #define BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED // Copyright 2015-2017 Peter Dimov. // #line 12 "boost/leaf/detail/mp11.hpp" #include #include namespace boost { namespace leaf { namespace leaf_detail_mp11 { // mp_list template struct mp_list { }; // mp_identity template struct mp_identity { using type = T; }; // mp_inherit template struct mp_inherit: T... {}; // mp_if, mp_if_c namespace detail { template struct mp_if_c_impl { }; template struct mp_if_c_impl { using type = T; }; template struct mp_if_c_impl { using type = E; }; } // namespace detail template using mp_if_c = typename detail::mp_if_c_impl::type; template using mp_if = typename detail::mp_if_c_impl(C::value), T, E...>::type; // mp_bool template using mp_bool = std::integral_constant; using mp_true = mp_bool; using mp_false = mp_bool; // mp_to_bool template using mp_to_bool = mp_bool( T::value )>; // mp_not template using mp_not = mp_bool< !T::value >; // mp_int template using mp_int = std::integral_constant; // mp_size_t template using mp_size_t = std::integral_constant; // mp_set_contains namespace detail { template struct mp_set_contains_impl; template class L, class... T, class V> struct mp_set_contains_impl, V> { using type = mp_to_bool, mp_inherit...> > >; }; } // namespace detail template using mp_set_contains = typename detail::mp_set_contains_impl::type; // mp_set_push_back namespace detail { template struct mp_set_push_back_impl; template class L, class... U> struct mp_set_push_back_impl> { using type = L; }; template class L, class... U, class T1, class... T> struct mp_set_push_back_impl, T1, T...> { using S = mp_if, T1>, L, L>; using type = typename mp_set_push_back_impl::type; }; } // namespace detail template using mp_set_push_back = typename detail::mp_set_push_back_impl::type; // mp_unique namespace detail { template struct mp_unique_impl; template class L, class... T> struct mp_unique_impl> { using type = mp_set_push_back, T...>; }; } // namespace detail template using mp_unique = typename detail::mp_unique_impl::type; // mp_append namespace detail { template struct mp_append_impl; template<> struct mp_append_impl<> { using type = mp_list<>; }; template class L, class... T> struct mp_append_impl> { using type = L; }; template class L1, class... T1, template class L2, class... T2, class... Lr> struct mp_append_impl, L2, Lr...> { using type = typename mp_append_impl, Lr...>::type; }; } template using mp_append = typename detail::mp_append_impl::type; // mp_front namespace detail { template struct mp_front_impl { // An error "no type named 'type'" here means that the argument to mp_front // is either not a list, or is an empty list }; template class L, class T1, class... T> struct mp_front_impl> { using type = T1; }; } // namespace detail template using mp_front = typename detail::mp_front_impl::type; // mp_pop_front namespace detail { template struct mp_pop_front_impl { // An error "no type named 'type'" here means that the argument to mp_pop_front // is either not a list, or is an empty list }; template class L, class T1, class... T> struct mp_pop_front_impl> { using type = L; }; } // namespace detail template using mp_pop_front = typename detail::mp_pop_front_impl::type; // mp_first template using mp_first = mp_front; // mp_rest template using mp_rest = mp_pop_front; // mp_remove_if namespace detail { template class P> struct mp_remove_if_impl; template class L, class... T, template class P> struct mp_remove_if_impl, P> { template using _f = mp_if, mp_list<>, mp_list>; using type = mp_append, _f...>; }; } // namespace detail template class P> using mp_remove_if = typename detail::mp_remove_if_impl::type; // integer_sequence template struct integer_sequence { }; // detail::make_integer_sequence_impl namespace detail { // iseq_if_c template struct iseq_if_c_impl; template struct iseq_if_c_impl { using type = T; }; template struct iseq_if_c_impl { using type = E; }; template using iseq_if_c = typename iseq_if_c_impl::type; // iseq_identity template struct iseq_identity { using type = T; }; template struct append_integer_sequence; template struct append_integer_sequence, integer_sequence> { using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >; }; template struct make_integer_sequence_impl; template struct make_integer_sequence_impl_ { private: static_assert( N >= 0, "make_integer_sequence: N must not be negative" ); static T const M = N / 2; static T const R = N % 2; using S1 = typename make_integer_sequence_impl::type; using S2 = typename append_integer_sequence::type; using S3 = typename make_integer_sequence_impl::type; using S4 = typename append_integer_sequence::type; public: using type = S4; }; template struct make_integer_sequence_impl: iseq_if_c>, iseq_if_c>, make_integer_sequence_impl_ > > { }; } // namespace detail // make_integer_sequence template using make_integer_sequence = typename detail::make_integer_sequence_impl::type; // index_sequence template using index_sequence = integer_sequence; // make_index_sequence template using make_index_sequence = make_integer_sequence; // index_sequence_for template using index_sequence_for = make_integer_sequence; // implementation by Bruno Dutra (by the name is_evaluable) namespace detail { template class F, class... T> struct mp_valid_impl { template class G, class = G> static mp_true check(int); template class> static mp_false check(...); using type = decltype(check(0)); }; } // namespace detail template class F, class... T> using mp_valid = typename detail::mp_valid_impl::type; } } } #endif // BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED // <<< #include // #line 9 "boost/leaf/detail/function_traits.hpp" #include namespace boost { namespace leaf { namespace detail { template struct remove_noexcept { using type = T; }; template struct remove_noexcept { using type = R(*)(A...); }; template struct remove_noexcept { using type = R(C::*)(A...); }; template struct remove_noexcept { using type = R(C::*)(A...) const; }; template struct gcc49_workaround //Thanks Glen Fernandes { using type = void; }; template using void_t = typename gcc49_workaround::type; template struct function_traits_impl { constexpr static int arity = -1; }; template struct function_traits_impl> { private: using tr = function_traits_impl::type>; public: using return_type = typename tr::return_type; static constexpr int arity = tr::arity - 1; using mp_args = typename leaf_detail_mp11::mp_rest; template struct arg: tr::template arg { }; }; template struct function_traits_impl { using return_type = R; static constexpr int arity = sizeof...(A); using mp_args = leaf_detail_mp11::mp_list; template struct arg { static_assert(I < arity, "I out of range"); using type = typename std::tuple_element>::type; }; }; template struct function_traits_impl : function_traits_impl { }; template struct function_traits_impl : function_traits_impl { }; template struct function_traits_impl : function_traits_impl { }; template struct function_traits_impl : function_traits_impl { }; template struct function_traits_impl : function_traits_impl { }; template struct function_traits_impl : function_traits_impl { }; template struct function_traits_impl : function_traits_impl { }; template struct function_traits_impl : function_traits_impl { }; template struct function_traits: function_traits_impl::type> { }; template using fn_return_type = typename function_traits::return_type; template using fn_arg_type = typename function_traits::template arg::type; template using fn_mp_args = typename function_traits::mp_args; } } } #endif // BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED // <<< #include // #line 11 "boost/leaf/error.hpp" // >>> #include #ifndef BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED #define BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED // #line 8 "boost/leaf/detail/capture_list.hpp" // #include // Expanded at line 14 // >>> #include #ifndef BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED #define BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED // #line 8 "boost/leaf/detail/print.hpp" // #include // Expanded at line 14 // #include // Expanded at line 616 #include #include #include #include namespace boost { namespace leaf { template struct show_in_diagnostics: std::true_type { }; namespace detail { template struct is_printable: std::false_type { }; template struct is_printable()<(), void())>: show_in_diagnostics { }; //////////////////////////////////////// template struct has_printable_member_value: std::false_type { }; template struct has_printable_member_value()<().value, void())>: show_in_diagnostics { }; //////////////////////////////////////// template void print_name(std::basic_ostream & os, char const * & prefix, char const * delimiter) { static_assert(show_in_diagnostics::value, "show_in_diagnostics violation"); BOOST_LEAF_ASSERT(delimiter); char const * p = prefix; prefix = nullptr; os << (p ? p : delimiter) << parse(); } template bool print_impl(std::basic_ostream & os, char const * & prefix, char const * delimiter, char const * mid, PrintableInfo const & x) { print_name(os, prefix, delimiter); if( mid ) os << mid << x; return true; } template bool print_impl(std::basic_ostream & os, char const * & prefix, char const * delimiter, char const * mid, PrintableInfo const * x) { print_name(os, prefix, delimiter); if( mid ) { os << mid; if( x ) os << x; else os << ""; } return true; } //////////////////////////////////////// template < class Wrapper, bool ShowInDiagnostics = show_in_diagnostics::value, bool WrapperPrintable = is_printable::value, bool ValuePrintable = has_printable_member_value::value, bool IsException = std::is_base_of::value, bool IsEnum = std::is_enum::value> struct diagnostic; template struct diagnostic { template static bool print(std::basic_ostream &, char const * &, char const *, Wrapper const & x) noexcept { return false; } }; template struct diagnostic { template static bool print(std::basic_ostream & os, char const * & prefix, char const * delimiter, Wrapper const & x) { return print_impl(os, prefix, delimiter, ": ", x); } }; template struct diagnostic { template static bool print(std::basic_ostream & os, char const * & prefix, char const * delimiter, Wrapper const & x) { return print_impl(os, prefix, delimiter, ": ", x.value); } }; template struct diagnostic { template static bool print(std::basic_ostream & os, char const * & prefix, char const * delimiter, Exception const & ex) { if( print_impl(os, prefix, delimiter, ": \"", static_cast(ex).what()) ) { os << '"'; return true; } return false; } }; template struct diagnostic { template static bool print(std::basic_ostream & os, char const * & prefix, char const * delimiter, Wrapper const &) { return print_impl(os, prefix, delimiter, nullptr, 0); } }; template struct diagnostic { template static bool print(std::basic_ostream & os, char const * & prefix, char const * delimiter, Enum const & enum_) { return print_impl(os, prefix, delimiter, ": ", static_cast::type>(enum_)); } }; } } } #endif // BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED // <<< #include // #line 10 "boost/leaf/detail/capture_list.hpp" #if BOOST_LEAF_CFG_CAPTURE #include namespace boost { namespace leaf { class error_id; namespace detail { struct BOOST_LEAF_SYMBOL_VISIBLE tls_tag_id_factory_current_id; class capture_list { capture_list( capture_list const & ) = delete; capture_list & operator=( capture_list const & ) = delete; protected: class node { friend class capture_list; virtual void unload( int err_id ) = 0; #if BOOST_LEAF_CFG_DIAGNOSTICS virtual void print(std::ostream &, error_id const & to_print, char const * & prefix) const = 0; #endif protected: virtual ~node() noexcept { }; node * next_; BOOST_LEAF_CONSTEXPR explicit node( node * * & last ) noexcept: next_(nullptr) { BOOST_LEAF_ASSERT(last != nullptr); *last = this; last = &next_; } } * first_; template BOOST_LEAF_CONSTEXPR void for_each( F f ) const { for( node * p=first_; p; p=p->next_ ) f(*p); } public: BOOST_LEAF_CONSTEXPR explicit capture_list( node * first ) noexcept: first_(first) { } BOOST_LEAF_CONSTEXPR capture_list( capture_list && other ) noexcept: first_(other.first_) { other.first_ = nullptr; } ~capture_list() noexcept { for( node const * p = first_; p; ) { node const * n = p -> next_; delete p; p = n; } } void unload( int const err_id ) { capture_list moved(first_); first_ = nullptr; tls::write_uint(unsigned(err_id)); moved.for_each( [err_id]( node & n ) { n.unload(err_id); // last node may throw } ); } template void print(std::basic_ostream & os, error_id const & to_print, char const * & prefix) const { #if BOOST_LEAF_CFG_DIAGNOSTICS if( first_ ) { for_each( [&os, &to_print, &prefix]( node const & n ) { n.print(os, to_print, prefix); } ); } #else (void) os; (void) prefix; (void) to_print; #endif } }; } } } #endif #endif // BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED // <<< #include // #line 12 "boost/leaf/error.hpp" #if BOOST_LEAF_CFG_DIAGNOSTICS # include #endif #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR # include #endif #define BOOST_LEAF_TOKEN_PASTE(x, y) x ## y #define BOOST_LEAF_TOKEN_PASTE2(x, y) BOOST_LEAF_TOKEN_PASTE(x, y) #define BOOST_LEAF_TMP BOOST_LEAF_TOKEN_PASTE2(boost_leaf_tmp_, __LINE__) #define BOOST_LEAF_ASSIGN(v,r)\ auto && BOOST_LEAF_TMP = r;\ static_assert(::boost::leaf::is_result_type::type>::value,\ "BOOST_LEAF_ASSIGN/BOOST_LEAF_AUTO requires a result object as the second argument (see is_result_type)");\ if( !BOOST_LEAF_TMP )\ return BOOST_LEAF_TMP.error();\ v = std::forward(BOOST_LEAF_TMP).value() #define BOOST_LEAF_AUTO(v, r)\ BOOST_LEAF_ASSIGN(auto v, r) #if BOOST_LEAF_CFG_GNUC_STMTEXPR #define BOOST_LEAF_CHECK(r)\ ({\ auto && BOOST_LEAF_TMP = (r);\ static_assert(::boost::leaf::is_result_type::type>::value,\ "BOOST_LEAF_CHECK requires a result object (see is_result_type)");\ if( !BOOST_LEAF_TMP )\ return BOOST_LEAF_TMP.error();\ std::move(BOOST_LEAF_TMP);\ }).value() #else #define BOOST_LEAF_CHECK(r)\ {\ auto && BOOST_LEAF_TMP = (r);\ static_assert(::boost::leaf::is_result_type::type>::value,\ "BOOST_LEAF_CHECK requires a result object (see is_result_type)");\ if( !BOOST_LEAF_TMP )\ return BOOST_LEAF_TMP.error();\ } #endif #define BOOST_LEAF_NEW_ERROR ::boost::leaf::detail::inject_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::new_error namespace boost { namespace leaf { struct BOOST_LEAF_SYMBOL_VISIBLE e_source_location { char const * file; int line; char const * function; template friend std::ostream & operator<<(std::basic_ostream & os, e_source_location const & x) { return os << x.file << '(' << x.line << ") in function " << x.function; } }; template <> struct show_in_diagnostics: std::false_type { }; //////////////////////////////////////// class BOOST_LEAF_SYMBOL_VISIBLE error_id; namespace detail { class BOOST_LEAF_SYMBOL_VISIBLE exception_base { public: virtual error_id get_error_id() const noexcept = 0; #if BOOST_LEAF_CFG_DIAGNOSTICS && !defined(BOOST_LEAF_NO_EXCEPTIONS) virtual void print_type_name(std::ostream &) const = 0; #endif protected: exception_base() noexcept { } ~exception_base() noexcept { } }; } //////////////////////////////////////// namespace detail { template class BOOST_LEAF_SYMBOL_VISIBLE slot: optional { slot( slot const & ) = delete; slot & operator=( slot const & ) = delete; using impl = optional; slot * prev_; public: BOOST_LEAF_CONSTEXPR slot() noexcept: prev_(nullptr) { } BOOST_LEAF_CONSTEXPR slot( slot && x ) noexcept: optional(std::move(x)), prev_(nullptr) { BOOST_LEAF_ASSERT(x.prev_ == nullptr); } ~slot() noexcept { BOOST_LEAF_ASSERT(tls::read_ptr>() != this); } void activate() noexcept { prev_ = tls::read_ptr>(); tls::write_ptr>(this); } void deactivate() const noexcept { tls::write_ptr>(prev_); } void unload( int err_id ) noexcept(!BOOST_LEAF_CFG_CAPTURE); template void print(std::basic_ostream & os, ErrorID to_print, char const * & prefix) const { if( int k = this->key() ) { if( to_print && to_print.value() != k ) return; if( diagnostic::print(os, prefix, BOOST_LEAF_CFG_DIAGNOSTICS_DELIMITER, value(k)) && !to_print ) os << '(' << k/4 << ')'; } } using impl::load; using impl::has_value; using impl::has_value_any_key; using impl::value; using impl::value_or_default; }; } //////////////////////////////////////// #if BOOST_LEAF_CFG_CAPTURE namespace detail { class BOOST_LEAF_SYMBOL_VISIBLE dynamic_allocator: capture_list { dynamic_allocator( dynamic_allocator const & ) = delete; dynamic_allocator & operator=( dynamic_allocator const & ) = delete; class capturing_node: public capture_list::node { protected: BOOST_LEAF_CONSTEXPR explicit capturing_node( capture_list::node * * & last ) noexcept: node(last) { BOOST_LEAF_ASSERT(last == &next_); BOOST_LEAF_ASSERT(next_ == nullptr); } public: virtual void deactivate() const noexcept = 0; }; template class capturing_slot_node: public capturing_node, public slot { using impl = slot; capturing_slot_node( capturing_slot_node const & ) = delete; capturing_slot_node & operator=( capturing_slot_node const & ) = delete; void deactivate() const noexcept final override { impl::deactivate(); } void unload( int err_id ) final override { impl::unload(err_id); } #if BOOST_LEAF_CFG_DIAGNOSTICS void print(std::ostream & os, error_id const & to_print, char const * & prefix) const final override { impl::print(os, to_print, prefix); } #endif public: template BOOST_LEAF_CONSTEXPR capturing_slot_node( capture_list::node * * & last, int err_id, T && e ): capturing_node(last) { BOOST_LEAF_ASSERT(last == &next_); BOOST_LEAF_ASSERT(next_ == nullptr); impl::load(err_id, std::forward(e)); } }; #ifndef BOOST_LEAF_NO_EXCEPTIONS class capturing_exception_node: public capturing_node { capturing_exception_node( capturing_exception_node const & ) = delete; capturing_exception_node & operator=( capturing_exception_node const & ) = delete; void deactivate() const noexcept final override { BOOST_LEAF_ASSERT(0); } void unload( int ) final override { std::rethrow_exception(ex_); } #if BOOST_LEAF_CFG_DIAGNOSTICS void print(std::ostream &, error_id const &, char const * &) const final override { } #endif std::exception_ptr const ex_; public: capturing_exception_node( capture_list::node * * & last, std::exception_ptr && ex ) noexcept: capturing_node(last), ex_(std::move(ex)) { BOOST_LEAF_ASSERT(last == &next_); BOOST_LEAF_ASSERT(ex_); } }; #endif node * * last_; public: dynamic_allocator() noexcept: capture_list(nullptr), last_(&first_) { BOOST_LEAF_ASSERT(first_ == nullptr); } dynamic_allocator( dynamic_allocator && other ) noexcept: capture_list(std::move(other)), last_(other.last_ == &other.first_? &first_ : other.last_) { BOOST_LEAF_ASSERT(last_ != nullptr); BOOST_LEAF_ASSERT(*last_ == nullptr); BOOST_LEAF_ASSERT(other.first_ == nullptr); other.last_ = &other.first_; } template typename std::decay::type & dynamic_load(int err_id, E && e) { using T = typename std::decay::type; BOOST_LEAF_ASSERT(last_ != nullptr); BOOST_LEAF_ASSERT(*last_ == nullptr); BOOST_LEAF_ASSERT(tls::read_ptr>() == nullptr); capturing_slot_node * csn = new capturing_slot_node(last_, err_id, std::forward(e)); csn->activate(); return csn->value(err_id); } void deactivate() const noexcept { for_each( []( capture_list::node const & n ) { static_cast(n).deactivate(); } ); } template LeafResult extract_capture_list(int err_id) { #ifndef BOOST_LEAF_NO_EXCEPTIONS if( std::exception_ptr ex = std::current_exception() ) (void) new capturing_exception_node(last_, std::move(ex)); #endif detail::capture_list::node * const f = first_; first_ = nullptr; last_ = &first_; return { err_id, capture_list(f) }; } using capture_list::unload; using capture_list::print; }; template <> inline void slot::deactivate() const noexcept { if( dynamic_allocator const * c = this->has_value_any_key() ) c->deactivate(); tls::write_ptr>(prev_); } template <> inline void slot::unload( int err_id ) noexcept(false) { BOOST_LEAF_ASSERT(err_id); if( dynamic_allocator * da1 = this->has_value_any_key() ) da1->unload(err_id); } template inline void dynamic_load_( int err_id, E && e ) { if( slot * sl = tls::read_ptr>() ) { if( dynamic_allocator * c = sl->has_value_any_key() ) c->dynamic_load(err_id, std::forward(e)); else sl->load(err_id).dynamic_load(err_id, std::forward(e)); } } template inline void dynamic_accumulate_( int err_id, F && f ) { if( slot * sl = tls::read_ptr>() ) { if( dynamic_allocator * c = sl->has_value(err_id) ) (void) std::forward(f)(c->dynamic_load(err_id, E{})); else (void) std::forward(f)(sl->load(err_id).dynamic_load(err_id, E{})); } } template inline void dynamic_load( int err_id, E && e ) noexcept(OnError) { if( OnError ) { #ifndef BOOST_LEAF_NO_EXCEPTIONS try { #endif dynamic_load_(err_id, std::forward(e)); #ifndef BOOST_LEAF_NO_EXCEPTIONS } catch(...) { } #endif } else dynamic_load_(err_id, std::forward(e)); } template inline void dynamic_load_accumulate( int err_id, F && f ) noexcept(OnError) { if( OnError ) { #ifndef BOOST_LEAF_NO_EXCEPTIONS try { #endif dynamic_accumulate_(err_id, std::forward(f)); #ifndef BOOST_LEAF_NO_EXCEPTIONS } catch(...) { } #endif } else dynamic_accumulate_(err_id, std::forward(f)); } } template <> struct show_in_diagnostics: std::false_type { }; #endif //////////////////////////////////////// namespace detail { template inline void slot::unload( int err_id ) noexcept(!BOOST_LEAF_CFG_CAPTURE) { BOOST_LEAF_ASSERT(err_id); if( this->key() != err_id ) return; if( impl * p = tls::read_ptr>() ) { if( !p->has_value(err_id) ) *p = std::move(*this); } #if BOOST_LEAF_CFG_CAPTURE else dynamic_load(err_id, std::move(*this).value(err_id)); #endif } template BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept(OnError) { using T = typename std::decay::type; static_assert(!std::is_pointer::value, "Error objects of pointer types are not allowed"); static_assert(!std::is_same::value, "Error objects of type error_id are not allowed"); BOOST_LEAF_ASSERT((err_id&3) == 1); if( slot * p = tls::read_ptr>() ) { if( !OnError || !p->has_value(err_id) ) (void) p->load(err_id, std::forward(e)); } #if BOOST_LEAF_CFG_CAPTURE else dynamic_load(err_id, std::forward(e)); #endif return 0; } template BOOST_LEAF_CONSTEXPR inline int load_slot_deferred( int err_id, F && f ) noexcept(OnError) { using E = typename function_traits::return_type; using T = typename std::decay::type; static_assert(!std::is_pointer::value, "Error objects of pointer types are not allowed"); static_assert(!std::is_same::value, "Error objects of type error_id are not allowed"); BOOST_LEAF_ASSERT((err_id&3) == 1); if( slot * p = tls::read_ptr>() ) { if( !OnError || !p->has_value(err_id) ) (void) p->load(err_id, std::forward(f)()); } #if BOOST_LEAF_CFG_CAPTURE else dynamic_load(err_id, std::forward(f)()); #endif return 0; } template BOOST_LEAF_CONSTEXPR inline int load_slot_accumulate( int err_id, F && f ) noexcept(OnError) { static_assert(function_traits::arity == 1, "Lambdas passed to accumulate must take a single e-type argument by reference"); using E = typename std::decay>::type; static_assert(!std::is_pointer::value, "Error objects of pointer types are not allowed"); BOOST_LEAF_ASSERT((err_id&3) == 1); if( auto sl = tls::read_ptr>() ) { if( auto v = sl->has_value(err_id) ) (void) std::forward(f)(*v); else (void) std::forward(f)(sl->load(err_id,E())); } #if BOOST_LEAF_CFG_CAPTURE else dynamic_load_accumulate(err_id, std::forward(f)); #endif return 0; } } //////////////////////////////////////// namespace detail { template ::arity> struct load_item { static_assert(Arity == 0 || Arity == 1, "If a functions is passed to new_error or load, it must take zero or one argument"); }; template struct load_item { BOOST_LEAF_CONSTEXPR static int load_( int err_id, E && e ) noexcept { return load_slot(err_id, std::forward(e)); } }; template struct load_item { BOOST_LEAF_CONSTEXPR static int load_( int err_id, F && f ) noexcept { return load_slot_deferred(err_id, std::forward(f)); } }; template struct load_item { BOOST_LEAF_CONSTEXPR static int load_( int err_id, F && f ) noexcept { return load_slot_accumulate(err_id, std::forward(f)); } }; } //////////////////////////////////////// namespace detail { struct BOOST_LEAF_SYMBOL_VISIBLE tls_tag_id_factory_current_id; template struct BOOST_LEAF_SYMBOL_VISIBLE id_factory { static atomic_unsigned_int counter; BOOST_LEAF_CONSTEXPR static unsigned generate_next_id() noexcept { auto id = (counter+=4); BOOST_LEAF_ASSERT((id&3) == 1); return id; } }; template atomic_unsigned_int id_factory::counter(1); inline int current_id() noexcept { unsigned id = tls::read_uint(); BOOST_LEAF_ASSERT(id == 0 || (id&3) == 1); return int(id); } inline int new_id() noexcept { unsigned id = id_factory<>::generate_next_id(); tls::write_uint(id); return int(id); } struct inject_loc { char const * file; int line; char const * fn; template friend T operator+( inject_loc loc, T && x ) noexcept { x.load_source_location_(loc.file, loc.line, loc.fn); return std::move(x); } }; } #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR namespace detail { class leaf_error_category final: public std::error_category { bool equivalent( int, std::error_condition const & ) const noexcept final override { return false; } bool equivalent( std::error_code const &, int ) const noexcept final override { return false; } char const * name() const noexcept final override { return "LEAF error"; } std::string message( int ) const final override { return name(); } public: ~leaf_error_category() noexcept final override { } }; template struct get_leaf_error_category { static leaf_error_category cat; }; template leaf_error_category get_leaf_error_category::cat; inline int import_error_code( std::error_code const & ec ) noexcept { if( int err_id = ec.value() ) { std::error_category const & cat = get_leaf_error_category<>::cat; if( &ec.category() == &cat ) { BOOST_LEAF_ASSERT((err_id&3) == 1); return (err_id&~3)|1; } else { err_id = new_id(); (void) load_slot(err_id, ec); return (err_id&~3)|1; } } else return 0; } } inline bool is_error_id( std::error_code const & ec ) noexcept { bool res = (&ec.category() == &detail::get_leaf_error_category<>::cat); BOOST_LEAF_ASSERT(!res || !ec.value() || ((ec.value()&3) == 1)); return res; } #endif //////////////////////////////////////// namespace detail { BOOST_LEAF_CONSTEXPR error_id make_error_id(int) noexcept; } class BOOST_LEAF_SYMBOL_VISIBLE error_id { friend error_id BOOST_LEAF_CONSTEXPR detail::make_error_id(int) noexcept; int value_; BOOST_LEAF_CONSTEXPR explicit error_id( int value ) noexcept: value_(value) { BOOST_LEAF_ASSERT(value_ == 0 || ((value_&3) == 1)); } public: BOOST_LEAF_CONSTEXPR error_id() noexcept: value_(0) { } #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR explicit error_id( std::error_code const & ec ) noexcept: value_(detail::import_error_code(std::error_code(ec))) { BOOST_LEAF_ASSERT(!value_ || ((value_&3) == 1)); } template error_id( Enum e, typename std::enable_if::value, int>::type = 0 ) noexcept: value_(detail::import_error_code(e)) { } template ::value, int>::type = 0> operator T() const noexcept { return std::error_code(value_, detail::get_leaf_error_category<>::cat); } #endif BOOST_LEAF_CONSTEXPR error_id load() const noexcept { return *this; } template BOOST_LEAF_CONSTEXPR error_id load(Item && item) const noexcept { if (int err_id = value()) { int const unused[] = { 42, detail::load_item::load_(err_id, std::forward(item)) }; (void)unused; } return *this; } template BOOST_LEAF_CONSTEXPR error_id load( Item && ... item ) const noexcept { if( int err_id = value() ) { int const unused[] = { 42, detail::load_item::load_(err_id, std::forward(item))... }; (void) unused; } return *this; } BOOST_LEAF_CONSTEXPR int value() const noexcept { BOOST_LEAF_ASSERT(value_ == 0 || ((value_&3) == 1)); return value_; } BOOST_LEAF_CONSTEXPR explicit operator bool() const noexcept { return value_ != 0; } BOOST_LEAF_CONSTEXPR friend bool operator==( error_id a, error_id b ) noexcept { return a.value_ == b.value_; } BOOST_LEAF_CONSTEXPR friend bool operator!=( error_id a, error_id b ) noexcept { return !(a == b); } BOOST_LEAF_CONSTEXPR friend bool operator<( error_id a, error_id b ) noexcept { return a.value_ < b.value_; } template friend std::ostream & operator<<( std::basic_ostream & os, error_id x ) { return os << (x.value_ / 4); } BOOST_LEAF_CONSTEXPR void load_source_location_( char const * file, int line, char const * function ) const noexcept { BOOST_LEAF_ASSERT(file&&*file); BOOST_LEAF_ASSERT(line>0); BOOST_LEAF_ASSERT(function&&*function); BOOST_LEAF_ASSERT(value_); (void) load(e_source_location {file,line,function}); } }; namespace detail { BOOST_LEAF_CONSTEXPR inline error_id make_error_id( int err_id ) noexcept { BOOST_LEAF_ASSERT(err_id == 0 || (err_id&3) == 1); return error_id((err_id&~3)|1); } } inline error_id new_error() noexcept { return detail::make_error_id(detail::new_id()); } template inline error_id new_error( Item && ... item ) noexcept { return detail::make_error_id(detail::new_id()).load(std::forward(item)...); } inline error_id current_error() noexcept { return detail::make_error_id(detail::current_id()); } //////////////////////////////////////// template struct is_result_type: std::false_type { }; template struct is_result_type: is_result_type { }; } } #endif // BOOST_LEAF_ERROR_HPP_INCLUDED // <<< #include // #line 10 "boost/leaf/context.hpp" #if !defined(BOOST_LEAF_NO_THREADS) && !defined(NDEBUG) # include #endif namespace boost { namespace leaf { class error_info; class diagnostic_info; class diagnostic_details; template struct is_predicate: std::false_type { }; namespace detail { template struct is_exception: std::is_base_of::type> { }; template struct handler_argument_traits; template ::value> struct handler_argument_traits_defaults; template struct handler_argument_traits_defaults { using error_type = typename std::decay::type; using context_types = leaf_detail_mp11::mp_list; constexpr static bool always_available = false; template BOOST_LEAF_CONSTEXPR static error_type const * check( Tup const &, error_info const & ) noexcept; template BOOST_LEAF_CONSTEXPR static error_type * check( Tup &, error_info const & ) noexcept; template BOOST_LEAF_CONSTEXPR static E get( Tup & tup, error_info const & ei ) noexcept { return *check(tup, ei); } static_assert(!is_predicate::value, "Handlers must take predicate arguments by value"); static_assert(!std::is_same::value, "Handlers must take leaf::error_info arguments by const &"); static_assert(!std::is_same::value, "Handlers must take leaf::diagnostic_info arguments by const &"); static_assert(!std::is_same::value, "Handlers must take leaf::diagnostic_details arguments by const &"); }; template struct handler_argument_traits_defaults: handler_argument_traits { using base = handler_argument_traits; static_assert(!base::always_available, "Predicates can't use types that are always_available"); template BOOST_LEAF_CONSTEXPR static bool check( Tup const & tup, error_info const & ei ) noexcept { auto e = base::check(tup, ei); return e && Pred::evaluate(*e); } template BOOST_LEAF_CONSTEXPR static Pred get( Tup const & tup, error_info const & ei ) noexcept { return Pred{*base::check(tup, ei)}; } }; template struct handler_argument_always_available { using context_types = leaf_detail_mp11::mp_list; constexpr static bool always_available = true; template BOOST_LEAF_CONSTEXPR static bool check( Tup &, error_info const & ) noexcept { return true; } }; template struct handler_argument_traits: handler_argument_traits_defaults { }; template <> struct handler_argument_traits { using context_types = leaf_detail_mp11::mp_list<>; constexpr static bool always_available = false; template BOOST_LEAF_CONSTEXPR static std::exception const * check( Tup const &, error_info const & ) noexcept; }; template struct handler_argument_traits { static_assert(sizeof(E) == 0, "Error handlers may not take rvalue ref arguments"); }; template struct handler_argument_traits: handler_argument_always_available::type> { template BOOST_LEAF_CONSTEXPR static E * get( Tup & tup, error_info const & ei) noexcept { return handler_argument_traits_defaults::check(tup, ei); } }; template struct handler_argument_traits_require_by_value { static_assert(sizeof(E) == 0, "Error handlers must take this type by value"); }; } //////////////////////////////////////// namespace detail { template struct get_dispatch { static BOOST_LEAF_CONSTEXPR T const * get(T const * x) noexcept { return x; } static BOOST_LEAF_CONSTEXPR T const * get(void const *) noexcept { return nullptr; } }; template BOOST_LEAF_CONSTEXPR inline T * find_in_tuple(std::tuple<> const &) { return nullptr; } template BOOST_LEAF_CONSTEXPR inline typename std::enable_if::type const * find_in_tuple(std::tuple const & t) noexcept { return get_dispatch::get(&std::get(t)); } template BOOST_LEAF_CONSTEXPR inline typename std::enable_if::type const * find_in_tuple(std::tuple const & t) noexcept { if( T const * x = get_dispatch::get(&std::get(t)) ) return x; else return find_in_tuple(t); } } //////////////////////////////////////// namespace detail { template struct tuple_for_each { BOOST_LEAF_CONSTEXPR static void activate( Tup & tup ) noexcept { static_assert(!std::is_same(tup))>::type>::value, "Bug in LEAF: context type deduction"); tuple_for_each::activate(tup); std::get(tup).activate(); } BOOST_LEAF_CONSTEXPR static void deactivate( Tup & tup ) noexcept { static_assert(!std::is_same(tup))>::type>::value, "Bug in LEAF: context type deduction"); std::get(tup).deactivate(); tuple_for_each::deactivate(tup); } BOOST_LEAF_CONSTEXPR static void unload( Tup & tup, int err_id ) noexcept { static_assert(!std::is_same(tup))>::type>::value, "Bug in LEAF: context type deduction"); BOOST_LEAF_ASSERT(err_id != 0); auto & sl = std::get(tup); sl.unload(err_id); tuple_for_each::unload(tup, err_id); } template static void print(std::basic_ostream & os, void const * tup, error_id to_print, char const * & prefix) { BOOST_LEAF_ASSERT(tup != nullptr); tuple_for_each::print(os, tup, to_print, prefix); std::get(*static_cast(tup)).print(os, to_print, prefix); } }; template struct tuple_for_each<0, Tup> { BOOST_LEAF_CONSTEXPR static void activate( Tup & ) noexcept { } BOOST_LEAF_CONSTEXPR static void deactivate( Tup & ) noexcept { } BOOST_LEAF_CONSTEXPR static void unload( Tup &, int ) noexcept { } template BOOST_LEAF_CONSTEXPR static void print(std::basic_ostream &, void const *, error_id, char const * &) { } }; template BOOST_LEAF_CONSTEXPR void print_tuple_contents(std::basic_ostream & os, void const * tup, error_id to_print, char const * & prefix) { tuple_for_each::value, Tup>::print(os, tup, to_print, prefix); } } //////////////////////////////////////// namespace detail { template struct does_not_participate_in_context_deduction: std::is_abstract { }; template <> struct does_not_participate_in_context_deduction: std::true_type { }; template struct deduce_e_type_list; template class L, class... T> struct deduce_e_type_list> { using type = leaf_detail_mp11::mp_remove_if< leaf_detail_mp11::mp_unique< leaf_detail_mp11::mp_append::context_types...> >, does_not_participate_in_context_deduction >; }; template struct deduce_e_tuple_impl; template