mirror of
https://github.com/nlohmann/json.git
synced 2026-10-01 06:25:17 +00:00
Fix from_json() for enums with underlying type bool (#5679)
get_arithmetic_value() rejects boolean_t, so the default from_json()
for enums failed to compile for an enum whose underlying type is
bool (e.g. enum class Flag : bool { off, on }), even though the
matching to_json() serializes such enums as an unsigned number.
Read the underlying value through number_unsigned_t in that case,
matching what to_json() writes, then cast back to the underlying
type before constructing the enum.
Fixes #5671.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -167,9 +167,13 @@ template<typename BasicJsonType, typename EnumType,
|
||||
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
||||
inline void from_json(const BasicJsonType& j, EnumType& e)
|
||||
{
|
||||
typename std::underlying_type<EnumType>::type val;
|
||||
using underlying_type = typename std::underlying_type<EnumType>::type;
|
||||
// get_arithmetic_value() does not accept boolean_t; read the number that to_json() wrote instead
|
||||
using value_type = typename std::conditional<std::is_same<underlying_type, typename BasicJsonType::boolean_t>::value,
|
||||
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
||||
value_type val;
|
||||
get_arithmetic_value(j, val);
|
||||
e = static_cast<EnumType>(val);
|
||||
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
||||
}
|
||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||
|
||||
|
||||
@@ -5664,9 +5664,13 @@ template<typename BasicJsonType, typename EnumType,
|
||||
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
||||
inline void from_json(const BasicJsonType& j, EnumType& e)
|
||||
{
|
||||
typename std::underlying_type<EnumType>::type val;
|
||||
using underlying_type = typename std::underlying_type<EnumType>::type;
|
||||
// get_arithmetic_value() does not accept boolean_t; read the number that to_json() wrote instead
|
||||
using value_type = typename std::conditional<std::is_same<underlying_type, typename BasicJsonType::boolean_t>::value,
|
||||
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
||||
value_type val;
|
||||
get_arithmetic_value(j, val);
|
||||
e = static_cast<EnumType>(val);
|
||||
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
||||
}
|
||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||
|
||||
|
||||
@@ -1358,6 +1358,14 @@ TEST_CASE("value conversion")
|
||||
CHECK(json(value_1).get<c_enum>() == value_1);
|
||||
CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
|
||||
}
|
||||
|
||||
SECTION("get an enum with underlying type bool (#5671)")
|
||||
{
|
||||
enum class bool_enum : bool { off, on };
|
||||
|
||||
CHECK(json(bool_enum::off).get<bool_enum>() == bool_enum::off);
|
||||
CHECK(json(bool_enum::on).get<bool_enum>() == bool_enum::on);
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("more involved conversions")
|
||||
|
||||
Reference in New Issue
Block a user