Allow disabling default enum conversions (#3536)

This commit is contained in:
Richard Hozák 2022-06-16 19:34:32 +02:00 committed by GitHub
parent e80945da2c
commit f6acdbec2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 172 additions and 2 deletions

View File

@ -41,6 +41,7 @@ option(JSON_BuildTests "Build the unit tests when BUILD_TEST
option(JSON_CI "Enable CI build targets." OFF)
option(JSON_Diagnostics "Use extended diagnostic messages." OFF)
option(JSON_ImplicitConversions "Enable implicit conversions." ON)
option(JSON_DisableEnumSerialization "Disable default integer enum serialization." OFF)
option(JSON_LegacyDiscardedValueComparison "Enable legacy discarded value comparison." OFF)
option(JSON_Install "Install CMake targets during install step." ${MAIN_PROJECT})
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." ON)
@ -78,6 +79,10 @@ if (NOT JSON_ImplicitConversions)
message(STATUS "Implicit conversions are disabled")
endif()
if (JSON_DisableEnumSerialization)
message(STATUS "Enum integer serialization is disabled")
endif()
if (JSON_LegacyDiscardedValueComparison)
message(STATUS "Legacy discarded value comparison enabled")
endif()
@ -106,6 +111,7 @@ target_compile_definitions(
${NLOHMANN_JSON_TARGET_NAME}
INTERFACE
$<$<NOT:$<BOOL:${JSON_ImplicitConversions}>>:JSON_USE_IMPLICIT_CONVERSIONS=0>
$<$<BOOL:${JSON_DisableEnumSerialization}>:JSON_DISABLE_ENUM_SERIALIZATION=1>
$<$<BOOL:${JSON_Diagnostics}>:JSON_DIAGNOSTICS=1>
$<$<BOOL:${JSON_LegacyDiscardedValueComparison}>:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1>
)

View File

@ -838,8 +838,8 @@ endfunction()
ci_get_cmake(3.1.0 CMAKE_3_1_0_BINARY)
ci_get_cmake(3.13.0 CMAKE_3_13_0_BINARY)
set(JSON_CMAKE_FLAGS_3_1_0 JSON_Diagnostics JSON_ImplicitConversions JSON_LegacyDiscardedValueComparison
JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind)
set(JSON_CMAKE_FLAGS_3_1_0 JSON_Diagnostics JSON_ImplicitConversions JSON_DisableEnumSerialization
JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind)
set(JSON_CMAKE_FLAGS_3_13_0 JSON_BuildTests)
function(ci_add_cmake_flags_targets flag min_version)

View File

@ -140,6 +140,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('SAX Interface', 'Guide', 'fea
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'features/macros/index.html#json_assertx');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'features/macros/index.html#json_catch_userexception');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'features/macros/index.html#json_diagnostics');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_ENUM_SERIALIZATION', 'Macro', 'features/macros/index.html#json_disable_enum_serialization');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_11', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_14', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_17', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');

View File

@ -29,6 +29,7 @@ header. See also the [macro overview page](../../features/macros.md).
## Type conversions
- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums
- [**JSON_USE_IMPLICIT_CONVERSIONS**](json_use_implicit_conversions.md) - control implicit conversions
<!-- comment-->

View File

@ -0,0 +1,135 @@
# JSON_DISABLE_ENUM_SERIALIZATION
```cpp
#define JSON_DISABLE_ENUM_SERIALIZATION
```
When defined, default serialization and deserialization functions for enums are excluded and have to be provided by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) (see [arbitrary type conversions](../../features/arbitrary_types.md) for more details).
Parsing or serializing an enum will result in a compiler error.
This works for both unscoped and scoped enums.
## Default definition
By default, `#!cpp JSON_DISABLE_ENUM_SERIALIZATION` is not defined.
```cpp
#undef JSON_DISABLE_ENUM_SERIALIZATION
```
## Examples
??? example "Example 1: Disabled behavior"
The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, meaning the code below **does not** compile.
```cpp
#define JSON_DISABLE_ENUM_SERIALIZATION 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
enum class Choice
{
first,
second,
};
int main()
{
// normally invokes to_json serialization function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not
const json j = Choice::first;
// normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not
Choice ch = j.get<Choice>();
}
```
??? example "Example 2: Serialize enum macro"
The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) to parse and serialize the enum.
```cpp
#define JSON_DISABLE_ENUM_SERIALIZATION 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
enum class Choice
{
first,
second,
};
NLOHMANN_JSON_SERIALIZE_ENUM(Choice,
{
{ Choice::first, "first" },
{ Choice::second, "second" },
})
int main()
{
// uses user-defined to_json function defined by macro
const json j = Choice::first;
// uses user-defined from_json function defined by macro
Choice ch = j.get<Choice>();
}
```
??? example "Example 3: User-defined serialization/deserialization functions"
The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses user-defined functions to parse and serialize the enum.
```cpp
#define JSON_DISABLE_ENUM_SERIALIZATION 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
enum class Choice
{
first,
second,
};
void from_json(const json& j, Choice& ch)
{
auto value = j.get<std::string>();
if (value == "first")
{
ch = Choice::first;
}
else if (value == "second")
{
ch = Choice::second;
}
}
void to_json(json& j, const Choice& ch)
{
auto value = j.get<std::string>();
if (value == "first")
{
ch = Choice::first;
}
else if (value == "second")
{
ch = Choice::second;
}
}
int main()
{
// uses user-defined to_json function
const json j = Choice::first;
// uses user-defined from_json function
Choice ch = j.get<Choice>();
}
```
## See also
- [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md)

