mirror of
https://github.com/boostorg/leaf.git
synced 2026-01-19 04:22:08 +00:00
std::error_code interoperability improvements
This commit is contained in:
@@ -579,30 +579,30 @@ namespace detail
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class leaf_category final: public std::error_category
|
||||
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_category() noexcept final override { }
|
||||
~leaf_error_category() noexcept final override { }
|
||||
};
|
||||
|
||||
template <class=void>
|
||||
struct get_error_category
|
||||
struct get_leaf_error_category
|
||||
{
|
||||
static leaf_category cat;
|
||||
static leaf_error_category cat;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
leaf_category get_error_category<T>::cat;
|
||||
leaf_error_category get_leaf_error_category<T>::cat;
|
||||
|
||||
inline int import_error_code( std::error_code const & ec ) noexcept
|
||||
{
|
||||
if( int err_id = ec.value() )
|
||||
{
|
||||
std::error_category const & cat = get_error_category<>::cat;
|
||||
std::error_category const & cat = get_leaf_error_category<>::cat;
|
||||
if( &ec.category() == &cat )
|
||||
{
|
||||
BOOST_LEAF_ASSERT((err_id&3) == 1);
|
||||
@@ -622,7 +622,7 @@ namespace detail
|
||||
|
||||
inline bool is_error_id( std::error_code const & ec ) noexcept
|
||||
{
|
||||
bool res = (&ec.category() == &detail::get_error_category<>::cat);
|
||||
bool res = (&ec.category() == &detail::get_leaf_error_category<>::cat);
|
||||
BOOST_LEAF_ASSERT(!res || !ec.value() || ((ec.value()&3) == 1));
|
||||
return res;
|
||||
}
|
||||
@@ -656,21 +656,22 @@ public:
|
||||
}
|
||||
|
||||
#if BOOST_LEAF_CFG_STD_SYSTEM_ERROR
|
||||
error_id( std::error_code const & ec ) noexcept:
|
||||
value_(detail::import_error_code(ec))
|
||||
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 <class Enum>
|
||||
error_id( Enum e, typename std::enable_if<std::is_error_code_enum<Enum>::value, Enum>::type * = 0 ) noexcept:
|
||||
error_id( Enum e, typename std::enable_if<std::is_error_code_enum<Enum>::value, int>::type = 0 ) noexcept:
|
||||
value_(detail::import_error_code(e))
|
||||
{
|
||||
}
|
||||
|
||||
operator std::error_code() const noexcept
|
||||
template <class T, typename std::enable_if<std::is_constructible<T, std::error_code>::value, int>::type = 0>
|
||||
operator T() const noexcept
|
||||
{
|
||||
return std::error_code(value_, detail::get_error_category<>::cat);
|
||||
return std::error_code(value_, detail::get_leaf_error_category<>::cat);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -530,7 +530,7 @@ try_handle_all( TryBlock && try_block, H && ... h ) noexcept
|
||||
else
|
||||
{
|
||||
detail::unload_result(&r);
|
||||
error_id id = r.error();
|
||||
error_id id(r.error());
|
||||
ctx.deactivate();
|
||||
using R = typename std::decay<decltype(std::declval<TryBlock>()().value())>::type;
|
||||
return ctx.template handle_error<R>(std::move(id), std::forward<H>(h)...);
|
||||
@@ -550,12 +550,12 @@ try_handle_some( TryBlock && try_block, H && ... h ) noexcept
|
||||
else
|
||||
{
|
||||
detail::unload_result(&r);
|
||||
error_id id = r.error();
|
||||
error_id id(r.error());
|
||||
ctx.deactivate();
|
||||
using R = typename std::decay<decltype(std::declval<TryBlock>()())>::type;
|
||||
auto rr = ctx.template handle_error<R>(std::move(id), std::forward<H>(h)..., [&r]()->R { return std::move(r); });
|
||||
if( !rr )
|
||||
ctx.unload(rr.error());
|
||||
ctx.unload(error_id(rr.error()));
|
||||
return rr;
|
||||
}
|
||||
}
|
||||
@@ -585,7 +585,7 @@ namespace detail
|
||||
{
|
||||
auto r = std::forward<TryBlock>(try_block)();
|
||||
unload_result(&r);
|
||||
return std::move(r);
|
||||
return r;
|
||||
}
|
||||
catch( std::exception & ex )
|
||||
{
|
||||
@@ -626,7 +626,7 @@ try_handle_all( TryBlock && try_block, H && ... h )
|
||||
{
|
||||
BOOST_LEAF_ASSERT(ctx.is_active());
|
||||
detail::unload_result(&r);
|
||||
error_id id = r.error();
|
||||
error_id id(r.error());
|
||||
ctx.deactivate();
|
||||
using R = typename std::decay<decltype(std::declval<TryBlock>()().value())>::type;
|
||||
return ctx.template handle_error<R>(std::move(id), std::forward<H>(h)...);
|
||||
@@ -646,7 +646,7 @@ try_handle_some( TryBlock && try_block, H && ... h )
|
||||
else if( ctx.is_active() )
|
||||
{
|
||||
detail::unload_result(&r);
|
||||
error_id id = r.error();
|
||||
error_id id(r.error());
|
||||
ctx.deactivate();
|
||||
using R = typename std::decay<decltype(std::declval<TryBlock>()())>::type;
|
||||
auto rr = ctx.template handle_error<R>(std::move(id), std::forward<H>(h)...,
|
||||
@@ -655,12 +655,12 @@ try_handle_some( TryBlock && try_block, H && ... h )
|
||||
return std::move(r);
|
||||
});
|
||||
if( !rr )
|
||||
ctx.unload(rr.error());
|
||||
ctx.unload(error_id(rr.error()));
|
||||
return rr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.unload(r.error());
|
||||
ctx.unload(error_id(r.error()));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,10 +228,12 @@ class BOOST_LEAF_SYMBOL_VISIBLE BOOST_LEAF_ATTRIBUTE_NODISCARD result
|
||||
}
|
||||
}
|
||||
|
||||
operator error_id() noexcept
|
||||
operator error_id() const noexcept
|
||||
{
|
||||
result_discriminant const what = r_.what_;
|
||||
return what.kind() == result_discriminant::val? error_id() : what.get_error_id();
|
||||
return what.kind() == result_discriminant::val?
|
||||
error_id() :
|
||||
what.get_error_id();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,11 @@ int main()
|
||||
#include "_test_res.hpp"
|
||||
#include "lightweight_test.hpp"
|
||||
|
||||
#include "boost/system/result.hpp"
|
||||
namespace boost { namespace leaf {
|
||||
template <class T> struct is_result_type<boost::system::result<T, std::error_code>>: std::true_type { };
|
||||
} }
|
||||
|
||||
namespace leaf = boost::leaf;
|
||||
|
||||
struct e_wrapped_error_code { std::error_code value; };
|
||||
@@ -213,7 +218,7 @@ void test()
|
||||
int r = leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[]( e_wrapped_error_code const & wec )
|
||||
{
|
||||
@@ -231,7 +236,7 @@ void test()
|
||||
int r = leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[]( leaf::match_value<leaf::condition<e_wrapped_error_code, errc_a>, errc_a::a0> code )
|
||||
{
|
||||
@@ -251,7 +256,7 @@ void test()
|
||||
int r = leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[]( leaf::match_value<e_wrapped_error_code, errc_a::a0> code )
|
||||
{
|
||||
@@ -271,7 +276,7 @@ void test()
|
||||
int r = leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[]( leaf::match_value<leaf::condition<e_wrapped_error_code, cond_x>, cond_x::x00> cond )
|
||||
{
|
||||
@@ -292,7 +297,7 @@ void test()
|
||||
int r = leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[]( leaf::match_value<e_wrapped_error_code, cond_x::x00> cond )
|
||||
{
|
||||
@@ -503,7 +508,7 @@ void test_void()
|
||||
leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[&]( e_wrapped_error_code const & wec )
|
||||
{
|
||||
@@ -522,7 +527,7 @@ void test_void()
|
||||
leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[&]( leaf::match_value<leaf::condition<e_wrapped_error_code, errc_a>, errc_a::a0> code )
|
||||
{
|
||||
@@ -543,7 +548,7 @@ void test_void()
|
||||
leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[&]( leaf::match_value<e_wrapped_error_code, errc_a::a0> code )
|
||||
{
|
||||
@@ -564,7 +569,7 @@ void test_void()
|
||||
leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[&]( leaf::match_value<leaf::condition<e_wrapped_error_code, cond_x>, cond_x::x00> cond )
|
||||
{
|
||||
@@ -586,7 +591,7 @@ void test_void()
|
||||
leaf::try_handle_all(
|
||||
[]() -> R
|
||||
{
|
||||
return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ));
|
||||
return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } );
|
||||
},
|
||||
[&]( leaf::match_value<e_wrapped_error_code, cond_x::x00> cond )
|
||||
{
|
||||
@@ -611,6 +616,7 @@ int main()
|
||||
test<test_res<int, std::error_code>>();
|
||||
test_void<leaf::result<void>>();
|
||||
test_void<test_res<void, std::error_code>>();
|
||||
test<boost::system::result<int, std::error_code>>();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ ResType g( bool succeed )
|
||||
if( auto r = f<ResType>(succeed) )
|
||||
return r;
|
||||
else
|
||||
return ResType(leaf::error_id(r.error()).load(info<42>{42}));
|
||||
return leaf::error_id(r.error()).load(info<42>{42});
|
||||
}
|
||||
|
||||
template <class ResType>
|
||||
|
||||
@@ -45,7 +45,7 @@ ResType g( bool succeed )
|
||||
if( auto r = f<ResType>(succeed) )
|
||||
return r;
|
||||
else
|
||||
return ResType(leaf::error_id(r.error()).load(info<42>{42}));
|
||||
return leaf::error_id(r.error()).load(info<42>{42});
|
||||
}
|
||||
|
||||
template <class ResType>
|
||||
|
||||
@@ -48,8 +48,9 @@ int main()
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
[](leaf::diagnostic_details const & vinfo)
|
||||
{
|
||||
std::cout << "Test is failing\n" << vinfo;
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
@@ -79,8 +80,9 @@ int main()
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
[](leaf::diagnostic_details const & vinfo)
|
||||
{
|
||||
std::cout << "Test is failing\n" << vinfo;
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
|
||||
Reference in New Issue
Block a user