mirror of
https://github.com/boostorg/exception.git
synced 2026-02-02 20:52:21 +00:00
Improved SFINAE in the JSON encoders
This commit is contained in:
@@ -1084,8 +1084,9 @@ struct boost_json_encoder
|
||||
{
|
||||
boost::json::value & v_;
|
||||
|
||||
// Enabled if x is assignable to boost::json::value, or
|
||||
// if tag_invoke is defined for boost::json::value_from_tag.
|
||||
// Uses unspecified SFINAE expression designed to make the
|
||||
// overload selected only if no other compatible overload is found.
|
||||
// Implemented in terms of boost::json::value_from.
|
||||
template <class T>
|
||||
friend void output( boost_json_encoder &, T const & x );
|
||||
|
||||
@@ -1114,7 +1115,9 @@ struct nlohmann_json_encoder
|
||||
{
|
||||
Json & j_;
|
||||
|
||||
// Enabled if to_json is available for Json and T.
|
||||
// Uses unspecified SFINAE expression designed to make the
|
||||
// overload selected only if no other compatible overload is found.
|
||||
// Implemented in terms of to_json.
|
||||
template <class T>
|
||||
friend void output( nlohmann_json_encoder &, T const & x );
|
||||
|
||||
@@ -1156,8 +1159,9 @@ struct boost_json_encoder
|
||||
{
|
||||
boost::json::value & v_;
|
||||
|
||||
// Enabled if x is assignable to boost::json::value, or
|
||||
// if tag_invoke is defined for boost::json::value_from_tag.
|
||||
// Uses unspecified SFINAE expression designed to make the
|
||||
// overload selected only if no other compatible overload is found.
|
||||
// Implemented in terms of boost::json::value_from.
|
||||
template <class T>
|
||||
friend void output( boost_json_encoder &, T const & x );
|
||||
|
||||
@@ -1168,10 +1172,7 @@ struct boost_json_encoder
|
||||
} }
|
||||
----
|
||||
|
||||
The `boost_json_encoder` type serializes objects to JSON format using https://www.boost.org/doc/libs/release/libs/json/[Boost.JSON]. The `output` function is enabled for:
|
||||
|
||||
* Types directly assignable to `boost::json::value`
|
||||
* Types for which a `tag_invoke` overload for `value_from_tag` can be found via ADL
|
||||
The `boost_json_encoder` type serializes objects to JSON format using https://www.boost.org/doc/libs/release/libs/json/[Boost.JSON]. The `output` function is implemented in terms of `boost::json::value_from`.
|
||||
|
||||
See <<tutorial_serialization>>.
|
||||
|
||||
@@ -1592,7 +1593,9 @@ struct nlohmann_json_encoder
|
||||
{
|
||||
Json & j_;
|
||||
|
||||
// Enabled if to_json is available for Json and T.
|
||||
// Uses unspecified SFINAE expression designed to make the
|
||||
// overload selected only if no other compatible overload is found.
|
||||
// Implemented in terms of to_json.
|
||||
template <class T>
|
||||
friend void output( nlohmann_json_encoder &, T const & x );
|
||||
|
||||
@@ -1603,7 +1606,9 @@ struct nlohmann_json_encoder
|
||||
} }
|
||||
----
|
||||
|
||||
The `nlohmann_json_encoder` type serializes objects to JSON format based on ADL calls to `to_json`. This is compatible with https://github.com/nlohmann/json[nlohmann/json]. See <<tutorial_serialization>>.
|
||||
The `nlohmann_json_encoder` type serializes objects to JSON format based on ADL calls to `to_json`. This is compatible with https://github.com/nlohmann/json[nlohmann/json].
|
||||
|
||||
See <<tutorial_serialization>>.
|
||||
|
||||
'''
|
||||
|
||||
|
||||
@@ -6,43 +6,36 @@
|
||||
#ifndef BOOST_EXCEPTION_SERIALIZATION_BOOST_JSON_ENCODER_HPP_INCLUDED
|
||||
#define BOOST_EXCEPTION_SERIALIZATION_BOOST_JSON_ENCODER_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace json {
|
||||
|
||||
class value;
|
||||
|
||||
template <class T>
|
||||
void value_from(T &&, value &);
|
||||
|
||||
} }
|
||||
|
||||
namespace
|
||||
boost
|
||||
{
|
||||
namespace
|
||||
json
|
||||
{
|
||||
class value;
|
||||
struct value_from_tag;
|
||||
}
|
||||
|
||||
namespace
|
||||
exception_serialization
|
||||
{
|
||||
// Baast.JSON does not provide ADL interface for serializing user-defined types.
|
||||
// This limits the functionality of boost_json_encoder to only types that provide tag_invoke.
|
||||
template <class Value = boost::json::value, class ValueFromTag = boost::json::value_from_tag>
|
||||
template <class Value = boost::json::value>
|
||||
struct
|
||||
boost_json_encoder_
|
||||
{
|
||||
Value & v_;
|
||||
|
||||
template <class T>
|
||||
template <class Encoder, class T, class... Deprioritize>
|
||||
friend
|
||||
auto
|
||||
output(boost_json_encoder_ & e, T const & x) -> decltype(std::declval<Value &>() = x, void())
|
||||
typename std::enable_if<std::is_same<Encoder, boost_json_encoder_>::value>::type
|
||||
output(Encoder & e, T const & x, Deprioritize...)
|
||||
{
|
||||
e.v_ = x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
friend
|
||||
auto
|
||||
output(boost_json_encoder_ & e, T const & x) -> decltype(tag_invoke(std::declval<ValueFromTag>(), std::declval<Value &>(), x), void())
|
||||
{
|
||||
tag_invoke(ValueFromTag{}, e.v_, x);
|
||||
boost::json::value_from(x, e.v_);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef BOOST_EXCEPTION_SERIALIZATION_NLOHMANN_JSON_ENCODER_HPP_INCLUDED
|
||||
#define BOOST_EXCEPTION_SERIALIZATION_NLOHMANN_JSON_ENCODER_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace
|
||||
@@ -20,12 +21,12 @@ boost
|
||||
{
|
||||
Json & j_;
|
||||
|
||||
template <class T>
|
||||
friend
|
||||
auto
|
||||
output(nlohmann_json_encoder & e, T const & x) -> decltype(to_json(std::declval<Json &>(), x))
|
||||
template <class Encoder, class T, class... Deprioritize>
|
||||
friend typename std::enable_if<std::is_same<Encoder, nlohmann_json_encoder>::value, Json *>::type
|
||||
output(Encoder & e, T const & x, Deprioritize...)
|
||||
{
|
||||
to_json(e.j_, x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
|
||||
using output_encoder = boost::exception_serialization::boost_json_encoder;
|
||||
|
||||
@@ -39,6 +40,7 @@ boost
|
||||
|
||||
typedef boost::error_info<struct my_error1_, int> my_error1;
|
||||
typedef boost::error_info<struct my_error2_, std::string> my_error2;
|
||||
typedef boost::error_info<struct my_error4_, std::vector<int>> my_error4;
|
||||
|
||||
struct
|
||||
my_info
|
||||
@@ -97,6 +99,13 @@ check_output(boost::json::value const & j, bool has_source_location)
|
||||
auto const & mij = obj.at("my_error3_").as_object();
|
||||
BOOST_TEST_EQ(mij.at("code").as_int64(), 1);
|
||||
BOOST_TEST_EQ(mij.at("message").as_string(), "error one");
|
||||
|
||||
BOOST_TEST(obj.contains("my_error4_"));
|
||||
auto const & vec = obj.at("my_error4_").as_array();
|
||||
BOOST_TEST_EQ(vec.size(), 3u);
|
||||
BOOST_TEST_EQ(vec[0].as_int64(), 1);
|
||||
BOOST_TEST_EQ(vec[1].as_int64(), 2);
|
||||
BOOST_TEST_EQ(vec[2].as_int64(), 3);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -111,7 +120,8 @@ main()
|
||||
e <<
|
||||
my_error1(42) <<
|
||||
my_error2("hello") <<
|
||||
my_error3({1, "error one"});
|
||||
my_error3({1, "error one"}) <<
|
||||
my_error4({1, 2, 3});
|
||||
BOOST_THROW_EXCEPTION(e);
|
||||
}
|
||||
catch( test_exception & e )
|
||||
@@ -132,7 +142,8 @@ main()
|
||||
e <<
|
||||
my_error1(42) <<
|
||||
my_error2("hello") <<
|
||||
my_error3({1, "error one"});
|
||||
my_error3({1, "error one"}) <<
|
||||
my_error4({1, 2, 3});
|
||||
BOOST_THROW_EXCEPTION(e);
|
||||
}
|
||||
catch( ... )
|
||||
|
||||
Reference in New Issue
Block a user