Commit be1d3de4 by Niels Lohmann Committed by Théo DELRIEU

💄 moved changes to re2c file and ran `make pretty`

parent aa2679a8
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -39,66 +39,66 @@ TEST_CASE("lexer class")
SECTION("structural characters")
{
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("["),
1).scan() == json::lexer::token_type::begin_array));
1).scan() == json::lexer::token_type::begin_array));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("]"),
1).scan() == json::lexer::token_type::end_array));
1).scan() == json::lexer::token_type::end_array));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("{"),
1).scan() == json::lexer::token_type::begin_object));
1).scan() == json::lexer::token_type::begin_object));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("}"),
1).scan() == json::lexer::token_type::end_object));
1).scan() == json::lexer::token_type::end_object));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(","),
1).scan() == json::lexer::token_type::value_separator));
1).scan() == json::lexer::token_type::value_separator));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(":"),
1).scan() == json::lexer::token_type::name_separator));
1).scan() == json::lexer::token_type::name_separator));
}
SECTION("literal names")
{
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("null"),
4).scan() == json::lexer::token_type::literal_null));
4).scan() == json::lexer::token_type::literal_null));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("true"),
4).scan() == json::lexer::token_type::literal_true));
4).scan() == json::lexer::token_type::literal_true));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("false"),
5).scan() == json::lexer::token_type::literal_false));
5).scan() == json::lexer::token_type::literal_false));
}
SECTION("numbers")
{
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("0"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("1"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("2"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("3"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("4"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("5"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("6"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("7"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("8"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("9"),
1).scan() == json::lexer::token_type::value_number));
1).scan() == json::lexer::token_type::value_number));
}
SECTION("whitespace")
{
// result is end_of_input, because not token is following
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(" "),
1).scan() == json::lexer::token_type::end_of_input));
1).scan() == json::lexer::token_type::end_of_input));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("\t"),
1).scan() == json::lexer::token_type::end_of_input));
1).scan() == json::lexer::token_type::end_of_input));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("\n"),
1).scan() == json::lexer::token_type::end_of_input));
1).scan() == json::lexer::token_type::end_of_input));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>("\r"),
1).scan() == json::lexer::token_type::end_of_input));
1).scan() == json::lexer::token_type::end_of_input));
CHECK((json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(" \t\n\r\n\t "),
7).scan() == json::lexer::token_type::end_of_input));
7).scan() == json::lexer::token_type::end_of_input));
}
}
......
......@@ -38,252 +38,257 @@ using nlohmann::json;
namespace udt
{
enum class country
{
enum class country
{
china,
france,
russia
};
};
struct age
{
struct age
{
int m_val;
};
};
struct name
{
struct name
{
std::string m_val;
};
};
struct address
{
struct address
{
std::string m_val;
};
};
struct person
{
struct person
{
age m_age;
name m_name;
country m_country;
};
};
struct contact
{
struct contact
{
person m_person;
address m_address;
};
};
struct contact_book
{
struct contact_book
{
name m_book_name;
std::vector<contact> m_contacts;
};
};
}
// to_json methods
namespace udt
{
// templates because of the custom_json tests (see below)
template <typename Json>
void to_json(Json& j, age a)
{
// templates because of the custom_json tests (see below)
template <typename Json>
void to_json(Json& j, age a)
{
j = a.m_val;
}
}
template <typename Json>
void to_json(Json& j, name const& n)
{
template <typename Json>
void to_json(Json& j, name const& n)
{
j = n.m_val;
}
}
template <typename Json>
void to_json(Json& j, country c)
{
template <typename Json>
void to_json(Json& j, country c)
{
switch (c)
{
case country::china:
j = u8"中华人民共和国";
return;
case country::france:
j = "France";
return;
case country::russia:
j = u8"Российская Федерация";
return;
case country::china:
j = u8"中华人民共和国";
return;
case country::france:
j = "France";
return;
case country::russia:
j = u8"Российская Федерация";
return;
}
}
}
template <typename Json>
void to_json(Json& j, person const& p)
{
template <typename Json>
void to_json(Json& j, person const& p)
{
j = Json{{"age", p.m_age}, {"name", p.m_name}, {"country", p.m_country}};
}
}
void to_json(nlohmann::json& j, address const& a)
{
void to_json(nlohmann::json& j, address const& a)
{
j = a.m_val;
}
}
void to_json(nlohmann::json& j, contact const& c)
{
void to_json(nlohmann::json& j, contact const& c)
{
j = json{{"person", c.m_person}, {"address", c.m_address}};
}
}
void to_json(nlohmann::json& j, contact_book const& cb)
{
void to_json(nlohmann::json& j, contact_book const& cb)
{
j = json{{"name", cb.m_book_name}, {"contacts", cb.m_contacts}};
}
}
// operators
bool operator==(age lhs, age rhs)
{
// operators
bool operator==(age lhs, age rhs)
{
return lhs.m_val == rhs.m_val;
}
}
bool operator==(address const &lhs, address const &rhs)
{
bool operator==(address const& lhs, address const& rhs)
{
return lhs.m_val == rhs.m_val;
}
}
bool operator==(name const &lhs, name const &rhs)
{
bool operator==(name const& lhs, name const& rhs)
{
return lhs.m_val == rhs.m_val;
}
}
bool operator==(person const &lhs, person const &rhs)
{
bool operator==(person const& lhs, person const& rhs)
{
return std::tie(lhs.m_name, lhs.m_age) == std::tie(rhs.m_name, rhs.m_age);
}
}
bool operator==(contact const &lhs, contact const &rhs)
{
bool operator==(contact const& lhs, contact const& rhs)
{
return std::tie(lhs.m_person, lhs.m_address) ==
std::tie(rhs.m_person, rhs.m_address);
}
}
bool operator==(contact_book const &lhs, contact_book const &rhs)
{
bool operator==(contact_book const& lhs, contact_book const& rhs)
{
return std::tie(lhs.m_book_name, lhs.m_contacts) ==
std::tie(rhs.m_book_name, rhs.m_contacts);
}
}
}
// from_json methods
namespace udt
{
template <typename Json>
void from_json(Json const& j, age &a)
{
template <typename Json>
void from_json(Json const& j, age& a)
{
a.m_val = j.template get<int>();
}
}
template <typename Json>
void from_json(Json const& j, name &n)
{
template <typename Json>
void from_json(Json const& j, name& n)
{
n.m_val = j.template get<std::string>();
}
}
template <typename Json>
void from_json(Json const &j, country &c)
{
template <typename Json>
void from_json(Json const& j, country& c)
{
const auto str = j.template get<std::string>();
static const std::map<std::string, country> m = {
static const std::map<std::string, country> m =
{
{u8"中华人民共和国", country::china},
{"France", country::france},
{"Российская Федерация", country::russia}};
{"Российская Федерация", country::russia}
};
const auto it = m.find(str);
// TODO test exceptions
c = it->second;
}
}
template <typename Json>
void from_json(Json const& j, person &p)
{
template <typename Json>
void from_json(Json const& j, person& p)
{
p.m_age = j["age"].template get<age>();
p.m_name = j["name"].template get<name>();
p.m_country = j["country"].template get<country>();
}
}
void from_json(nlohmann::json const &j, address &a)
{
void from_json(nlohmann::json const& j, address& a)
{
a.m_val = j.get<std::string>();
}
}
void from_json(nlohmann::json const& j, contact &c)
{
void from_json(nlohmann::json const& j, contact& c)
{
c.m_person = j["person"].get<person>();
c.m_address = j["address"].get<address>();
}
}
void from_json(nlohmann::json const&j, contact_book &cb)
{
void from_json(nlohmann::json const& j, contact_book& cb)
{
cb.m_book_name = j["name"].get<name>();
cb.m_contacts = j["contacts"].get<std::vector<contact>>();
}
}
}
TEST_CASE("basic usage", "[udt]")
{
// a bit narcissic maybe :) ?
const udt::age a{23};
const udt::name n{"theo"};
const udt::country c{udt::country::france};
const udt::person sfinae_addict{a, n, c};
const udt::person senior_programmer{{42}, {u8"王芳"}, udt::country::china};
const udt::address addr{"Paris"};
const udt::contact cpp_programmer{sfinae_addict, addr};
const udt::contact_book book{{"C++"}, {cpp_programmer, {senior_programmer, addr}}};
SECTION("conversion to json via free-functions")
{
CHECK(json(a) == json(23));
CHECK(json(n) == json("theo"));
CHECK(json(c) == json("France"));
CHECK(json(sfinae_addict) == R"({"name":"theo", "age":23, "country":"France"})"_json);
CHECK(json("Paris") == json(addr));
CHECK(json(cpp_programmer) ==
R"({"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"})"_json);
CHECK(
json(book) ==
u8R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json);
}
SECTION("conversion from json via free-functions")
{
const auto big_json =
u8R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json;
const auto parsed_book = big_json.get<udt::contact_book>();
const auto book_name = big_json["name"].get<udt::name>();
const auto contacts = big_json["contacts"].get<std::vector<udt::contact>>();
const auto contact_json = big_json["contacts"].at(0);
const auto contact = contact_json.get<udt::contact>();
const auto person = contact_json["person"].get<udt::person>();
const auto address = contact_json["address"].get<udt::address>();
const auto age = contact_json["person"]["age"].get<udt::age>();
const auto country = contact_json["person"]["country"].get<udt::country>();
const auto name = contact_json["person"]["name"].get<udt::name>();
CHECK(age == a);
CHECK(name == n);
CHECK(country == c);
CHECK(address == addr);
CHECK(person == sfinae_addict);
CHECK(contact == cpp_programmer);
CHECK(contacts == book.m_contacts);
CHECK(book_name == udt::name{"C++"});
CHECK(book == parsed_book);
}
// a bit narcissic maybe :) ?
const udt::age a
{
23
};
const udt::name n{"theo"};
const udt::country c{udt::country::france};
const udt::person sfinae_addict{a, n, c};
const udt::person senior_programmer{{42}, {u8"王芳"}, udt::country::china};
const udt::address addr{"Paris"};
const udt::contact cpp_programmer{sfinae_addict, addr};
const udt::contact_book book{{"C++"}, {cpp_programmer, {senior_programmer, addr}}};
SECTION("conversion to json via free-functions")
{
CHECK(json(a) == json(23));
CHECK(json(n) == json("theo"));
CHECK(json(c) == json("France"));
CHECK(json(sfinae_addict) == R"({"name":"theo", "age":23, "country":"France"})"_json);
CHECK(json("Paris") == json(addr));
CHECK(json(cpp_programmer) ==
R"({"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"})"_json);
CHECK(
json(book) ==
u8R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json);
}
SECTION("conversion from json via free-functions")
{
const auto big_json =
u8R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json;
const auto parsed_book = big_json.get<udt::contact_book>();
const auto book_name = big_json["name"].get<udt::name>();
const auto contacts = big_json["contacts"].get<std::vector<udt::contact>>();
const auto contact_json = big_json["contacts"].at(0);
const auto contact = contact_json.get<udt::contact>();
const auto person = contact_json["person"].get<udt::person>();
const auto address = contact_json["address"].get<udt::address>();
const auto age = contact_json["person"]["age"].get<udt::age>();
const auto country = contact_json["person"]["country"].get<udt::country>();
const auto name = contact_json["person"]["name"].get<udt::name>();
CHECK(age == a);
CHECK(name == n);
CHECK(country == c);
CHECK(address == addr);
CHECK(person == sfinae_addict);
CHECK(contact == cpp_programmer);
CHECK(contacts == book.m_contacts);
CHECK(book_name == udt::name{"C++"});
CHECK(book == parsed_book);
}
}
namespace udt
{
struct legacy_type
{
std::string number;
std::string number;
};
}
......@@ -292,88 +297,96 @@ namespace nlohmann
template <typename T>
struct adl_serializer<std::shared_ptr<T>>
{
static void to_json(json& j, std::shared_ptr<T> const& opt)
{
if (opt)
j = *opt;
else
j = nullptr;
}
static void from_json(json const &j, std::shared_ptr<T> &opt)
{
if (j.is_null())
opt = nullptr;
else
opt.reset(new T(j.get<T>()));
}
static void to_json(json& j, std::shared_ptr<T> const& opt)
{
if (opt)
{
j = *opt;
}
else
{
j = nullptr;
}
}
static void from_json(json const& j, std::shared_ptr<T>& opt)
{
if (j.is_null())
{
opt = nullptr;
}
else
{
opt.reset(new T(j.get<T>()));
}
}
};
template <>
struct adl_serializer<udt::legacy_type>
{
static void to_json(json& j, udt::legacy_type const& l)
{
j = std::stoi(l.number);
}
static void to_json(json& j, udt::legacy_type const& l)
{
j = std::stoi(l.number);
}
static void from_json(json const& j, udt::legacy_type& l)
{
l.number = std::to_string(j.get<int>());
}
static void from_json(json const& j, udt::legacy_type& l)
{
l.number = std::to_string(j.get<int>());
}
};
}
TEST_CASE("adl_serializer specialization", "[udt]")
{
SECTION("partial specialization")
{
SECTION("to_json")
SECTION("partial specialization")
{
std::shared_ptr<udt::person> optPerson;
SECTION("to_json")
{
std::shared_ptr<udt::person> optPerson;
json j = optPerson;
CHECK(j.is_null());
json j = optPerson;
CHECK(j.is_null());
optPerson.reset(new udt::person{{42}, {"John Doe"}});
j = optPerson;
CHECK_FALSE(j.is_null());
optPerson.reset(new udt::person{{42}, {"John Doe"}});
j = optPerson;
CHECK_FALSE(j.is_null());
CHECK(j.get<udt::person>() == *optPerson);
}
CHECK(j.get<udt::person>() == *optPerson);
}
SECTION("from_json")
{
auto person = udt::person{{42}, {"John Doe"}};
json j = person;
SECTION("from_json")
{
auto person = udt::person{{42}, {"John Doe"}};
json j = person;
auto optPerson = j.get<std::shared_ptr<udt::person>>();
REQUIRE(optPerson);
CHECK(*optPerson == person);
auto optPerson = j.get<std::shared_ptr<udt::person>>();
REQUIRE(optPerson);
CHECK(*optPerson == person);
j = nullptr;
optPerson = j.get<std::shared_ptr<udt::person>>();
CHECK(!optPerson);
j = nullptr;
optPerson = j.get<std::shared_ptr<udt::person>>();
CHECK(!optPerson);
}
}
}
SECTION("total specialization")
{
SECTION("to_json")
SECTION("total specialization")
{
udt::legacy_type lt{"4242"};
json j = lt;
CHECK(j.get<int>() == 4242);
SECTION("to_json")
{
udt::legacy_type lt{"4242"};
json j = lt;
CHECK(j.get<int>() == 4242);
}
SECTION("from_json")
{
json j = 4242;
auto lt = j.get<udt::legacy_type>();
CHECK(lt.number == "4242");
}
}
SECTION("from_json")
{
json j = 4242;
auto lt = j.get<udt::legacy_type>();
CHECK(lt.number == "4242");
}
}
}
namespace nlohmann
......@@ -383,22 +396,22 @@ namespace nlohmann
template <typename T>
struct adl_serializer<std::vector<T>>
{
static void to_json(json& j, std::vector<T> const& opt)
{
}
static void to_json(json& j, std::vector<T> const& opt)
{
}
static void from_json(json const &j, std::vector<T> &opt)
{
}
static void from_json(json const& j, std::vector<T>& opt)
{
}
};
}
TEST_CASE("current supported types are preferred over specializations", "[udt]")
{
json j = std::vector<int>{1, 2, 3};
auto f = j.get<std::vector<int>>();
CHECK((f == std::vector<int>{1, 2, 3}));
json j = std::vector<int> {1, 2, 3};
auto f = j.get<std::vector<int>>();
CHECK((f == std::vector<int> {1, 2, 3}));
}
namespace nlohmann
......@@ -406,55 +419,63 @@ namespace nlohmann
template <typename T>
struct adl_serializer<std::unique_ptr<T>>
{
static void to_json(json& j, std::unique_ptr<T> const& opt)
{
if (opt)
j = *opt;
else
j = nullptr;
}
// this is the overload needed for non-copyable types,
// should we add a priority tag in the implementation to prefer this overload if it exists?
static std::unique_ptr<T> from_json(json const &j)
{
if (j.is_null())
return nullptr;
else
return std::unique_ptr<T>(new T(j.get<T>()));
}
static void to_json(json& j, std::unique_ptr<T> const& opt)
{
if (opt)
{
j = *opt;
}
else
{
j = nullptr;
}
}
// this is the overload needed for non-copyable types,
// should we add a priority tag in the implementation to prefer this overload if it exists?
static std::unique_ptr<T> from_json(json const& j)
{
if (j.is_null())
{
return nullptr;
}
else
{
return std::unique_ptr<T>(new T(j.get<T>()));
}
}
};
}
TEST_CASE("Non-copyable types", "[udt]")
{
SECTION("to_json")
{
std::unique_ptr<udt::person> optPerson;
SECTION("to_json")
{
std::unique_ptr<udt::person> optPerson;
json j = optPerson;
CHECK(j.is_null());
json j = optPerson;
CHECK(j.is_null());
optPerson.reset(new udt::person{{42}, {"John Doe"}});
j = optPerson;
CHECK_FALSE(j.is_null());
optPerson.reset(new udt::person{{42}, {"John Doe"}});
j = optPerson;
CHECK_FALSE(j.is_null());
CHECK(j.get<udt::person>() == *optPerson);
}
CHECK(j.get<udt::person>() == *optPerson);
}
SECTION("from_json")
{
auto person = udt::person{{42}, {"John Doe"}};
json j = person;
SECTION("from_json")
{
auto person = udt::person{{42}, {"John Doe"}};
json j = person;
auto optPerson = j.get<std::unique_ptr<udt::person>>();
REQUIRE(optPerson);
CHECK(*optPerson == person);
auto optPerson = j.get<std::unique_ptr<udt::person>>();
REQUIRE(optPerson);
CHECK(*optPerson == person);
j = nullptr;
optPerson = j.get<std::unique_ptr<udt::person>>();
CHECK(!optPerson);
}
j = nullptr;
optPerson = j.get<std::unique_ptr<udt::person>>();
CHECK(!optPerson);
}
}
// custom serializer
......@@ -462,87 +483,89 @@ TEST_CASE("Non-copyable types", "[udt]")
template <typename T, typename = typename std::enable_if<std::is_pod<T>::value>::type>
struct pod_serializer
{
// I could forward-declare this struct, and add a basic_json alias
template <typename Json>
static void from_json(Json const& j , T& t)
{
auto value = j.template get<std::uint64_t>();
auto bytes = static_cast<char*>(static_cast<void*>(&value));
std::memcpy(&t, bytes, sizeof(value));
}
template <typename Json>
static void to_json(Json& j, T const& t)
{
auto bytes = static_cast<char const*>(static_cast<void const*>(&t));
std::uint64_t value = bytes[0];
for (auto i = 1; i < 8; ++i)
value |= bytes[i] << 8 * i;
j = value;
}
// I could forward-declare this struct, and add a basic_json alias
template <typename Json>
static void from_json(Json const& j , T& t)
{
auto value = j.template get<std::uint64_t>();
auto bytes = static_cast<char*>(static_cast<void*>(&value));
std::memcpy(&t, bytes, sizeof(value));
}
template <typename Json>
static void to_json(Json& j, T const& t)
{
auto bytes = static_cast<char const*>(static_cast<void const*>(&t));
std::uint64_t value = bytes[0];
for (auto i = 1; i < 8; ++i)
{
value |= bytes[i] << 8 * i;
}
j = value;
}
};
namespace udt
{
struct small_pod
{
int begin;
char middle;
short end;
int begin;
char middle;
short end;
};
bool operator==(small_pod lhs, small_pod rhs)
{
return std::tie(lhs.begin, lhs.middle, lhs.end) ==
std::tie(lhs.begin, lhs.middle, lhs.end);
return std::tie(lhs.begin, lhs.middle, lhs.end) ==
std::tie(lhs.begin, lhs.middle, lhs.end);
}
}
TEST_CASE("custom serializer for pods", "[udt]")
{
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, pod_serializer>;
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, pod_serializer>;
auto p = udt::small_pod{42, '/', 42};
custom_json j = p;
auto p = udt::small_pod{42, '/', 42};
custom_json j = p;
auto p2 = j.get<udt::small_pod>();
auto p2 = j.get<udt::small_pod>();
CHECK(p == p2);
CHECK(p == p2);
}
template <typename T, typename>
struct another_adl_serializer;
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, another_adl_serializer>;
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, another_adl_serializer>;
template <typename T, typename>
struct another_adl_serializer
{
static void from_json(custom_json const& j , T& t)
{
using nlohmann::from_json;
from_json(j, t);
}
static void to_json(custom_json& j , T const& t)
{
using nlohmann::to_json;
to_json(j, t);
}
static void from_json(custom_json const& j , T& t)
{
using nlohmann::from_json;
from_json(j, t);
}
static void to_json(custom_json& j , T const& t)
{
using nlohmann::to_json;
to_json(j, t);
}
};
TEST_CASE("custom serializer that does adl by default", "[udt]")
{
using json = nlohmann::json;
using json = nlohmann::json;
auto me = udt::person{23, "theo", udt::country::france};
auto me = udt::person{23, "theo", udt::country::france};
json j = me;
custom_json cj = me;
json j = me;
custom_json cj = me;
CHECK(j.dump() == cj.dump());
CHECK(j.dump() == cj.dump());
CHECK(me == j.get<udt::person>());
CHECK(me == cj.get<udt::person>());
CHECK(me == j.get<udt::person>());
CHECK(me == cj.get<udt::person>());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment