2
0
mirror of https://github.com/boostorg/leaf.git synced 2026-02-08 23:02:15 +00:00

e_unexpected_diagnostic_output

This commit is contained in:
Emil Dotchevski
2018-11-27 09:15:34 -08:00
parent d25518d863
commit e76f4e6325
9 changed files with 133 additions and 93 deletions

View File

@@ -25,7 +25,7 @@ namespace boost { namespace leaf {
friend std::ostream & operator<<( std::ostream & os, e_errno const & err ) {
using namespace std;
return os << type<e_errno>() << " = " << err.value << ", \"" << std::strerror(err.value) << '"';
return os << type<e_errno>() << ": " << err.value << ", \"" << std::strerror(err.value) << '"';
}
};

View File

@@ -69,7 +69,7 @@ namespace boost { namespace leaf {
{
static bool print( std::ostream & os, Wrapper const & x )
{
os << type<Wrapper>() << " = " << x.value;
os << type<Wrapper>() << ": " << x.value;
return true;
}
};
@@ -79,7 +79,7 @@ namespace boost { namespace leaf {
{
static bool print( std::ostream & os, Wrapper const & )
{
os << type<Wrapper>() << " = N/A";
os << type<Wrapper>() << ": N/A";
return true;
}
};

View File

@@ -10,7 +10,7 @@
#include <boost/leaf/common.hpp>
#include <exception>
#define LEAF_THROW ::boost::leaf::next_error_value().propagate(::boost::leaf::meta::e_source_location{__FILE__,__LINE__,__FUNCTION__}),throw::boost::leaf::exception
#define LEAF_THROW ::boost::leaf::next_error_value().propagate(::boost::leaf::e_source_location{__FILE__,__LINE__,__FUNCTION__}),throw::boost::leaf::exception
namespace boost { namespace leaf {

View File

@@ -15,40 +15,52 @@
#include <ostream>
#include <type_traits>
#include <system_error>
#include <sstream>
#define LEAF_ERROR ::boost::leaf::next_error_value().propagate(::boost::leaf::meta::e_source_location{__FILE__,__LINE__,__FUNCTION__}),::boost::leaf::error
#define LEAF_ERROR ::boost::leaf::next_error_value().propagate(::boost::leaf::e_source_location{__FILE__,__LINE__,__FUNCTION__}),::boost::leaf::error
namespace boost { namespace system { class error_code; } }
namespace boost { namespace leaf {
namespace meta
struct e_source_location
{
struct e_source_location
char const * const file;
int const line;
char const * const function;
friend std::ostream & operator<<( std::ostream & os, e_source_location const & x )
{
char const * const file;
int const line;
char const * const function;
return os << "At " << x.file << '(' << x.line << ") in function " << x.function;
}
};
friend std::ostream & operator<<( std::ostream & os, e_source_location const & x )
{
return os << "At " << x.file << '(' << x.line << ") in function " << x.function;
}
};
struct e_unexpected
{
char const * (*first_type)() noexcept;
int count;
struct e_unexpected
friend std::ostream & operator<<( std::ostream & os, e_unexpected const & x )
{
char const * (*first_type)() noexcept;
int count;
assert(x.first_type!=0);
assert(x.count>0);
if( x.count==1 )
os << "Detected 1 attempt to communicate an unexpected error object of type ";
else
os << "Detected " << x.count << " attempts to communicate unexpected error objects, the first one of type ";
return os << x.first_type();
}
};
friend std::ostream & operator<<( std::ostream & os, e_unexpected const & x )
{
assert(x.first_type!=0);
assert(x.count>0);
return os << "Detected " << x.count << " attempt(s) to communicate unexpected error object(s), the first one is of type " << x.first_type();
}
};
}
struct e_unexpected_diagnostic_output
{
std::string value;
friend std::ostream & operator<<( std::ostream & os, e_unexpected_diagnostic_output const & x )
{
return os << x.value;
}
};
namespace leaf_detail
{
@@ -73,8 +85,8 @@ namespace boost { namespace leaf {
template <> struct is_error_type<system::error_code>: std::true_type { };
template <> struct is_error_type<std::error_code>: std::true_type { };
template <> struct is_error_type<meta::e_unexpected>: std::true_type { };
template <> struct is_error_type<meta::e_source_location>: std::true_type { };
template <> struct is_error_type<e_unexpected>: std::true_type { };
template <> struct is_error_type<e_source_location>: std::true_type { };
////////////////////////////////////////
@@ -218,29 +230,63 @@ namespace boost { namespace leaf {
}
template <class E>
void put_unexpected( leaf_detail::slot<meta::e_unexpected> & p, error const & e ) noexcept
void put_unexpected( error_info<E> const & ev ) noexcept
{
if( p.has_value() )
if( slot<e_unexpected> * p = tl_slot_ptr<e_unexpected>() )
{
auto & v = p.value();
if( v.e==e )
if( p->has_value() )
{
++v.v.count;
return;
auto & p_ev = p->value();
if( p_ev.e==ev.e )
{
++p_ev.v.count;
return;
}
}
(void) p->put( error_info<e_unexpected>{e_unexpected{&type<E>,1},ev.e} );
}
(void) p.put( leaf_detail::error_info<meta::e_unexpected>{meta::e_unexpected{&type<E>,1},e} );
}
template <class E>
void put_unexpected_diagnostic_output( error_info<E> const & ev ) noexcept
{
if( slot<e_unexpected_diagnostic_output> * p = tl_slot_ptr<e_unexpected_diagnostic_output>() )
{
std::stringstream s;
if( !diagnostic<decltype(ev.v)>::print(s,ev.v) )
return;
if( p->has_value() )
{
auto & p_ev = p->value();
if( p_ev.e==ev.e )
{
std::string & value = p_ev.v.value;
value += "\n(unexpected) ";
value += s.str();
return;
}
}
(void) p->put( error_info<e_unexpected_diagnostic_output>{e_unexpected_diagnostic_output{"(unexpected) "+s.str()},ev.e} );
}
}
template <class E>
void no_expect_slot( error_info<E> const & ev ) noexcept
{
put_unexpected(ev);
put_unexpected_diagnostic_output(ev);
}
template <class E>
E * put_slot( E && v, error const & e ) noexcept
{
if( leaf_detail::slot<E> * p = leaf_detail::tl_slot_ptr<E>() )
return &p->put( leaf_detail::error_info<E>{std::forward<E>(v),e} ).v;
if( slot<E> * p = tl_slot_ptr<E>() )
return &p->put( error_info<E>{std::forward<E>(v),e} ).v;
else
if( leaf_detail::slot<meta::e_unexpected> * p = leaf_detail::tl_slot_ptr<meta::e_unexpected>() )
put_unexpected<E>(*p,e);
return 0;
{
no_expect_slot( error_info<E>{std::forward<E>(v),e} );
return 0;
}
}
template <class E>
@@ -261,8 +307,7 @@ namespace boost { namespace leaf {
}
else
if( has_value() )
if( leaf_detail::slot<meta::e_unexpected> * p = leaf_detail::tl_slot_ptr<meta::e_unexpected>() )
put_unexpected<E>(*p,value().e);
no_expect_slot(value());
tl_slot_ptr<E>() = prev_;
}
} //leaf_detail