simplify exception wrapping in value_to

This commit is contained in:
Dmitry Arkhipov 2024-09-16 22:05:23 +03:00
parent b6c916f3a6
commit 6071cd5808
3 changed files with 12 additions and 119 deletions

View File

@ -525,55 +525,6 @@ initialize_variant( V&& v, mp11::mp_int<1> )
} }
#endif // BOOST_NO_CXX17_HDR_VARIANT #endif // BOOST_NO_CXX17_HDR_VARIANT
struct locally_prohibit_exceptions
{};
template< class Ctx >
Ctx const&
make_locally_nonthrowing_context(Ctx const& ctx) noexcept
{
return ctx;
}
template< class... Ctxes >
std::tuple<Ctxes...> const&
make_locally_nonthrowing_context(std::tuple<Ctxes...> const& ctx) noexcept
{
return ctx;
}
template< class... Ctxes >
std::tuple<locally_prohibit_exceptions, allow_exceptions, Ctxes...>
make_locally_nonthrowing_context(std::tuple<allow_exceptions, Ctxes...> const& ctx)
noexcept
{
return std::tuple_cat(std::make_tuple( locally_prohibit_exceptions() ), ctx);
}
template< class Ctx >
Ctx const&
remove_local_exception_prohibition(Ctx const& ctx) noexcept
{
return ctx;
}
template< class T, class... Ts, std::size_t... Is>
std::tuple<Ts...>
remove_local_exception_prohibition_helper(
std::tuple<T, Ts...> const& tup,
mp11::index_sequence<Is...>) noexcept
{
return std::tuple<Ts...>( std::get<Is + 1>(tup)... );
}
template< class... Ctxes >
std::tuple<Ctxes...>
remove_local_exception_prohibition(
std::tuple<locally_prohibit_exceptions, Ctxes...> const& ctx) noexcept
{
return remove_local_exception_prohibition_helper(
ctx, mp11::index_sequence_for<Ctxes...>() );
}
template< class T, class Ctx > template< class T, class Ctx >
struct alternative_converter struct alternative_converter
@ -588,9 +539,8 @@ struct alternative_converter
if( res ) if( res )
return; return;
auto&& local_ctx = make_locally_nonthrowing_context(ctx);
using V = mp11::mp_at<T, I>; using V = mp11::mp_at<T, I>;
auto attempt = try_value_to<V>(jv, local_ctx); auto attempt = try_value_to<V>(jv, ctx);
if( attempt ) if( attempt )
{ {
using cat = variant_construction_category<T, V, I>; using cat = variant_construction_category<T, V, I>;
@ -709,28 +659,6 @@ value_to_impl(
return std::move(*res); return std::move(*res);
} }
template< class Ctx >
std::tuple<allow_exceptions, Ctx>
make_throwing_context(Ctx const& ctx)
{
return std::tuple<allow_exceptions, Ctx>(allow_exceptions(), ctx);
}
template< class... Ctxes >
std::tuple<allow_exceptions, Ctxes...>
make_throwing_context(std::tuple<Ctxes...> const& ctx)
{
return std::tuple_cat(std::make_tuple( allow_exceptions() ), ctx);
}
template< class... Ctxes >
std::tuple<allow_exceptions, Ctxes...> const&
make_throwing_context(std::tuple<allow_exceptions, Ctxes...> const& ctx)
noexcept
{
return ctx;
}
template< template<
class T, class T,
class Ctx, class Ctx,
@ -746,11 +674,7 @@ value_to_impl(
value const& jv, value const& jv,
Ctx const& ctx ) Ctx const& ctx )
{ {
auto res = tag_invoke( auto res = tag_invoke(try_value_to_tag<T>(), jv, Sup::get(ctx), ctx);
try_value_to_tag<T>(),
jv,
Sup::get(ctx),
make_throwing_context(ctx));
if( res.has_error() ) if( res.has_error() )
throw_system_error( res.error() ); throw_system_error( res.error() );
return std::move(*res); return std::move(*res);
@ -809,36 +733,17 @@ value_to_impl(
//---------------------------------------------------------- //----------------------------------------------------------
// User-provided conversions; nonthrowing -> throwing // User-provided conversions; nonthrowing -> throwing
template< class Ctx >
struct does_allow_exceptions : std::false_type
{ };
template< class... Ctxes >
struct does_allow_exceptions< std::tuple<allow_exceptions, Ctxes...> >
: std::true_type
{ };
template< class T, class... Args > template< class T, class... Args >
system::result<T> system::result<T>
wrap_conversion_exceptions( std::true_type, value_to_tag<T>, Args&& ... args ) wrap_conversion_exceptions( value_to_tag<T>, Args&& ... args )
{
return {
boost::system::in_place_value,
tag_invoke( value_to_tag<T>(), static_cast<Args&&>(args)... )};
}
template< class T, class... Args >
system::result<T>
wrap_conversion_exceptions( std::false_type, value_to_tag<T>, Args&& ... args )
{ {
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
try try
{ {
#endif #endif
return wrap_conversion_exceptions( return {
std::true_type(), boost::system::in_place_value,
value_to_tag<T>(), tag_invoke( value_to_tag<T>(), static_cast<Args&&>(args)... )};
static_cast<Args&&>(args)... );
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
} }
catch( std::bad_alloc const&) catch( std::bad_alloc const&)
@ -865,8 +770,7 @@ mp11::mp_if_c<
value_to_impl( value_to_impl(
user_conversion_tag, try_value_to_tag<T>, value const& jv, Ctx const& ) user_conversion_tag, try_value_to_tag<T>, value const& jv, Ctx const& )
{ {
return wrap_conversion_exceptions( return wrap_conversion_exceptions(value_to_tag<T>(), jv);
does_allow_exceptions<Ctx>(), value_to_tag<T>(), jv);
} }
template< template<
@ -886,8 +790,7 @@ value_to_impl(
value const& jv, value const& jv,
Ctx const& ctx ) Ctx const& ctx )
{ {
return wrap_conversion_exceptions( return wrap_conversion_exceptions( value_to_tag<T>(), jv, Sup::get(ctx) );
does_allow_exceptions<Ctx>(), value_to_tag<T>(), jv, Sup::get(ctx) );
} }
template< template<
@ -908,11 +811,7 @@ value_to_impl(
Ctx const& ctx ) Ctx const& ctx )
{ {
return wrap_conversion_exceptions( return wrap_conversion_exceptions(
does_allow_exceptions<Ctx>(), value_to_tag<T>(), jv, Sup::get(ctx), ctx);
value_to_tag<T>(),
jv,
Sup::get(ctx),
remove_local_exception_prohibition(ctx) );
} }
// no suitable conversion implementation // no suitable conversion implementation
@ -930,8 +829,7 @@ template< class Impl, class T, class Ctx >
T T
value_to_impl( Impl impl, value_to_tag<T>, value const& jv, Ctx const& ctx ) value_to_impl( Impl impl, value_to_tag<T>, value const& jv, Ctx const& ctx )
{ {
return value_to_impl( return value_to_impl(impl, try_value_to_tag<T>(), jv, ctx).value();
impl, try_value_to_tag<T>(), jv, make_throwing_context(ctx) ).value();
} }
template< class Ctx, class T > template< class Ctx, class T >

View File

@ -387,9 +387,6 @@ struct conversion_category_impl< std::tuple<Ctxs...>, T, Dir >
struct no_context struct no_context
{}; {};
struct allow_exceptions
{};
template <class T, class Dir> template <class T, class Dir>
using can_convert = mp11::mp_not< using can_convert = mp11::mp_not<
std::is_same< std::is_same<

View File

@ -23,7 +23,6 @@
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <iostream>
#ifndef BOOST_NO_CXX17_HDR_VARIANT #ifndef BOOST_NO_CXX17_HDR_VARIANT
# include <variant> # include <variant>
@ -485,10 +484,9 @@ public:
#endif // BOOST_NO_CXX17_HDR_OPTIONAL #endif // BOOST_NO_CXX17_HDR_OPTIONAL
} }
BOOST_TEST_THROWS( BOOST_TEST_THROWS_WITH_LOCATION(
value_to<::value_to_test_ns::T10>( value_to<::value_to_test_ns::T10>(
value{{"n", 0}, {"t3", "t10"}}, ctx... ), value{{"n", 0}, {"t3", "t10"}}, ctx... ));
std::invalid_argument);
#endif // BOOST_DESCRIBE_CXX14 #endif // BOOST_DESCRIBE_CXX14
} }