mirror of
https://github.com/nlohmann/json.git
synced 2026-09-29 11:10:30 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
056d187986 | ||
|
|
90078597c7 | ||
|
|
fa28fff7d6 | ||
|
|
e9c84befa1 | ||
|
|
8a26f2dc8f | ||
|
|
2c108d0b56 |
@@ -31,45 +31,6 @@ jobs:
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_gcc
|
||||
|
||||
ci_meson_install:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
|
||||
- name: Install Meson
|
||||
run: pip install meson
|
||||
- name: Install with Meson
|
||||
run: |
|
||||
meson setup build-meson --prefix=${{ github.workspace }}/install
|
||||
meson install -C build-meson
|
||||
- name: Use the installed package with find_package
|
||||
run: |
|
||||
cmake -S tests/cmake_import/project -B build-import -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install
|
||||
cmake --build build-import
|
||||
- name: Install with Meson and non-default options
|
||||
run: |
|
||||
meson setup build-meson-options --prefix=${{ github.workspace }}/install-options -DMultipleHeaders=true -DDiagnostics=true -DGlobalUDLs=false
|
||||
meson install -C build-meson-options
|
||||
- name: Check that the options reach the installed files
|
||||
run: |
|
||||
test -d install-options/include/nlohmann/detail
|
||||
cflags=$(PKG_CONFIG_PATH=${{ github.workspace }}/install-options/share/pkgconfig pkg-config --cflags nlohmann_json)
|
||||
echo "$cflags"
|
||||
echo "$cflags" | grep -q -- '-DJSON_DIAGNOSTICS=1'
|
||||
echo "$cflags" | grep -q -- '-DJSON_USE_GLOBAL_UDLS=0'
|
||||
grep -q 'JSON_USE_GLOBAL_UDLS=0;JSON_DIAGNOSTICS=1' install-options/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake
|
||||
cmake -S tests/cmake_import/project -B build-import-options -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install-options
|
||||
cmake --build build-import-options
|
||||
- name: Install with Meson and the include directory outside the prefix
|
||||
run: |
|
||||
meson setup build-meson-split --prefix=${{ github.workspace }}/install-split --includedir=${{ github.workspace }}/install-split-dev/include
|
||||
meson install -C build-meson-split
|
||||
cmake -S tests/cmake_import/project -B build-import-split -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install-split
|
||||
cmake --build build-import-split
|
||||
|
||||
ci_infer:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
+1
-24
@@ -168,30 +168,7 @@ if (MSVC)
|
||||
)
|
||||
endif()
|
||||
|
||||
# Install a pkg-config file, so other tools can find this. It carries the same
|
||||
# compile definitions as the target above.
|
||||
set(NLOHMANN_JSON_PKGCONFIG_CFLAGS "")
|
||||
if (NOT JSON_GlobalUDLs)
|
||||
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_GLOBAL_UDLS=0")
|
||||
endif()
|
||||
if (NOT JSON_ImplicitConversions)
|
||||
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_IMPLICIT_CONVERSIONS=0")
|
||||
endif()
|
||||
if (JSON_DisableEnumSerialization)
|
||||
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DISABLE_ENUM_SERIALIZATION=1")
|
||||
endif()
|
||||
if (JSON_Diagnostics)
|
||||
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DIAGNOSTICS=1")
|
||||
endif()
|
||||
if (JSON_Diagnostic_Positions)
|
||||
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DIAGNOSTIC_POSITIONS=1")
|
||||
endif()
|
||||
if (JSON_LegacyDiscardedValueComparison)
|
||||
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1")
|
||||
endif()
|
||||
if (JSON_StrictNulHandling)
|
||||
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_STRICT_NUL_HANDLING=1")
|
||||
endif()
|
||||
# Install a pkg-config file, so other tools can find this.
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
|
||||
|
||||
@@ -260,29 +260,9 @@ make BUILD.bazel
|
||||
|
||||
The "Check amalgamation" workflow fails if the file is out of date.
|
||||
|
||||
### `meson.build` and `meson_options.txt`
|
||||
### `meson.build`
|
||||
|
||||
Meson build definitions suitable for use as a subproject ("wrap" in Meson terminology).
|
||||
|
||||
Projects wishing to use the wrap can execute:
|
||||
```sh
|
||||
meson wrap install nlohmann_json
|
||||
```
|
||||
|
||||
Which allows Meson to build from source when a system provided dependency isn't available.
|
||||
|
||||
To build directly:
|
||||
```sh
|
||||
meson setup builddir
|
||||
ninja -C builddir
|
||||
```
|
||||
|
||||
`meson_options.txt` defines the options, which mirror the CMake options that change the library's target (for example,
|
||||
`-DDiagnostics=true`). Meson requires this file next to `meson.build`, so it is also part of `include.zip`.
|
||||
|
||||
When installing, `meson.build` installs the headers, a pkg-config file, and the CMake package config files, so that
|
||||
`find_package(nlohmann_json)` works. As Meson cannot generate `nlohmann_jsonTargets.cmake` itself, it is created from
|
||||
the template `cmake/nlohmann_jsonTargets.cmake.in`, which is only used by Meson.
|
||||
The build definition for the [Meson](https://mesonbuild.com) build system.
|
||||
|
||||
### `Package.swift`
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ json.tar.xz:
|
||||
# We use `-X` to make the resulting ZIP file reproducible, see
|
||||
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
|
||||
include.zip: BUILD.bazel
|
||||
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) BUILD.bazel MODULE.bazel meson.build meson_options.txt LICENSE.MIT
|
||||
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT
|
||||
|
||||
# Create the files for a release and add signatures and hashes.
|
||||
release: include.zip json.tar.xz
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
# Imported target for installations made with Meson (see meson.build).
|
||||
#
|
||||
# CMake installations generate this file with install(EXPORT ...). Meson cannot
|
||||
# do that, but as the library is header-only, the target only needs an include
|
||||
# directory, the C++ standard, and the compile definitions of the options that
|
||||
# differ from their defaults. Paths are computed relative to this file so that
|
||||
# the installation can be relocated (e.g., into a sysroot), unless includedir or
|
||||
# datadir is outside the prefix.
|
||||
|
||||
if(TARGET @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@)
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_CONFIG_TO_PREFIX@" ABSOLUTE)
|
||||
|
||||
add_library(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ INTERFACE IMPORTED)
|
||||
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "@NLOHMANN_JSON_INCLUDE_DIR@"
|
||||
)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.8)
|
||||
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
|
||||
INTERFACE_COMPILE_FEATURES cxx_range_for
|
||||
)
|
||||
else()
|
||||
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
|
||||
INTERFACE_COMPILE_FEATURES cxx_std_11
|
||||
)
|
||||
endif()
|
||||
|
||||
set(_NLOHMANN_JSON_COMPILE_DEFINITIONS "@NLOHMANN_JSON_COMPILE_DEFINITIONS@")
|
||||
if(_NLOHMANN_JSON_COMPILE_DEFINITIONS)
|
||||
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "${_NLOHMANN_JSON_COMPILE_DEFINITIONS}"
|
||||
)
|
||||
endif()
|
||||
|
||||
unset(_NLOHMANN_JSON_COMPILE_DEFINITIONS)
|
||||
unset(_IMPORT_PREFIX)
|
||||
@@ -4,4 +4,4 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
Name: @PROJECT_NAME@
|
||||
Description: JSON for Modern C++
|
||||
Version: @PROJECT_VERSION@
|
||||
Cflags: -I${includedir}@NLOHMANN_JSON_PKGCONFIG_CFLAGS@
|
||||
Cflags: -I${includedir}
|
||||
|
||||
@@ -121,23 +121,10 @@ meson wrap install nlohmann_json
|
||||
Please see the Meson project for any issues regarding the packaging.
|
||||
|
||||
The provided `meson.build` can also be used as an alternative to CMake for installing `nlohmann_json` system-wide in
|
||||
which case a pkg-config file and the CMake package config files are installed. To use it, have your build system require
|
||||
the `nlohmann_json` pkg-config dependency, or use [`find_package(nlohmann_json)`](cmake.md#external) in CMake. In Meson,
|
||||
it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a
|
||||
subproject fallback, rather than using the subproject directly.
|
||||
|
||||
The options that change the library's configuration are available in Meson as well, named like the
|
||||
[CMake options](cmake.md#cmake-options) without the `JSON_` prefix: `MultipleHeaders`, `GlobalUDLs`,
|
||||
`ImplicitConversions`, `DisableEnumSerialization`, `Diagnostics`, `Diagnostic_Positions`,
|
||||
`LegacyDiscardedValueComparison`, and `StrictNulHandling`. They have the same defaults as in CMake, except that
|
||||
`MultipleHeaders` is `false`. Set them with `-D` when setting up the build, or with the subproject name as prefix when
|
||||
the library is used as a subproject:
|
||||
|
||||
```shell
|
||||
meson setup build -Dnlohmann_json:Diagnostics=true
|
||||
```
|
||||
|
||||
The resulting compile definitions are part of the Meson dependency, the pkg-config file, and the CMake target.
|
||||
which case a pkg-config file is installed. To use it, have your build system require the `nlohmann_json`
|
||||
pkg-config dependency. In Meson, it is preferred to use the
|
||||
[`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than
|
||||
using the subproject directly.
|
||||
|
||||
??? example "Example: Wrap"
|
||||
|
||||
|
||||
@@ -42,6 +42,10 @@ namespace detail
|
||||
* j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
|
||||
* allocated value (e.g., a string). See bug issue
|
||||
* https://github.com/nlohmann/json/issues/2865 for more information.
|
||||
*
|
||||
* A value that has to be allocated is created before the old one is destroyed:
|
||||
* were it the other way around, an exception while creating the new value would
|
||||
* leave j with the type of the new value, but the pointer to the destroyed old one.
|
||||
*/
|
||||
|
||||
template<value_t> struct external_constructor;
|
||||
@@ -65,18 +69,20 @@ struct external_constructor<value_t::string>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(s);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value = s;
|
||||
j.m_data.m_value = value;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(std::move(s));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value = std::move(s);
|
||||
j.m_data.m_value = value;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@@ -85,9 +91,10 @@ struct external_constructor<value_t::string>
|
||||
int > = 0 >
|
||||
static void construct(BasicJsonType& j, const CompatibleStringType& str)
|
||||
{
|
||||
auto* created = j.template create<typename BasicJsonType::string_t>(str);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
|
||||
j.m_data.m_value.string = created;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@@ -98,18 +105,20 @@ struct external_constructor<value_t::binary>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(b);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::binary;
|
||||
j.m_data.m_value = typename BasicJsonType::binary_t(b);
|
||||
j.m_data.m_value = value;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(std::move(b));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::binary;
|
||||
j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
|
||||
j.m_data.m_value = value;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@@ -159,9 +168,10 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(arr);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = arr;
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -169,9 +179,10 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(std::move(arr));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = std::move(arr);
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -187,9 +198,10 @@ struct external_constructor<value_t::array>
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
auto* created = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
|
||||
j.m_data.m_value.array = created;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -197,15 +209,17 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const std::vector<bool>& arr)
|
||||
{
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value_t::array;
|
||||
j.m_data.m_value.array->reserve(arr.size());
|
||||
typename BasicJsonType::array_t elements;
|
||||
elements.reserve(arr.size());
|
||||
for (const bool x : arr)
|
||||
{
|
||||
j.m_data.m_value.array->push_back(x);
|
||||
j.set_parent(j.m_data.m_value.array->back());
|
||||
elements.push_back(x);
|
||||
}
|
||||
const typename BasicJsonType::json_value value(std::move(elements));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@@ -213,11 +227,12 @@ struct external_constructor<value_t::array>
|
||||
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
||||
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
|
||||
{
|
||||
typename BasicJsonType::array_t elements(arr.size());
|
||||
std::copy(std::begin(arr), std::end(arr), elements.begin());
|
||||
const typename BasicJsonType::json_value value(std::move(elements));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value_t::array;
|
||||
j.m_data.m_value.array->resize(arr.size());
|
||||
std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -229,14 +244,16 @@ struct external_constructor<value_t::array>
|
||||
enable_if_t<is_compatible_range_view<std::remove_cvref_t<CompatibleArrayType>>::value, int> = 0>
|
||||
static void construct(BasicJsonType& j, CompatibleArrayType && arr)
|
||||
{
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value_t::array;
|
||||
typename BasicJsonType::array_t elements;
|
||||
for (auto&& x : std::forward<CompatibleArrayType>(arr))
|
||||
{
|
||||
j.m_data.m_value.array->push_back(x);
|
||||
j.set_parent(j.m_data.m_value.array->back());
|
||||
elements.push_back(x);
|
||||
}
|
||||
const typename BasicJsonType::json_value value(std::move(elements));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
#endif
|
||||
@@ -248,9 +265,10 @@ struct external_constructor<value_t::object>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(obj);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value = obj;
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -258,9 +276,10 @@ struct external_constructor<value_t::object>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(std::move(obj));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value = std::move(obj);
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -272,9 +291,10 @@ struct external_constructor<value_t::object>
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
auto* created = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
|
||||
j.m_data.m_value.object = created;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
+15
-15
@@ -1702,8 +1702,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_an_object)
|
||||
{
|
||||
// the initializer list is a list of pairs -> create an object
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value = value_t::object;
|
||||
m_data.m_type = value_t::object;
|
||||
|
||||
for (auto& element_ref : init)
|
||||
{
|
||||
@@ -1725,8 +1725,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
#endif
|
||||
// the initializer list describes an array -> create an array
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value.array = create<array_t>(init.begin(), init.end());
|
||||
m_data.m_type = value_t::array;
|
||||
}
|
||||
|
||||
set_parents();
|
||||
@@ -1739,8 +1739,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static basic_json binary(const typename binary_t::container_type& init)
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_data.m_type = value_t::binary;
|
||||
res.m_data.m_value = init;
|
||||
res.m_data.m_type = value_t::binary;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1750,8 +1750,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_data.m_type = value_t::binary;
|
||||
res.m_data.m_value = binary_t(init, subtype);
|
||||
res.m_data.m_type = value_t::binary;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1761,8 +1761,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static basic_json binary(typename binary_t::container_type&& init)
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_data.m_type = value_t::binary;
|
||||
res.m_data.m_value = std::move(init);
|
||||
res.m_data.m_type = value_t::binary;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1772,8 +1772,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_data.m_type = value_t::binary;
|
||||
res.m_data.m_value = binary_t(std::move(init), subtype);
|
||||
res.m_data.m_type = value_t::binary;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -2819,8 +2819,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// implicitly convert a null value to an empty array
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value.array = create<array_t>();
|
||||
m_data.m_type = value_t::array;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -2879,8 +2879,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// implicitly convert a null value to an empty object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value.object = create<object_t>();
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -2932,8 +2932,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// implicitly convert a null value to an empty object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value.object = create<object_t>();
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -3868,8 +3868,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an array
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value = value_t::array;
|
||||
m_data.m_type = value_t::array;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -3901,8 +3901,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an array
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value = value_t::array;
|
||||
m_data.m_type = value_t::array;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -3933,8 +3933,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value = value_t::object;
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -3989,8 +3989,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an array
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value = value_t::array;
|
||||
m_data.m_type = value_t::array;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -4014,8 +4014,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value = value_t::object;
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -4196,8 +4196,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// implicitly convert a null value to an empty object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value.object = create<object_t>();
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
|
||||
+8
-96
@@ -2,111 +2,23 @@ project('nlohmann_json',
|
||||
'cpp',
|
||||
version : '3.12.0',
|
||||
license : 'MIT',
|
||||
meson_version : '>= 0.64',
|
||||
default_options: ['cpp_std=c++11'],
|
||||
)
|
||||
|
||||
if get_option('MultipleHeaders')
|
||||
incdir = 'include'
|
||||
else
|
||||
incdir = 'single_include'
|
||||
endif
|
||||
|
||||
# The same compile definitions as the CMake target (see target_compile_definitions
|
||||
# in CMakeLists.txt): only an option that differs from its default adds one.
|
||||
json_defines = []
|
||||
if not get_option('GlobalUDLs')
|
||||
json_defines += 'JSON_USE_GLOBAL_UDLS=0'
|
||||
endif
|
||||
if not get_option('ImplicitConversions')
|
||||
json_defines += 'JSON_USE_IMPLICIT_CONVERSIONS=0'
|
||||
endif
|
||||
if get_option('DisableEnumSerialization')
|
||||
json_defines += 'JSON_DISABLE_ENUM_SERIALIZATION=1'
|
||||
endif
|
||||
if get_option('Diagnostics')
|
||||
json_defines += 'JSON_DIAGNOSTICS=1'
|
||||
endif
|
||||
if get_option('Diagnostic_Positions')
|
||||
json_defines += 'JSON_DIAGNOSTIC_POSITIONS=1'
|
||||
endif
|
||||
if get_option('LegacyDiscardedValueComparison')
|
||||
json_defines += 'JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1'
|
||||
endif
|
||||
if get_option('StrictNulHandling')
|
||||
json_defines += 'JSON_STRICT_NUL_HANDLING=1'
|
||||
endif
|
||||
|
||||
cpp_args = []
|
||||
foreach define : json_defines
|
||||
cpp_args += '-D' + define
|
||||
endforeach
|
||||
|
||||
nlohmann_json_dep = declare_dependency(
|
||||
compile_args: cpp_args,
|
||||
include_directories: include_directories(incdir)
|
||||
include_directories: include_directories('single_include')
|
||||
)
|
||||
meson.override_dependency('nlohmann_json', nlohmann_json_dep)
|
||||
|
||||
# The multi-header version under the name earlier versions of this file used
|
||||
nlohmann_json_multiple_headers = declare_dependency(
|
||||
compile_args: cpp_args,
|
||||
include_directories: include_directories('include')
|
||||
)
|
||||
|
||||
if not meson.is_subproject()
|
||||
install_subdir(
|
||||
incdir / 'nlohmann',
|
||||
install_dir: get_option('includedir'),
|
||||
install_tag: 'devel',
|
||||
)
|
||||
install_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann')
|
||||
install_headers('single_include/nlohmann/json_fwd.hpp', subdir: 'nlohmann')
|
||||
|
||||
pkgc = import('pkgconfig')
|
||||
pkgc.generate(name: 'nlohmann_json',
|
||||
version: meson.project_version(),
|
||||
description: 'JSON for Modern C++',
|
||||
extra_cflags: cpp_args,
|
||||
install_dir: get_option('datadir') / 'pkgconfig',
|
||||
)
|
||||
|
||||
# CMake package config files, so that find_package(nlohmann_json) works. The
|
||||
# include directory is given relative to the config files, so that the
|
||||
# installation can be relocated. This is not possible if includedir or datadir
|
||||
# is an absolute path outside the prefix (e.g., with the separate outputs of
|
||||
# Nix); then the absolute include directory is used, as CMake does.
|
||||
fs = import('fs')
|
||||
cmake_install_dir = get_option('datadir') / 'cmake' / meson.project_name()
|
||||
cmake_to_prefix = []
|
||||
if fs.is_absolute(get_option('includedir')) or fs.is_absolute(cmake_install_dir)
|
||||
cmake_include_dir = (get_option('prefix') / get_option('includedir')).replace('\\', '/')
|
||||
else
|
||||
foreach component : cmake_install_dir.split('/')
|
||||
cmake_to_prefix += '..'
|
||||
endforeach
|
||||
cmake_include_dir = '${_IMPORT_PREFIX}/' + get_option('includedir')
|
||||
endif
|
||||
|
||||
cmake_conf = configuration_data()
|
||||
cmake_conf.set('PROJECT_NAME', meson.project_name())
|
||||
cmake_conf.set('PROJECT_VERSION', meson.project_version())
|
||||
cmake_conf.set('PROJECT_VERSION_MAJOR', meson.project_version().split('.')[0])
|
||||
cmake_conf.set('NLOHMANN_JSON_TARGET_NAME', meson.project_name())
|
||||
cmake_conf.set('NLOHMANN_JSON_TARGETS_EXPORT_NAME', meson.project_name() + 'Targets')
|
||||
cmake_conf.set('NLOHMANN_JSON_INCLUDE_DIR', cmake_include_dir)
|
||||
cmake_conf.set('NLOHMANN_JSON_CONFIG_TO_PREFIX', '/'.join(cmake_to_prefix))
|
||||
cmake_conf.set('NLOHMANN_JSON_COMPILE_DEFINITIONS', ';'.join(json_defines))
|
||||
|
||||
foreach cmake_file : [
|
||||
['cmake/config.cmake.in', 'nlohmann_jsonConfig.cmake'],
|
||||
['cmake/nlohmann_jsonConfigVersion.cmake.in', 'nlohmann_jsonConfigVersion.cmake'],
|
||||
['cmake/nlohmann_jsonTargets.cmake.in', 'nlohmann_jsonTargets.cmake'],
|
||||
]
|
||||
configure_file(
|
||||
input: cmake_file[0],
|
||||
output: cmake_file[1],
|
||||
configuration: cmake_conf,
|
||||
format: 'cmake@',
|
||||
install_dir: cmake_install_dir,
|
||||
)
|
||||
endforeach
|
||||
pkgc = import('pkgconfig')
|
||||
pkgc.generate(name: 'nlohmann_json',
|
||||
version: meson.project_version(),
|
||||
description: 'JSON for Modern C++'
|
||||
)
|
||||
endif
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
option(
|
||||
'MultipleHeaders',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Use non-amalgamated version of the library',
|
||||
)
|
||||
option(
|
||||
'GlobalUDLs',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Place user-defined string literals in the global namespace',
|
||||
)
|
||||
option(
|
||||
'ImplicitConversions',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Enable implicit conversions',
|
||||
)
|
||||
option(
|
||||
'DisableEnumSerialization',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Disable default integer enum serialization',
|
||||
)
|
||||
option(
|
||||
'Diagnostics',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Use extended diagnostic messages',
|
||||
)
|
||||
option(
|
||||
'Diagnostic_Positions',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Enable diagnostic positions',
|
||||
)
|
||||
option(
|
||||
'LegacyDiscardedValueComparison',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Enable legacy discarded value comparison',
|
||||
)
|
||||
option(
|
||||
'StrictNulHandling',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Enable strict NUL-byte handling',
|
||||
)
|
||||
@@ -6571,6 +6571,10 @@ namespace detail
|
||||
* j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
|
||||
* allocated value (e.g., a string). See bug issue
|
||||
* https://github.com/nlohmann/json/issues/2865 for more information.
|
||||
*
|
||||
* A value that has to be allocated is created before the old one is destroyed:
|
||||
* were it the other way around, an exception while creating the new value would
|
||||
* leave j with the type of the new value, but the pointer to the destroyed old one.
|
||||
*/
|
||||
|
||||
template<value_t> struct external_constructor;
|
||||
@@ -6594,18 +6598,20 @@ struct external_constructor<value_t::string>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(s);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value = s;
|
||||
j.m_data.m_value = value;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(std::move(s));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value = std::move(s);
|
||||
j.m_data.m_value = value;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@@ -6614,9 +6620,10 @@ struct external_constructor<value_t::string>
|
||||
int > = 0 >
|
||||
static void construct(BasicJsonType& j, const CompatibleStringType& str)
|
||||
{
|
||||
auto* created = j.template create<typename BasicJsonType::string_t>(str);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
|
||||
j.m_data.m_value.string = created;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@@ -6627,18 +6634,20 @@ struct external_constructor<value_t::binary>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(b);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::binary;
|
||||
j.m_data.m_value = typename BasicJsonType::binary_t(b);
|
||||
j.m_data.m_value = value;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(std::move(b));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::binary;
|
||||
j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
|
||||
j.m_data.m_value = value;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@@ -6688,9 +6697,10 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(arr);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = arr;
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -6698,9 +6708,10 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(std::move(arr));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = std::move(arr);
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -6716,9 +6727,10 @@ struct external_constructor<value_t::array>
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
auto* created = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
|
||||
j.m_data.m_value.array = created;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -6726,15 +6738,17 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const std::vector<bool>& arr)
|
||||
{
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value_t::array;
|
||||
j.m_data.m_value.array->reserve(arr.size());
|
||||
typename BasicJsonType::array_t elements;
|
||||
elements.reserve(arr.size());
|
||||
for (const bool x : arr)
|
||||
{
|
||||
j.m_data.m_value.array->push_back(x);
|
||||
j.set_parent(j.m_data.m_value.array->back());
|
||||
elements.push_back(x);
|
||||
}
|
||||
const typename BasicJsonType::json_value value(std::move(elements));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@@ -6742,11 +6756,12 @@ struct external_constructor<value_t::array>
|
||||
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
||||
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
|
||||
{
|
||||
typename BasicJsonType::array_t elements(arr.size());
|
||||
std::copy(std::begin(arr), std::end(arr), elements.begin());
|
||||
const typename BasicJsonType::json_value value(std::move(elements));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value_t::array;
|
||||
j.m_data.m_value.array->resize(arr.size());
|
||||
std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -6758,14 +6773,16 @@ struct external_constructor<value_t::array>
|
||||
enable_if_t<is_compatible_range_view<std::remove_cvref_t<CompatibleArrayType>>::value, int> = 0>
|
||||
static void construct(BasicJsonType& j, CompatibleArrayType && arr)
|
||||
{
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value_t::array;
|
||||
typename BasicJsonType::array_t elements;
|
||||
for (auto&& x : std::forward<CompatibleArrayType>(arr))
|
||||
{
|
||||
j.m_data.m_value.array->push_back(x);
|
||||
j.set_parent(j.m_data.m_value.array->back());
|
||||
elements.push_back(x);
|
||||
}
|
||||
const typename BasicJsonType::json_value value(std::move(elements));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
#endif
|
||||
@@ -6777,9 +6794,10 @@ struct external_constructor<value_t::object>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(obj);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value = obj;
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -6787,9 +6805,10 @@ struct external_constructor<value_t::object>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
||||
{
|
||||
const typename BasicJsonType::json_value value(std::move(obj));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value = std::move(obj);
|
||||
j.m_data.m_value = value;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -6801,9 +6820,10 @@ struct external_constructor<value_t::object>
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
auto* created = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
|
||||
j.m_data.m_value.object = created;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@@ -27585,8 +27605,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_an_object)
|
||||
{
|
||||
// the initializer list is a list of pairs -> create an object
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value = value_t::object;
|
||||
m_data.m_type = value_t::object;
|
||||
|
||||
for (auto& element_ref : init)
|
||||
{
|
||||
@@ -27608,8 +27628,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
#endif
|
||||
// the initializer list describes an array -> create an array
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value.array = create<array_t>(init.begin(), init.end());
|
||||
m_data.m_type = value_t::array;
|
||||
}
|
||||
|
||||
set_parents();
|
||||
@@ -27622,8 +27642,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static basic_json binary(const typename binary_t::container_type& init)
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_data.m_type = value_t::binary;
|
||||
res.m_data.m_value = init;
|
||||
res.m_data.m_type = value_t::binary;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -27633,8 +27653,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_data.m_type = value_t::binary;
|
||||
res.m_data.m_value = binary_t(init, subtype);
|
||||
res.m_data.m_type = value_t::binary;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -27644,8 +27664,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static basic_json binary(typename binary_t::container_type&& init)
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_data.m_type = value_t::binary;
|
||||
res.m_data.m_value = std::move(init);
|
||||
res.m_data.m_type = value_t::binary;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -27655,8 +27675,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_data.m_type = value_t::binary;
|
||||
res.m_data.m_value = binary_t(std::move(init), subtype);
|
||||
res.m_data.m_type = value_t::binary;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -28702,8 +28722,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// implicitly convert a null value to an empty array
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value.array = create<array_t>();
|
||||
m_data.m_type = value_t::array;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -28762,8 +28782,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// implicitly convert a null value to an empty object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value.object = create<object_t>();
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -28815,8 +28835,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// implicitly convert a null value to an empty object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value.object = create<object_t>();
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -29751,8 +29771,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an array
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value = value_t::array;
|
||||
m_data.m_type = value_t::array;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -29784,8 +29804,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an array
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value = value_t::array;
|
||||
m_data.m_type = value_t::array;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -29816,8 +29836,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value = value_t::object;
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -29872,8 +29892,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an array
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::array;
|
||||
m_data.m_value = value_t::array;
|
||||
m_data.m_type = value_t::array;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -29897,8 +29917,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// transform a null object into an object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value = value_t::object;
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@@ -30079,8 +30099,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// implicitly convert a null value to an empty object
|
||||
if (is_null())
|
||||
{
|
||||
m_data.m_type = value_t::object;
|
||||
m_data.m_value.object = create<object_t>();
|
||||
m_data.m_type = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <valarray>
|
||||
#if JSON_HAS_RANGES
|
||||
#include <ranges>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
// special test case to check if memory is leaked if constructor throws
|
||||
@@ -394,3 +399,173 @@ TEST_CASE("bad my_allocator::construct")
|
||||
j["test"].push_back("should not leak");
|
||||
}
|
||||
}
|
||||
|
||||
// the no-exceptions CI job skips every CHECK_THROWS_AS, which would leave
|
||||
// next_construct_fails set for the next allocation outside a check
|
||||
#if !defined(JSON_NOEXCEPTION)
|
||||
TEST_CASE("a failed allocation leaves the value unchanged")
|
||||
{
|
||||
// create JSON type using the throwing allocator
|
||||
using my_json = nlohmann::basic_json<std::map,
|
||||
std::vector,
|
||||
std::string,
|
||||
bool,
|
||||
std::int64_t,
|
||||
std::uint64_t,
|
||||
double,
|
||||
my_allocator>;
|
||||
|
||||
// Each of these creates a string, array, object, or binary value. The
|
||||
// value must be created before the type is changed: otherwise, a failed
|
||||
// creation left a value of the new type without anything behind it (an
|
||||
// assertion in its destructor, a null pointer everywhere else) or, when
|
||||
// an old value was destroyed first, with a pointer to that destroyed one.
|
||||
|
||||
SECTION("creating a binary value")
|
||||
{
|
||||
const std::vector<std::uint8_t> bytes = {1, 2, 3};
|
||||
my_json _;
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(_ = my_json::binary(bytes), std::bad_alloc&);
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(_ = my_json::binary(bytes, 42), std::bad_alloc&);
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(_ = my_json::binary(std::vector<std::uint8_t>(bytes)), std::bad_alloc&);
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(_ = my_json::binary(std::vector<std::uint8_t>(bytes), 42), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
|
||||
SECTION("turning a null value into an array or object")
|
||||
{
|
||||
my_json j;
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j[0], std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j["key"], std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j[std::string_view("key")], std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
#endif
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j.push_back(my_json(1)), std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
|
||||
const my_json one = 1;
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j.push_back(one), std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j.push_back(my_json::object_t::value_type("key", 1)), std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j.emplace_back(1), std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j.emplace("key", 1), std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
|
||||
const my_json object = {{"key", 1}};
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(j.update(object), std::bad_alloc&);
|
||||
CHECK(j.is_null());
|
||||
|
||||
next_construct_fails = false;
|
||||
}
|
||||
|
||||
SECTION("converting into an existing value")
|
||||
{
|
||||
// to_json replaces the value it is given; the old one must survive a
|
||||
// failed creation of the new one
|
||||
my_json j = "old";
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, std::string("new")), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, std::vector<int> {1, 2}), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
// with iterator debugging, the default constructor of VS 2015's
|
||||
// std::vector is noexcept but constructs a proxy with the allocator,
|
||||
// which terminates when this allocator throws
|
||||
#if !(defined(_MSC_VER) && _MSC_VER < 1910 && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL > 0)
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, std::vector<bool> {true, false}), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
#endif
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, std::map<std::string, int> {{"a", 1}}), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, my_json::binary_t({1, 2})), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
// the overloads for lvalues of the value types, for the value types
|
||||
// themselves, and for the remaining compatible types
|
||||
const std::string string = "new";
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, string), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, "new"), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
// to_json only moves a binary value that it converted from another
|
||||
// container type, which my_json's std::vector<std::uint8_t> is not
|
||||
using binary_constructor = nlohmann::detail::external_constructor<nlohmann::detail::value_t::binary>;
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(binary_constructor::construct(j, my_json::binary_t({1, 2})), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
my_json::array_t array = {1, 2};
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, array), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, std::move(array)), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
my_json::object_t object = {{"a", 1}};
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, object), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, std::move(object)), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, std::valarray<int> {1, 2}), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
|
||||
#if JSON_HAS_RANGES && !defined(__MINGW32__)
|
||||
const std::vector<int> numbers = {1, 2};
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(nlohmann::to_json(j, numbers | std::views::filter([](int /*unused*/)
|
||||
{
|
||||
return true;
|
||||
})), std::bad_alloc&);
|
||||
CHECK(j == "old");
|
||||
#endif
|
||||
|
||||
next_construct_fails = false;
|
||||
nlohmann::to_json(j, std::vector<int> {1, 2});
|
||||
CHECK(j == my_json({1, 2}));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user