. This is becaus
namespace boost { namespace leaf {
- class diagnostic_details: public error_info
+ class diagnostic_details: public diagnostic_info
{
//Constructors unspecified
+ public:
+
+ template <class Writer>
+ void write_to( Writer & w ) const;
+
template <class CharT, class Traits>
friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> &, diagnostic_details const & );
};
@@ -5070,6 +5574,9 @@ The caller is required to specify the return type R. This is becaus
The additional information includes the types and the values of all such error objects (but see show_in_diagnostics).
+
+
The write_to member function is used with the serialization system; see Serialization.
+
@@ -5119,6 +5626,11 @@ Using diagnostic_details may allocate memory dynamically, but only
{
//Constructors unspecified
+ public:
+
+ template <class Writer>
+ void write_to( Writer & w ) const;
+
template <class CharT, class Traits>
friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> &, diagnostic_info const & );
};
@@ -5135,6 +5647,9 @@ Using diagnostic_details may allocate memory dynamically, but only
The additional information is limited to the type name of the first such error object, as well as their total count.
+
+
The write_to member function is used with the serialization system; see Serialization.
+
@@ -5797,6 +6312,9 @@ It is probably better to define your own file name wrappers to avoid clashes if
bool exception_caught() const noexcept;
std::exception const * exception() const noexcept;
+ template <class Writer>
+ void write_to( Writer & w ) const;
+
template <class CharT, class Traits>
friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> &, error_info const & );
};
@@ -5831,6 +6349,44 @@ It is illegal to call the exception member function unless ex
The operator<< overload prints diagnostic information about each error object currently stored in the context local to the try_handle_some, try_handle_all or try_catch scope that invoked the handler, but only if it is associated with the error_id returned by error().
+
+
The write_to member function is used with the serialization system; see Serialization.
+
+
+
+
+
json_writer
+
+
#include <boost/leaf/serialization/json_writer.hpp>
+
+
namespace boost { namespace leaf {
+
+namespace serialization
+{
+ template <class Json>
+ class json_writer: public writer
+ {
+ public:
+
+ explicit json_writer( Json & ) noexcept;
+
+ template <class E>
+ void write( E const & );
+ };
+}
+
+} }
+
+
+
+
The json_writer class template is used to serialize error objects to a JSON object. The Json template parameter is the type of the JSON object, for example nlohmann/json.
+
+
+
The constructor takes a reference to a JSON object, which will be populated with serialized error data.
+
+
+
The write member function serializes an error object by calling to_json(json, e), found via ADL; see Serialization.
+
@@ -5903,6 +6459,9 @@ It is illegal to call the exception member function unless ex
void unload();
+ template <class Writer>
+ void write_to( Writer & w ) const;
+
template <class CharT, class Traits>
friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> &, result const & );
};
@@ -5949,6 +6508,9 @@ It is illegal to call the exception member function unless ex
void unload();
+ template <class Writer>
+ void write_to( Writer & w ) const;
+
template <class CharT, class Traits>
friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> &, result const &);
};
@@ -5964,7 +6526,7 @@ It is illegal to call the exception member function unless ex
The result<T> type can be returned by functions which produce a value of type T but may fail doing so.
@@ -6211,6 +6773,52 @@ The returned proxy object refers to
*this; avoid holding on to it.
+
has_error
+
+
#include <boost/leaf/result.hpp>
+
+
namespace boost { namespace leaf {
+
+ template <class T>
+ bool result<T>::has_error() const noexcept;
+
+} }
+
+
+
+
+- Returns:
+-
+
If *this is in value state, returns false, otherwise returns true.
+
+
+
+
+
+
+
has_value
+
+
#include <boost/leaf/result.hpp>
+
+
namespace boost { namespace leaf {
+
+ template <class T>
+ bool result<T>::has_value() const noexcept;
+
+} }
+
+
+
+
+- Returns:
+-
+
If *this is in value state, returns true, otherwise returns false.
+
+
+
+
+
+
load
#include <boost/leaf/result.hpp>
@@ -6242,6 +6850,59 @@ The returned proxy object refers to
*this; avoid holding on to it.
+
operator bool
+
+
#include <boost/leaf/result.hpp>
+
+
namespace boost { namespace leaf {
+
+ template <class T>
+ result<T>::operator bool() const noexcept;
+
+} }
+
+
+
+
+- Returns:
+-
+
If *this is in value state, returns true, otherwise returns false.
+
+
+
+
+
+
+
operator*
+
+
#include <boost/leaf/result.hpp>
+
+
namespace boost { namespace leaf {
+
+ template <class T>
+ T const & result<T>::operator*() const noexcept;
+
+ template <class T>
+ T & result<T>::operator*() noexcept;
+
+} }
+
+
+
+
+- Requires:
+-
+
*this must be in value state.
+
+- Returns
+-
+
a reference to the stored value.
+
+
+
+
+
+
operator=
#include <boost/leaf/result.hpp>
@@ -6269,69 +6930,26 @@ The returned proxy object refers to
*this; avoid holding on to it.
-
has_value
+
operator->
#include <boost/leaf/result.hpp>
namespace boost { namespace leaf {
template <class T>
- bool result<T>::has_value() const noexcept;
-
-} }
-
-
-
-
-- Returns:
--
-
If *this is in value state, returns true, otherwise returns false.
-
-
-
-
-
-
-
has_error
-
-
#include <boost/leaf/result.hpp>
-
-
namespace boost { namespace leaf {
+ T const * result<T>::operator->() const noexcept;
template <class T>
- bool result<T>::has_error() const noexcept;
+ T * result<T>::operator->() noexcept;
} }
-- Returns:
+- Returns
-
-
If *this is in value state, returns false, otherwise returns true.
-
-
-
-
-
-
-
operator bool
-
-
#include <boost/leaf/result.hpp>
-
-
namespace boost { namespace leaf {
-
- template <class T>
- result<T>::operator bool() const noexcept;
-
-} }
-
-
-
-
-- Returns:
--
-
If *this is in value state, returns true, otherwise returns false.
+If *this is in value state, returns a pointer to the stored value; otherwise returns nullptr.
@@ -6391,69 +7009,38 @@ The returned proxy object refers to
*this; avoid holding on to it.
A member type of result<T>, defined as a synonym for T.
-
-
-- Effects:
--
-
If *this is in value state, returns a reference to the stored value, otherwise throws bad_result.
-
-
-
-
-
operator->
+
write_to
#include <boost/leaf/result.hpp>
namespace boost { namespace leaf {
template <class T>
- T const * result<T>::operator->() const noexcept;
-
- template <class T>
- T * result<T>::operator->() noexcept;
+ template <class Writer>
+ void result<T>::write_to( Writer & w ) const;
} }
-
-
-- Returns
--
-
If *this is in value state, returns a pointer to the stored value; otherwise returns 0.
-
-
+
+
The write_to member function is used with the serialization system; see Serialization.
-
+
-
-
operator*
-
-
#include <boost/leaf/result.hpp>
-
-
namespace boost { namespace leaf {
-
- template <class T>
- T const & result<T>::operator*() const noexcept;
-
- template <class T>
- T & result<T>::operator*() noexcept;
-
-} }
-
-
-
-
-- Requires:
--
-
*this must be in value state.
-
-- Returns
--
-
a reference to the stored value.
-
-
+
+
+
+|
+
+ |
+
+Result objects carry error objects only when in capture state. Otherwise, to output error objects, use write_to on diagnostic_details in an error handling scope.
+ |
+
+
@@ -6493,6 +7080,109 @@ The returned proxy object refers to
*this; avoid holding on to it.
} }
+
+
+
+
type_name
+
+
#include <boost/leaf/serialization/type_name.hpp>
+
+
namespace boost { namespace leaf {
+
+namespace serialization
+{
+
+ struct type_name
+ {
+ char const * name_not_zero_terminated_at_length;
+ std::size_t length;
+ std::size_t hash;
+
+ friend bool operator==( type_name const &, type_name const & ) noexcept;
+ friend bool operator!=( type_name const &, type_name const & ) noexcept;
+ friend bool operator<( type_name const &, type_name const & ) noexcept;
+
+ template <class CharT, class Traits>
+ friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> &, type_name const & );
+
+#if __cplusplus >= 201703L
+ friend std::string_view to_string_view( type_name const & ) noexcept;
+#endif
+
+#if BOOST_LEAF_CFG_STD_STRING
+ friend std::string to_string( type_name const & );
+#endif
+ };
+
+} // namespace serialization
+
+} }
+
+namespace std
+{
+ template <> struct hash<boost::leaf::serialization::type_name>;
+}
+
+
+
+
The type_name struct represents a type name, extracted automatically in constant time. It contains a pointer to the type name string, its length, and a precomputed hash for efficient comparison.
+
+
+
Two type_name objects compare equal if they represent the same type. The operator< provides alphabetical ordering. A std::hash specialization is provided for use with std::unordered_map. See get_type_name.
+
+
+
The type names are not mangled.
+
+
+
Example:
+
+
namespace app
+{
+ struct my_error { };
+}
+
+using leaf::serialization::get_type_name;
+
+assert(to_string_view(get_type_name<int>()) == "int");
+assert(to_string_view(get_type_name<app::my_error>()) == "app::my_error");
+
+
+
+
+
+
writer
+
+
#include <boost/leaf/serialization/writer.hpp>
+
+
namespace boost { namespace leaf {
+
+namespace serialization
+{
+ class writer
+ {
+ protected:
+
+ template <class Derived>
+ explicit writer( Derived * ) noexcept;
+
+ ~writer() noexcept;
+
+ public:
+
+ template <class Derived>
+ Derived * get() noexcept;
+ };
+}
+
+} }
+
+
+
+
The writer class is the base class for custom serialization writers. The constructor takes a pointer to the derived class, which is used by the get member function to recognize writer types at runtime.
+
+
+
The get member function returns a pointer to the derived class if the type matches, or nullptr otherwise. This allows the serialize function to dispatch to the correct writer type; see Serialization.
+
diff --git a/leaf.hpp b/leaf.hpp
index 07f6e5b..00bab2b 100644
--- a/leaf.hpp
+++ b/leaf.hpp
@@ -2,7 +2,7 @@
#define BOOST_LEAF_HPP_INCLUDED
// Boost LEAF single header distribution. Do not edit.
-// Generated on Dec 27, 2025 from https://github.com/boostorg/leaf/tree/1c5dfc1.
+// Generated on Jan 08, 2026 from https://github.com/boostorg/leaf/tree/ea2e690.
// Latest published version of this file: https://raw.githubusercontent.com/boostorg/leaf/gh-pages/leaf.hpp.
@@ -10,6 +10,11 @@
// 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_COMMON_HPP_INCLUDED
+#define BOOST_LEAF_COMMON_HPP_INCLUDED
+
+// #line 8 "boost/leaf/common.hpp"
// >>> #include
#ifndef BOOST_LEAF_CONFIG_HPP_INCLUDED
#define BOOST_LEAF_CONFIG_HPP_INCLUDED
@@ -171,7 +176,6 @@
# define BOOST_LEAF_NO_EXCEPTIONS
# endif
# endif
-
#endif // #ifndef BOOST_LEAF_NO_EXCEPTIONS
////////////////////////////////////////
@@ -280,7 +284,7 @@ namespace detail
#endif // BOOST_LEAF_CONFIG_VISIBILITY_HPP_INCLUDED
// <<< #include
-// #line 230 "boost/leaf/config.hpp"
+// #line 229 "boost/leaf/config.hpp"
////////////////////////////////////////
@@ -302,22 +306,34 @@ namespace detail
namespace boost
{
- [[noreturn]] void throw_exception( std::exception const & ); // user defined
-}
-namespace boost { namespace leaf {
-
-template
-[[noreturn]] void throw_exception_( T && e )
-{
#ifdef BOOST_LEAF_NO_EXCEPTIONS
- ::boost::throw_exception(std::move(e));
-#else
- throw std::move(e);
-#endif
+
+[[noreturn]] void throw_exception( std::exception const & ); // user defined
+
+namespace leaf
+{
+ template
+ [[noreturn]] void throw_exception_( T && e )
+ {
+ ::boost::throw_exception(std::move(e));
+ }
}
-} }
+#else
+
+namespace leaf
+{
+ template
+ [[noreturn]] void throw_exception_( T && e )
+ {
+ throw std::move(e);
+ }
+}
+
+#endif
+
+} // namespace boost
////////////////////////////////////////
@@ -806,11 +822,11 @@ namespace detail
public:
BOOST_LEAF_ALWAYS_INLINE tls_slot_index():
- idx_(TlsAlloc())
+ idx_(TlsAlloc())
{
if (idx_ == TLS_OUT_OF_INDEXES)
throw_exception_(win32_tls_error("TLS_OUT_OF_INDEXES"));
- }
+ }
BOOST_LEAF_ALWAYS_INLINE ~tls_slot_index() noexcept
{
@@ -1297,269 +1313,13 @@ namespace tls
// #line 88 "boost/leaf/config/tls.hpp"
#endif
-#endif // #ifndef BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED// <<< #include
-// #line 272 "boost/leaf/config.hpp"
+#endif // #ifndef BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED
+// <<< #include
+// #line 283 "boost/leaf/config.hpp"
#endif // #ifndef 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 architectures (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 // #if BOOST_LEAF_CFG_DIAGNOSTICS
-
-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 bloat.
-
- 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 detail
-
-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 };
- }
-} // namespace n
-
-using parsed = n::r;
-
-template
-parsed parse()
-{
- return n::p();
-}
-
-} } // namespace boost::leaf
-
-////////////////////////////////////////
-
-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 // #if defined(BOOST_LEAF_CFG_DIAGNOSTICS) && defined(BOOST_LEAF_HAS_CXXABI_H)
- return os << mangled_name;
- }
-} // namespace detail
-
-} } // namespace boost::leaf
-
-#endif // #ifndef BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED
-// <<< #include
-// #line 10 "boost/leaf/common.hpp"
+// <<< #include
+// #line 9 "boost/leaf/common.hpp"
#include
#include
@@ -1669,19 +1429,711 @@ namespace windows
#define BOOST_LEAF_CONTEXT_HPP_INCLUDED
// #line 8 "boost/leaf/context.hpp"
-// #include // Expanded at line 14
+// #include // Expanded at line 19
+// >>> #include
+#ifndef BOOST_LEAF_SERIALIZATION_DIAGNOSTICS_WRITER_HPP_INCLUDED
+#define BOOST_LEAF_SERIALIZATION_DIAGNOSTICS_WRITER_HPP_INCLUDED
+
+// #line 8 "boost/leaf/serialization/diagnostics_writer.hpp"
+// #include // Expanded at line 19
+// >>> #include
+#ifndef BOOST_LEAF_SERIALIZATION_WRITER_HPP_INCLUDED
+#define BOOST_LEAF_SERIALIZATION_WRITER_HPP_INCLUDED
+
+// #line 8 "boost/leaf/serialization/writer.hpp"
+// #include // Expanded at line 19
+// >>> #include
+#ifndef BOOST_LEAF_SERIALIZATION_TYPE_NAME_HPP_INCLUDED
+#define BOOST_LEAF_SERIALIZATION_TYPE_NAME_HPP_INCLUDED
+
+// #line 8 "boost/leaf/serialization/type_name.hpp"
+// >>> #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 19
+#include
+#include
+#include
+
+// __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 architectures (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
+
+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 bloat.
+
+ 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;
+ }
+
+ ////////////////////////////////////////
+
+ template
+ BOOST_LEAF_ALWAYS_INLINE std::size_t compute_hash(char const (&str)[S], std::size_t begin, std::size_t end) noexcept
+ {
+ std::size_t h = 2166136261u;
+ for( std::size_t i = begin; i != end; ++i )
+ h = (h ^ static_cast(str[i])) * 16777619u;
+ return h;
+ }
+} // namespace detail
+
+namespace n
+{
+ struct r
+ {
+ char const * name_not_zero_terminated_at_length;
+ std::size_t length;
+ std::size_t hash;
+ };
+
+#ifdef _MSC_VER
+# define BOOST_LEAF_CDECL __cdecl
+#else
+# define BOOST_LEAF_CDECL
+#endif
+
+ template
+ BOOST_LEAF_ALWAYS_INLINE r BOOST_LEAF_CDECL 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:
+ std::size_t const p01 = BOOST_LEAF_P("r boost::leaf::n::p() [T = ");
+ std::size_t const p02 = BOOST_LEAF_P("r __cdecl boost::leaf::n::p(void) [T = ");
+ // old clang style:
+ std::size_t const p03 = BOOST_LEAF_P("boost::leaf::n::r boost::leaf::n::p() [T = ");
+ std::size_t const p04 = BOOST_LEAF_P("boost::leaf::n::r __cdecl boost::leaf::n::p(void) [T = ");
+ // gcc style:
+ std::size_t const p05 = BOOST_LEAF_P("boost::leaf::n::r boost::leaf::n::p() [with T = ");
+ std::size_t const p06 = BOOST_LEAF_P("boost::leaf::n::r __cdecl boost::leaf::n::p() [with T = ");
+ // msvc style, struct:
+ std::size_t const p07 = 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)))
+ ||
+ (s02 && (1 == (!!p07 + !!p08 + !!p09)))
+ ||
+ (s02 && !!p10)
+ ]
+ ) * 2 - 1];
+ (void) static_assert_unrecognized_pretty_function_format_please_file_github_issue;
+
+ if( std::size_t const p = sizeof(char[1 + !!s01 * (p01 + p02 + p03 + p04 + p05 + p06)]) - 1 )
+ return { BOOST_LEAF_PRETTY_FUNCTION + p, s01 - p, detail::compute_hash(BOOST_LEAF_PRETTY_FUNCTION, p, s01) };
+
+ if( std::size_t const p = sizeof(char[1 + !!s02 * (p07 + p08 + p09)]) - 1 )
+ return { BOOST_LEAF_PRETTY_FUNCTION + p, s02 - p, detail::compute_hash(BOOST_LEAF_PRETTY_FUNCTION, p, s02) };
+
+ std::size_t const p = sizeof(char[1 + !!s02 * p10]) - 1;
+ return { BOOST_LEAF_PRETTY_FUNCTION + p, s02 - p, detail::compute_hash(BOOST_LEAF_PRETTY_FUNCTION, p, s02) };
+ }
+
+#undef BOOST_LEAF_CDECL
+
+} // namespace n
+
+} } // namespace boost::leaf
+
+////////////////////////////////////////
+
+namespace boost { namespace leaf {
+
+namespace detail
+{
+ class demangler
+ {
+ char const * mangled_name_;
+#ifdef BOOST_LEAF_HAS_CXXABI_H
+ char * demangled_name_ = nullptr;
+#endif
+
+ public:
+
+ explicit demangler(char const * mangled_name) noexcept:
+ mangled_name_(mangled_name)
+ {
+ BOOST_LEAF_ASSERT(mangled_name_);
+#ifdef BOOST_LEAF_HAS_CXXABI_H
+ int status = 0;
+ demangled_name_ = abi::__cxa_demangle(mangled_name_, nullptr, nullptr, &status);
+#endif
+ }
+
+ ~demangler() noexcept
+ {
+#ifdef BOOST_LEAF_HAS_CXXABI_H
+ std::free(demangled_name_);
+#endif
+ }
+
+ char const * get() const noexcept
+ {
+#ifdef BOOST_LEAF_HAS_CXXABI_H
+ if( demangled_name_ )
+ return demangled_name_;
+#endif
+ return mangled_name_;
+ }
+ };
+} // namespace detail
+
+} } // namespace boost::leaf
+
+#endif // #ifndef BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED
+// <<< #include
+// #line 9 "boost/leaf/serialization/type_name.hpp"
+
+#include
+
+#if BOOST_LEAF_CFG_STD_STRING
+# include
+#endif
+
+#if __cplusplus >= 201703L
+# include
+#endif
+
+namespace boost { namespace leaf {
+
+namespace serialization
+{
+
+struct type_name
+{
+ char const * name_not_zero_terminated_at_length;
+ std::size_t length;
+ std::size_t hash;
+
+ friend bool operator==(type_name const & a, type_name const & b) noexcept
+ {
+ BOOST_LEAF_ASSERT((a.hash == b.hash) == (a.length == b.length && std::memcmp(a.name_not_zero_terminated_at_length, b.name_not_zero_terminated_at_length, a.length) == 0));
+ return a.hash == b.hash;
+ }
+
+ friend bool operator!=(type_name const & a, type_name const & b) noexcept
+ {
+ return !(a == b);
+ }
+
+ friend bool operator<(type_name const & a, type_name const & b) noexcept
+ {
+ if( int cmp = std::memcmp(a.name_not_zero_terminated_at_length, b.name_not_zero_terminated_at_length, a.length < b.length ? a.length : b.length) )
+ return cmp < 0;
+ return a.length < b.length;
+ }
+
+ template
+ friend std::ostream & operator<<(std::basic_ostream & os, type_name const & x)
+ {
+ return os.write(x.name_not_zero_terminated_at_length, x.length);
+ }
+
+#if __cplusplus >= 201703L
+ friend std::string_view to_string_view(type_name const & x) noexcept
+ {
+ return std::string_view(x.name_not_zero_terminated_at_length, x.length);
+ }
+#endif
+
+#if BOOST_LEAF_CFG_STD_STRING
+ friend std::string to_string(type_name const & x)
+ {
+ return std::string(x.name_not_zero_terminated_at_length, x.length);
+ }
+#endif
+
+ template
+ friend char * to_zstr(char (&zstr)[S], type_name const & x) noexcept
+ {
+ std::size_t n = x.length < S - 1 ? x.length : S - 1;
+ std::memcpy(zstr, x.name_not_zero_terminated_at_length, n);
+ zstr[n] = 0;
+ return zstr;
+ }
+};
+
+template
+type_name get_type_name()
+{
+ n::r parsed = n::p();
+ return { parsed.name_not_zero_terminated_at_length, parsed.length, parsed.hash };
+}
+
+} // namespace serialization
+
+} } // namespace boost::leaf
+
+namespace std
+{
+ template <>
+ struct hash
+ {
+ std::size_t operator()(boost::leaf::serialization::type_name const & x) const noexcept
+ {
+ return x.hash;
+ }
+ };
+} // namespace std
+
+#endif // #ifndef BOOST_LEAF_SERIALIZATION_TYPE_NAME_HPP_INCLUDED
+// <<< #include
+// #line 10 "boost/leaf/serialization/writer.hpp"
+
+#include
+
+namespace boost { namespace leaf {
+
+namespace serialization
+{
+class writer
+{
+ type_name const type_;
+
+protected:
+
+ template
+ explicit writer(Derived * d) noexcept:
+ type_(get_type_name())
+ {
+ BOOST_LEAF_ASSERT(d == this), (void) d;
+ }
+
+ ~writer() noexcept
+ {
+ }
+
+public:
+
+ template
+ Derived * get() noexcept
+ {
+ return type_ == get_type_name::type>() ? static_cast(this) : nullptr;
+ }
+};
+
+ template
+ typename std::enable_if::value>::type
+ serialize(W &, E const &)
+ {
+ }
+}
+
+namespace detail
+{
+ template
+ struct dependent_writer
+ {
+ using type = serialization::writer;
+ };
+}
+
+} } // namespace boost::leaf
+
+#endif // #ifndef BOOST_LEAF_SERIALIZATION_WRITER_HPP_INCLUDED
+// <<< #include
+// #line 10 "boost/leaf/serialization/diagnostics_writer.hpp"
+// >>> #include
+#ifndef BOOST_LEAF_DETAIL_EXCEPTION_BASE_HPP_INCLUDED
+#define BOOST_LEAF_DETAIL_EXCEPTION_BASE_HPP_INCLUDED
+
+// #line 8 "boost/leaf/detail/exception_base.hpp"
+// #include // Expanded at line 19
+// #include // Expanded at line 1446
+
+namespace boost { namespace leaf {
+
+class error_id;
+
+namespace detail
+{
+ class exception_base
+ {
+ public:
+ virtual error_id get_error_id() const noexcept = 0;
+ virtual serialization::type_name get_type_name() const = 0;
+ protected:
+ exception_base() noexcept { }
+ ~exception_base() noexcept { }
+ };
+}
+
+} }
+
+#endif // #ifndef BOOST_LEAF_DETAIL_EXCEPTION_BASE_HPP_INCLUDED
+// <<< #include
+// #line 11 "boost/leaf/serialization/diagnostics_writer.hpp"
+
+#include
+
+#if BOOST_LEAF_CFG_DIAGNOSTICS
+# include
+#else
+# include
+#endif
+
+#ifndef BOOST_LEAF_NO_EXCEPTIONS
+# include
+#endif
+
+namespace boost { namespace leaf {
+
+template
+struct show_in_diagnostics: std::integral_constant
+{
+};
+
+namespace serialization
+{
+ template
+ struct is_printable: std::false_type
+ {
+ };
+
+ template
+ struct is_printable()<(), void())>: std::true_type
+ {
+ };
+
+ template
+ struct has_printable_member_value: std::false_type
+ {
+ };
+
+ template
+ struct has_printable_member_value()<().value, void())>: std::true_type
+ {
+ };
+
+ template
+ struct has_member_value: std::false_type
+ {
+ };
+
+ template
+ struct has_member_value().value)>: std::true_type
+ {
+ };
+
+ ////////////////////////////////////////
+
+ class diagnostics_writer: public writer
+ {
+ diagnostics_writer(diagnostics_writer const &) = delete;
+ diagnostics_writer & operator=(diagnostics_writer const &) = delete;
+
+ std::ostream & os_;
+ char const * prefix_;
+ char const * delimiter_;
+ void (* const print_suffix_)(std::ostream &);
+
+ template
+ static 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) << get_type_name();
+ }
+
+ template
+ static 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
+ static 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;
+
+ public:
+
+ template
+ explicit diagnostics_writer(std::basic_ostream & os) noexcept:
+ writer(this),
+ os_(os),
+ prefix_(BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER),
+ delimiter_(BOOST_LEAF_CFG_DIAGNOSTICS_DELIMITER),
+ print_suffix_([](std::basic_ostream &) { })
+ {
+ }
+
+ template
+ diagnostics_writer(std::basic_ostream & os, error_id const & id, e_source_location const * loc, std::exception const * ex) noexcept:
+ writer(this),
+ os_(os),
+ prefix_(BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER),
+ delimiter_(BOOST_LEAF_CFG_DIAGNOSTICS_DELIMITER),
+ print_suffix_([](std::basic_ostream & os) { os << '\n'; })
+ {
+ os << "Error with serial #" << id;
+ if( loc )
+ os << " reported at " << *loc;
+#ifndef BOOST_LEAF_NO_EXCEPTIONS
+ if( ex )
+ {
+ os << "\nCaught:" BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER;
+ if( auto eb = dynamic_cast(ex) )
+ os << eb->get_type_name();
+ else
+ os << detail::demangler(typeid(*ex).name()).get();
+ os << ": \"" << ex->what() << '"';
+ }
+ else
+#endif
+ {
+ prefix_ = "\nCaught:" BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER;
+ }
+ (void) ex;
+ }
+
+ ~diagnostics_writer() noexcept
+ {
+ print_suffix_(os_);
+ }
+
+ void set_prefix(char const * prefix) noexcept
+ {
+ prefix_ = prefix;
+ }
+
+ void set_delimiter(char const * delimiter) noexcept
+ {
+ delimiter_ = delimiter;
+ }
+
+ template
+ void write(E const & e)
+ {
+ diagnostic::print(os_, prefix_, delimiter_, e);
+ }
+ }; // class diagnostics_writer
+
+ ////////////////////////////////////////
+
+ template
+ struct diagnostics_writer::diagnostic
+ {
+ template
+ static bool print(std::basic_ostream &, char const * &, char const *, Wrapper const &) noexcept
+ {
+ return false;
+ }
+ };
+
+ template
+ struct diagnostics_writer::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 diagnostics_writer::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 diagnostics_writer::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 diagnostics_writer::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 diagnostics_writer::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_));
+ }
+ };
+
+} // namespace serialization
+
+} } // namespace boost::leaf
+
+#endif // #ifndef BOOST_LEAF_SERIALIZATION_DIAGNOSTICS_WRITER_HPP_INCLUDED
+// <<< #include
+// #line 10 "boost/leaf/context.hpp"
// >>> #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 // Expanded at line 19
// >>> #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 // Expanded at line 19
#include
namespace boost { namespace leaf {
@@ -1862,6 +2314,7 @@ namespace detail
#define BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
// #line 8 "boost/leaf/detail/function_traits.hpp"
+// #include // Expanded at line 19
// >>> #include
#ifndef BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED
#define BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED
@@ -2161,7 +2614,7 @@ template class F, class... T> using mp_valid = typename detai
#endif // #ifndef BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED
// <<< #include
-// #line 9 "boost/leaf/detail/function_traits.hpp"
+// #line 10 "boost/leaf/detail/function_traits.hpp"
#include
@@ -2260,174 +2713,15 @@ namespace detail
#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 1312
-
-#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