View File

@ -78,6 +78,7 @@ inline void from_json(const BasicJsonType& j, type& e);
## See also
- [Specializing enum conversion](../../features/enum_conversion.md)
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
## Version history

View File

@ -58,3 +58,4 @@ Other Important points:
default pair carefully.
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the
map will be returned when converting to or from JSON.
- To disable the default serialization of enumerators as integers and force a compiler error instead, see [`JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md).

View File

@ -54,6 +54,12 @@ Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`.
See [full documentation of `JSON_NOEXCEPTION`](../api/macros/json_noexception.md).
## `JSON_DISABLE_ENUM_SERIALIZATION`
When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md).
See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md).
## `JSON_NO_IO`
When defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostream>` are not included and parse functions

View File

@ -241,6 +241,7 @@ nav:
- 'JSON_ASSERT': api/macros/json_assert.md
- 'JSON_CATCH_USER': api/macros/json_throw_user.md
- 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md
- 'JSON_DISABLE_ENUM_SERIALIZATION': api/macros/json_disable_enum_serialization.md
- 'JSON_HAS_CPP_11': api/macros/json_has_cpp_11.md
- 'JSON_HAS_CPP_14': api/macros/json_has_cpp_11.md
- 'JSON_HAS_CPP_17': api/macros/json_has_cpp_11.md

View File

@ -139,6 +139,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_int
get_arithmetic_value(j, val);
}
#if !JSON_DISABLE_ENUM_SERIALIZATION
template<typename BasicJsonType, typename EnumType,
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
inline void from_json(const BasicJsonType& j, EnumType& e)
@ -147,6 +148,7 @@ inline void from_json(const BasicJsonType& j, EnumType& e)
get_arithmetic_value(j, val);
e = static_cast<EnumType>(val);
}
#endif // JSON_DISABLE_ENUM_SERIALIZATION
// forward_list doesn't have an insert method
template<typename BasicJsonType, typename T, typename Allocator,

View File

@ -313,6 +313,7 @@ inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
}
#if !JSON_DISABLE_ENUM_SERIALIZATION
template<typename BasicJsonType, typename EnumType,
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
inline void to_json(BasicJsonType& j, EnumType e) noexcept
@ -320,6 +321,7 @@ inline void to_json(BasicJsonType& j, EnumType e) noexcept
using underlying_type = typename std::underlying_type<EnumType>::type;
external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
}
#endif // JSON_DISABLE_ENUM_SERIALIZATION
template<typename BasicJsonType>
inline void to_json(BasicJsonType& j, const std::vector<bool>& e)

View File

@ -456,3 +456,7 @@
#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
#endif
#ifndef JSON_DISABLE_ENUM_SERIALIZATION
#define JSON_DISABLE_ENUM_SERIALIZATION 0
#endif

View File

@ -16,6 +16,7 @@
#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
#undef JSON_INLINE_VARIABLE
#undef JSON_NO_UNIQUE_ADDRESS
#undef JSON_DISABLE_ENUM_SERIALIZATION
#ifndef JSON_TEST_KEEP_MACROS
#undef JSON_CATCH

View File

@ -2684,6 +2684,10 @@ using is_detected_convertible =
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
#endif
#ifndef JSON_DISABLE_ENUM_SERIALIZATION
#define JSON_DISABLE_ENUM_SERIALIZATION 0
#endif
#if JSON_HAS_THREE_WAY_COMPARISON
#include <compare> // partial_ordering
#endif
@ -4384,6 +4388,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_int
get_arithmetic_value(j, val);
}
#if !JSON_DISABLE_ENUM_SERIALIZATION
template<typename BasicJsonType, typename EnumType,
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
inline void from_json(const BasicJsonType& j, EnumType& e)
@ -4392,6 +4397,7 @@ inline void from_json(const BasicJsonType& j, EnumType& e)
get_arithmetic_value(j, val);
e = static_cast<EnumType>(val);
}
#endif // JSON_DISABLE_ENUM_SERIALIZATION
// forward_list doesn't have an insert method
template<typename BasicJsonType, typename T, typename Allocator,
@ -5294,6 +5300,7 @@ inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
}
#if !JSON_DISABLE_ENUM_SERIALIZATION
template<typename BasicJsonType, typename EnumType,
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
inline void to_json(BasicJsonType& j, EnumType e) noexcept
@ -5301,6 +5308,7 @@ inline void to_json(BasicJsonType& j, EnumType e) noexcept
using underlying_type = typename std::underlying_type<EnumType>::type;
external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
}
#endif // JSON_DISABLE_ENUM_SERIALIZATION
template<typename BasicJsonType>
inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
@ -23580,6 +23588,7 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std
#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
#undef JSON_INLINE_VARIABLE
#undef JSON_NO_UNIQUE_ADDRESS
#undef JSON_DISABLE_ENUM_SERIALIZATION
#ifndef JSON_TEST_KEEP_MACROS
#undef JSON_CATCH