mirror of
https://github.com/boostorg/json.git
synced 2025-05-12 06:01:41 +00:00
simplify exception wrapping in value_to
This commit is contained in:
parent
b6c916f3a6
commit
6071cd5808
@ -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 >
|
||||||
|
@ -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<
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user