Add versioned, ABI-tagged inline namespace and namespace macros (#3590)

* Add versioned inline namespace

Add a versioned inline namespace to prevent ABI issues when linking code
using multiple library versions.

* Add namespace macros

* Encode ABI information in inline namespace

Add _diag suffix to inline namespace if JSON_DIAGNOSTICS is enabled, and
_ldvcmp suffix if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON is enabled.

* Move ABI-affecting macros into abi_macros.hpp

* Move std_fs namespace definition into std_fs.hpp

* Remove std_fs namespace from unit test

* Format more files in tests directory

* Add unit tests

* Update documentation

* Fix GDB pretty printer

* fixup! Add namespace macros

* Derive ABI prefix from NLOHMANN_JSON_VERSION_*
pull/3633/head
Florian Albrechtskirchinger 2022-07-30 21:59:13 +02:00 committed by GitHub
parent fca1ddda96
commit d909f80960
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 23116 additions and 561 deletions

View File

@ -15,6 +15,9 @@ SED:=$(shell command -v gsed || which sed)
# the list of sources in the include folder
SRCS=$(shell find include -type f | sort)
# the list of sources in the tests folder
TESTS_SRCS=$(shell find tests -type f \( -name '*.hpp' -o -name '*.cpp' -o -name '*.cu' \) -not -path 'tests/thirdparty/*' | sort)
# the single header (amalgamated from the source files)
AMALGAMATED_FILE=single_include/nlohmann/json.hpp
@ -159,11 +162,11 @@ pretty:
--preserve-date \
--suffix=none \
--formatted \
$(SRCS) $(AMALGAMATED_FILE) tests/src/*.cpp tests/src/*.hpp tests/benchmarks/src/benchmarks.cpp docs/examples/*.cpp
$(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/examples/*.cpp
# call the Clang-Format on all source files
pretty_format:
for FILE in $(SRCS) $(AMALGAMATED_FILE) tests/src/*.cpp tests/src/*.hpp benchmarks/src/benchmarks.cpp docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done
for FILE in $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done
# create single header file
amalgamate: $(AMALGAMATED_FILE)

View File

@ -27,6 +27,11 @@ header. See also the [macro overview page](../../features/macros.md).
- [**JSON_SKIP_LIBRARY_VERSION_CHECK**](json_skip_library_version_check.md) - skip library version check
- [**NLOHMANN_JSON_VERSION_MAJOR**<br>**NLOHMANN_JSON_VERSION_MINOR**<br>**NLOHMANN_JSON_VERSION_PATCH**](nlohmann_json_version_major.md) - library version information
## Library namespace
- [**NLOHMANN_JSON_NAMESPACE**](nlohmann_json_namespace.md) - full name of the `nlohmann` namespace
- [**NLOHMANN_JSON_NAMESPACE_BEGIN**<br>**NLOHMANN_JSON_NAMESPACE_END**](nlohmann_json_namespace_begin.md) - open and close the library namespace
## Type conversions
- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums

View File

@ -26,11 +26,16 @@ When the macro is not defined, the library will define it to its default value.
## Notes
!!! danger "ABI incompatibility"
!!! note "ABI compatibility"
As this macro changes the definition of the `basic_json` object, it MUST be defined in the same way globally, even
across different compilation units: `basic_json` objects with differently defined `JSON_DIAGNOSTICS` macros are
not compatible!
As of version 3.11.0, this macro is no longer required to be defined consistently throughout a codebase to avoid
One Definition Rule (ODR) violations, as the value of this macro is encoded in the namespace, resulting in distinct
symbol names.
This allows different parts of a codebase to use different versions or configurations of this library without
causing improper behavior.
Where possible, it is still recommended that all code define this the same way for maximum interoperability.
## Examples
@ -65,3 +70,4 @@ When the macro is not defined, the library will define it to its default value.
## Version history
- Added in version 3.10.0.
- As of version 3.11.0 the definition is allowed to vary between translation units.

View File

@ -0,0 +1,26 @@
# NLOHMANN_JSON_NAMESPACE
```cpp
#define NLOHMANN_JSON_NAMESPACE
```
This macro evaluates to the full name of the `nlohmann` namespace, including
the name of a versioned and ABI-tagged inline namespace. Use this macro to
unambiguously refer to the `nlohmann` namespace.
## Default definition
The default value consists of a prefix, a version string, and optional ABI tags
depending on whether ABI-affecting macros are defined (e.g.,
[`JSON_DIAGNOSTICS`](json_diagnostics.md), and
[`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](json_use_legacy_discarded_value_comparison.md)).
When the macro is not defined, the library will define it to its default value.
## See also
- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](nlohmann_json_namespace_begin.md)
## Version history
- Added in version 3.11.0.

View File

@ -0,0 +1,40 @@
# NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END
```cpp
#define NLOHMANN_JSON_NAMESPACE_BEGIN // (1)
#define NLOHMANN_JSON_NAMESPACE_END // (2)
```
These macros can be used to open and close the `nlohmann` namespace. They
include an inline namespace used to differentiate symbols when linking multiple
versions (including different ABI-affecting macros) of this library.
1. Opens the namespace.
```cpp
namespace nlohmann
{
inline namespace json_v3_11_0
{
```
2. Closes the namespace.
```cpp
} // namespace nlohmann
} // json_v3_11_0
```
## Default definition
The default definitions open and close the `nlohmann` as well as an inline
namespace.
When these macros are not defined, the library will define them to their
default definitions.
## See also
- [NLOHMANN_JSON_NAMESPACE](nlohmann_json_namespace.md)
## Version history
- Added in version 3.11.0.

View File

@ -155,30 +155,35 @@ To solve this, you need to add a specialization of `adl_serializer` to the `nloh
```cpp
// partial specialization (full specialization works too)
namespace nlohmann {
template <typename T>
struct adl_serializer<boost::optional<T>> {
static void to_json(json& j, const boost::optional<T>& opt) {
if (opt == boost::none) {
j = nullptr;
} else {
j = *opt; // this will call adl_serializer<T>::to_json which will
// find the free function to_json in T's namespace!
}
NLOHMANN_JSON_NAMESPACE_BEGIN
template <typename T>
struct adl_serializer<boost::optional<T>> {
static void to_json(json& j, const boost::optional<T>& opt) {
if (opt == boost::none) {
j = nullptr;
} else {
j = *opt; // this will call adl_serializer<T>::to_json which will
// find the free function to_json in T's namespace!
}
}
static void from_json(const json& j, boost::optional<T>& opt) {
if (j.is_null()) {
opt = boost::none;
} else {
opt = j.get<T>(); // same as above, but with
// adl_serializer<T>::from_json
}
static void from_json(const json& j, boost::optional<T>& opt) {
if (j.is_null()) {
opt = boost::none;
} else {
opt = j.get<T>(); // same as above, but with
// adl_serializer<T>::from_json
}
};
}
}
};
NLOHMANN_JSON_NAMESPACE_END
```
!!! note "ABI compatibility"
Use [`NLOHMANN_JSON_NAMESPACE_BEGIN`](../api/macros/nlohmann_json_namespace_begin.md) and `NLOHMANN_JSON_NAMESPACE_END`
instead of `#!cpp namespace nlohmann { }` in code which may be linked with different versions of this library.
## How can I use `get()` for non-default constructible/non-copyable types?
There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:

View File

@ -264,6 +264,9 @@ nav:
- 'NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT': api/macros/nlohmann_define_type_intrusive.md
- 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE': api/macros/nlohmann_define_type_non_intrusive.md
- 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT': api/macros/nlohmann_define_type_non_intrusive.md
- 'NLOHMANN_JSON_NAMESPACE': api/macros/nlohmann_json_namespace.md
- 'NLOHMANN_JSON_NAMESPACE_BEGIN': api/macros/nlohmann_json_namespace_begin.md
- 'NLOHMANN_JSON_NAMESPACE_END': api/macros/nlohmann_json_namespace_begin.md
- 'NLOHMANN_JSON_SERIALIZE_ENUM': api/macros/nlohmann_json_serialize_enum.md
- 'NLOHMANN_JSON_VERSION_MAJOR': api/macros/nlohmann_json_version_major.md
- 'NLOHMANN_JSON_VERSION_MINOR': api/macros/nlohmann_json_version_major.md

View File

@ -8,16 +8,14 @@
#pragma once
#include <type_traits>
#include <utility>
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/conversions/from_json.hpp>
#include <nlohmann/detail/conversions/to_json.hpp>
#include <nlohmann/detail/meta/identity_tag.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
/// @sa https://json.nlohmann.me/api/adl_serializer/
template<typename ValueType, typename>
@ -53,4 +51,5 @@ struct adl_serializer
::nlohmann::to_json(j, std::forward<TargetType>(val));
}
};
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -12,8 +12,9 @@
#include <tuple> // tie
#include <utility> // move
namespace nlohmann
{
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
/// @brief an internal type for a backed binary type
/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/
@ -99,4 +100,4 @@ class byte_container_with_subtype : public BinaryType
bool m_has_subtype = false;
};
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -0,0 +1,71 @@
#pragma once
// 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 != 10 || NLOHMANN_JSON_VERSION_PATCH != 5
#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 10 // NOLINT(modernize-macro-to-enum)
#define NLOHMANN_JSON_VERSION_PATCH 5 // NOLINT(modernize-macro-to-enum)
#ifndef JSON_DIAGNOSTICS
#define JSON_DIAGNOSTICS 0
#endif
#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
#endif
#if JSON_DIAGNOSTICS
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
#else
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
#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
#define NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch) \
json_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_ABI_PREFIX(major, minor, patch) \
NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch)
#define NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c) a ## b ## c
#define NLOHMANN_JSON_ABI_CONCAT(a, b, c) \
NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c)
#define NLOHMANN_JSON_ABI_STRING \
NLOHMANN_JSON_ABI_CONCAT( \
NLOHMANN_JSON_ABI_PREFIX( \
NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH), \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
#ifndef NLOHMANN_JSON_NAMESPACE
#define NLOHMANN_JSON_NAMESPACE nlohmann::NLOHMANN_JSON_ABI_STRING
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_ABI_STRING \
{
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (abi_string) */ \
} /* namespace nlohmann */
#endif

