replace constructor by from/to_json: unscoped enum types

this also means that one can do: j.get<unscoped_enum>();
This commit is contained in:
Théo DELRIEU 2017-01-08 14:07:10 +01:00
parent f00898331e
commit 6d427acdde
3 changed files with 41 additions and 21 deletions

View file

@ -432,7 +432,6 @@ template <typename T, typename BasicJson>
struct is_compatible_basic_json_type struct is_compatible_basic_json_type
{ {
static auto constexpr value = static auto constexpr value =
is_unscoped_enum<T>::value or
std::is_same<T, BasicJson>::value or std::is_same<T, BasicJson>::value or
is_compatible_array_type<BasicJson, T>::value or is_compatible_array_type<BasicJson, T>::value or
is_compatible_object_type<typename BasicJson::object_t, T>::value; is_compatible_object_type<typename BasicJson::object_t, T>::value;
@ -569,6 +568,13 @@ void to_json(Json &j, CompatibleNumberIntegerType val) noexcept
external_constructor<value_t::number_integer>::construct(j, val); external_constructor<value_t::number_integer>::construct(j, val);
} }
template <typename Json, typename UnscopedEnumType,
enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
void to_json(Json &j, UnscopedEnumType e)
{
external_constructor<value_t::number_integer>::construct(j, e);
}
template <typename Json> template <typename Json>
void from_json(Json const& j, typename Json::boolean_t& b) void from_json(Json const& j, typename Json::boolean_t& b)
{ {
@ -603,6 +609,15 @@ void from_json(Json const& j, typename Json::number_integer_t& val)
get_arithmetic_value(j, val); get_arithmetic_value(j, val);
} }
template <typename Json, typename UnscopedEnumType,
enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
void from_json(Json const &j, UnscopedEnumType& e)
{
typename std::underlying_type<UnscopedEnumType>::type val = e;
get_arithmetic_value(j, val);
e = static_cast<UnscopedEnumType>(val);
}
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..) // overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
// //
// note: Is it really necessary to provide explicit overloads for boolean_t etc.. // note: Is it really necessary to provide explicit overloads for boolean_t etc..
@ -1848,15 +1863,6 @@ class basic_json
JSONSerializer<uncvref_t<T>>::to_json(*this, std::forward<T>(val)); JSONSerializer<uncvref_t<T>>::to_json(*this, std::forward<T>(val));
} }
// Constructor for unscoped enums (not enum classes)
template <typename T, enable_if_t<is_unscoped_enum<T>::value, int> = 0>
basic_json(T val) noexcept
: m_type(value_t::number_integer),
m_value(static_cast<number_integer_t>(val))
{
assert_invariant();
}
/*! /*!
@brief create a container (array or object) from an initializer list @brief create a container (array or object) from an initializer list

View file

@ -432,7 +432,6 @@ template <typename T, typename BasicJson>
struct is_compatible_basic_json_type struct is_compatible_basic_json_type
{ {
static auto constexpr value = static auto constexpr value =
is_unscoped_enum<T>::value or
std::is_same<T, BasicJson>::value or std::is_same<T, BasicJson>::value or
is_compatible_array_type<BasicJson, T>::value or is_compatible_array_type<BasicJson, T>::value or
is_compatible_object_type<typename BasicJson::object_t, T>::value; is_compatible_object_type<typename BasicJson::object_t, T>::value;
@ -569,6 +568,13 @@ void to_json(Json &j, CompatibleNumberIntegerType val) noexcept
external_constructor<value_t::number_integer>::construct(j, val); external_constructor<value_t::number_integer>::construct(j, val);
} }
template <typename Json, typename UnscopedEnumType,
enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
void to_json(Json &j, UnscopedEnumType e)
{
external_constructor<value_t::number_integer>::construct(j, e);
}
template <typename Json> template <typename Json>
void from_json(Json const& j, typename Json::boolean_t& b) void from_json(Json const& j, typename Json::boolean_t& b)
{ {
@ -603,6 +609,15 @@ void from_json(Json const& j, typename Json::number_integer_t& val)
get_arithmetic_value(j, val); get_arithmetic_value(j, val);
} }
template <typename Json, typename UnscopedEnumType,
enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
void from_json(Json const &j, UnscopedEnumType& e)
{
typename std::underlying_type<UnscopedEnumType>::type val = e;
get_arithmetic_value(j, val);
e = static_cast<UnscopedEnumType>(val);
}
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..) // overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
// //
// note: Is it really necessary to provide explicit overloads for boolean_t etc.. // note: Is it really necessary to provide explicit overloads for boolean_t etc..
@ -1849,15 +1864,6 @@ class basic_json
JSONSerializer<uncvref_t<T>>::to_json(*this, std::forward<T>(val)); JSONSerializer<uncvref_t<T>>::to_json(*this, std::forward<T>(val));
} }
// Constructor for unscoped enums (not enum classes)
template <typename T, enable_if_t<is_unscoped_enum<T>::value, int> = 0>
basic_json(T val) noexcept
: m_type(value_t::number_integer),
m_value(static_cast<number_integer_t>(val))
{
assert_invariant();
}
/*! /*!
@brief create a container (array or object) from an initializer list @brief create a container (array or object) from an initializer list

View file

@ -63,10 +63,18 @@ TEST_CASE("regression tests")
SECTION("pull request #71 - handle enum type") SECTION("pull request #71 - handle enum type")
{ {
enum { t = 0 }; enum { t = 0 , u = 1};
json j = json::array(); json j = json::array();
j.push_back(t); j.push_back(t);
// maybe this is not the place to test this?
json j2 = u;
auto anon_enum_value = j2.get<decltype(u)>();
CHECK(u == anon_enum_value);
static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, "");
j.push_back(json::object( j.push_back(json::object(
{ {
{"game_type", t} {"game_type", t}