Merge pull request #1821 from AnthonyVH/develop

Fix for #1647
This commit is contained in:
Niels Lohmann 2019-11-05 19:15:54 +01:00 committed by GitHub
commit 7bcaba0ca9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 53 deletions

View file

@ -78,30 +78,30 @@
@def NLOHMANN_JSON_SERIALIZE_ENUM @def NLOHMANN_JSON_SERIALIZE_ENUM
@since version 3.4.0 @since version 3.4.0
*/ */
#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
template<typename BasicJsonType> \ template<typename BasicJsonType> \
inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
{ \ { \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \ auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
{ \ { \
return ej_pair.first == e; \ return ej_pair.first == e; \
}); \ }); \
j = ((it != std::end(m)) ? it : std::begin(m))->second; \ j = ((it != std::end(m)) ? it : std::begin(m))->second; \
} \ } \
template<typename BasicJsonType> \ template<typename BasicJsonType> \
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
{ \ { \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \ auto it = std::find_if(std::begin(m), std::end(m), \
[j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
{ \ { \
return ej_pair.second == j; \ return ej_pair.second == j; \
}); \ }); \
e = ((it != std::end(m)) ? it : std::begin(m))->first; \ e = ((it != std::end(m)) ? it : std::begin(m))->first; \
} }
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They // Ugly macros to avoid uglier copy-paste when specializing basic_json. They

View file

@ -2633,11 +2633,11 @@ class basic_json
detail::has_non_default_from_json<basic_json_t, ValueType>::value, detail::has_non_default_from_json<basic_json_t, ValueType>::value,
int> = 0> int> = 0>
ValueType get() const noexcept(noexcept( ValueType get() const noexcept(noexcept(
JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>()))) JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
{ {
static_assert(not std::is_reference<ValueTypeCV>::value, static_assert(not std::is_reference<ValueTypeCV>::value,
"get() cannot be used with reference types, you might want to use get_ref()"); "get() cannot be used with reference types, you might want to use get_ref()");
return JSONSerializer<ValueTypeCV>::from_json(*this); return JSONSerializer<ValueType>::from_json(*this);
} }
/*! /*!
@ -8062,7 +8062,7 @@ struct hash<nlohmann::json>
/// @note: do not remove the space after '<', /// @note: do not remove the space after '<',
/// see https://github.com/nlohmann/json/pull/679 /// see https://github.com/nlohmann/json/pull/679
template<> template<>
struct less< ::nlohmann::detail::value_t> struct less<::nlohmann::detail::value_t>
{ {
/*! /*!
@brief compare two value_t enum values @brief compare two value_t enum values

View file

@ -1782,30 +1782,30 @@ JSON_HEDLEY_DIAGNOSTIC_POP
@def NLOHMANN_JSON_SERIALIZE_ENUM @def NLOHMANN_JSON_SERIALIZE_ENUM
@since version 3.4.0 @since version 3.4.0
*/ */
#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
template<typename BasicJsonType> \ template<typename BasicJsonType> \
inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
{ \ { \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \ auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
{ \ { \
return ej_pair.first == e; \ return ej_pair.first == e; \
}); \ }); \
j = ((it != std::end(m)) ? it : std::begin(m))->second; \ j = ((it != std::end(m)) ? it : std::begin(m))->second; \
} \ } \
template<typename BasicJsonType> \ template<typename BasicJsonType> \
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
{ \ { \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \ auto it = std::find_if(std::begin(m), std::end(m), \
[j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
{ \ { \
return ej_pair.second == j; \ return ej_pair.second == j; \
}); \ }); \
e = ((it != std::end(m)) ? it : std::begin(m))->first; \ e = ((it != std::end(m)) ? it : std::begin(m))->first; \
} }
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
@ -17176,11 +17176,11 @@ class basic_json
detail::has_non_default_from_json<basic_json_t, ValueType>::value, detail::has_non_default_from_json<basic_json_t, ValueType>::value,
int> = 0> int> = 0>
ValueType get() const noexcept(noexcept( ValueType get() const noexcept(noexcept(
JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>()))) JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
{ {
static_assert(not std::is_reference<ValueTypeCV>::value, static_assert(not std::is_reference<ValueTypeCV>::value,
"get() cannot be used with reference types, you might want to use get_ref()"); "get() cannot be used with reference types, you might want to use get_ref()");
return JSONSerializer<ValueTypeCV>::from_json(*this); return JSONSerializer<ValueType>::from_json(*this);
} }
/*! /*!

View file

@ -159,6 +159,39 @@ bool operator==(Data const& lhs, Data const& rhs)
using float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>; using float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;
/////////////////////////////////////////////////////////////////////
// for #1647
/////////////////////////////////////////////////////////////////////
namespace
{
struct NonDefaultFromJsonStruct { };
inline bool operator== (NonDefaultFromJsonStruct const& lhs, NonDefaultFromJsonStruct const& rhs)
{
return true;
}
enum class for_1647 { one, two };
NLOHMANN_JSON_SERIALIZE_ENUM(for_1647,
{
{for_1647::one, "one"},
{for_1647::two, "two"},
})
}
namespace nlohmann
{
template <>
struct adl_serializer<NonDefaultFromJsonStruct>
{
static NonDefaultFromJsonStruct from_json (json const& j)
{
return {};
}
};
}
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// for #1805 // for #1805
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@ -1836,6 +1869,13 @@ TEST_CASE("regression tests")
CHECK(j.contains(jptr1)); CHECK(j.contains(jptr1));
CHECK(j.contains(jptr2)); CHECK(j.contains(jptr2));
} }
SECTION("issue #1647 - compile error when deserializing enum if both non-default from_json and non-member operator== exists for other type")
{
auto val = nlohmann::json("one").get<for_1647>();
CHECK(val == for_1647::one);
}
SECTION("issue #1805 - A pair<T1, T2> is json constructible only if T1 and T2 are json constructible") SECTION("issue #1805 - A pair<T1, T2> is json constructible only if T1 and T2 are json constructible")
{ {
static_assert(!std::is_constructible<json, std::pair<std::string, NotSerializableData>>::value, ""); static_assert(!std::is_constructible<json, std::pair<std::string, NotSerializableData>>::value, "");