View File

@ -24,28 +24,15 @@
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/identity_tag.hpp>
#include <nlohmann/detail/meta/std_fs.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp>
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
#include <experimental/filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::experimental::filesystem;
} // namespace nlohmann::detail
#elif JSON_HAS_FILESYSTEM
#include <filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::filesystem;
} // namespace nlohmann::detail
#endif
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
template<typename BasicJsonType>
inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
{
@ -491,6 +478,7 @@ struct from_json_fn
return from_json(j, std::forward<T>(val));
}
};
} // namespace detail
#ifndef JSON_HAS_CPP_17
@ -503,6 +491,7 @@ namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-n
JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
detail::static_const<detail::from_json_fn>::value;
#ifndef JSON_HAS_CPP_17
} // namespace
} // namespace
#endif
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -18,8 +18,7 @@
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
@ -1048,7 +1047,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent,
return append_exponent(buf, n - 1);
}
} // namespace dtoa_impl
} // namespace dtoa_impl
/*!
@brief generates a decimal representation of the floating-point number value in [first, last).
@ -1115,5 +1114,5 @@ char* to_chars(char* first, const char* last, FloatType value)
return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
}
} // namespace detail
} // namespace nlohmann
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@ -17,30 +17,17 @@
#include <valarray> // valarray
#include <vector> // vector
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/std_fs.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp>
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
#include <experimental/filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::experimental::filesystem;
} // namespace nlohmann::detail
#elif JSON_HAS_FILESYSTEM
#include <filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::filesystem;
} // namespace nlohmann::detail
#endif
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
//////////////////
// constructors //
//////////////////
@ -447,6 +434,7 @@ namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-n
JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
detail::static_const<detail::to_json_fn>::value;
#ifndef JSON_HAS_CPP_17
} // namespace
} // namespace
#endif
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -23,10 +23,10 @@
#include <nlohmann/detail/string_concat.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
////////////////
// exceptions //
////////////////
@ -252,4 +252,4 @@ class other_error : public exception
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -12,11 +12,10 @@
#include <cstddef> // size_t
#include <functional> // hash
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/value_t.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
@ -127,4 +126,4 @@ std::size_t hash(const BasicJsonType& j)
}
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -32,8 +32,7 @@
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
@ -2969,5 +2968,6 @@ class binary_reader
/// the SAX parser
json_sax_t* sax = nullptr;
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -26,10 +26,10 @@
#include <nlohmann/detail/iterators/iterator_traits.hpp>
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
/// the supported input formats
enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata };
@ -410,7 +410,7 @@ struct container_input_adapter_factory< ContainerType,
}
};
} // namespace container_input_adapter_factory_impl
} // namespace container_input_adapter_factory_impl
template<typename ContainerType>
typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
@ -489,5 +489,6 @@ class span_input_adapter
private:
contiguous_bytes_input_adapter ia;
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -17,8 +17,7 @@
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/string_concat.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
/*!
@brief SAX interface
@ -724,6 +723,6 @@ class json_sax_acceptor
return false;
}
};
} // namespace detail
} // namespace nlohmann
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@ -22,10 +22,10 @@
#include <nlohmann/detail/input/position_t.hpp>
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
///////////
// lexer //
///////////
@ -1627,5 +1627,6 @@ scan_number_done:
/// the decimal point
const char_int_type decimal_point_char = '.';
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -24,8 +24,7 @@
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
////////////
@ -505,4 +504,4 @@ class parser
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -10,10 +10,12 @@
#include <cstddef> // size_t
namespace nlohmann
{
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
/// struct to capture the start position of the current token
struct position_t
{
@ -31,5 +33,5 @@ struct position_t
}
};
} // namespace detail
} // namespace nlohmann
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@ -8,12 +8,13 @@
#pragma once
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/iterators/primitive_iterator.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
/*!
@brief an iterator value
@ -29,5 +30,6 @@ template<typename BasicJsonType> struct internal_iterator
/// generic iterator for all other types
primitive_iterator_t primitive_iterator {};
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -19,10 +19,10 @@
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
// forward declare, to be able to friend it later on
template<typename IteratorType> class iteration_proxy;
template<typename IteratorType> class iteration_proxy_value;
@ -746,5 +746,6 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
/// the actual iterator of the associated instance
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
};
} // namespace detail
} // namespace nlohmann
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@ -18,13 +18,14 @@
#include <ranges> // enable_borrowed_range
#endif
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
template<typename string_type>
void int_to_string( string_type& target, std::size_t value )
{
@ -201,8 +202,9 @@ auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decl
{
return i.value();
}
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END
// The Addition to the STD Namespace is required to add
// Structured Bindings Support to the iteration_proxy_value class
@ -210,6 +212,7 @@ auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decl
// And see https://github.com/nlohmann/json/pull/1391
namespace std
{
#if defined(__clang__)
// Fix: https://github.com/nlohmann/json/issues/1401
#pragma clang diagnostic push
@ -230,7 +233,8 @@ class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
} // namespace std
} // namespace std
#if JSON_HAS_RANGES
template <typename IteratorType>

View File

@ -10,13 +10,14 @@
#include <iterator> // random_access_iterator_tag
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/meta/void_t.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
template<typename It, typename = void>
struct iterator_types {};
@ -55,5 +56,6 @@ struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
using pointer = T*;
using reference = T&;
};
} // namespace detail
} // namespace nlohmann
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@ -12,10 +12,12 @@
#include <iterator> // reverse_iterator
#include <utility> // declval
namespace nlohmann
{
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
//////////////////////
// reverse_iterator //
//////////////////////
@ -123,5 +125,6 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
return it.operator * ();
}
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -13,10 +13,10 @@
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
/*
@brief an iterator for primitive JSON types
@ -127,5 +127,6 @@ class primitive_iterator_t
return *this;
}
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -27,8 +27,7 @@
#include <nlohmann/detail/string_escape.hpp>
#include <nlohmann/detail/value_t.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
/// @sa https://json.nlohmann.me/api/json_pointer/
@ -897,4 +896,5 @@ inline bool operator!=(json_pointer<RefStringTypeLhs> const& lhs,
{
return !(lhs == rhs);
}
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -11,12 +11,13 @@
#include <initializer_list>
#include <utility>
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
template<typename BasicJsonType>
class json_ref
{
@ -72,5 +73,6 @@ class json_ref
mutable value_type owned_value = nullptr;
value_type const* value_ref = nullptr;
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -9,12 +9,14 @@
#pragma once
#include <utility> // declval, pair
#include <nlohmann/thirdparty/hedley/hedley.hpp>
#include <nlohmann/detail/meta/detected.hpp>
#include <nlohmann/thirdparty/hedley/hedley.hpp>
// This file contains all internal macro definitions
// This file contains all internal macro definitions (except those affecting ABI)
// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
#include <nlohmann/detail/abi_macros.hpp>
// exclude unsupported compilers
#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
#if defined(__clang__)
@ -457,14 +459,6 @@
#define JSON_EXPLICIT explicit
#endif
#ifndef JSON_DIAGNOSTICS
#define JSON_DIAGNOSTICS 0
#endif
#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

@ -10,7 +10,8 @@
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -10,7 +10,8 @@
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -15,8 +15,7 @@
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
@ -164,4 +163,4 @@ struct static_const
#endif
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -12,11 +12,11 @@
#include <nlohmann/detail/meta/void_t.hpp>
// https://en.cppreference.com/w/cpp/experimental/is_detected
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
// https://en.cppreference.com/w/cpp/experimental/is_detected
struct nonesuch
{
nonesuch() = delete;
@ -65,5 +65,6 @@ using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
template<class To, template<class...> class Op, class... Args>
using is_detected_convertible =
std::is_convertible<detected_t<Op, Args...>, To>;
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -8,11 +8,14 @@
#pragma once
namespace nlohmann
{
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
// dispatching helper struct
template <class T> struct identity_tag {};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -12,13 +12,14 @@
#include <utility> // declval
#include <string> // string
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/meta/detected.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
template<typename T>
using null_function_t = decltype(std::declval<T&>().null());
@ -153,5 +154,6 @@ struct is_sax_static_asserts
"Missing/invalid function: bool parse_error(std::size_t, const "
"std::string&, const exception&)");
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -0,0 +1,21 @@
#pragma once
#include <nlohmann/detail/macro_scope.hpp>
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
#include <experimental/filesystem>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace std_fs = std::experimental::filesystem;
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END
#elif JSON_HAS_FILESYSTEM
#include <filesystem>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace std_fs = std::filesystem;
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END
#endif

View File

@ -13,17 +13,15 @@
#include <utility> // declval
#include <tuple> // tuple
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/iterators/iterator_traits.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/call_std/begin.hpp>
#include <nlohmann/detail/meta/call_std/end.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/detected.hpp>
#include <nlohmann/json_fwd.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
/*!
@brief detail namespace with internal helper functions
@ -34,6 +32,7 @@ implementations of some @ref basic_json methods, and meta-programming helpers.
*/
namespace detail
{
/////////////
// helpers //
/////////////
@ -686,4 +685,4 @@ inline constexpr bool value_in_range_of(T val)
}
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -8,14 +8,17 @@
#pragma once
namespace nlohmann
{
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
template<typename ...Ts> struct make_void
{
using type = void;
};
template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
} // namespace detail
} // namespace nlohmann
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@ -24,10 +24,10 @@
#include <nlohmann/detail/output/output_adapters.hpp>
#include <nlohmann/detail/string_concat.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
///////////////////
// binary writer //
///////////////////
@ -1833,5 +1833,6 @@ class binary_writer
/// the output
output_adapter_t<CharType> oa = nullptr;
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -22,10 +22,10 @@
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
/// abstract output adapter interface
template<typename CharType> struct output_adapter_protocol
{
@ -142,5 +142,6 @@ class output_adapter
private:
output_adapter_t<CharType> oa = nullptr;
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -31,10 +31,10 @@
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
///////////////////
// serialization //
///////////////////
@ -983,5 +983,6 @@ class serializer
/// error_handler how to react on decoding errors
const error_handler_t error_handler;
};
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -15,8 +15,7 @@
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/detected.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
@ -143,5 +142,5 @@ inline OutStringType concat(Args && ... args)
return str;
}
} // namespace detail
} // namespace nlohmann
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@ -8,10 +8,9 @@
#pragma once
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/abi_macros.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
@ -69,5 +68,5 @@ static void unescape(StringType& s)
replace_substring(s, StringType{"~0"}, StringType{"~"});
}
} // namespace detail
} // namespace nlohmann
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@ -18,10 +18,10 @@
#include <compare> // partial_ordering
#endif
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
///////////////////////////
// JSON type enumeration //
///////////////////////////
@ -113,5 +113,6 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
return std::is_lt(lhs <=> rhs); // *NOPAD*
}
#endif
} // namespace detail
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

