mirror of
https://github.com/nlohmann/json.git
synced 2026-10-05 22:20:30 +00:00
* Store maps with enum keys as objects (opt-in) Maps with enum keys, such as std::map<E, T>, are stored as arrays of [key, value] pairs, because enums are not convertible to the string type of object keys - even if NLOHMANN_JSON_SERIALIZE_ENUM maps them to strings (#4378). The new JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS macro stores them as objects instead, converting each key with the enum's to_json. It applies to any map-like type with enum keys (std::map with any comparator, std::unordered_map, ...). A key that does not convert to a string throws type_error.302, and two keys converting to the same string throw the new type_error.318, rather than losing an entry. The macro changes the output of inline functions, so it is part of the ABI tag (_ekmo). Reading needs no macro: std::map and std::unordered_map with enum keys are now also read from objects, converting each key with the enum's from_json. That input was rejected before, and arrays of pairs are still read, so data written either way can be read. This supersedes #4531, which first proposed storing these maps as objects. Co-authored-by: Muhammad Amir bin Mohamad Ghazaly <amirghaz@umich.edu> Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Keep multimaps with enum keys as arrays of pairs With JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, is_enum_keyed_map also matched std::multimap and std::unordered_multimap. Storing them as objects throws type_error.318 as soon as a key occurs twice, which is the normal case for a multimap, so such values could no longer be serialized at all once the macro was enabled, although they are stored losslessly as arrays of [key, value] pairs without it. Exclude maps with non-unique keys from is_enum_keyed_map. They are detected by insert(value_type) returning an iterator rather than a pair<iterator, bool>. Map-like types without such an insert() are still treated as before. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Move the default enum-keyed map tests out of unit-conversions.cpp The Windows clang 20.1.8 job (MinGW, Debug) failed to link test-conversions_cpp17 with "relocation truncated to fit: IMAGE_REL_AMD64_REL32 against .rdata": the object file of unit-conversions.cpp was already close to the limit, and the new "maps with enum keys" test case pushed it over. windows.yml asks to keep these objects small by splitting test files. Move the test case unchanged into unit-enum_keyed_maps_default.cpp, with the three enums it needs. It still honors a -D flag for JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, as before. unit-conversions.cpp is back to its state on develop. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Build the enum-keyed map test object instead of parsing it ci_test_diagnostic_positions failed in unit-enum_keyed_maps_default.cpp: with JSON_DIAGNOSTIC_POSITIONS, a parsed value adds its byte range to the exception message ("(bytes 0-7) type must be array, but is object"), so the exact-message checks did not match. Build the object in memory, like unit-custom-array-type.cpp does. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me> Co-authored-by: Muhammad Amir bin Mohamad Ghazaly <amirghaz@umich.edu>
242 lines
8.2 KiB
C++
242 lines
8.2 KiB
C++
// __ _____ _____ _____
|
|
// __| | __| | | | JSON for Modern C++
|
|
// | | |__ | | | | | | version 3.12.0
|
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|
//
|
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
|
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
|
|
|
#include <cstdint> // int64_t, uint64_t
|
|
#include <map> // map
|
|
#include <string> // allocator, string
|
|
#include <vector> // vector
|
|
|
|
// #include <nlohmann/detail/abi_macros.hpp>
|
|
// __ _____ _____ _____
|
|
// __| | __| | | | JSON for Modern C++
|
|
// | | |__ | | | | | | version 3.12.0
|
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|
//
|
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
// This file contains all macro definitions affecting or depending on the ABI
|
|
|
|
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
|
|
#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
|
|
#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0
|
|
#warning "Already included a different version of the library!"
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
|
|
#define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum)
|
|
#define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum)
|
|
|
|
#ifndef JSON_DIAGNOSTICS
|
|
#define JSON_DIAGNOSTICS 0
|
|
#endif
|
|
|
|
#ifndef JSON_DIAGNOSTIC_POSITIONS
|
|
#define JSON_DIAGNOSTIC_POSITIONS 0
|
|
#endif
|
|
|
|
#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
|
|
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
|
|
#endif
|
|
|
|
#ifndef JSON_BRACE_INIT_COPY_SEMANTICS
|
|
#define JSON_BRACE_INIT_COPY_SEMANTICS 0
|
|
#endif
|
|
|
|
#ifndef JSON_PRECISE_STREAM_POSITION
|
|
#define JSON_PRECISE_STREAM_POSITION 0
|
|
#endif
|
|
|
|
#ifndef JSON_STRICT_NUL_HANDLING
|
|
#define JSON_STRICT_NUL_HANDLING 0
|
|
#endif
|
|
|
|
#ifndef JSON_STRICT_BINARY_UTF8
|
|
#define JSON_STRICT_BINARY_UTF8 0
|
|
#endif
|
|
|
|
#ifndef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 0
|
|
#endif
|
|
|
|
#if JSON_DIAGNOSTICS
|
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
|
|
#else
|
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
|
|
#endif
|
|
|
|
#if JSON_DIAGNOSTIC_POSITIONS
|
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp
|
|
#else
|
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS
|
|
#endif
|
|
|
|
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
|
|
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
|
|
#else
|
|
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
|
|
#endif
|
|
|
|
#if JSON_BRACE_INIT_COPY_SEMANTICS
|
|
#define NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS _bics
|
|
#else
|
|
#define NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS
|
|
#endif
|
|
|
|
#if JSON_PRECISE_STREAM_POSITION
|
|
#define NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION _psp
|
|
#else
|
|
#define NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION
|
|
#endif
|
|
|
|
#if JSON_STRICT_NUL_HANDLING
|
|
#define NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING _snul
|
|
#else
|
|
#define NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING
|
|
#endif
|
|
|
|
#if JSON_STRICT_BINARY_UTF8
|
|
#define NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8 _sbu8
|
|
#else
|
|
#define NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8
|
|
#endif
|
|
|
|
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
#define NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS _ekmo
|
|
#else
|
|
#define NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
#endif
|
|
|
|
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
|
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
|
#endif
|
|
|
|
// Construct the namespace ABI tags component
|
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h) json_abi ## a ## b ## c ## d ## e ## f ## g ## h
|
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h) \
|
|
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h)
|
|
|
|
#define NLOHMANN_JSON_ABI_TAGS \
|
|
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
|
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
|
|
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \
|
|
NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS, \
|
|
NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS, \
|
|
NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION, \
|
|
NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING, \
|
|
NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8, \
|
|
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS)
|
|
|
|
// Construct the namespace version component
|
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
|
_v ## major ## _ ## minor ## _ ## patch
|
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
|
|
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
|
|
|
|
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
|
#define NLOHMANN_JSON_NAMESPACE_VERSION
|
|
#else
|
|
#define NLOHMANN_JSON_NAMESPACE_VERSION \
|
|
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
|
|
NLOHMANN_JSON_VERSION_MINOR, \
|
|
NLOHMANN_JSON_VERSION_PATCH)
|
|
#endif
|
|
|
|
// Combine namespace components
|
|
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
|
|
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
|
|
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
|
|
|
|
#ifndef NLOHMANN_JSON_NAMESPACE
|
|
#define NLOHMANN_JSON_NAMESPACE \
|
|
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
|
|
NLOHMANN_JSON_ABI_TAGS, \
|
|
NLOHMANN_JSON_NAMESPACE_VERSION)
|
|
#endif
|
|
|
|
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
|
|
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
|
|
namespace nlohmann \
|
|
{ \
|
|
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
|
|
NLOHMANN_JSON_ABI_TAGS, \
|
|
NLOHMANN_JSON_NAMESPACE_VERSION) \
|
|
{
|
|
#endif
|
|
|
|
#ifndef NLOHMANN_JSON_NAMESPACE_END
|
|
#define NLOHMANN_JSON_NAMESPACE_END \
|
|
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
|
|
} // namespace nlohmann
|
|
#endif
|
|
|
|
|
|
/*!
|
|
@brief namespace for Niels Lohmann
|
|
@see https://github.com/nlohmann
|
|
@since version 1.0.0
|
|
*/
|
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
|
|
|
/*!
|
|
@brief default JSONSerializer template argument
|
|
|
|
This serializer ignores the template arguments and uses ADL
|
|
([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
|
|
for serialization.
|
|
*/
|
|
template<typename T = void, typename SFINAE = void>
|
|
struct adl_serializer; // IWYU pragma: keep
|
|
|
|
/// a class to store JSON values
|
|
/// @sa https://json.nlohmann.me/api/basic_json/
|
|
template<template<typename U, typename V, typename... Args> class ObjectType =
|
|
std::map,
|
|
template<typename U, typename... Args> class ArrayType = std::vector,
|
|
class StringType = std::string, class BooleanType = bool,
|
|
class NumberIntegerType = std::int64_t,
|
|
class NumberUnsignedType = std::uint64_t,
|
|
class NumberFloatType = double,
|
|
template<typename U> class AllocatorType = std::allocator,
|
|
template<typename T, typename SFINAE = void> class JSONSerializer =
|
|
adl_serializer,
|
|
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
|
|
class CustomBaseClass = void>
|
|
class basic_json; // IWYU pragma: keep
|
|
|
|
/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
|
|
/// @sa https://json.nlohmann.me/api/json_pointer/
|
|
template<typename RefStringType>
|
|
class json_pointer; // IWYU pragma: keep
|
|
|
|
/*!
|
|
@brief default specialization
|
|
@sa https://json.nlohmann.me/api/json/
|
|
*/
|
|
using json = basic_json<>;
|
|
|
|
/// @brief a minimal map-like container that preserves insertion order
|
|
/// @sa https://json.nlohmann.me/api/ordered_map/
|
|
template<class Key, class T, class IgnoredLess, class Allocator>
|
|
struct ordered_map; // IWYU pragma: keep
|
|
|
|
/// @brief specialization that maintains the insertion order of object keys
|
|
/// @sa https://json.nlohmann.me/api/ordered_json/
|
|
using ordered_json = basic_json<nlohmann::ordered_map>;
|
|
|
|
NLOHMANN_JSON_NAMESPACE_END
|
|
|
|
#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
|