View File

@ -18,18 +18,6 @@
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
#define INCLUDE_NLOHMANN_JSON_HPP_
#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 != 10 || NLOHMANN_JSON_VERSION_PATCH != 5
#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 10 // NOLINT(modernize-macro-to-enum)
#define NLOHMANN_JSON_VERSION_PATCH 5 // NOLINT(modernize-macro-to-enum)
#include <algorithm> // all_of, find, for_each
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
#include <functional> // hash, less
@ -83,8 +71,7 @@
@see https://github.com/nlohmann
@since version 1.0.0
*/
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
/*!
@brief a class to store JSON values
@ -5087,7 +5074,7 @@ std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
return j.dump();
}
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END
///////////////////////
// nonmember support //
@ -5141,7 +5128,7 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC
#endif
} // namespace std
} // namespace std
/// @brief user-defined string literal for JSON values
/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/

View File

@ -15,13 +15,15 @@
#include <string> // string
#include <vector> // vector
#include <nlohmann/detail/abi_macros.hpp>
/*!
@brief namespace for Niels Lohmann
@see https://github.com/nlohmann
@since version 1.0.0
*/
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
/*!
@brief default JSONSerializer template argument
@ -67,6 +69,6 @@ struct ordered_map;
/// @sa https://json.nlohmann.me/api/ordered_json/
using ordered_json = basic_json<nlohmann::ordered_map>;
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END
#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_

View File

@ -20,8 +20,7 @@
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
namespace nlohmann
{
NLOHMANN_JSON_NAMESPACE_BEGIN
/// ordered_map: a minimal map-like container that preserves insertion order
/// for use within nlohmann::basic_json<ordered_map>
@ -357,4 +356,4 @@ private:
JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
};
} // namespace nlohmann
NLOHMANN_JSON_NAMESPACE_END

File diff suppressed because it is too large Load Diff

View File

@ -147,6 +147,12 @@ json_test_add_test_for(src/unit-comparison.cpp
# *DO NOT* use json_test_set_test_options() below this line
#############################################################################
# test ABI compatibility
#############################################################################
add_subdirectory(abi)
#############################################################################
# Test the generated build configs
#############################################################################

View File

@ -0,0 +1,29 @@
# common build settings
add_library(abi_compat_common INTERFACE)
target_compile_definitions(abi_compat_common INTERFACE
DOCTEST_CONFIG_SUPER_FAST_ASSERTS
JSON_TEST_KEEP_MACROS)
target_compile_features(abi_compat_common INTERFACE cxx_std_11)
target_compile_options(abi_compat_common INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
# MSVC: Force to always compile with W4
$<$<CXX_COMPILER_ID:MSVC>:/W4>
# https://github.com/nlohmann/json/pull/3229
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>)
target_include_directories(abi_compat_common SYSTEM INTERFACE
../thirdparty/doctest
include)
target_link_libraries(abi_compat_common INTERFACE ${NLOHMANN_JSON_TARGET_NAME})
# shared main()
add_library(abi_compat_main STATIC main.cpp)
target_link_libraries(abi_compat_main PUBLIC abi_compat_common)
# add individual tests
add_subdirectory(diag)
add_subdirectory(inline_ns)

View File

@ -0,0 +1,19 @@
# test linking library built with different JSON_DIAGNOSTICS setting
# into the same executable
# compile code using JSON_DIAGNOSTICS=1
add_library(abi_compat_diag_on STATIC diag_on.cpp)
target_link_libraries(abi_compat_diag_on PUBLIC abi_compat_common)
# compile code using JSON_DIAGNOSTICS=0
add_library(abi_compat_diag_off STATIC diag_off.cpp)
target_link_libraries(abi_compat_diag_off PUBLIC abi_compat_common)
# build test executable and add test
add_executable(abi_compat_diag diag.cpp)
target_link_libraries(abi_compat_diag PRIVATE
abi_compat_main abi_compat_diag_on abi_compat_diag_off)
add_test(
NAME test-abi_compat_diag
COMMAND abi_compat_diag ${DOCTEST_TEST_FILTER})

View File

@ -0,0 +1,21 @@
#include "doctest_compatibility.h"
#include "diag.hpp"
TEST_CASE("ABI compatible diagnostics")
{
SECTION("basic_json size")
{
// basic_json with diagnostics is larger because of added data members
CHECK(json_sizeof_diag_on() == json_sizeof_diag_on_explicit());
CHECK(json_sizeof_diag_off() == json_sizeof_diag_off_explicit());
CHECK(json_sizeof_diag_on() > json_sizeof_diag_off());
}
SECTION("basic_json at")
{
// accessing a nonexistent key throws different exception with diagnostics
CHECK_THROWS_WITH(json_at_diag_on(), "[json.exception.out_of_range.403] (/foo) key 'bar' not found");
CHECK_THROWS_WITH(json_at_diag_off(), "[json.exception.out_of_range.403] key 'bar' not found");
}
}

View File

@ -0,0 +1,12 @@
#pragma once
#include <cstddef>
std::size_t json_sizeof_diag_on();
std::size_t json_sizeof_diag_on_explicit();
std::size_t json_sizeof_diag_off();
std::size_t json_sizeof_diag_off_explicit();
void json_at_diag_on();
void json_at_diag_off();

View File

@ -0,0 +1,22 @@
#undef JSON_DIAGNOSTICS
#define JSON_DIAGNOSTICS 0
#include <nlohmann/json.hpp>
#include "diag.hpp"
std::size_t json_sizeof_diag_off()
{
return sizeof(nlohmann::json);
}
std::size_t json_sizeof_diag_off_explicit()
{
return sizeof(::NLOHMANN_JSON_NAMESPACE::json);
}
void json_at_diag_off()
{
using nlohmann::json;
json j = json{{"foo", json::object()}};
j.at(json::json_pointer("/foo/bar"));
}

View File

@ -0,0 +1,22 @@
#undef JSON_DIAGNOSTICS
#define JSON_DIAGNOSTICS 1
#include <nlohmann/json.hpp>
#include "diag.hpp"
std::size_t json_sizeof_diag_on()
{
return sizeof(nlohmann::json);
}
std::size_t json_sizeof_diag_on_explicit()
{
return sizeof(::NLOHMANN_JSON_NAMESPACE::json);
}
void json_at_diag_on()
{
using nlohmann::json;
json j = json{{"foo", json::object()}};
j.at(json::json_pointer("/foo/bar"));
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
# test linking an old library version without an inline namespace
# with the current library using an inline namespace into the same executable
# build test executable and add test
add_executable(abi_compat_inline_ns
use_v3_10_5.cpp
use_current.cpp)
target_link_libraries(abi_compat_inline_ns PRIVATE abi_compat_main)
add_test(
NAME test-abi_compat_inline_ns
COMMAND abi_compat_inline_ns ${DOCTEST_TEST_FILTER})

View File

@ -0,0 +1,28 @@
#include "doctest_compatibility.h"
#include <nlohmann/json.hpp>
TEST_CASE("use current library with inline namespace")
{
SECTION("implicitly")
{
using nlohmann::json;
using nlohmann::ordered_json;
json j;
// In v3.10.5 mixing json_pointers of different basic_json types
// results in implicit string conversion
j[ordered_json::json_pointer("/root")] = json::object();
CHECK(j.dump() == "{\"root\":{}}");
}
SECTION("explicitly")
{
using NLOHMANN_JSON_NAMESPACE::json;
using NLOHMANN_JSON_NAMESPACE::ordered_json;
json j;
j[ordered_json::json_pointer("/root")] = json::object();
CHECK(j.dump() == "{\"root\":{}}");
}
}

View File

@ -0,0 +1,14 @@
#include "doctest_compatibility.h"
#include <nlohmann/json_v3_10_5.hpp>
using nlohmann::json;
using nlohmann::ordered_json;
TEST_CASE("use library v3.10.5 without inline namespace")
{
json j;
j[ordered_json::json_pointer("/root")] = json::object();
// In v3.10.5 mixing json_pointers of different basic_json types
// results in implicit string conversion
CHECK(j.dump() == "{\"/root\":{}}");
}

31
tests/abi/main.cpp 100644
View File

@ -0,0 +1,31 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.10.5
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
SPDX-License-Identifier: MIT
Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest_compatibility.h"

View File

@ -1,6 +1,6 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
int main(int argc, char** argv)
{
nlohmann::json j;

View File

@ -1,6 +1,6 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
int main(int argc, char** argv)
{
nlohmann::json j;

View File

@ -1,6 +1,6 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
int main(int argc, char** argv)
{
nlohmann::json j;

View File

@ -1,6 +1,6 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
int main(int argc, char** argv)
{
nlohmann::json j;

View File

@ -1,6 +1,6 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
int main(int argc, char** argv)
{
nlohmann::json j;

View File

@ -1,4 +1,4 @@
#include <nlohmann/json.hpp>
#include "Foo.hpp"
class Bar : public Foo{};
class Bar : public Foo {};

View File

@ -1,4 +1,4 @@
#pragma once
#include <nlohmann/json.hpp>
class Foo{};
class Foo {};

View File

@ -1,6 +1,6 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
int main(int argc, char** argv)
{
nlohmann::json j;

View File

@ -33,20 +33,6 @@ using ordered_json = nlohmann::ordered_json;
#include <variant>
#endif
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
#include <experimental/filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::experimental::filesystem;
} // namespace nlohmann::detail
#elif JSON_HAS_FILESYSTEM
#include <filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::filesystem;
} // namespace nlohmann::detail
#endif
#ifdef JSON_HAS_CPP_20
#include <span>
#endif

View File

@ -50,7 +50,8 @@ File [nlohmann-json.py](nlohmann-json.py) contains a pretty printer for GDB for
}
```
Tested with GDB 9.2. See [#1952](https://github.com/nlohmann/json/issues/1952) for more information. Please post questions there.
Requires Python 3.9+. Last tested with GDB 12.1.
See [#1952](https://github.com/nlohmann/json/issues/1952) for more information. Please post questions there.
## Copyright

View File

@ -1,5 +1,7 @@
import gdb
import re
ns_pattern = re.compile(r'nlohmann::json_v(?P<v_major>\d+)_(?P<v_minor>\d+)_(?P<v_patch>\d+)(?P<tags>\w*)::(?P<name>.+)')
class JsonValuePrinter:
"Print a json-value"
@ -12,12 +14,14 @@ class JsonValuePrinter:
return self.val
def json_lookup_function(val):
name = val.type.strip_typedefs().name
if name and name.startswith("nlohmann::basic_json<") and name.endswith(">"):
t = str(val['m_type'])
if t.startswith("nlohmann::detail::value_t::"):
m = ns_pattern.fullmatch(val.type.strip_typedefs().name)
name = m.group('name')
if name and name.startswith('basic_json<') and name.endswith('>'):
m = ns_pattern.fullmatch(str(val['m_type']))
t = m.group('name')
if t and t.startswith('detail::value_t::'):
try:
union_val = val['m_value'][t[27:]]
union_val = val['m_value'][t.removeprefix('detail::value_t::')]
if union_val.type.code == gdb.TYPE_CODE_PTR:
return gdb.default_visualizer(union_val.dereference())
else: