Merge branch 'develop' of https://github.com/nlohmann/json into update_doctest
This commit is contained in:
commit
78580ca8bd
1
.github/workflows/codeql-analysis.yml
vendored
1
.github/workflows/codeql-analysis.yml
vendored
@ -9,6 +9,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 19 * * 1'
|
- cron: '0 19 * * 1'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
CodeQL-Build:
|
CodeQL-Build:
|
||||||
|
|||||||
3
.github/workflows/macos.yml
vendored
3
.github/workflows/macos.yml
vendored
@ -7,6 +7,7 @@ on:
|
|||||||
- master
|
- master
|
||||||
- release/*
|
- release/*
|
||||||
pull_request:
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
xcode:
|
xcode:
|
||||||
@ -37,7 +38,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: cmake
|
- name: cmake
|
||||||
run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DJSON_TestStandards=${{ matrix.standard }}
|
||||||
- name: build
|
- name: build
|
||||||
run: cmake --build build --parallel 10
|
run: cmake --build build --parallel 10
|
||||||
- name: test
|
- name: test
|
||||||
|
|||||||
1
.github/workflows/ubuntu.yml
vendored
1
.github/workflows/ubuntu.yml
vendored
@ -7,6 +7,7 @@ on:
|
|||||||
- master
|
- master
|
||||||
- release/*
|
- release/*
|
||||||
pull_request:
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci_test_clang:
|
ci_test_clang:
|
||||||
|
|||||||
41
.github/workflows/windows.yml
vendored
41
.github/workflows/windows.yml
vendored
@ -7,6 +7,7 @@ on:
|
|||||||
- master
|
- master
|
||||||
- release/*
|
- release/*
|
||||||
pull_request:
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
mingw:
|
mingw:
|
||||||
@ -64,7 +65,7 @@ jobs:
|
|||||||
run: cd build ; ctest -j 10 -C Release --output-on-failure
|
run: cd build ; ctest -j 10 -C Release --output-on-failure
|
||||||
|
|
||||||
msvc2019:
|
msvc2019:
|
||||||
runs-on: windows-latest
|
runs-on: windows-2019
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
build_type: [Debug, Release]
|
build_type: [Debug, Release]
|
||||||
@ -84,7 +85,7 @@ jobs:
|
|||||||
run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure
|
run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure
|
||||||
|
|
||||||
msvc2019_latest:
|
msvc2019_latest:
|
||||||
runs-on: windows-latest
|
runs-on: windows-2019
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@ -95,8 +96,40 @@ jobs:
|
|||||||
- name: test
|
- name: test
|
||||||
run: cd build ; ctest -j 10 -C Release --output-on-failure
|
run: cd build ; ctest -j 10 -C Release --output-on-failure
|
||||||
|
|
||||||
|
msvc2022:
|
||||||
|
runs-on: windows-2022
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
build_type: [Debug, Release]
|
||||||
|
architecture: [Win32, x64]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: cmake
|
||||||
|
run: cmake -S . -B build -G "Visual Studio 17 2022" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/W4 /WX"
|
||||||
|
if: matrix.build_type == 'Release'
|
||||||
|
- name: cmake
|
||||||
|
run: cmake -S . -B build -G "Visual Studio 17 2022" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_CXX_FLAGS="/W4 /WX"
|
||||||
|
if: matrix.build_type == 'Debug'
|
||||||
|
- name: build
|
||||||
|
run: cmake --build build --config ${{ matrix.build_type }} --parallel 10
|
||||||
|
- name: test
|
||||||
|
run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure
|
||||||
|
|
||||||
|
msvc2022_latest:
|
||||||
|
runs-on: windows-2022
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: cmake
|
||||||
|
run: cmake -S . -B build -G "Visual Studio 17 2022" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX"
|
||||||
|
- name: build
|
||||||
|
run: cmake --build build --config Release --parallel 10
|
||||||
|
- name: test
|
||||||
|
run: cd build ; ctest -j 10 -C Release --output-on-failure
|
||||||
|
|
||||||
clang:
|
clang:
|
||||||
runs-on: windows-latest
|
runs-on: windows-2019
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
version: [11, 12]
|
version: [11, 12]
|
||||||
@ -113,7 +146,7 @@ jobs:
|
|||||||
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
|
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
|
||||||
|
|
||||||
clang-cl-11:
|
clang-cl-11:
|
||||||
runs-on: windows-latest
|
runs-on: windows-2019
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
architecture: [Win32, x64]
|
architecture: [Win32, x64]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
cff-version: 1.1.0
|
cff-version: 1.2.0
|
||||||
message: "If you use this software, please cite it as below."
|
message: "If you use this software, please cite it as below."
|
||||||
authors:
|
authors:
|
||||||
- family-names: Lohmann
|
- family-names: Lohmann
|
||||||
given-names: Niels
|
given-names: Niels
|
||||||
orcid: https://orcid.org/0000-0001-9037-795X
|
orcid: https://orcid.org/0000-0001-9037-795X
|
||||||
@ -8,7 +8,7 @@ authors:
|
|||||||
website: https://nlohmann.me
|
website: https://nlohmann.me
|
||||||
title: "JSON for Modern C++"
|
title: "JSON for Modern C++"
|
||||||
version: 3.10.5
|
version: 3.10.5
|
||||||
date-released: 2022
|
date-released: 2022-01-03
|
||||||
license: MIT
|
license: MIT
|
||||||
repository-code: "https://github.com/nlohmann"
|
repository-code: "https://github.com/nlohmann"
|
||||||
url: https://json.nlohmann.me
|
url: https://json.nlohmann.me
|
||||||
|
|||||||
@ -19,6 +19,7 @@ endif()
|
|||||||
## INCLUDE
|
## INCLUDE
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -30,7 +31,13 @@ if (POLICY CMP0077)
|
|||||||
cmake_policy(SET CMP0077 NEW)
|
cmake_policy(SET CMP0077 NEW)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ${MAIN_PROJECT})
|
# VERSION_GREATER_EQUAL is not available in CMake 3.1
|
||||||
|
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13))
|
||||||
|
set(JSON_BuildTests_INIT ON)
|
||||||
|
else()
|
||||||
|
set(JSON_BuildTests_INIT OFF)
|
||||||
|
endif()
|
||||||
|
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ${JSON_BuildTests_INIT})
|
||||||
option(JSON_CI "Enable CI build targets." OFF)
|
option(JSON_CI "Enable CI build targets." OFF)
|
||||||
option(JSON_Diagnostics "Use extended diagnostic messages." OFF)
|
option(JSON_Diagnostics "Use extended diagnostic messages." OFF)
|
||||||
option(JSON_ImplicitConversions "Enable implicit conversions." ON)
|
option(JSON_ImplicitConversions "Enable implicit conversions." ON)
|
||||||
@ -39,7 +46,7 @@ option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OF
|
|||||||
option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF)
|
option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF)
|
||||||
|
|
||||||
if (JSON_CI)
|
if (JSON_CI)
|
||||||
include(cmake/ci.cmake)
|
include(ci)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|||||||
36
Makefile
36
Makefile
@ -4,9 +4,6 @@
|
|||||||
# configuration
|
# configuration
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
# directory to recent compiler binaries
|
|
||||||
COMPILER_DIR=/usr/local/opt/llvm/bin
|
|
||||||
|
|
||||||
# find GNU sed to use `-i` parameter
|
# find GNU sed to use `-i` parameter
|
||||||
SED:=$(shell command -v gsed || which sed)
|
SED:=$(shell command -v gsed || which sed)
|
||||||
|
|
||||||
@ -62,6 +59,7 @@ run_benchmarks:
|
|||||||
cd cmake-build-benchmarks ; ninja
|
cd cmake-build-benchmarks ; ninja
|
||||||
cd cmake-build-benchmarks ; ./json_benchmarks
|
cd cmake-build-benchmarks ; ./json_benchmarks
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# fuzzing
|
# fuzzing
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@ -135,6 +133,7 @@ pvs_studio:
|
|||||||
cd cmake-build-pvs-studio ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs
|
cd cmake-build-pvs-studio ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs
|
||||||
open cmake-build-pvs-studio/pvs/index.html
|
open cmake-build-pvs-studio/pvs/index.html
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Code format and source amalgamation
|
# Code format and source amalgamation
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@ -203,20 +202,29 @@ ChangeLog.md:
|
|||||||
# Release files
|
# Release files
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
# Create the files for a release and add signatures and hashes. We use `-X` to make the resulting ZIP file
|
# Create a tar.gz archive that contains sufficient files to be used as CMake project (e.g., using FetchContent). The
|
||||||
# reproducible, see <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
|
# archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>.
|
||||||
|
json.tar.xz:
|
||||||
|
mkdir json
|
||||||
|
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include -type f) json
|
||||||
|
gtar --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz
|
||||||
|
rm -fr json
|
||||||
|
|
||||||
release:
|
# We use `-X` to make the resulting ZIP file reproducible, see
|
||||||
|
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
|
||||||
|
include.zip:
|
||||||
|
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) meson.build LICENSE.MIT
|
||||||
|
|
||||||
|
# Create the files for a release and add signatures and hashes.
|
||||||
|
release: include.zip json.tar.xz
|
||||||
rm -fr release_files
|
rm -fr release_files
|
||||||
mkdir release_files
|
mkdir release_files
|
||||||
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) meson.build LICENSE.MIT
|
|
||||||
gpg --armor --detach-sig include.zip
|
gpg --armor --detach-sig include.zip
|
||||||
mv include.zip include.zip.asc release_files
|
|
||||||
gpg --armor --detach-sig $(AMALGAMATED_FILE)
|
gpg --armor --detach-sig $(AMALGAMATED_FILE)
|
||||||
|
gpg --armor --detach-sig json.tar.xz
|
||||||
cp $(AMALGAMATED_FILE) release_files
|
cp $(AMALGAMATED_FILE) release_files
|
||||||
mv $(AMALGAMATED_FILE).asc release_files
|
mv $(AMALGAMATED_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc release_files
|
||||||
cd release_files ; shasum -a 256 json.hpp > hashes.txt
|
cd release_files ; shasum -a 256 json.hpp include.zip json.tar.xz > hashes.txt
|
||||||
cd release_files ; shasum -a 256 include.zip >> hashes.txt
|
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@ -225,12 +233,12 @@ release:
|
|||||||
|
|
||||||
# clean up
|
# clean up
|
||||||
clean:
|
clean:
|
||||||
rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM oclint_report.html
|
rm -fr fuzz fuzz-testing *.dSYM test/*.dSYM
|
||||||
rm -fr benchmarks/files/numbers/*.json
|
rm -fr benchmarks/files/numbers/*.json
|
||||||
rm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64
|
rm -fr cmake-build-benchmarks fuzz-testing cmake-build-pvs-studio release_files
|
||||||
rm -fr cmake-build-benchmarks cmake-build-pedantic fuzz-testing cmake-build-clang-analyze cmake-build-pvs-studio cmake-build-infer cmake_build
|
|
||||||
$(MAKE) clean -Cdoc
|
$(MAKE) clean -Cdoc
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Thirdparty code
|
# Thirdparty code
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|||||||
28
README.md
28
README.md
@ -10,7 +10,7 @@
|
|||||||
[](https://lgtm.com/projects/g/nlohmann/json/context:cpp)
|
[](https://lgtm.com/projects/g/nlohmann/json/context:cpp)
|
||||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json)
|
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json)
|
||||||
[](https://wandbox.org/permlink/1mp10JbaANo6FUc7)
|
[](https://wandbox.org/permlink/1mp10JbaANo6FUc7)
|
||||||
[](https://nlohmann.github.io/json/doxygen/index.html)
|
[](https://json.nlohmann.me)
|
||||||
[](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
|
[](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
|
||||||
[](https://github.com/nlohmann/json/releases)
|
[](https://github.com/nlohmann/json/releases)
|
||||||
[](https://github.com/nlohmann/json/releases)
|
[](https://github.com/nlohmann/json/releases)
|
||||||
@ -85,7 +85,7 @@ Thanks everyone!
|
|||||||
|
|
||||||
:books: If you want to **learn more** about how to use the library, check out the rest of the [**README**](#examples), have a look at [**code examples**](https://github.com/nlohmann/json/tree/develop/doc/examples), or browse through the [**help pages**](https://json.nlohmann.me).
|
:books: If you want to **learn more** about how to use the library, check out the rest of the [**README**](#examples), have a look at [**code examples**](https://github.com/nlohmann/json/tree/develop/doc/examples), or browse through the [**help pages**](https://json.nlohmann.me).
|
||||||
|
|
||||||
:construction: If you want to understand the **API** better, check out the [**API Reference**](https://json.nlohmann.me/api/basic_json/) or the [**Doxygen documentation**](https://json.nlohmann.me/doxygen/index.html).
|
:construction: If you want to understand the **API** better, check out the [**API Reference**](https://json.nlohmann.me/api/basic_json/).
|
||||||
|
|
||||||
:bug: If you found a **bug**, please check the [**FAQ**](https://json.nlohmann.me/home/faq/) if it is a known issue or the result of a design decision. Please also have a look at the [**issue list**](https://github.com/nlohmann/json/issues) before you [**create a new issue**](https://github.com/nlohmann/json/issues/new/choose). Please provide as much information as possible to help us understand and reproduce your issue.
|
:bug: If you found a **bug**, please check the [**FAQ**](https://json.nlohmann.me/home/faq/) if it is a known issue or the result of a design decision. Please also have a look at the [**issue list**](https://github.com/nlohmann/json/issues) before you [**create a new issue**](https://github.com/nlohmann/json/issues/new/choose). Please provide as much information as possible to help us understand and reproduce your issue.
|
||||||
|
|
||||||
@ -1045,6 +1045,7 @@ Though it's 2022 already, the support for C++11 is still a bit sparse. Currently
|
|||||||
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
|
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
|
||||||
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
|
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
|
||||||
- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)
|
- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)
|
||||||
|
- Microsoft Visual C++ 2022 / Build Tools 19.30.30709.0 (and possibly later)
|
||||||
|
|
||||||
I would be happy to learn about other compilers/versions.
|
I would be happy to learn about other compilers/versions.
|
||||||
|
|
||||||
@ -1119,6 +1120,7 @@ The following compilers are currently used in continuous integration at [AppVeyo
|
|||||||
| Visual Studio 15 2017 MSVC 19.16.27045.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | GitHub Actions |
|
| Visual Studio 15 2017 MSVC 19.16.27045.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | GitHub Actions |
|
||||||
| Visual Studio 16 2019 MSVC 19.28.29912.0 (Build Engine version 16.9.0+57a23d249 for .NET Framework) | Windows-10.0.17763 | GitHub Actions |
|
| Visual Studio 16 2019 MSVC 19.28.29912.0 (Build Engine version 16.9.0+57a23d249 for .NET Framework) | Windows-10.0.17763 | GitHub Actions |
|
||||||
| Visual Studio 16 2019 MSVC 19.28.29912.0 (Build Engine version 16.9.0+57a23d249 for .NET Framework) | Windows-10.0.17763 | AppVeyor |
|
| Visual Studio 16 2019 MSVC 19.28.29912.0 (Build Engine version 16.9.0+57a23d249 for .NET Framework) | Windows-10.0.17763 | AppVeyor |
|
||||||
|
| Visual Studio 17 2022 MSVC 19.30.30709.0 (Build Engine version 17.0.31804.368 for .NET Framework) | Windows-10.0.20348 | GitHub Actions |
|
||||||
|
|
||||||
|
|
||||||
## Integration
|
## Integration
|
||||||
@ -1183,29 +1185,20 @@ target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
|||||||
|
|
||||||
Since CMake v3.11,
|
Since CMake v3.11,
|
||||||
[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
|
[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
|
||||||
be used to automatically download the repository as a dependency at configure time.
|
be used to automatically download a release as a dependency at configure time.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```cmake
|
```cmake
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
FetchContent_Declare(json
|
FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.10.5/json.tar.xz)
|
||||||
GIT_REPOSITORY https://github.com/nlohmann/json.git
|
FetchContent_MakeAvailable(json)
|
||||||
GIT_TAG v3.7.3)
|
|
||||||
|
|
||||||
FetchContent_GetProperties(json)
|
|
||||||
if(NOT json_POPULATED)
|
|
||||||
FetchContent_Populate(json)
|
|
||||||
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note**: The repository https://github.com/nlohmann/json download size is huge.
|
**Note**: It is recommended to use the URL approach described above which is supported as of version 3.10.0. See
|
||||||
It contains all the dataset used for the benchmarks. You might want to depend on
|
<https://json.nlohmann.me/integration/cmake/#fetchcontent> for more information.
|
||||||
a smaller repository. For instance, you might want to replace the URL above by
|
|
||||||
https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent
|
|
||||||
|
|
||||||
#### Supporting Both
|
#### Supporting Both
|
||||||
|
|
||||||
@ -1624,13 +1617,14 @@ The library itself consists of a single header file licensed under the MIT licen
|
|||||||
- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json)
|
- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json)
|
||||||
- [**cppcheck**](http://cppcheck.sourceforge.net) for static analysis
|
- [**cppcheck**](http://cppcheck.sourceforge.net) for static analysis
|
||||||
- [**doctest**](https://github.com/onqtam/doctest) for the unit tests
|
- [**doctest**](https://github.com/onqtam/doctest) for the unit tests
|
||||||
- [**Doxygen**](https://www.doxygen.nl/index.html) to generate [documentation](https://nlohmann.github.io/json/doxygen/index.html)
|
|
||||||
- [**git-update-ghpages**](https://github.com/rstacruz/git-update-ghpages) to upload the documentation to gh-pages
|
- [**git-update-ghpages**](https://github.com/rstacruz/git-update-ghpages) to upload the documentation to gh-pages
|
||||||
- [**GitHub Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md)
|
- [**GitHub Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md)
|
||||||
- [**Google Benchmark**](https://github.com/google/benchmark) to implement the benchmarks
|
- [**Google Benchmark**](https://github.com/google/benchmark) to implement the benchmarks
|
||||||
- [**Hedley**](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros
|
- [**Hedley**](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros
|
||||||
- [**lcov**](http://ltp.sourceforge.net/coverage/lcov.php) to process coverage information and create an HTML view
|
- [**lcov**](http://ltp.sourceforge.net/coverage/lcov.php) to process coverage information and create an HTML view
|
||||||
- [**libFuzzer**](https://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz
|
- [**libFuzzer**](https://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz
|
||||||
|
- [**Material for MkDocs**](https://squidfunk.github.io/mkdocs-material/) for the style of the documentation site
|
||||||
|
- [**MkDocs**](https://www.mkdocs.org) for the documentation site
|
||||||
- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json))
|
- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json))
|
||||||
- [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments.
|
- [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments.
|
||||||
- [**Valgrind**](https://valgrind.org) to check for correct memory management
|
- [**Valgrind**](https://valgrind.org) to check for correct memory management
|
||||||
|
|||||||
@ -23,7 +23,7 @@ if(NOT benchmark_POPULATED)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# download test data
|
# download test data
|
||||||
include(${CMAKE_SOURCE_DIR}/../cmake/download_test_data.cmake)
|
include(download_test_data)
|
||||||
|
|
||||||
# benchmark binary
|
# benchmark binary
|
||||||
add_executable(json_benchmarks src/benchmarks.cpp)
|
add_executable(json_benchmarks src/benchmarks.cpp)
|
||||||
|
|||||||
694
cmake/ci.cmake
694
cmake/ci.cmake
@ -30,7 +30,7 @@ execute_process(COMMAND ${CPPCHECK_TOOL} --version OUTPUT_VARIABLE CPPCHECK_TOOL
|
|||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CPPCHECK_TOOL_VERSION "${CPPCHECK_TOOL_VERSION}")
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CPPCHECK_TOOL_VERSION "${CPPCHECK_TOOL_VERSION}")
|
||||||
message(STATUS "🔖 Cppcheck ${CPPCHECK_TOOL_VERSION} (${CPPCHECK_TOOL})")
|
message(STATUS "🔖 Cppcheck ${CPPCHECK_TOOL_VERSION} (${CPPCHECK_TOOL})")
|
||||||
|
|
||||||
find_program(GCC_TOOL NAMES g++-HEAD g++-11 g++-latest)
|
find_program(GCC_TOOL NAMES g++-latest g++-HEAD g++-11)
|
||||||
execute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION)
|
execute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION)
|
||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}")
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}")
|
||||||
message(STATUS "🔖 GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})")
|
message(STATUS "🔖 GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})")
|
||||||
@ -98,19 +98,20 @@ file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp)
|
|||||||
# -Wno-weak-vtables The library is header-only.
|
# -Wno-weak-vtables The library is header-only.
|
||||||
# -Wreserved-identifier See https://github.com/onqtam/doctest/issues/536.
|
# -Wreserved-identifier See https://github.com/onqtam/doctest/issues/536.
|
||||||
|
|
||||||
set(CLANG_CXXFLAGS "-std=c++11 \
|
set(CLANG_CXXFLAGS
|
||||||
-Werror \
|
-Werror
|
||||||
-Weverything \
|
-Weverything
|
||||||
-Wno-c++98-compat \
|
-Wno-c++98-compat
|
||||||
-Wno-c++98-compat-pedantic \
|
-Wno-c++98-compat-pedantic
|
||||||
-Wno-deprecated-declarations \
|
-Wno-deprecated-declarations
|
||||||
-Wno-extra-semi-stmt \
|
-Wno-extra-semi-stmt
|
||||||
-Wno-padded \
|
-Wno-padded
|
||||||
-Wno-covered-switch-default \
|
-Wno-covered-switch-default
|
||||||
-Wno-weak-vtables \
|
-Wno-weak-vtables
|
||||||
-Wno-reserved-identifier \
|
-Wno-reserved-identifier
|
||||||
")
|
)
|
||||||
|
|
||||||
|
# Warning flags determined for GCC 12.0 (experimental) with https://github.com/nlohmann/gcc_flags:
|
||||||
# Ignored GCC warnings:
|
# Ignored GCC warnings:
|
||||||
# -Wno-abi-tag We do not care about ABI tags.
|
# -Wno-abi-tag We do not care about ABI tags.
|
||||||
# -Wno-aggregate-return The library uses aggregate returns.
|
# -Wno-aggregate-return The library uses aggregate returns.
|
||||||
@ -120,283 +121,295 @@ set(CLANG_CXXFLAGS "-std=c++11 \
|
|||||||
# -Wno-system-headers We do not care about warnings in system headers.
|
# -Wno-system-headers We do not care about warnings in system headers.
|
||||||
# -Wno-templates The library uses templates.
|
# -Wno-templates The library uses templates.
|
||||||
|
|
||||||
set(GCC_CXXFLAGS "-std=c++11 \
|
set(GCC_CXXFLAGS
|
||||||
-pedantic \
|
-pedantic
|
||||||
-Werror \
|
-Werror
|
||||||
--all-warnings \
|
--all-warnings
|
||||||
--extra-warnings \
|
--extra-warnings
|
||||||
-W \
|
-W
|
||||||
-WNSObject-attribute \
|
-WNSObject-attribute
|
||||||
-Wno-abi-tag \
|
-Wno-abi-tag
|
||||||
-Waddress \
|
-Waddress
|
||||||
-Waddress-of-packed-member \
|
-Waddress-of-packed-member
|
||||||
-Wno-aggregate-return \
|
-Wno-aggregate-return
|
||||||
-Waggressive-loop-optimizations \
|
-Waggressive-loop-optimizations
|
||||||
-Waligned-new=all \
|
-Waligned-new=all
|
||||||
-Wall \
|
-Wall
|
||||||
-Walloc-zero \
|
-Walloc-zero
|
||||||
-Walloca \
|
-Walloca
|
||||||
-Wanalyzer-double-fclose \
|
-Wanalyzer-double-fclose
|
||||||
-Wanalyzer-double-free \
|
-Wanalyzer-double-free
|
||||||
-Wanalyzer-exposure-through-output-file \
|
-Wanalyzer-exposure-through-output-file
|
||||||
-Wanalyzer-file-leak \
|
-Wanalyzer-file-leak
|
||||||
-Wanalyzer-free-of-non-heap \
|
-Wanalyzer-free-of-non-heap
|
||||||
-Wanalyzer-malloc-leak \
|
-Wanalyzer-malloc-leak
|
||||||
-Wanalyzer-mismatching-deallocation \
|
-Wanalyzer-mismatching-deallocation
|
||||||
-Wanalyzer-null-argument \
|
-Wanalyzer-null-argument
|
||||||
-Wanalyzer-null-dereference \
|
-Wanalyzer-null-dereference
|
||||||
-Wanalyzer-possible-null-argument \
|
-Wanalyzer-possible-null-argument
|
||||||
-Wanalyzer-possible-null-dereference \
|
-Wanalyzer-possible-null-dereference
|
||||||
-Wanalyzer-shift-count-negative \
|
-Wanalyzer-shift-count-negative
|
||||||
-Wanalyzer-shift-count-overflow \
|
-Wanalyzer-shift-count-overflow
|
||||||
-Wanalyzer-stale-setjmp-buffer \
|
-Wanalyzer-stale-setjmp-buffer
|
||||||
-Wanalyzer-tainted-array-index \
|
-Wanalyzer-tainted-allocation-size
|
||||||
-Wanalyzer-too-complex \
|
-Wanalyzer-tainted-array-index
|
||||||
-Wanalyzer-unsafe-call-within-signal-handler \
|
-Wanalyzer-tainted-divisor
|
||||||
-Wanalyzer-use-after-free \
|
-Wanalyzer-tainted-offset
|
||||||
-Wanalyzer-use-of-pointer-in-stale-stack-frame \
|
-Wanalyzer-tainted-size
|
||||||
-Wanalyzer-write-to-const \
|
-Wanalyzer-too-complex
|
||||||
-Wanalyzer-write-to-string-literal \
|
-Wanalyzer-unsafe-call-within-signal-handler
|
||||||
-Warith-conversion \
|
-Wanalyzer-use-after-free
|
||||||
-Warray-bounds \
|
-Wanalyzer-use-of-pointer-in-stale-stack-frame
|
||||||
-Warray-bounds=2 \
|
-Wanalyzer-use-of-uninitialized-value
|
||||||
-Warray-parameter=2 \
|
-Wanalyzer-write-to-const
|
||||||
-Wattribute-alias=2 \
|
-Wanalyzer-write-to-string-literal
|
||||||
-Wattribute-warning \
|
-Warith-conversion
|
||||||
-Wattributes \
|
-Warray-bounds
|
||||||
-Wbool-compare \
|
-Warray-bounds=2
|
||||||
-Wbool-operation \
|
-Warray-compare
|
||||||
-Wbuiltin-declaration-mismatch \
|
-Warray-parameter=2
|
||||||
-Wbuiltin-macro-redefined \
|
-Wattribute-alias=2
|
||||||
-Wc++0x-compat \
|
-Wattribute-warning
|
||||||
-Wc++11-compat \
|
-Wattributes
|
||||||
-Wc++14-compat \
|
-Wbool-compare
|
||||||
-Wc++17-compat \
|
-Wbool-operation
|
||||||
-Wc++1z-compat \
|
-Wbuiltin-declaration-mismatch
|
||||||
-Wc++20-compat \
|
-Wbuiltin-macro-redefined
|
||||||
-Wc++2a-compat \
|
-Wc++0x-compat
|
||||||
-Wcannot-profile \
|
-Wc++11-compat
|
||||||
-Wcast-align \
|
-Wc++11-extensions
|
||||||
-Wcast-align=strict \
|
-Wc++14-compat
|
||||||
-Wcast-function-type \
|
-Wc++14-extensions
|
||||||
-Wcast-qual \
|
-Wc++17-compat
|
||||||
-Wcatch-value=3 \
|
-Wc++17-extensions
|
||||||
-Wchar-subscripts \
|
-Wc++1z-compat
|
||||||
-Wclass-conversion \
|
-Wc++20-compat
|
||||||
-Wclass-memaccess \
|
-Wc++20-extensions
|
||||||
-Wclobbered \
|
-Wc++23-extensions
|
||||||
-Wcomma-subscript \
|
-Wc++2a-compat
|
||||||
-Wcomment \
|
-Wcannot-profile
|
||||||
-Wcomments \
|
-Wcast-align
|
||||||
-Wconditionally-supported \
|
-Wcast-align=strict
|
||||||
-Wconversion \
|
-Wcast-function-type
|
||||||
-Wconversion-null \
|
-Wcast-qual
|
||||||
-Wcoverage-mismatch \
|
-Wcatch-value=3
|
||||||
-Wcpp \
|
-Wchar-subscripts
|
||||||
-Wctad-maybe-unsupported \
|
-Wclass-conversion
|
||||||
-Wctor-dtor-privacy \
|
-Wclass-memaccess
|
||||||
-Wdangling-else \
|
-Wclobbered
|
||||||
-Wdate-time \
|
-Wcomma-subscript
|
||||||
-Wdelete-incomplete \
|
-Wcomment
|
||||||
-Wdelete-non-virtual-dtor \
|
-Wcomments
|
||||||
-Wdeprecated \
|
-Wconditionally-supported
|
||||||
-Wdeprecated-copy \
|
-Wconversion
|
||||||
-Wdeprecated-copy-dtor \
|
-Wconversion-null
|
||||||
-Wdeprecated-declarations \
|
-Wcoverage-invalid-line-number
|
||||||
-Wdeprecated-enum-enum-conversion \
|
-Wcoverage-mismatch
|
||||||
-Wdeprecated-enum-float-conversion \
|
-Wcpp
|
||||||
-Wdisabled-optimization \
|
-Wctad-maybe-unsupported
|
||||||
-Wdiv-by-zero \
|
-Wctor-dtor-privacy
|
||||||
-Wdouble-promotion \
|
-Wdangling-else
|
||||||
-Wduplicated-branches \
|
-Wdate-time
|
||||||
-Wduplicated-cond \
|
-Wdelete-incomplete
|
||||||
-Weffc++ \
|
-Wdelete-non-virtual-dtor
|
||||||
-Wempty-body \
|
-Wdeprecated
|
||||||
-Wendif-labels \
|
-Wdeprecated-copy
|
||||||
-Wenum-compare \
|
-Wdeprecated-copy-dtor
|
||||||
-Wenum-conversion \
|
-Wdeprecated-declarations
|
||||||
-Wexpansion-to-defined \
|
-Wdeprecated-enum-enum-conversion
|
||||||
-Wextra \
|
-Wdeprecated-enum-float-conversion
|
||||||
-Wextra-semi \
|
-Wdisabled-optimization
|
||||||
-Wfloat-conversion \
|
-Wdiv-by-zero
|
||||||
-Wfloat-equal \
|
-Wdouble-promotion
|
||||||
-Wformat-contains-nul \
|
-Wduplicated-branches
|
||||||
-Wformat-diag \
|
-Wduplicated-cond
|
||||||
-Wformat-extra-args \
|
-Weffc++
|
||||||
-Wformat-nonliteral \
|
-Wempty-body
|
||||||
-Wformat-overflow=2 \
|
-Wendif-labels
|
||||||
-Wformat-security \
|
-Wenum-compare
|
||||||
-Wformat-signedness \
|
-Wenum-conversion
|
||||||
-Wformat-truncation=2 \
|
-Wexceptions
|
||||||
-Wformat-y2k \
|
-Wexpansion-to-defined
|
||||||
-Wformat-zero-length \
|
-Wextra
|
||||||
-Wformat=2 \
|
-Wextra-semi
|
||||||
-Wframe-address \
|
-Wfloat-conversion
|
||||||
-Wfree-nonheap-object \
|
-Wfloat-equal
|
||||||
-Whsa \
|
-Wformat-diag
|
||||||
-Wif-not-aligned \
|
-Wformat-overflow=2
|
||||||
-Wignored-attributes \
|
-Wformat-signedness
|
||||||
-Wignored-qualifiers \
|
-Wformat-truncation=2
|
||||||
-Wimplicit-fallthrough=5 \
|
-Wformat=2
|
||||||
-Winaccessible-base \
|
-Wframe-address
|
||||||
-Winherited-variadic-ctor \
|
-Wfree-nonheap-object
|
||||||
-Winit-list-lifetime \
|
-Whsa
|
||||||
-Winit-self \
|
-Wif-not-aligned
|
||||||
-Winline \
|
-Wignored-attributes
|
||||||
-Wint-in-bool-context \
|
-Wignored-qualifiers
|
||||||
-Wint-to-pointer-cast \
|
-Wimplicit-fallthrough=5
|
||||||
-Winvalid-memory-model \
|
-Winaccessible-base
|
||||||
-Winvalid-offsetof \
|
-Winfinite-recursion
|
||||||
-Winvalid-pch \
|
-Winherited-variadic-ctor
|
||||||
-Wliteral-suffix \
|
-Winit-list-lifetime
|
||||||
-Wlogical-not-parentheses \
|
-Winit-self
|
||||||
-Wlogical-op \
|
-Winline
|
||||||
-Wno-long-long \
|
-Wint-in-bool-context
|
||||||
-Wlto-type-mismatch \
|
-Wint-to-pointer-cast
|
||||||
-Wmain \
|
-Winterference-size
|
||||||
-Wmaybe-uninitialized \
|
-Winvalid-imported-macros
|
||||||
-Wmemset-elt-size \
|
-Winvalid-memory-model
|
||||||
-Wmemset-transposed-args \
|
-Winvalid-offsetof
|
||||||
-Wmisleading-indentation \
|
-Winvalid-pch
|
||||||
-Wmismatched-dealloc \
|
-Wliteral-suffix
|
||||||
-Wmismatched-new-delete \
|
-Wlogical-not-parentheses
|
||||||
-Wmismatched-tags \
|
-Wlogical-op
|
||||||
-Wmissing-attributes \
|
-Wno-long-long
|
||||||
-Wmissing-braces \
|
-Wlto-type-mismatch
|
||||||
-Wmissing-declarations \
|
-Wmain
|
||||||
-Wmissing-field-initializers \
|
-Wmaybe-uninitialized
|
||||||
-Wmissing-include-dirs \
|
-Wmemset-elt-size
|
||||||
-Wmissing-profile \
|
-Wmemset-transposed-args
|
||||||
-Wmultichar \
|
-Wmisleading-indentation
|
||||||
-Wmultiple-inheritance \
|
-Wmismatched-dealloc
|
||||||
-Wmultistatement-macros \
|
-Wmismatched-new-delete
|
||||||
-Wno-namespaces \
|
-Wmismatched-tags
|
||||||
-Wnarrowing \
|
-Wmissing-attributes
|
||||||
-Wnoexcept \
|
-Wmissing-braces
|
||||||
-Wnoexcept-type \
|
-Wmissing-declarations
|
||||||
-Wnon-template-friend \
|
-Wmissing-field-initializers
|
||||||
-Wnon-virtual-dtor \
|
-Wmissing-include-dirs
|
||||||
-Wnonnull \
|
-Wmissing-profile
|
||||||
-Wnonnull-compare \
|
-Wmissing-requires
|
||||||
-Wnormalized=nfkc \
|
-Wmultichar
|
||||||
-Wnull-dereference \
|
-Wmultiple-inheritance
|
||||||
-Wodr \
|
-Wmultistatement-macros
|
||||||
-Wold-style-cast \
|
-Wno-namespaces
|
||||||
-Wopenmp-simd \
|
-Wnarrowing
|
||||||
-Woverflow \
|
-Wnoexcept
|
||||||
-Woverlength-strings \
|
-Wnoexcept-type
|
||||||
-Woverloaded-virtual \
|
-Wnon-template-friend
|
||||||
-Wpacked \
|
-Wnon-virtual-dtor
|
||||||
-Wpacked-bitfield-compat \
|
-Wnonnull
|
||||||
-Wpacked-not-aligned \
|
-Wnonnull-compare
|
||||||
-Wno-padded \
|
-Wnormalized=nfkc
|
||||||
-Wparentheses \
|
-Wnull-dereference
|
||||||
-Wpedantic \
|
-Wodr
|
||||||
-Wpessimizing-move \
|
-Wold-style-cast
|
||||||
-Wplacement-new=2 \
|
-Wopenacc-parallelism
|
||||||
-Wpmf-conversions \
|
-Wopenmp-simd
|
||||||
-Wpointer-arith \
|
-Woverflow
|
||||||
-Wpointer-compare \
|
-Woverlength-strings
|
||||||
-Wpragmas \
|
-Woverloaded-virtual
|
||||||
-Wprio-ctor-dtor \
|
-Wpacked
|
||||||
-Wpsabi \
|
-Wpacked-bitfield-compat
|
||||||
-Wrange-loop-construct \
|
-Wpacked-not-aligned
|
||||||
-Wredundant-decls \
|
-Wno-padded
|
||||||
-Wredundant-move \
|
-Wparentheses
|
||||||
-Wredundant-tags \
|
-Wpedantic
|
||||||
-Wregister \
|
-Wpessimizing-move
|
||||||
-Wreorder \
|
-Wplacement-new=2
|
||||||
-Wrestrict \
|
-Wpmf-conversions
|
||||||
-Wreturn-local-addr \
|
-Wpointer-arith
|
||||||
-Wreturn-type \
|
-Wpointer-compare
|
||||||
-Wscalar-storage-order \
|
-Wpragmas
|
||||||
-Wsequence-point \
|
-Wprio-ctor-dtor
|
||||||
-Wshadow=compatible-local \
|
-Wpsabi
|
||||||
-Wshadow=global \
|
-Wrange-loop-construct
|
||||||
-Wshadow=local \
|
-Wredundant-decls
|
||||||
-Wshift-count-negative \
|
-Wredundant-move
|
||||||
-Wshift-count-overflow \
|
-Wredundant-tags
|
||||||
-Wshift-negative-value \
|
-Wregister
|
||||||
-Wshift-overflow=2 \
|
-Wreorder
|
||||||
-Wsign-compare \
|
-Wrestrict
|
||||||
-Wsign-conversion \
|
-Wreturn-local-addr
|
||||||
-Wsign-promo \
|
-Wreturn-type
|
||||||
-Wsized-deallocation \
|
-Wscalar-storage-order
|
||||||
-Wsizeof-array-argument \
|
-Wsequence-point
|
||||||
-Wsizeof-array-div \
|
-Wshadow=compatible-local
|
||||||
-Wsizeof-pointer-div \
|
-Wshadow=global
|
||||||
-Wsizeof-pointer-memaccess \
|
-Wshadow=local
|
||||||
-Wstack-protector \
|
-Wshift-count-negative
|
||||||
-Wstrict-aliasing \
|
-Wshift-count-overflow
|
||||||
-Wstrict-aliasing=3 \
|
-Wshift-negative-value
|
||||||
-Wstrict-null-sentinel \
|
-Wshift-overflow=2
|
||||||
-Wstrict-overflow \
|
-Wsign-compare
|
||||||
-Wstrict-overflow=5 \
|
-Wsign-conversion
|
||||||
-Wstring-compare \
|
-Wsign-promo
|
||||||
-Wstringop-overflow=4 \
|
-Wsized-deallocation
|
||||||
-Wstringop-overread \
|
-Wsizeof-array-argument
|
||||||
-Wstringop-truncation \
|
-Wsizeof-array-div
|
||||||
-Wsubobject-linkage \
|
-Wsizeof-pointer-div
|
||||||
-Wsuggest-attribute=cold \
|
-Wsizeof-pointer-memaccess
|
||||||
-Wsuggest-attribute=const \
|
-Wstack-protector
|
||||||
-Wsuggest-attribute=format \
|
-Wstrict-aliasing
|
||||||
-Wsuggest-attribute=malloc \
|
-Wstrict-aliasing=3
|
||||||
-Wsuggest-attribute=noreturn \
|
-Wstrict-null-sentinel
|
||||||
-Wsuggest-attribute=pure \
|
-Wstrict-overflow
|
||||||
-Wsuggest-final-methods \
|
-Wstrict-overflow=5
|
||||||
-Wsuggest-final-types \
|
-Wstring-compare
|
||||||
-Wsuggest-override \
|
-Wstringop-overflow=4
|
||||||
-Wswitch \
|
-Wstringop-overread
|
||||||
-Wswitch-bool \
|
-Wstringop-truncation
|
||||||
-Wswitch-default \
|
-Wsubobject-linkage
|
||||||
-Wswitch-enum \
|
-Wsuggest-attribute=cold
|
||||||
-Wswitch-outside-range \
|
-Wsuggest-attribute=const
|
||||||
-Wswitch-unreachable \
|
-Wsuggest-attribute=format
|
||||||
-Wsync-nand \
|
-Wsuggest-attribute=malloc
|
||||||
-Wsynth \
|
-Wsuggest-attribute=noreturn
|
||||||
-Wno-system-headers \
|
-Wsuggest-attribute=pure
|
||||||
-Wtautological-compare \
|
-Wsuggest-final-methods
|
||||||
-Wno-templates \
|
-Wsuggest-final-types
|
||||||
-Wterminate \
|
-Wsuggest-override
|
||||||
-Wtrampolines \
|
-Wswitch
|
||||||
-Wtrigraphs \
|
-Wswitch-bool
|
||||||
-Wtsan \
|
-Wswitch-default
|
||||||
-Wtype-limits \
|
-Wswitch-enum
|
||||||
-Wundef \
|
-Wswitch-outside-range
|
||||||
-Wuninitialized \
|
-Wswitch-unreachable
|
||||||
-Wunknown-pragmas \
|
-Wsync-nand
|
||||||
-Wunreachable-code \
|
-Wsynth
|
||||||
-Wunsafe-loop-optimizations \
|
-Wno-system-headers
|
||||||
-Wunused \
|
-Wtautological-compare
|
||||||
-Wunused-but-set-parameter \
|
-Wno-templates
|
||||||
-Wunused-but-set-variable \
|
-Wterminate
|
||||||
-Wunused-const-variable=2 \
|
-Wtrampolines
|
||||||
-Wunused-function \
|
-Wtrigraphs
|
||||||
-Wunused-label \
|
-Wtsan
|
||||||
-Wunused-local-typedefs \
|
-Wtype-limits
|
||||||
-Wunused-macros \
|
-Wundef
|
||||||
-Wunused-parameter \
|
-Wuninitialized
|
||||||
-Wunused-result \
|
-Wunknown-pragmas
|
||||||
-Wunused-value \
|
-Wunreachable-code
|
||||||
-Wunused-variable \
|
-Wunsafe-loop-optimizations
|
||||||
-Wuseless-cast \
|
-Wunused
|
||||||
-Wvarargs \
|
-Wunused-but-set-parameter
|
||||||
-Wvariadic-macros \
|
-Wunused-but-set-variable
|
||||||
-Wvector-operation-performance \
|
-Wunused-const-variable=2
|
||||||
-Wvexing-parse \
|
-Wunused-function
|
||||||
-Wvirtual-inheritance \
|
-Wunused-label
|
||||||
-Wvirtual-move-assign \
|
-Wunused-local-typedefs
|
||||||
-Wvla \
|
-Wunused-macros
|
||||||
-Wvla-parameter \
|
-Wunused-parameter
|
||||||
-Wvolatile \
|
-Wunused-result
|
||||||
-Wvolatile-register-var \
|
-Wunused-value
|
||||||
-Wwrite-strings \
|
-Wunused-variable
|
||||||
-Wzero-as-null-pointer-constant \
|
-Wuseless-cast
|
||||||
-Wzero-length-bounds \
|
-Wvarargs
|
||||||
")
|
-Wvariadic-macros
|
||||||
|
-Wvector-operation-performance
|
||||||
|
-Wvexing-parse
|
||||||
|
-Wvirtual-inheritance
|
||||||
|
-Wvirtual-move-assign
|
||||||
|
-Wvla
|
||||||
|
-Wvla-parameter
|
||||||
|
-Wvolatile
|
||||||
|
-Wvolatile-register-var
|
||||||
|
-Wwrite-strings
|
||||||
|
-Wzero-as-null-pointer-constant
|
||||||
|
-Wzero-length-bounds
|
||||||
|
)
|
||||||
|
|
||||||
add_custom_target(ci_test_gcc
|
add_custom_target(ci_test_gcc
|
||||||
COMMAND CXX=${GCC_TOOL} CXXFLAGS=${GCC_CXXFLAGS} ${CMAKE_COMMAND}
|
COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND}
|
||||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||||
-DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON
|
-DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc
|
||||||
@ -406,7 +419,7 @@ add_custom_target(ci_test_gcc
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(ci_test_clang
|
add_custom_target(ci_test_clang
|
||||||
COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXXFLAGS} ${CMAKE_COMMAND}
|
COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND}
|
||||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||||
-DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON
|
-DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang
|
||||||
@ -421,10 +434,10 @@ add_custom_target(ci_test_clang
|
|||||||
|
|
||||||
foreach(CXX_STANDARD 11 14 17 20)
|
foreach(CXX_STANDARD 11 14 17 20)
|
||||||
add_custom_target(ci_test_gcc_cxx${CXX_STANDARD}
|
add_custom_target(ci_test_gcc_cxx${CXX_STANDARD}
|
||||||
COMMAND CXX=${GCC_TOOL} ${CMAKE_COMMAND}
|
COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND}
|
||||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||||
-DCMAKE_CXX_STANDARD=${CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
|
||||||
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
||||||
|
-DJSON_TestStandards=${CXX_STANDARD}
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD}
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD}
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD}
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD}
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
||||||
@ -432,10 +445,10 @@ foreach(CXX_STANDARD 11 14 17 20)
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(ci_test_clang_cxx${CXX_STANDARD}
|
add_custom_target(ci_test_clang_cxx${CXX_STANDARD}
|
||||||
COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}
|
COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND}
|
||||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||||
-DCMAKE_CXX_STANDARD=${CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
||||||
-DJSON_BuildTests=ON
|
-DJSON_TestStandards=${CXX_STANDARD}
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD}
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD}
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD}
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD}
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
||||||
@ -756,50 +769,67 @@ add_custom_target(ci_benchmarks
|
|||||||
# CMake flags
|
# CMake flags
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
if (APPLE)
|
function(ci_get_cmake version var)
|
||||||
set(CMAKE_310_BINARY ${PROJECT_BINARY_DIR}/cmake-3.1.0-Darwin64/CMake.app/Contents/bin/cmake)
|
if (APPLE)
|
||||||
add_custom_command(
|
set(${var} ${PROJECT_BINARY_DIR}/cmake-${version}-Darwin64/CMake.app/Contents/bin/cmake)
|
||||||
OUTPUT ${CMAKE_310_BINARY}
|
add_custom_command(
|
||||||
COMMAND wget https://github.com/Kitware/CMake/releases/download/v3.1.0/cmake-3.1.0-Darwin64.tar.gz
|
OUTPUT ${${var}}
|
||||||
COMMAND tar xfz cmake-3.1.0-Darwin64.tar.gz
|
COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-Darwin64.tar.gz
|
||||||
COMMAND rm cmake-3.1.0-Darwin64.tar.gz
|
COMMAND tar xfz cmake-${version}-Darwin64.tar.gz
|
||||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
COMMAND rm cmake-${version}-Darwin64.tar.gz
|
||||||
COMMENT "Download CMake 3.1.0"
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
)
|
COMMENT "Download CMake ${version}"
|
||||||
else()
|
)
|
||||||
set(CMAKE_310_BINARY ${PROJECT_BINARY_DIR}/cmake-3.1.0-Linux-x86_64/bin/cmake)
|
else()
|
||||||
add_custom_command(
|
set(${var} ${PROJECT_BINARY_DIR}/cmake-${version}-Linux-x86_64/bin/cmake)
|
||||||
OUTPUT ${CMAKE_310_BINARY}
|
add_custom_command(
|
||||||
COMMAND wget https://github.com/Kitware/CMake/releases/download/v3.1.0/cmake-3.1.0-Linux-x86_64.tar.gz
|
OUTPUT ${${var}}
|
||||||
COMMAND tar xfz cmake-3.1.0-Linux-x86_64.tar.gz
|
COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-Linux-x86_64.tar.gz
|
||||||
COMMAND rm cmake-3.1.0-Linux-x86_64.tar.gz
|
COMMAND tar xfz cmake-${version}-Linux-x86_64.tar.gz
|
||||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
COMMAND rm cmake-${version}-Linux-x86_64.tar.gz
|
||||||
COMMENT "Download CMake 3.1.0"
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
)
|
COMMENT "Download CMake ${version}"
|
||||||
endif()
|
)
|
||||||
|
endif()
|
||||||
|
set(${var} ${${var}} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
set(JSON_CMAKE_FLAGS "JSON_BuildTests;JSON_Install;JSON_MultipleHeaders;JSON_ImplicitConversions;JSON_Valgrind;JSON_Diagnostics;JSON_SystemInclude")
|
ci_get_cmake(3.1.0 CMAKE_3_1_0_BINARY)
|
||||||
|
ci_get_cmake(3.13.0 CMAKE_3_13_0_BINARY)
|
||||||
|
|
||||||
foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS})
|
set(JSON_CMAKE_FLAGS_3_1_0 "JSON_Install;JSON_MultipleHeaders;JSON_ImplicitConversions;JSON_Valgrind;JSON_Diagnostics;JSON_SystemInclude")
|
||||||
string(TOLOWER "ci_cmake_flag_${JSON_CMAKE_FLAG}" JSON_CMAKE_FLAG_TARGET)
|
set(JSON_CMAKE_FLAGS_3_13_0 "JSON_BuildTests")
|
||||||
add_custom_target("${JSON_CMAKE_FLAG_TARGET}"
|
|
||||||
COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${CMAKE_VERSION})"
|
function(ci_add_cmake_flags_targets flag min_version)
|
||||||
|
string(TOLOWER "ci_cmake_flag_${flag}" flag_target)
|
||||||
|
string(REPLACE . _ min_version_var ${min_version})
|
||||||
|
set(cmake_binary ${CMAKE_${min_version_var}_BINARY})
|
||||||
|
add_custom_target(${flag_target}
|
||||||
|
COMMENT "Check CMake flag ${flag} (CMake ${CMAKE_VERSION})"
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
-Werror=dev
|
-Werror=dev
|
||||||
-D${JSON_CMAKE_FLAG}=ON
|
-D${flag}=ON
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${flag_target}
|
||||||
)
|
)
|
||||||
add_custom_target("${JSON_CMAKE_FLAG_TARGET}_31"
|
add_custom_target(${flag_target}_${min_version_var}
|
||||||
COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake 3.1)"
|
COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${min_version})"
|
||||||
COMMAND mkdir ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}_31
|
COMMAND mkdir -pv ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var}
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}_31 && ${CMAKE_310_BINARY}
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var}
|
||||||
-Werror=dev ${PROJECT_SOURCE_DIR}
|
&& ${cmake_binary} -Werror=dev ${PROJECT_SOURCE_DIR} -D${flag}=ON
|
||||||
-D${JSON_CMAKE_FLAG}=ON
|
DEPENDS ${cmake_binary}
|
||||||
-DCMAKE_CXX_COMPILE_FEATURES="cxx_range_for" -DCMAKE_CXX_FLAGS="-std=gnu++11"
|
|
||||||
DEPENDS ${CMAKE_310_BINARY}
|
|
||||||
)
|
)
|
||||||
list(APPEND JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGET} ${JSON_CMAKE_FLAG_TARGET}_31)
|
list(APPEND JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGET} ${flag_target}_${min_version_var})
|
||||||
list(APPEND JSON_CMAKE_FLAG_BUILD_DIRS ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET} ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}_31)
|
list(APPEND JSON_CMAKE_FLAG_BUILD_DIRS ${PROJECT_BINARY_DIR}/build_${flag_target} ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var})
|
||||||
|
set(JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGETS} PARENT_SCOPE)
|
||||||
|
set(JSON_CMAKE_FLAG_BUILD_DIRS ${JSON_CMAKE_FLAG_BUILD_DIRS} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS_3_1_0})
|
||||||
|
ci_add_cmake_flags_targets(${JSON_CMAKE_FLAG} 3.1.0)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS_3_13_0})
|
||||||
|
ci_add_cmake_flags_targets(${JSON_CMAKE_FLAG} 3.13.0)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
add_custom_target(ci_cmake_flags
|
add_custom_target(ci_cmake_flags
|
||||||
|
|||||||
204
cmake/test.cmake
Normal file
204
cmake/test.cmake
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
set(_json_test_cmake_list_file ${CMAKE_CURRENT_LIST_FILE})
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# download test data
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
include(download_test_data)
|
||||||
|
|
||||||
|
# test fixture to download test data
|
||||||
|
add_test(NAME "download_test_data" COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}
|
||||||
|
--target download_test_data
|
||||||
|
)
|
||||||
|
set_tests_properties(download_test_data PROPERTIES FIXTURES_SETUP TEST_DATA)
|
||||||
|
|
||||||
|
if(JSON_Valgrind)
|
||||||
|
find_program(CMAKE_MEMORYCHECK_COMMAND valgrind)
|
||||||
|
message(STATUS "Executing test suite with Valgrind (${CMAKE_MEMORYCHECK_COMMAND})")
|
||||||
|
set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode=1 --leak-check=full")
|
||||||
|
separate_arguments(memcheck_command)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# detect standard support
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
# C++11 is the minimum required
|
||||||
|
set(compiler_supports_cpp_11 TRUE)
|
||||||
|
|
||||||
|
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
|
||||||
|
if (${feature} STREQUAL cxx_std_14)
|
||||||
|
set(compiler_supports_cpp_14 TRUE)
|
||||||
|
elseif (${feature} STREQUAL cxx_std_17)
|
||||||
|
set(compiler_supports_cpp_17 TRUE)
|
||||||
|
elseif (${feature} STREQUAL cxx_std_20)
|
||||||
|
set(compiler_supports_cpp_20 TRUE)
|
||||||
|
elseif (${feature} STREQUAL cxx_std_23)
|
||||||
|
set(compiler_supports_cpp_23 TRUE)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# test functions
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# json_test_set_test_options(
|
||||||
|
# all|<tests>
|
||||||
|
# [CXX_STANDARDS all|<args>...]
|
||||||
|
# [COMPILE_DEFINITIONS <args>...]
|
||||||
|
# [COMPILE_FEATURES <args>...]
|
||||||
|
# [COMPILE_OPTIONS <args>...]
|
||||||
|
# [LINK_LIBRARIES <args>...]
|
||||||
|
# [LINK_OPTIONS <args>...])
|
||||||
|
#
|
||||||
|
# Supply test- and standard-specific build settings.
|
||||||
|
# Specify multiple tests using a list e.g., "test-foo;test-bar".
|
||||||
|
#
|
||||||
|
# Must be called BEFORE the test is created.
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
function(json_test_set_test_options tests)
|
||||||
|
cmake_parse_arguments(args "" ""
|
||||||
|
"CXX_STANDARDS;COMPILE_DEFINITIONS;COMPILE_FEATURES;COMPILE_OPTIONS;LINK_LIBRARIES;LINK_OPTIONS"
|
||||||
|
${ARGN})
|
||||||
|
|
||||||
|
if(NOT args_CXX_STANDARDS)
|
||||||
|
set(args_CXX_STANDARDS "all")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(test ${tests})
|
||||||
|
if("${test}" STREQUAL "all")
|
||||||
|
set(test "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(cxx_standard ${args_CXX_STANDARDS})
|
||||||
|
if("${cxx_standard}" STREQUAL "all")
|
||||||
|
if("${test}" STREQUAL "")
|
||||||
|
message(FATAL_ERROR "Not supported. Change defaults in: ${_json_test_cmake_list_file}")
|
||||||
|
endif()
|
||||||
|
set(test_interface _json_test_interface_${test})
|
||||||
|
else()
|
||||||
|
set(test_interface _json_test_interface_${test}_cpp_${cxx_standard})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT TARGET ${test_interface})
|
||||||
|
add_library(${test_interface} INTERFACE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(${test_interface} INTERFACE ${args_COMPILE_DEFINITIONS})
|
||||||
|
target_compile_features(${test_interface} INTERFACE ${args_COMPILE_FEATURES})
|
||||||
|
target_compile_options(${test_interface} INTERFACE ${args_COMPILE_OPTIONS})
|
||||||
|
target_link_libraries (${test_interface} INTERFACE ${args_LINK_LIBRARIES})
|
||||||
|
target_link_options(${test_interface} INTERFACE ${args_LINK_OPTIONS})
|
||||||
|
endforeach()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# for internal use by json_test_add_test_for()
|
||||||
|
function(_json_test_add_test test_name file main cxx_standard)
|
||||||
|
set(test_target ${test_name}_cpp${cxx_standard})
|
||||||
|
|
||||||
|
if(TARGET ${test_target})
|
||||||
|
message(FATAL_ERROR "Target ${test_target} has already been added.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(${test_target} ${file})
|
||||||
|
target_link_libraries(${test_target} PRIVATE ${main})
|
||||||
|
|
||||||
|
# set and require C++ standard
|
||||||
|
set_target_properties(${test_target} PROPERTIES
|
||||||
|
CXX_STANDARD ${cxx_standard}
|
||||||
|
CXX_STANDARD_REQUIRED ON
|
||||||
|
)
|
||||||
|
|
||||||
|
# apply standard-specific build settings
|
||||||
|
if(TARGET _json_test_interface__cpp_${cxx_standard})
|
||||||
|
target_link_libraries(${test_target} PRIVATE _json_test_interface__cpp_${cxx_standard})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# apply test-specific build settings
|
||||||
|
if(TARGET _json_test_interface_${test_name})
|
||||||
|
target_link_libraries(${test_target} PRIVATE _json_test_interface_${test_name})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# apply test- and standard-specific build settings
|
||||||
|
if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard})
|
||||||
|
target_link_libraries(${test_target} PRIVATE
|
||||||
|
_json_test_interface_${test_name}_cpp_${cxx_standard}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (JSON_FastTests)
|
||||||
|
add_test(NAME ${test_target}
|
||||||
|
COMMAND ${test_target} ${DOCTEST_TEST_FILTER}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
add_test(NAME ${test_target}
|
||||||
|
COMMAND ${test_target} ${DOCTEST_TEST_FILTER} --no-skip
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
set_tests_properties(${test_target} PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
|
||||||
|
|
||||||
|
if(JSON_Valgrind)
|
||||||
|
add_test(NAME ${test_target}_valgrind
|
||||||
|
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
set_tests_properties(${test_target}_valgrind PROPERTIES
|
||||||
|
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# json_test_add_test_for(
|
||||||
|
# <file>
|
||||||
|
# MAIN <main>
|
||||||
|
# [CXX_STANDARDS <version_number>...] [FORCE])
|
||||||
|
#
|
||||||
|
# Given a <file> unit-foo.cpp, produces
|
||||||
|
#
|
||||||
|
# test-foo_cpp<version_number>
|
||||||
|
#
|
||||||
|
# if C++ standard <version_number> is supported by the compiler and the
|
||||||
|
# source file contains JSON_HAS_CPP_<version_number>.
|
||||||
|
# Use FORCE to create the test regardless of the file containing
|
||||||
|
# JSON_HAS_CPP_<version_number>.
|
||||||
|
# Test targets are linked against <main>.
|
||||||
|
# CXX_STANDARDS defaults to "11".
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
function(json_test_add_test_for file)
|
||||||
|
cmake_parse_arguments(args "FORCE" "MAIN" "CXX_STANDARDS" ${ARGN})
|
||||||
|
|
||||||
|
get_filename_component(file_basename ${file} NAME_WE)
|
||||||
|
string(REGEX REPLACE "unit-([^$]+)" "test-\\1" test_name ${file_basename})
|
||||||
|
|
||||||
|
if("${args_MAIN}" STREQUAL "")
|
||||||
|
message(FATAL_ERROR "Required argument MAIN <main> missing.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if("${args_CXX_STANDARDS}" STREQUAL "")
|
||||||
|
set(args_CXX_STANDARDS 11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(READ ${file} file_content)
|
||||||
|
foreach(cxx_standard ${args_CXX_STANDARDS})
|
||||||
|
if(NOT compiler_supports_cpp_${cxx_standard})
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# add unconditionally if C++11 (default) or forced
|
||||||
|
if(NOT ("${cxx_standard}" STREQUAL 11 OR args_FORCE))
|
||||||
|
string(FIND "${file_content}" JSON_HAS_CPP_${cxx_standard} has_cpp_found)
|
||||||
|
if(${has_cpp_found} EQUAL -1)
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
_json_test_add_test(${test_name} ${file} ${args_MAIN} ${cxx_standard})
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
@ -43,6 +43,10 @@ Linear.
|
|||||||
--8<-- "examples/operator_literal_json_pointer.output"
|
--8<-- "examples/operator_literal_json_pointer.output"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [json_pointer](../json_pointer/index.md) - type to represent JSON Pointers
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 2.0.0.
|
- Added in version 2.0.0.
|
||||||
|
|||||||
@ -29,6 +29,7 @@ are the base for JSON patches.
|
|||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
|
- [operator""_json_pointer](../basic_json/operator_literal_json_pointer.md) - user-defined string literal for JSON pointers
|
||||||
- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)
|
- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|||||||
@ -85,29 +85,31 @@ Some important things:
|
|||||||
|
|
||||||
If you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate.
|
If you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate.
|
||||||
|
|
||||||
There are two macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object:
|
There are four macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object:
|
||||||
|
|
||||||
- `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the namespace of the class/struct to create code for.
|
- `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the namespace of the class/struct to create code for. It will throw an exception in `from_json()` due to a missing value in the JSON object.
|
||||||
- `NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the class/struct to create code for. This macro can also access private members.
|
- `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...)` is to be defined inside the namespace of the class/struct to create code for. It will not throw an exception in `from_json()` due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type.
|
||||||
|
- `NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the class/struct to create code for. This macro can also access private members. It will throw an exception in `from_json()` due to a missing value in the JSON object.
|
||||||
|
- `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...)` is to be defined inside the class/struct to create code for. This macro can also access private members. It will not throw an exception in `from_json()` due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type.
|
||||||
|
|
||||||
In both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members.
|
In all macros, the first parameter is the name of the class/struct, and all remaining parameters name the members. You can read more docs about them starting from [here](macros.md#nlohmann_define_type_intrusivetype-member).
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
At most 64 member variables can be passed to `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` or `NLOHMANN_DEFINE_TYPE_INTRUSIVE`.
|
At most 64 member variables can be passed to these macros.
|
||||||
|
|
||||||
??? example
|
??? example
|
||||||
|
|
||||||
The `to_json`/`from_json` functions for the `person` struct above can be created with:
|
The `to_json`/`from_json` functions for the `person` struct above can be created with:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
namespace ns {
|
namespace ns {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed:
|
Here is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
namespace ns {
|
namespace ns {
|
||||||
class address {
|
class address {
|
||||||
@ -115,7 +117,7 @@ In both macros, the first parameter is the name of the class/struct, and all rem
|
|||||||
std::string street;
|
std::string street;
|
||||||
int housenumber;
|
int housenumber;
|
||||||
int postcode;
|
int postcode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,19 +1,123 @@
|
|||||||
# JSON Pointer
|
# JSON Pointer
|
||||||
|
|
||||||
The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values.
|
## Introduction
|
||||||
|
|
||||||
|
The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address
|
||||||
|
structured values. A JSON Pointer is a string that identifies a specific value withing a JSON document.
|
||||||
|
|
||||||
|
Consider the following JSON document
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"array": ["A", "B", "C"],
|
||||||
|
"nested": {
|
||||||
|
"one": 1,
|
||||||
|
"two": 2,
|
||||||
|
"three": [true, false]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then every value inside the JSON document can be idientified as follows:
|
||||||
|
|
||||||
|
| JSON Pointer | JSON value |
|
||||||
|
|-------------------|----------------------------------------------------------------------------------|
|
||||||
|
| `/` | `#!json {"array":["A","B","C"],"nested":{"one":1,"two":2,"three":[true,false]}}` |
|
||||||
|
| `/array` | `#!json ["A","B","C"]` |
|
||||||
|
| `/array/0` | `#!json A` |
|
||||||
|
| `/array/1` | `#!json B` |
|
||||||
|
| `/array/2` | `#!json C` |
|
||||||
|
| `/nested` | `#!json {"one":1,"two":2,"three":[true,false]}` |
|
||||||
|
| `/nested/one` | `#!json 1` |
|
||||||
|
| `/nested/two` | `#!json 2` |
|
||||||
|
| `/nested/three` | `#!json [true,false]` |
|
||||||
|
| `/nested/three/0` | `#!json true` |
|
||||||
|
| `/nested/three/1` | `#!json false` |
|
||||||
|
|
||||||
|
## JSON Pointer creation
|
||||||
|
|
||||||
|
JSON Pointers can be created from a string:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// a JSON value
|
json::json_pointer p = "/nested/one";
|
||||||
json j_original = R"({
|
```
|
||||||
"baz": ["one", "two", "three"],
|
|
||||||
"foo": "bar"
|
|
||||||
})"_json;
|
|
||||||
|
|
||||||
// access members with a JSON pointer (RFC 6901)
|
Furthermore, a user-defined string literal can be used to achieve the same result:
|
||||||
j_original["/baz/1"_json_pointer];
|
|
||||||
// "two"
|
```cpp
|
||||||
|
auto p = "/nested/one"_json_pointer;
|
||||||
|
```
|
||||||
|
|
||||||
|
The escaping rules of [RFC 6901](https://tools.ietf.org/html/rfc6901) are implemented. See the
|
||||||
|
[constructor documentation](../api/json_pointer/json_pointer.md) for more information.
|
||||||
|
|
||||||
|
## Value access
|
||||||
|
|
||||||
|
JSON Pointers can be used in the [`at`](../api/basic_json/at.md), [`operator[]`](../api/basic_json/operator%5B%5D.md),
|
||||||
|
and [`value`](../api/basic_json/value.md) functions just like object keys or array indices.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// the JSON value from above
|
||||||
|
auto j = json::parse(R"({
|
||||||
|
"array": ["A", "B", "C"],
|
||||||
|
"nested": {
|
||||||
|
"one": 1,
|
||||||
|
"two": 2,
|
||||||
|
"three": [true, false]
|
||||||
|
}
|
||||||
|
})");
|
||||||
|
|
||||||
|
// access values
|
||||||
|
auto val = j["/"_json_pointer]; // {"array":["A","B","C"],...}
|
||||||
|
auto val1 = j["/nested/one"_json_pointer]; // 1
|
||||||
|
auto val2 = j.at[json::json_pointer("/nested/three/1")]; // false
|
||||||
|
auto val3 = j.value[json::json_pointer("/nested/four", 0)]; // 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Flatten / unflatten
|
||||||
|
|
||||||
|
The library implements a function [`flatten`](../api/basic_json/flatten.md) to convert any JSON document into a JSON
|
||||||
|
object where each key is a JSON Pointer and each value is a primitive JSON value (i.e., a string, boolean, number, or
|
||||||
|
null).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// the JSON value from above
|
||||||
|
auto j = json::parse(R"({
|
||||||
|
"array": ["A", "B", "C"],
|
||||||
|
"nested": {
|
||||||
|
"one": 1,
|
||||||
|
"two": 2,
|
||||||
|
"three": [true, false]
|
||||||
|
}
|
||||||
|
})");
|
||||||
|
|
||||||
|
// create flattened value
|
||||||
|
auto j_flat = j.flatten();
|
||||||
|
```
|
||||||
|
|
||||||
|
The resulting value `j_flat` is:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"/array/0": "A",
|
||||||
|
"/array/1": "B",
|
||||||
|
"/array/2": "C",
|
||||||
|
"/nested/one": 1,
|
||||||
|
"/nested/two": 2,
|
||||||
|
"/nested/three/0": true,
|
||||||
|
"/nested/three/1": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The reverse function, [`unflatten`](../api/basic_json/unflatten.md) recreates the original value.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
auto j_original = j_flat.unflatten();
|
||||||
```
|
```
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
- Class [`json_pointer`](../api/json_pointer/index.md)
|
- Class [`json_pointer`](../api/json_pointer/index.md)
|
||||||
|
- Function [`flatten`](../api/basic_json/flatten.md)
|
||||||
|
- Function [`unflatten`](../api/basic_json/unflatten.md)
|
||||||
|
- [JSON Patch](json_patch.md)
|
||||||
|
|||||||
@ -4,16 +4,41 @@ Some aspects of the library can be configured by defining preprocessor macros be
|
|||||||
|
|
||||||
## `JSON_ASSERT(x)`
|
## `JSON_ASSERT(x)`
|
||||||
|
|
||||||
The default value is `#!cpp assert(x)`.
|
This macro controls which code is executed for runtime assertions of the libraries.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
The default value is [`#!cpp assert(x)`](https://en.cppreference.com/w/cpp/error/assert).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_ASSERT(x) assert(x)
|
||||||
|
```
|
||||||
|
|
||||||
## `JSON_CATCH_USER(exception)`
|
## `JSON_CATCH_USER(exception)`
|
||||||
|
|
||||||
This macro overrides `#!cpp catch` calls inside the library. The argument is the type of the exception to catch. As of
|
This macro overrides [`#!cpp catch`](https://en.cppreference.com/w/cpp/language/try_catch) calls inside the library.
|
||||||
version 3.8.0, the library only catches `std::out_of_range` exceptions internally to rethrow them as
|
The argument is the type of the exception to catch. As of version 3.8.0, the library only catches `std::out_of_range`
|
||||||
[`json::out_of_range`](../home/exceptions.md#out-of-range) exceptions. The macro is always followed by a scope.
|
exceptions internally to rethrow them as [`json::out_of_range`](../home/exceptions.md#out-of-range) exceptions. The
|
||||||
|
macro is always followed by a scope.
|
||||||
|
|
||||||
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
When exceptions are enabled, the default value is
|
||||||
|
[`#!cpp catch(exception)`](https://en.cppreference.com/w/cpp/language/try_catch).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_CATCH_USER(exception) catch(exception)
|
||||||
|
```
|
||||||
|
|
||||||
|
When exceptions are switched off by the compiler, the default value is `#!cpp if (false)` to make the catch block
|
||||||
|
unreachable.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_CATCH_USER(exception) if (false)
|
||||||
|
```
|
||||||
|
|
||||||
## `JSON_DIAGNOSTICS`
|
## `JSON_DIAGNOSTICS`
|
||||||
|
|
||||||
This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable
|
This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable
|
||||||
@ -26,6 +51,18 @@ that enabling this macro increases the size of every JSON value by one pointer a
|
|||||||
The diagnostics messages can also be controlled with the CMake option `JSON_Diagnostics` (`OFF` by default) which sets
|
The diagnostics messages can also be controlled with the CMake option `JSON_Diagnostics` (`OFF` by default) which sets
|
||||||
`JSON_DIAGNOSTICS` accordingly.
|
`JSON_DIAGNOSTICS` accordingly.
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
|
||||||
|
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; DO NOT link together code compiled with different definitions of
|
||||||
|
`JSON_DIAGNOSTICS` as this is a violation of the One Definition Rule and will cause undefined behaviour.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_DIAGNOSTICS 0
|
||||||
|
```
|
||||||
|
|
||||||
## `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`
|
## `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`
|
||||||
|
|
||||||
The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view`
|
The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view`
|
||||||
@ -34,6 +71,11 @@ standard. By defining any of these symbols, the internal check is overridden and
|
|||||||
unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be
|
unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be
|
||||||
detected incorrectly.
|
detected incorrectly.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
The default value is detected based on the preprocessor macros `#!cpp __cplusplus`, `#!cpp _HAS_CXX17`, or
|
||||||
|
`#!cpp _MSVC_LANG`.
|
||||||
|
|
||||||
## `JSON_HAS_FILESYSTEM`, `JSON_HAS_EXPERIMENTAL_FILESYSTEM`
|
## `JSON_HAS_FILESYSTEM`, `JSON_HAS_EXPERIMENTAL_FILESYSTEM`
|
||||||
|
|
||||||
When compiling with C++17, the library provides conversions from and to `std::filesystem::path`. As compiler support
|
When compiling with C++17, the library provides conversions from and to `std::filesystem::path`. As compiler support
|
||||||
@ -41,12 +83,29 @@ for filesystem is limited, the library tries to detect whether `<filesystem>`/`s
|
|||||||
or `<experimental/filesystem>`/`std::experimental::filesystem` (`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used.
|
or `<experimental/filesystem>`/`std::experimental::filesystem` (`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used.
|
||||||
To override the built-in check, define `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`.
|
To override the built-in check, define `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
The default value is detected based on the preprocessor macros `#!cpp __cpp_lib_filesystem`,
|
||||||
|
`#!cpp __cpp_lib_experimental_filesystem`, `#!cpp __has_include(<filesystem>)`, or
|
||||||
|
`#!cpp __has_include(<experimental/filesystem>)`.
|
||||||
|
|
||||||
|
Note that older compilers or older versions of libstd++ also require the library `stdc++fs` to be linked to for
|
||||||
|
filesystem support.
|
||||||
|
|
||||||
## `JSON_NOEXCEPTION`
|
## `JSON_NOEXCEPTION`
|
||||||
|
|
||||||
Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. When defining `JSON_NOEXCEPTION`, `#!cpp try`
|
Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. When defining `JSON_NOEXCEPTION`, `#!cpp try`
|
||||||
is replaced by `#!cpp if (true)`, `#!cpp catch` is replaced by `#!cpp if (false)`, and `#!cpp throw` is replaced by
|
is replaced by `#!cpp if (true)`, `#!cpp catch` is replaced by `#!cpp if (false)`, and `#!cpp throw` is replaced by
|
||||||
`#!cpp std::abort()`.
|
`#!cpp std::abort()`.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
By default, the macro is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#undef JSON_NOEXCEPTION
|
||||||
|
```
|
||||||
|
|
||||||
The same effect is achieved by setting the compiler flag `-fno-exceptions`.
|
The same effect is achieved by setting the compiler flag `-fno-exceptions`.
|
||||||
|
|
||||||
Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not
|
Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not
|
||||||
@ -58,23 +117,72 @@ When defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostrea
|
|||||||
relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for
|
relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for
|
||||||
security reasons (e.g., Intel Software Guard Extensions (SGX)).
|
security reasons (e.g., Intel Software Guard Extensions (SGX)).
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
By default, the macro is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#undef JSON_NO_IO
|
||||||
|
```
|
||||||
|
|
||||||
## `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`
|
## `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`
|
||||||
|
|
||||||
When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows to
|
When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows to
|
||||||
use the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.
|
use the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
By default, the macro is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK
|
||||||
|
```
|
||||||
|
|
||||||
## `JSON_THROW_USER(exception)`
|
## `JSON_THROW_USER(exception)`
|
||||||
|
|
||||||
This macro overrides `#!cpp throw` calls inside the library. The argument is the exception to be thrown. Note that
|
This macro overrides `#!cpp throw` calls inside the library. The argument is the exception to be thrown. Note that
|
||||||
`JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield
|
`JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield
|
||||||
undefined behavior.
|
undefined behavior.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
When exceptions are enabled, the default value is
|
||||||
|
[`#!cpp throw exception`](https://en.cppreference.com/w/cpp/language/throw).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_THROW_USER(exception) throw exception
|
||||||
|
```
|
||||||
|
|
||||||
|
When exceptions are switched off by the compiler, the default value is
|
||||||
|
[`#!cpp std::abort()`](https://en.cppreference.com/w/cpp/utility/program/abort) to make reaching the throw branch
|
||||||
|
abort the process.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_THROW_USER(exception) std::abort()
|
||||||
|
```
|
||||||
|
|
||||||
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
||||||
|
|
||||||
## `JSON_TRY_USER`
|
## `JSON_TRY_USER`
|
||||||
|
|
||||||
This macro overrides `#!cpp try` calls inside the library. It has no arguments and is always followed by a scope.
|
This macro overrides `#!cpp try` calls inside the library. It has no arguments and is always followed by a scope.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
When exceptions are enabled, the default value is
|
||||||
|
[`#!cpp try`](https://en.cppreference.com/w/cpp/language/try_catch).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_TRY_USER try
|
||||||
|
```
|
||||||
|
|
||||||
|
When exceptions are switched off by the compiler, the default value is `#!cpp if (true)` to unconditionally execute
|
||||||
|
the following code block.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_TRY_USER if (true)
|
||||||
|
```
|
||||||
|
|
||||||
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
||||||
|
|
||||||
## `JSON_USE_IMPLICIT_CONVERSIONS`
|
## `JSON_USE_IMPLICIT_CONVERSIONS`
|
||||||
@ -84,12 +192,12 @@ When defined to `0`, implicit conversions are switched off. By default, implicit
|
|||||||
??? example
|
??? example
|
||||||
|
|
||||||
This is an example for an implicit conversion:
|
This is an example for an implicit conversion:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
json j = "Hello, world!";
|
json j = "Hello, world!";
|
||||||
std::string s = j;
|
std::string s = j;
|
||||||
```
|
```
|
||||||
|
|
||||||
When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be
|
When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be
|
||||||
written like this:
|
written like this:
|
||||||
|
|
||||||
@ -101,6 +209,12 @@ When defined to `0`, implicit conversions are switched off. By default, implicit
|
|||||||
Implicit conversions can also be controlled with the CMake option `JSON_ImplicitConversions` (`ON` by default) which
|
Implicit conversions can also be controlled with the CMake option `JSON_ImplicitConversions` (`ON` by default) which
|
||||||
sets `JSON_USE_IMPLICIT_CONVERSIONS` accordingly.
|
sets `JSON_USE_IMPLICIT_CONVERSIONS` accordingly.
|
||||||
|
|
||||||
|
!!! info "Default behavior"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_USE_IMPLICIT_CONVERSIONS 1
|
||||||
|
```
|
||||||
|
|
||||||
## `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)`
|
## `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)`
|
||||||
|
|
||||||
This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as
|
This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as
|
||||||
@ -112,6 +226,10 @@ The first parameter is the name of the class/struct, and all remaining parameter
|
|||||||
|
|
||||||
See [Simplify your life with macros](arbitrary_types.md#simplify-your-life-with-macros) for an example.
|
See [Simplify your life with macros](arbitrary_types.md#simplify-your-life-with-macros) for an example.
|
||||||
|
|
||||||
|
## `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...)`
|
||||||
|
|
||||||
|
This macro is similar to `NLOHMANN_DEFINE_TYPE_INTRUSIVE`. It will not throw an exception in `from_json()` due to a missing value in the JSON object, but can throw due to a mismatched type. In order to support that it requires that the type be default constructible. The `from_json()` function default constructs an object and uses its values as the defaults when calling the `value()` function.
|
||||||
|
|
||||||
## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)`
|
## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)`
|
||||||
|
|
||||||
This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as
|
This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as
|
||||||
@ -123,6 +241,10 @@ first parameter is the name of the class/struct, and all remaining parameters na
|
|||||||
|
|
||||||
See [Simplify your life with macros](arbitrary_types.md#simplify-your-life-with-macros) for an example.
|
See [Simplify your life with macros](arbitrary_types.md#simplify-your-life-with-macros) for an example.
|
||||||
|
|
||||||
|
## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...)`
|
||||||
|
|
||||||
|
This macro is similar to `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`. It will not throw an exception in `from_json()` due to a missing value in the JSON object, but can throw due to a mismatched type. In order to support that it requires that the type be default constructible. The `from_json()` function default constructs an object and uses its values as the defaults when calling the `value()` function.
|
||||||
|
|
||||||
## `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)`
|
## `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)`
|
||||||
|
|
||||||
This macro simplifies the serialization/deserialization of enum types. See
|
This macro simplifies the serialization/deserialization of enum types. See
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
The [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". As such, an implementation does not need to preserve any specific order of object keys.
|
The [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". As such, an implementation does not need to preserve any specific order of object keys.
|
||||||
|
|
||||||
|
## Default behavior: sort keys
|
||||||
|
|
||||||
The default type `nlohmann::json` uses a `std::map` to store JSON objects, and thus stores object keys **sorted alphabetically**.
|
The default type `nlohmann::json` uses a `std::map` to store JSON objects, and thus stores object keys **sorted alphabetically**.
|
||||||
|
|
||||||
??? example
|
??? example
|
||||||
@ -33,6 +35,8 @@ The default type `nlohmann::json` uses a `std::map` to store JSON objects, and t
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Alternative behavior: preserve insertion order
|
||||||
|
|
||||||
If you do want to preserve the **insertion order**, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179).
|
If you do want to preserve the **insertion order**, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179).
|
||||||
|
|
||||||
??? example
|
??? example
|
||||||
@ -65,3 +69,58 @@ If you do want to preserve the **insertion order**, you can try the type [`nlohm
|
|||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)).
|
Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)).
|
||||||
|
|
||||||
|
### Notes on parsing
|
||||||
|
|
||||||
|
Note that you also need to call the right [`parse`](../api/basic_json/parse.md) function when reading from a file.
|
||||||
|
Assume file `input.json` contains the JSON object above:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"one": 1,
|
||||||
|
"two": 2,
|
||||||
|
"three": 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! success "Right way"
|
||||||
|
|
||||||
|
The following code correctly calls the `parse` function from `nlohmann::ordered_json`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::ifstream i("input.json");
|
||||||
|
auto j = nlohmann::ordered_json::parse(i);
|
||||||
|
std::cout << j.dump(2) << std::endl;
|
||||||
|
```
|
||||||
|
|
||||||
|
The output will be:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"one": 1,
|
||||||
|
"two": 2,
|
||||||
|
"three": 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
??? failure "Wrong way"
|
||||||
|
|
||||||
|
The following code incorrectly calls the `parse` function from `nlohmann::json` which does not preserve the
|
||||||
|
insertion order, but sorts object keys. Assigning the result to `nlohmann::ordered_json` compiles, but does not
|
||||||
|
restore the order from the input file.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::ifstream i("input.json");
|
||||||
|
nlohmann::ordered_json j = nlohmann::json::parse(i);
|
||||||
|
std::cout << j.dump(2) << std::endl;
|
||||||
|
```
|
||||||
|
|
||||||
|
The output will be:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"one": 1,
|
||||||
|
"three": 3
|
||||||
|
"two": 2,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@ -2,102 +2,126 @@
|
|||||||
|
|
||||||
## Integration
|
## Integration
|
||||||
|
|
||||||
You can also use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.
|
You can use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage
|
||||||
|
requirements for [`INTERFACE_INCLUDE_DIRECTORIES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html)
|
||||||
|
to point to the appropriate include directories and [`INTERFACE_COMPILE_FEATURES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_COMPILE_FEATURES.html)
|
||||||
|
for the necessary C++11 flags.
|
||||||
|
|
||||||
### External
|
### External
|
||||||
|
|
||||||
To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:
|
To use this library from a CMake project, you can locate it directly with [`find_package()`](https://cmake.org/cmake/help/latest/command/find_package.html)
|
||||||
|
and use the namespaced imported target from the generated package configuration:
|
||||||
|
|
||||||
```cmake
|
!!! example
|
||||||
# CMakeLists.txt
|
|
||||||
find_package(nlohmann_json 3.2.0 REQUIRED)
|
|
||||||
...
|
|
||||||
add_library(foo ...)
|
|
||||||
...
|
|
||||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
|
||||||
```
|
|
||||||
|
|
||||||
The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.
|
```cmake title="CMakeLists.txt"
|
||||||
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
project(ExampleProject LANGUAGES CXX)
|
||||||
|
|
||||||
|
find_package(nlohmann_json 3.10.5 REQUIRED)
|
||||||
|
|
||||||
|
add_executable(example example.cpp)
|
||||||
|
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
|
||||||
|
```
|
||||||
|
|
||||||
|
The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of
|
||||||
|
the build tree.
|
||||||
|
|
||||||
### Embedded
|
### Embedded
|
||||||
|
|
||||||
To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:
|
To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call
|
||||||
|
`add_subdirectory()` in your `CMakeLists.txt` file.
|
||||||
|
|
||||||
```cmake
|
!!! example
|
||||||
# If you only include this third party in PRIVATE source files, you do not
|
|
||||||
# need to install it when your main project gets installed.
|
|
||||||
# set(JSON_Install OFF CACHE INTERNAL "")
|
|
||||||
|
|
||||||
# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
|
```cmake title="CMakeLists.txt"
|
||||||
# unintended consequences that will break the build. It's generally
|
cmake_minimum_required(VERSION 3.1)
|
||||||
# discouraged (although not necessarily well documented as such) to use
|
project(ExampleProject LANGUAGES CXX)
|
||||||
# include(...) for pulling in other CMake projects anyways.
|
|
||||||
add_subdirectory(nlohmann_json)
|
|
||||||
...
|
|
||||||
add_library(foo ...)
|
|
||||||
...
|
|
||||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Embedded (FetchContent)
|
# If you only include this third party in PRIVATE source files, you do not need to install it
|
||||||
|
# when your main project gets installed.
|
||||||
|
set(JSON_Install OFF CACHE INTERNAL "")
|
||||||
|
|
||||||
|
add_subdirectory(nlohmann_json)
|
||||||
|
|
||||||
Since CMake v3.11,
|
add_executable(example example.cpp)
|
||||||
[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
|
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
|
||||||
be used to automatically download the repository as a dependency at configure type.
|
```
|
||||||
|
|
||||||
Example:
|
!!! note
|
||||||
```cmake
|
|
||||||
include(FetchContent)
|
|
||||||
|
|
||||||
FetchContent_Declare(json
|
Do not use `#!cmake include(nlohmann_json/CMakeLists.txt)`, since that carries with it unintended consequences that
|
||||||
GIT_REPOSITORY https://github.com/nlohmann/json
|
will break the build. It is generally discouraged (although not necessarily well documented as such) to use
|
||||||
GIT_TAG v3.7.3)
|
`#!cmake include(...)` for pulling in other CMake projects anyways.
|
||||||
|
|
||||||
FetchContent_GetProperties(json)
|
|
||||||
if(NOT json_POPULATED)
|
|
||||||
FetchContent_Populate(json)
|
|
||||||
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
|
||||||
```
|
|
||||||
|
|
||||||
!!! Note
|
|
||||||
The repository <https://github.com/nlohmann/json> download size is quite large.
|
|
||||||
You might want to depend on a smaller repository. For instance, you might want to replace the URL above by
|
|
||||||
<https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent>.
|
|
||||||
|
|
||||||
### Supporting Both
|
### Supporting Both
|
||||||
|
|
||||||
To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:
|
To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin
|
||||||
|
to the following.
|
||||||
|
|
||||||
``` cmake
|
!!! example
|
||||||
# Top level CMakeLists.txt
|
|
||||||
project(FOO)
|
|
||||||
...
|
|
||||||
option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
|
|
||||||
...
|
|
||||||
add_subdirectory(thirdparty)
|
|
||||||
...
|
|
||||||
add_library(foo ...)
|
|
||||||
...
|
|
||||||
# Note that the namespaced target will always be available regardless of the
|
|
||||||
# import method
|
|
||||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
|
||||||
```
|
|
||||||
```cmake
|
|
||||||
# thirdparty/CMakeLists.txt
|
|
||||||
...
|
|
||||||
if(FOO_USE_EXTERNAL_JSON)
|
|
||||||
find_package(nlohmann_json 3.2.0 REQUIRED)
|
|
||||||
else()
|
|
||||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
|
||||||
add_subdirectory(nlohmann_json)
|
|
||||||
endif()
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
`thirdparty/nlohmann_json` is then a complete copy of this source tree.
|
```cmake title="CMakeLists.txt"
|
||||||
|
project(ExampleProject LANGUAGES CXX)
|
||||||
|
|
||||||
|
option(EXAMPLE_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
|
||||||
|
|
||||||
|
add_subdirectory(thirdparty)
|
||||||
|
|
||||||
|
add_executable(example example.cpp)
|
||||||
|
|
||||||
|
# Note that the namespaced target will always be available regardless of the import method
|
||||||
|
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
|
||||||
|
```
|
||||||
|
|
||||||
|
```cmake title="thirdparty/CMakeLists.txt"
|
||||||
|
if(EXAMPLE_USE_EXTERNAL_JSON)
|
||||||
|
find_package(nlohmann_json 3.10.5 REQUIRED)
|
||||||
|
else()
|
||||||
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||||
|
add_subdirectory(nlohmann_json)
|
||||||
|
endif()
|
||||||
|
```
|
||||||
|
|
||||||
|
`thirdparty/nlohmann_json` is then a complete copy of this source tree.
|
||||||
|
|
||||||
|
|
||||||
|
### FetchContent
|
||||||
|
|
||||||
|
Since CMake v3.11, [FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can be used to
|
||||||
|
automatically download a release as a dependency at configure type.
|
||||||
|
|
||||||
|
!!! example
|
||||||
|
|
||||||
|
```cmake title="CMakeLists.txt"
|
||||||
|
cmake_minimum_required(VERSION 3.11)
|
||||||
|
project(ExampleProject LANGUAGES CXX)
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.10.5/json.tar.xz)
|
||||||
|
FetchContent_MakeAvailable(json)
|
||||||
|
|
||||||
|
add_executable(example example.cpp)
|
||||||
|
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
|
||||||
|
It is recommended to use the URL approach described above which is supported as of version 3.10.0. It is also
|
||||||
|
possible to pass the Git repository like
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
FetchContent_Declare(json
|
||||||
|
GIT_REPOSITORY https://github.com/nlohmann/json
|
||||||
|
GIT_TAG v3.10.5
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
However, the repository <https://github.com/nlohmann/json> download size is quite large. You might want to depend on
|
||||||
|
a smaller repository. For instance, you might want to replace the URL in the example by
|
||||||
|
<https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent>.
|
||||||
|
|
||||||
## CMake Options
|
## CMake Options
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
std::cout << json::meta() << std::endl;
|
std::cout << std::setw(4) << json::meta() << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
# Header only
|
# Header only
|
||||||
|
|
||||||
[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add
|
[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required
|
||||||
|
file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
@ -9,6 +10,9 @@
|
|||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
```
|
```
|
||||||
|
|
||||||
to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
|
to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and
|
||||||
|
Clang).
|
||||||
|
|
||||||
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of `json_fwd.hpp` (as part of CMake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.
|
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp)
|
||||||
|
for forward-declarations. The installation of `json_fwd.hpp` (as part of CMake's install step), can be achieved by
|
||||||
|
setting `-DJSON_MultipleHeaders=ON`.
|
||||||
|
|||||||
@ -6,6 +6,12 @@ Throughout this page, we will describe how to compile the example file `example.
|
|||||||
--8<-- "integration/example.cpp"
|
--8<-- "integration/example.cpp"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
When executed, this program should create output similar to
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "../../examples/meta.output"
|
||||||
|
```
|
||||||
|
|
||||||
## Homebrew
|
## Homebrew
|
||||||
|
|
||||||
If you are using OS X and [Homebrew](http://brew.sh), just type
|
If you are using OS X and [Homebrew](http://brew.sh), just type
|
||||||
@ -26,11 +32,9 @@ instead. See [nlohmann-json](https://formulae.brew.sh/formula/nlohmann-json) for
|
|||||||
|
|
||||||
1. Create the following file:
|
1. Create the following file:
|
||||||
|
|
||||||
=== "example.cpp"
|
```cpp title="example.cpp"
|
||||||
|
--8<-- "integration/example.cpp"
|
||||||
```cpp
|
```
|
||||||
--8<-- "integration/example.cpp"
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Install the package
|
2. Install the package
|
||||||
|
|
||||||
@ -50,6 +54,8 @@ instead. See [nlohmann-json](https://formulae.brew.sh/formula/nlohmann-json) for
|
|||||||
clang++ example.cpp -I/usr/local/Cellar/nlohmann-json/3.7.3/include -std=c++11 -o example
|
clang++ example.cpp -I/usr/local/Cellar/nlohmann-json/3.7.3/include -std=c++11 -o example
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:material-update: The [formula](https://formulae.brew.sh/formula/nlohmann-json) is updated automatically.
|
||||||
|
|
||||||
## Meson
|
## Meson
|
||||||
|
|
||||||
If you are using the [Meson Build System](http://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging.
|
If you are using the [Meson Build System](http://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging.
|
||||||
@ -64,24 +70,17 @@ If you are using [Conan](https://www.conan.io/) to manage your dependencies, mer
|
|||||||
|
|
||||||
1. Create the following files:
|
1. Create the following files:
|
||||||
|
|
||||||
=== "Conanfile.txt"
|
```ini title="Conanfile.txt"
|
||||||
|
--8<-- "integration/conan/Conanfile.txt"
|
||||||
```ini
|
```
|
||||||
--8<-- "integration/conan/Conanfile.txt"
|
|
||||||
```
|
|
||||||
|
|
||||||
=== "CMakeLists.txt"
|
```cmake title="CMakeLists.txt"
|
||||||
|
--8<-- "integration/conan/CMakeLists.txt"
|
||||||
```cmake
|
```
|
||||||
--8<-- "integration/conan/CMakeLists.txt"
|
|
||||||
```
|
|
||||||
|
|
||||||
=== "example.cpp"
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
--8<-- "integration/conan/example.cpp"
|
|
||||||
```
|
|
||||||
|
|
||||||
|
```cpp title="example.cpp"
|
||||||
|
--8<-- "integration/conan/example.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
2. Build:
|
2. Build:
|
||||||
|
|
||||||
@ -93,6 +92,8 @@ If you are using [Conan](https://www.conan.io/) to manage your dependencies, mer
|
|||||||
cmake --build .
|
cmake --build .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:material-update: The [package](https://conan.io/center/nlohmann_json) is updated automatically.
|
||||||
|
|
||||||
## Spack
|
## Spack
|
||||||
|
|
||||||
If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging.
|
If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging.
|
||||||
@ -113,17 +114,13 @@ If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project fo
|
|||||||
|
|
||||||
1. Create the following files:
|
1. Create the following files:
|
||||||
|
|
||||||
=== "CMakeLists.txt"
|
```cmake title="CMakeLists.txt"
|
||||||
|
--8<-- "integration/vcpkg/CMakeLists.txt"
|
||||||
```cmake
|
```
|
||||||
--8<-- "integration/vcpkg/CMakeLists.txt"
|
|
||||||
```
|
```cpp title="example.cpp"
|
||||||
|
--8<-- "integration/vcpkg/example.cpp"
|
||||||
=== "example.cpp"
|
```
|
||||||
|
|
||||||
```cpp
|
|
||||||
--8<-- "integration/vcpkg/example.cpp"
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Install package:
|
2. Install package:
|
||||||
|
|
||||||
@ -146,6 +143,8 @@ If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project fo
|
|||||||
|
|
||||||
If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).
|
If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).
|
||||||
|
|
||||||
|
:material-update: cget reads directly from the [GitHub repository](https://github.com/nlohmann/json) and is always up-to-date.
|
||||||
|
|
||||||
## CocoaPods
|
## CocoaPods
|
||||||
|
|
||||||
If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).
|
If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).
|
||||||
@ -162,19 +161,27 @@ If you are using [conda](https://conda.io/), you can use the package [nlohmann_j
|
|||||||
|
|
||||||
If you are using [MSYS2](http://www.msys2.org/), you can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages.
|
If you are using [MSYS2](http://www.msys2.org/), you can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages.
|
||||||
|
|
||||||
|
:material-update: The [package](https://packages.msys2.org/base/mingw-w64-nlohmann-json) is updated automatically.
|
||||||
|
|
||||||
## MacPorts
|
## MacPorts
|
||||||
|
|
||||||
If you are using [MacPorts](https://ports.macports.org), execute `sudo port install nlohmann-json` to install the [nlohmann-json](https://ports.macports.org/port/nlohmann-json/) package.
|
If you are using [MacPorts](https://ports.macports.org), execute `sudo port install nlohmann-json` to install the [nlohmann-json](https://ports.macports.org/port/nlohmann-json/) package.
|
||||||
|
|
||||||
|
:material-update: The [package](https://ports.macports.org/port/nlohmann-json/) is updated automatically.
|
||||||
|
|
||||||
## build2
|
## build2
|
||||||
|
|
||||||
If you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository http://cppget.org or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml).
|
If you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository <http://cppget.org> or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml).
|
||||||
Please file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages.
|
Please file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages.
|
||||||
|
|
||||||
|
:material-update: The [package](https://cppget.org/nlohmann-json) is updated automatically.
|
||||||
|
|
||||||
## wsjcpp
|
## wsjcpp
|
||||||
|
|
||||||
If you are using [`wsjcpp`](http://wsjcpp.org), you can use the command `wsjcpp install "https://github.com/nlohmann/json:develop"` to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch.
|
If you are using [`wsjcpp`](http://wsjcpp.org), you can use the command `wsjcpp install "https://github.com/nlohmann/json:develop"` to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch.
|
||||||
|
|
||||||
|
:material-update: wsjcpp reads directly from the [GitHub repository](https://github.com/nlohmann/json) and is always up-to-date.
|
||||||
|
|
||||||
## CPM.cmake
|
## CPM.cmake
|
||||||
|
|
||||||
If you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), you can check this [`example`](https://github.com/TheLartians/CPM.cmake/tree/master/examples/json). After [adding CPM script](https://github.com/TheLartians/CPM.cmake#adding-cpm) to your project, implement the following snippet to your CMake:
|
If you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), you can check this [`example`](https://github.com/TheLartians/CPM.cmake/tree/master/examples/json). After [adding CPM script](https://github.com/TheLartians/CPM.cmake#adding-cpm) to your project, implement the following snippet to your CMake:
|
||||||
|
|||||||
@ -464,7 +464,8 @@ void from_json(const BasicJsonType& j, std_fs::path& p)
|
|||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
|
// Not tested because of #3377 (related #3070)
|
||||||
|
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -352,7 +352,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
@brief post-increment (it++)
|
@brief post-increment (it++)
|
||||||
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
||||||
*/
|
*/
|
||||||
iter_impl const operator++(int) // NOLINT(readability-const-return-type)
|
iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
++(*this);
|
++(*this);
|
||||||
@ -403,7 +403,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
@brief post-decrement (it--)
|
@brief post-decrement (it--)
|
||||||
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
||||||
*/
|
*/
|
||||||
iter_impl const operator--(int) // NOLINT(readability-const-return-type)
|
iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
--(*this);
|
--(*this);
|
||||||
|
|||||||
@ -48,7 +48,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
|
|||||||
explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
|
explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
|
||||||
|
|
||||||
/// post-increment (it++)
|
/// post-increment (it++)
|
||||||
json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
|
json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
|
return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// post-decrement (it--)
|
/// post-decrement (it--)
|
||||||
json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
|
json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
|
return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,7 +87,7 @@ class primitive_iterator_t
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
|
primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
++m_it;
|
++m_it;
|
||||||
@ -100,7 +100,7 @@ class primitive_iterator_t
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
|
primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
--m_it;
|
--m_it;
|
||||||
|
|||||||
@ -97,6 +97,15 @@
|
|||||||
#define JSON_HAS_FILESYSTEM 0
|
#define JSON_HAS_FILESYSTEM 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef JSON_HAS_THREE_WAY_COMPARISON
|
||||||
|
#if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L \
|
||||||
|
&& defined(__cpp_impl_three_way_comparison)&& __cpp_impl_three_way_comparison >= 201907L
|
||||||
|
#define JSON_HAS_THREE_WAY_COMPARISON 1
|
||||||
|
#else
|
||||||
|
#define JSON_HAS_THREE_WAY_COMPARISON 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// disable documentation warnings on clang
|
// disable documentation warnings on clang
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
@ -334,6 +343,7 @@
|
|||||||
|
|
||||||
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
|
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
|
||||||
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
|
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
|
||||||
|
#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@ -344,6 +354,10 @@
|
|||||||
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
||||||
|
|
||||||
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
|
||||||
|
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
|
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
|
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
|
||||||
@ -353,6 +367,10 @@
|
|||||||
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
||||||
|
|
||||||
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
|
||||||
|
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
|
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
|
||||||
|
|
||||||
|
|
||||||
// inspired from https://stackoverflow.com/a/26745591
|
// inspired from https://stackoverflow.com/a/26745591
|
||||||
// allows to call any std function as if (e.g. with begin):
|
// allows to call any std function as if (e.g. with begin):
|
||||||
|
|||||||
@ -8,19 +8,23 @@
|
|||||||
// clean up
|
// clean up
|
||||||
#undef JSON_ASSERT
|
#undef JSON_ASSERT
|
||||||
#undef JSON_INTERNAL_CATCH
|
#undef JSON_INTERNAL_CATCH
|
||||||
#undef JSON_CATCH
|
|
||||||
#undef JSON_THROW
|
#undef JSON_THROW
|
||||||
#undef JSON_TRY
|
|
||||||
#undef JSON_PRIVATE_UNLESS_TESTED
|
#undef JSON_PRIVATE_UNLESS_TESTED
|
||||||
#undef JSON_HAS_CPP_11
|
|
||||||
#undef JSON_HAS_CPP_14
|
|
||||||
#undef JSON_HAS_CPP_17
|
|
||||||
#undef JSON_HAS_CPP_20
|
|
||||||
#undef JSON_HAS_FILESYSTEM
|
|
||||||
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL
|
#undef NLOHMANN_BASIC_JSON_TPL
|
||||||
#undef JSON_EXPLICIT
|
#undef JSON_EXPLICIT
|
||||||
#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
|
#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_KEEP_MACROS
|
||||||
|
#undef JSON_CATCH
|
||||||
|
#undef JSON_TRY
|
||||||
|
#undef JSON_HAS_CPP_11
|
||||||
|
#undef JSON_HAS_CPP_14
|
||||||
|
#undef JSON_HAS_CPP_17
|
||||||
|
#undef JSON_HAS_CPP_20
|
||||||
|
#undef JSON_HAS_FILESYSTEM
|
||||||
|
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
||||||
|
#undef JSON_HAS_THREE_WAY_COMPARISON
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
|
#include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
|
||||||
|
|||||||
@ -147,8 +147,12 @@ struct static_const
|
|||||||
static constexpr T value{};
|
static constexpr T value{};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
#ifndef JSON_HAS_CPP_17
|
||||||
constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|||||||
@ -1872,6 +1872,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
template < typename ValueType, typename std::enable_if <
|
template < typename ValueType, typename std::enable_if <
|
||||||
detail::conjunction <
|
detail::conjunction <
|
||||||
detail::negation<std::is_pointer<ValueType>>,
|
detail::negation<std::is_pointer<ValueType>>,
|
||||||
|
detail::negation<std::is_same<ValueType, std::nullptr_t>>,
|
||||||
detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
|
detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
|
||||||
detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
|
detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
|
||||||
detail::negation<detail::is_basic_json<ValueType>>,
|
detail::negation<detail::is_basic_json<ValueType>>,
|
||||||
|
|||||||
@ -30,11 +30,12 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
|
|
||||||
// Explicit constructors instead of `using Container::Container`
|
// Explicit constructors instead of `using Container::Container`
|
||||||
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
|
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
|
||||||
ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
|
ordered_map() noexcept(noexcept(Container())) : Container{} {}
|
||||||
|
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
|
||||||
template <class It>
|
template <class It>
|
||||||
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
||||||
: Container{first, last, alloc} {}
|
: Container{first, last, alloc} {}
|
||||||
ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
|
ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
|
||||||
: Container{init, alloc} {}
|
: Container{init, alloc} {}
|
||||||
|
|
||||||
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
|
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
|
||||||
|
|||||||
@ -2394,6 +2394,15 @@ using is_detected_convertible =
|
|||||||
#define JSON_HAS_FILESYSTEM 0
|
#define JSON_HAS_FILESYSTEM 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef JSON_HAS_THREE_WAY_COMPARISON
|
||||||
|
#if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L \
|
||||||
|
&& defined(__cpp_impl_three_way_comparison)&& __cpp_impl_three_way_comparison >= 201907L
|
||||||
|
#define JSON_HAS_THREE_WAY_COMPARISON 1
|
||||||
|
#else
|
||||||
|
#define JSON_HAS_THREE_WAY_COMPARISON 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// disable documentation warnings on clang
|
// disable documentation warnings on clang
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
@ -2631,6 +2640,7 @@ using is_detected_convertible =
|
|||||||
|
|
||||||
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
|
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
|
||||||
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
|
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
|
||||||
|
#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@ -2641,6 +2651,10 @@ using is_detected_convertible =
|
|||||||
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
||||||
|
|
||||||
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
|
||||||
|
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
|
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
|
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
|
||||||
@ -2650,6 +2664,10 @@ using is_detected_convertible =
|
|||||||
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
||||||
|
|
||||||
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
|
||||||
|
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||||
|
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
|
||||||
|
|
||||||
|
|
||||||
// inspired from https://stackoverflow.com/a/26745591
|
// inspired from https://stackoverflow.com/a/26745591
|
||||||
// allows to call any std function as if (e.g. with begin):
|
// allows to call any std function as if (e.g. with begin):
|
||||||
@ -3173,8 +3191,12 @@ struct static_const
|
|||||||
static constexpr T value{};
|
static constexpr T value{};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
#ifndef JSON_HAS_CPP_17
|
||||||
constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
@ -4257,7 +4279,8 @@ void from_json(const BasicJsonType& j, std_fs::path& p)
|
|||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
|
// Not tested because of #3377 (related #3070)
|
||||||
|
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
||||||
}
|
}
|
||||||
@ -11299,7 +11322,7 @@ class primitive_iterator_t
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
|
primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
++m_it;
|
++m_it;
|
||||||
@ -11312,7 +11335,7 @@ class primitive_iterator_t
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
|
primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
--m_it;
|
--m_it;
|
||||||
@ -11719,7 +11742,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
@brief post-increment (it++)
|
@brief post-increment (it++)
|
||||||
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
||||||
*/
|
*/
|
||||||
iter_impl const operator++(int) // NOLINT(readability-const-return-type)
|
iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
++(*this);
|
++(*this);
|
||||||
@ -11770,7 +11793,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
@brief post-decrement (it--)
|
@brief post-decrement (it--)
|
||||||
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
||||||
*/
|
*/
|
||||||
iter_impl const operator--(int) // NOLINT(readability-const-return-type)
|
iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
--(*this);
|
--(*this);
|
||||||
@ -12158,7 +12181,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
|
|||||||
explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
|
explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
|
||||||
|
|
||||||
/// post-increment (it++)
|
/// post-increment (it++)
|
||||||
json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
|
json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
|
return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
|
||||||
}
|
}
|
||||||
@ -12170,7 +12193,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// post-decrement (it--)
|
/// post-decrement (it--)
|
||||||
json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
|
json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
|
||||||
{
|
{
|
||||||
return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
|
return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
|
||||||
}
|
}
|
||||||
@ -17057,11 +17080,12 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
|
|
||||||
// Explicit constructors instead of `using Container::Container`
|
// Explicit constructors instead of `using Container::Container`
|
||||||
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
|
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
|
||||||
ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
|
ordered_map() noexcept(noexcept(Container())) : Container{} {}
|
||||||
|
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
|
||||||
template <class It>
|
template <class It>
|
||||||
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
||||||
: Container{first, last, alloc} {}
|
: Container{first, last, alloc} {}
|
||||||
ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
|
ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
|
||||||
: Container{init, alloc} {}
|
: Container{init, alloc} {}
|
||||||
|
|
||||||
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
|
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
|
||||||
@ -19043,6 +19067,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
template < typename ValueType, typename std::enable_if <
|
template < typename ValueType, typename std::enable_if <
|
||||||
detail::conjunction <
|
detail::conjunction <
|
||||||
detail::negation<std::is_pointer<ValueType>>,
|
detail::negation<std::is_pointer<ValueType>>,
|
||||||
|
detail::negation<std::is_same<ValueType, std::nullptr_t>>,
|
||||||
detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
|
detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
|
||||||
detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
|
detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
|
||||||
detail::negation<detail::is_basic_json<ValueType>>,
|
detail::negation<detail::is_basic_json<ValueType>>,
|
||||||
@ -21928,21 +21953,25 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std
|
|||||||
// clean up
|
// clean up
|
||||||
#undef JSON_ASSERT
|
#undef JSON_ASSERT
|
||||||
#undef JSON_INTERNAL_CATCH
|
#undef JSON_INTERNAL_CATCH
|
||||||
#undef JSON_CATCH
|
|
||||||
#undef JSON_THROW
|
#undef JSON_THROW
|
||||||
#undef JSON_TRY
|
|
||||||
#undef JSON_PRIVATE_UNLESS_TESTED
|
#undef JSON_PRIVATE_UNLESS_TESTED
|
||||||
#undef JSON_HAS_CPP_11
|
|
||||||
#undef JSON_HAS_CPP_14
|
|
||||||
#undef JSON_HAS_CPP_17
|
|
||||||
#undef JSON_HAS_CPP_20
|
|
||||||
#undef JSON_HAS_FILESYSTEM
|
|
||||||
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL
|
#undef NLOHMANN_BASIC_JSON_TPL
|
||||||
#undef JSON_EXPLICIT
|
#undef JSON_EXPLICIT
|
||||||
#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
|
#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_KEEP_MACROS
|
||||||
|
#undef JSON_CATCH
|
||||||
|
#undef JSON_TRY
|
||||||
|
#undef JSON_HAS_CPP_11
|
||||||
|
#undef JSON_HAS_CPP_14
|
||||||
|
#undef JSON_HAS_CPP_17
|
||||||
|
#undef JSON_HAS_CPP_20
|
||||||
|
#undef JSON_HAS_FILESYSTEM
|
||||||
|
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
||||||
|
#undef JSON_HAS_THREE_WAY_COMPARISON
|
||||||
|
#endif
|
||||||
|
|
||||||
// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
|
// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,163 +1,131 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
option(JSON_Valgrind "Execute test suite with Valgrind." OFF)
|
option(JSON_Valgrind "Execute test suite with Valgrind." OFF)
|
||||||
option(JSON_FastTests "Skip expensive/slow tests." OFF)
|
option(JSON_FastTests "Skip expensive/slow tests." OFF)
|
||||||
|
|
||||||
# download test data
|
set(JSON_TestStandards "" CACHE STRING "The list of standards to test explicitly.")
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/download_test_data.cmake)
|
|
||||||
|
|
||||||
# test fixture to download test data
|
include(test)
|
||||||
add_test(NAME "download_test_data" COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target download_test_data)
|
|
||||||
set_tests_properties(download_test_data PROPERTIES FIXTURES_SETUP TEST_DATA)
|
|
||||||
|
|
||||||
if(JSON_Valgrind)
|
#############################################################################
|
||||||
find_program(CMAKE_MEMORYCHECK_COMMAND valgrind)
|
# override standard support
|
||||||
message(STATUS "Executing test suite with Valgrind (${CMAKE_MEMORYCHECK_COMMAND})")
|
#############################################################################
|
||||||
set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode=1 --leak-check=full")
|
|
||||||
separate_arguments(memcheck_command)
|
# compiling json.hpp in C++14 mode fails with Clang <4.0
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
|
||||||
|
unset(compiler_supports_cpp_14)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#############################################################################
|
|
||||||
# doctest library with the main function to speed up build
|
|
||||||
#############################################################################
|
|
||||||
|
|
||||||
add_library(doctest_main OBJECT src/unit.cpp)
|
|
||||||
set_target_properties(doctest_main PROPERTIES
|
|
||||||
COMPILE_DEFINITIONS "$<$<CXX_COMPILER_ID:MSVC>:_SCL_SECURE_NO_WARNINGS>"
|
|
||||||
COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>"
|
|
||||||
)
|
|
||||||
if (${CMAKE_VERSION} VERSION_LESS "3.8.0")
|
|
||||||
target_compile_features(doctest_main PUBLIC cxx_range_for)
|
|
||||||
else()
|
|
||||||
target_compile_features(doctest_main PUBLIC cxx_std_11)
|
|
||||||
endif()
|
|
||||||
target_include_directories(doctest_main PRIVATE "thirdparty/doctest")
|
|
||||||
|
|
||||||
# https://stackoverflow.com/questions/2368811/how-to-set-warning-level-in-cmake
|
|
||||||
if(MSVC)
|
|
||||||
# Force to always compile with W4
|
|
||||||
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
|
||||||
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
||||||
else()
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Disable warning C4566: character represented by universal-character-name '\uFF01' cannot be represented in the current code page (1252)
|
|
||||||
# Disable warning C4996: 'nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>::operator <<': was declared deprecated
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4566 /wd4996")
|
|
||||||
|
|
||||||
# https://github.com/nlohmann/json/issues/1114
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#############################################################################
|
|
||||||
# one executable for each unit test file
|
|
||||||
#############################################################################
|
|
||||||
|
|
||||||
# check if compiler supports C++17
|
|
||||||
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
|
|
||||||
if (${feature} STREQUAL cxx_std_17)
|
|
||||||
set(compiler_supports_cpp_17 TRUE)
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
# Clang only supports C++17 starting from Clang 5.0
|
# Clang only supports C++17 starting from Clang 5.0
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
||||||
unset(compiler_supports_cpp_17)
|
unset(compiler_supports_cpp_17)
|
||||||
endif()
|
endif()
|
||||||
# MSVC 2015 (14.0) does not support C++17
|
# MSVC 2015 (14.0) does not support C++17
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.1)
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.1)
|
||||||
unset(compiler_supports_cpp_17)
|
unset(compiler_supports_cpp_17)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
file(GLOB files src/unit-*.cpp)
|
# Clang C++20 support appears insufficient prior to Clang 9.0 (based on CI build failure)
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
|
||||||
|
unset(compiler_supports_cpp_20)
|
||||||
|
endif()
|
||||||
|
# GCC started supporting C++20 features in 8.0 but a test for #3070 segfaults prior to 9.0
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
|
||||||
|
unset(compiler_supports_cpp_20)
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(file ${files})
|
#############################################################################
|
||||||
get_filename_component(file_basename ${file} NAME_WE)
|
# test_main library with shared code to speed up build and common settings
|
||||||
string(REGEX REPLACE "unit-([^$]+)" "test-\\1" testcase ${file_basename})
|
#############################################################################
|
||||||
|
|
||||||
add_executable(${testcase} $<TARGET_OBJECTS:doctest_main> ${file})
|
add_library(test_main OBJECT src/unit.cpp)
|
||||||
target_compile_definitions(${testcase} PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
|
target_compile_definitions(test_main PUBLIC
|
||||||
target_compile_options(${testcase} PRIVATE
|
DOCTEST_CONFIG_SUPER_FAST_ASSERTS
|
||||||
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
JSON_TEST_KEEP_MACROS
|
||||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
)
|
||||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
target_compile_features(test_main PRIVATE cxx_std_11)
|
||||||
)
|
target_compile_options(test_main PUBLIC
|
||||||
target_include_directories(${testcase} PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
|
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
||||||
target_link_libraries(${testcase} PRIVATE ${NLOHMANN_JSON_TARGET_NAME})
|
# MSVC: Force to always compile with W4
|
||||||
|
# Disable warning C4566: character represented by universal-character-name '\uFF01'
|
||||||
|
# cannot be represented in the current code page (1252)
|
||||||
|
# Disable warning C4996: 'nlohmann::basic_json<...>::operator <<': was declared deprecated
|
||||||
|
$<$<CXX_COMPILER_ID:MSVC>:/W4 /wd4566 /wd4996>
|
||||||
|
# https://github.com/nlohmann/json/issues/1114
|
||||||
|
$<$<CXX_COMPILER_ID:MSVC>:/bigobj> $<$<BOOL:${MINGW}>:-Wa,-mbig-obj>
|
||||||
|
|
||||||
# add a copy with C++17 compilation
|
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
||||||
if (compiler_supports_cpp_17)
|
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
||||||
file(READ ${file} FILE_CONTENT)
|
)
|
||||||
string(FIND "${FILE_CONTENT}" "JSON_HAS_CPP_17" CPP_17_FOUND)
|
target_include_directories(test_main PUBLIC
|
||||||
if(NOT ${CPP_17_FOUND} EQUAL -1)
|
thirdparty/doctest
|
||||||
add_executable(${testcase}_cpp17 $<TARGET_OBJECTS:doctest_main> ${file})
|
thirdparty/fifo_map
|
||||||
target_compile_definitions(${testcase}_cpp17 PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
|
${PROJECT_BINARY_DIR}/include
|
||||||
target_compile_options(${testcase}_cpp17 PRIVATE
|
)
|
||||||
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME})
|
||||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
|
||||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
|
||||||
)
|
|
||||||
target_include_directories(${testcase}_cpp17 PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
|
|
||||||
target_link_libraries(${testcase}_cpp17 PRIVATE ${NLOHMANN_JSON_TARGET_NAME})
|
|
||||||
target_compile_features(${testcase}_cpp17 PRIVATE cxx_std_17)
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0 AND NOT MINGW)
|
#############################################################################
|
||||||
# fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90050
|
# define test- and standard-specific build settings
|
||||||
target_link_libraries(${testcase}_cpp17 PRIVATE stdc++fs)
|
#############################################################################
|
||||||
endif()
|
|
||||||
|
|
||||||
if (JSON_FastTests)
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
|
||||||
add_test(NAME "${testcase}_cpp17"
|
AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0
|
||||||
COMMAND ${testcase}_cpp17 ${DOCTEST_TEST_FILTER}
|
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0 AND NOT MINGW)
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
# fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90050
|
||||||
)
|
json_test_set_test_options(all CXX_STANDARDS 17 LINK_LIBRARIES stdc++fs)
|
||||||
else()
|
endif()
|
||||||
add_test(NAME "${testcase}_cpp17"
|
|
||||||
COMMAND ${testcase}_cpp17 ${DOCTEST_TEST_FILTER} --no-skip
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
set_tests_properties("${testcase}_cpp17" PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (JSON_FastTests)
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
add_test(NAME "${testcase}"
|
# avoid stack overflow, see https://github.com/nlohmann/json/issues/2955
|
||||||
COMMAND ${testcase} ${DOCTEST_TEST_FILTER}
|
json_test_set_test_options("test-cbor;test-msgpack;test-ubjson" LINK_OPTIONS /STACK:4000000)
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
endif()
|
||||||
)
|
|
||||||
else()
|
|
||||||
add_test(NAME "${testcase}"
|
|
||||||
COMMAND ${testcase} ${DOCTEST_TEST_FILTER} --no-skip
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
set_tests_properties("${testcase}" PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
|
|
||||||
|
|
||||||
if(JSON_Valgrind)
|
|
||||||
add_test(NAME "${testcase}_valgrind"
|
|
||||||
COMMAND ${memcheck_command} ${CMAKE_CURRENT_BINARY_DIR}/${testcase} ${DOCTEST_TEST_FILTER}
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
)
|
|
||||||
set_tests_properties("${testcase}_valgrind" PROPERTIES LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA)
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# disable exceptions for test-disabled_exceptions
|
# disable exceptions for test-disabled_exceptions
|
||||||
target_compile_definitions(test-disabled_exceptions PUBLIC JSON_NOEXCEPTION)
|
json_test_set_test_options(test-disabled_exceptions COMPILE_DEFINITIONS JSON_NOEXCEPTION)
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
target_compile_options(test-disabled_exceptions PUBLIC -fno-exceptions)
|
json_test_set_test_options(test-disabled_exceptions COMPILE_OPTIONS -fno-exceptions)
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
# disabled due to https://github.com/nlohmann/json/discussions/2824
|
# disabled due to https://github.com/nlohmann/json/discussions/2824
|
||||||
#target_compile_options(test-disabled_exceptions PUBLIC /EH)
|
#json_test_set_test_options(test-disabled_exceptions COMPILE_DEFINITIONS _HAS_EXCEPTIONS=0 COMPILE_OPTIONS /EH)
|
||||||
#target_compile_definitions(test-disabled_exceptions PUBLIC _HAS_EXCEPTIONS=0)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# avoid stack overflow, see https://github.com/nlohmann/json/issues/2955
|
#############################################################################
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
# add unit tests
|
||||||
set_property(TARGET test-cbor APPEND_STRING PROPERTY LINK_FLAGS " /STACK:4000000")
|
#############################################################################
|
||||||
set_property(TARGET test-msgpack APPEND_STRING PROPERTY LINK_FLAGS " /STACK:4000000")
|
|
||||||
set_property(TARGET test-ubjson APPEND_STRING PROPERTY LINK_FLAGS " /STACK:4000000")
|
if("${JSON_TestStandards}" STREQUAL "")
|
||||||
|
set(test_cxx_standards 11 14 17 20 23)
|
||||||
|
unset(test_force)
|
||||||
|
else()
|
||||||
|
set(test_cxx_standards ${JSON_TestStandards})
|
||||||
|
set(test_force FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Print selected standards marking unavailable ones with brackets
|
||||||
|
set(msg_standards "")
|
||||||
|
foreach(cxx_standard ${test_cxx_standards})
|
||||||
|
if(compiler_supports_cpp_${cxx_standard})
|
||||||
|
list(APPEND msg_standards ${cxx_standard})
|
||||||
|
else()
|
||||||
|
list(APPEND msg_standards [${cxx_standard}])
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
string(JOIN " " msg_standards ${msg_standards})
|
||||||
|
set(msg "Testing standards: ${msg_standards}")
|
||||||
|
if(test_force)
|
||||||
|
string(APPEND msg " (forced)")
|
||||||
|
endif()
|
||||||
|
message(STATUS "${msg}")
|
||||||
|
|
||||||
|
# *DO* use json_test_set_test_options() above this line
|
||||||
|
|
||||||
|
file(GLOB files src/unit-*.cpp)
|
||||||
|
foreach(file ${files})
|
||||||
|
json_test_add_test_for(${file} MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# *DO NOT* use json_test_set_test_options() below this line
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# Test the generated build configs
|
# Test the generated build configs
|
||||||
#############################################################################
|
#############################################################################
|
||||||
@ -170,4 +138,5 @@ endif()
|
|||||||
|
|
||||||
add_subdirectory(cmake_add_subdirectory)
|
add_subdirectory(cmake_add_subdirectory)
|
||||||
add_subdirectory(cmake_fetch_content)
|
add_subdirectory(cmake_fetch_content)
|
||||||
|
add_subdirectory(cmake_fetch_content2)
|
||||||
add_subdirectory(cmake_target_include_directories)
|
add_subdirectory(cmake_target_include_directories)
|
||||||
|
|||||||
20
test/cmake_fetch_content2/CMakeLists.txt
Normal file
20
test/cmake_fetch_content2/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
if (${CMAKE_VERSION} VERSION_GREATER "3.14.0")
|
||||||
|
add_test(NAME cmake_fetch_content2_configure
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
-G "${CMAKE_GENERATOR}"
|
||||||
|
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||||
|
-Dnlohmann_json_source=${PROJECT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/project
|
||||||
|
)
|
||||||
|
add_test(NAME cmake_fetch_content2_build
|
||||||
|
COMMAND ${CMAKE_COMMAND} --build .
|
||||||
|
)
|
||||||
|
set_tests_properties(cmake_fetch_content2_configure PROPERTIES
|
||||||
|
FIXTURES_SETUP cmake_fetch_content2
|
||||||
|
LABELS "git_required;not_reproducible"
|
||||||
|
)
|
||||||
|
set_tests_properties(cmake_fetch_content2_build PROPERTIES
|
||||||
|
FIXTURES_REQUIRED cmake_fetch_content2
|
||||||
|
LABELS "git_required;not_reproducible"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
15
test/cmake_fetch_content2/project/CMakeLists.txt
Normal file
15
test/cmake_fetch_content2/project/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
project(DummyImport CXX)
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
get_filename_component(GIT_REPOSITORY_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../.. ABSOLUTE)
|
||||||
|
FetchContent_Declare(json GIT_REPOSITORY ${GIT_REPOSITORY_DIRECTORY} GIT_TAG HEAD)
|
||||||
|
FetchContent_MakeAvailable(json)
|
||||||
|
|
||||||
|
add_executable(with_namespace_target main.cpp)
|
||||||
|
target_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)
|
||||||
|
|
||||||
|
add_executable(without_namespace_target main.cpp)
|
||||||
|
target_link_libraries(without_namespace_target nlohmann_json)
|
||||||
8
test/cmake_fetch_content2/project/main.cpp
Normal file
8
test/cmake_fetch_content2/project/main.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
nlohmann::json j;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -39,6 +39,8 @@ namespace
|
|||||||
template<class T>
|
template<class T>
|
||||||
struct bad_allocator : std::allocator<T>
|
struct bad_allocator : std::allocator<T>
|
||||||
{
|
{
|
||||||
|
using std::allocator<T>::allocator;
|
||||||
|
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
void construct(T* /*unused*/, Args&& ... /*unused*/)
|
void construct(T* /*unused*/, Args&& ... /*unused*/)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -37,7 +37,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
class alt_string;
|
class alt_string;
|
||||||
bool operator<(const char* op1, const alt_string& op2);
|
bool operator<(const char* op1, const alt_string& op2) noexcept;
|
||||||
void int_to_string(alt_string& target, std::size_t value);
|
void int_to_string(alt_string& target, std::size_t value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -104,12 +104,12 @@ class alt_string
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename op_type>
|
template <typename op_type>
|
||||||
bool operator<(const op_type& op) const
|
bool operator<(const op_type& op) const noexcept
|
||||||
{
|
{
|
||||||
return str_impl < op;
|
return str_impl < op;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const alt_string& op) const
|
bool operator<(const alt_string& op) const noexcept
|
||||||
{
|
{
|
||||||
return str_impl < op.str_impl;
|
return str_impl < op.str_impl;
|
||||||
}
|
}
|
||||||
@ -152,7 +152,7 @@ class alt_string
|
|||||||
private:
|
private:
|
||||||
std::string str_impl {};
|
std::string str_impl {};
|
||||||
|
|
||||||
friend bool ::operator<(const char* /*op1*/, const alt_string& /*op2*/);
|
friend bool ::operator<(const char* /*op1*/, const alt_string& /*op2*/) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
void int_to_string(alt_string& target, std::size_t value)
|
void int_to_string(alt_string& target, std::size_t value)
|
||||||
@ -172,7 +172,7 @@ using alt_json = nlohmann::basic_json <
|
|||||||
nlohmann::adl_serializer >;
|
nlohmann::adl_serializer >;
|
||||||
|
|
||||||
|
|
||||||
bool operator<(const char* op1, const alt_string& op2)
|
bool operator<(const char* op1, const alt_string& op2) noexcept
|
||||||
{
|
{
|
||||||
return op1 < op2.str_impl;
|
return op1 < op2.str_impl;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1609,7 +1609,7 @@ TEST_CASE("CBOR")
|
|||||||
|
|
||||||
// callback to set binary_seen to true if a binary value was seen
|
// callback to set binary_seen to true if a binary value was seen
|
||||||
bool binary_seen = false;
|
bool binary_seen = false;
|
||||||
auto callback = [&binary_seen](int /*depth*/, json::parse_event_t /*event*/, json & parsed)
|
auto callback = [&binary_seen](int /*depth*/, json::parse_event_t /*event*/, json & parsed) noexcept
|
||||||
{
|
{
|
||||||
if (parsed.is_binary())
|
if (parsed.is_binary())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -33,6 +33,12 @@ SOFTWARE.
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
|
template<typename Iter>
|
||||||
|
using can_post_increment_temporary = decltype((std::declval<Iter>()++)++);
|
||||||
|
|
||||||
|
template<typename Iter>
|
||||||
|
using can_post_decrement_temporary = decltype((std::declval<Iter>()--)--);
|
||||||
|
|
||||||
TEST_CASE("iterator class")
|
TEST_CASE("iterator class")
|
||||||
{
|
{
|
||||||
SECTION("construction")
|
SECTION("construction")
|
||||||
@ -399,4 +405,89 @@ TEST_CASE("iterator class")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SECTION("equality-preserving")
|
||||||
|
{
|
||||||
|
SECTION("post-increment")
|
||||||
|
{
|
||||||
|
SECTION("primitive_iterator_t")
|
||||||
|
{
|
||||||
|
using Iter = nlohmann::detail::primitive_iterator_t;
|
||||||
|
CHECK(std::is_same < decltype(std::declval<Iter&>()++), Iter >::value);
|
||||||
|
}
|
||||||
|
SECTION("iter_impl")
|
||||||
|
{
|
||||||
|
using Iter = nlohmann::detail::iter_impl<json>;
|
||||||
|
CHECK(std::is_same < decltype(std::declval<Iter&>()++), Iter >::value);
|
||||||
|
}
|
||||||
|
SECTION("json_reverse_iterator")
|
||||||
|
{
|
||||||
|
using Base = nlohmann::detail::iter_impl<json>;
|
||||||
|
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
|
||||||
|
CHECK(std::is_same < decltype(std::declval<Iter&>()++), Iter >::value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SECTION("post-decrement")
|
||||||
|
{
|
||||||
|
SECTION("primitive_iterator_t")
|
||||||
|
{
|
||||||
|
using Iter = nlohmann::detail::primitive_iterator_t;
|
||||||
|
CHECK(std::is_same < decltype(std::declval<Iter&>()--), Iter >::value);
|
||||||
|
}
|
||||||
|
SECTION("iter_impl")
|
||||||
|
{
|
||||||
|
using Iter = nlohmann::detail::iter_impl<json>;
|
||||||
|
CHECK(std::is_same < decltype(std::declval<Iter&>()--), Iter >::value );
|
||||||
|
}
|
||||||
|
SECTION("json_reverse_iterator")
|
||||||
|
{
|
||||||
|
using Base = nlohmann::detail::iter_impl<json>;
|
||||||
|
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
|
||||||
|
CHECK(std::is_same < decltype(std::declval<Iter&>()--), Iter >::value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// prevent "accidental mutation of a temporary object"
|
||||||
|
SECTION("cert-dcl21-cpp")
|
||||||
|
{
|
||||||
|
using nlohmann::detail::is_detected;
|
||||||
|
SECTION("post-increment")
|
||||||
|
{
|
||||||
|
SECTION("primitive_iterator_t")
|
||||||
|
{
|
||||||
|
using Iter = nlohmann::detail::primitive_iterator_t;
|
||||||
|
CHECK_FALSE(is_detected<can_post_increment_temporary, Iter&>::value);
|
||||||
|
}
|
||||||
|
SECTION("iter_impl")
|
||||||
|
{
|
||||||
|
using Iter = nlohmann::detail::iter_impl<json>;
|
||||||
|
CHECK_FALSE(is_detected<can_post_increment_temporary, Iter&>::value);
|
||||||
|
}
|
||||||
|
SECTION("json_reverse_iterator")
|
||||||
|
{
|
||||||
|
using Base = nlohmann::detail::iter_impl<json>;
|
||||||
|
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
|
||||||
|
CHECK_FALSE(is_detected<can_post_increment_temporary, Iter&>::value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SECTION("post-decrement")
|
||||||
|
{
|
||||||
|
SECTION("primitive_iterator_t")
|
||||||
|
{
|
||||||
|
using Iter = nlohmann::detail::primitive_iterator_t;
|
||||||
|
CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
|
||||||
|
}
|
||||||
|
SECTION("iter_impl")
|
||||||
|
{
|
||||||
|
using Iter = nlohmann::detail::iter_impl<json>;
|
||||||
|
CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
|
||||||
|
}
|
||||||
|
SECTION("json_reverse_iterator")
|
||||||
|
{
|
||||||
|
using Base = nlohmann::detail::iter_impl<json>;
|
||||||
|
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
|
||||||
|
CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -267,7 +267,7 @@ bool accept_helper(const std::string& s)
|
|||||||
CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept(false) == !el.errored);
|
CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept(false) == !el.errored);
|
||||||
|
|
||||||
// 5. parse with simple callback
|
// 5. parse with simple callback
|
||||||
json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/)
|
json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -1499,7 +1499,7 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
// test case to make sure the callback is properly evaluated after reading a key
|
// test case to make sure the callback is properly evaluated after reading a key
|
||||||
{
|
{
|
||||||
json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t event, json& /*unused*/)
|
json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t event, json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return event != json::parse_event_t::key;
|
return event != json::parse_event_t::key;
|
||||||
};
|
};
|
||||||
@ -1538,14 +1538,14 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
SECTION("filter nothing")
|
SECTION("filter nothing")
|
||||||
{
|
{
|
||||||
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)
|
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
CHECK (j_object == json({{"foo", 2}, {"bar", {{"baz", 1}}}}));
|
CHECK (j_object == json({{"foo", 2}, {"bar", {{"baz", 1}}}}));
|
||||||
|
|
||||||
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)
|
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@ -1555,7 +1555,7 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
SECTION("filter everything")
|
SECTION("filter everything")
|
||||||
{
|
{
|
||||||
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)
|
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@ -1563,7 +1563,7 @@ TEST_CASE("parser class")
|
|||||||
// the top-level object will be discarded, leaving a null
|
// the top-level object will be discarded, leaving a null
|
||||||
CHECK (j_object.is_null());
|
CHECK (j_object.is_null());
|
||||||
|
|
||||||
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)
|
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@ -1574,7 +1574,7 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
SECTION("filter specific element")
|
SECTION("filter specific element")
|
||||||
{
|
{
|
||||||
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j)
|
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j) noexcept
|
||||||
{
|
{
|
||||||
// filter all number(2) elements
|
// filter all number(2) elements
|
||||||
return j != json(2);
|
return j != json(2);
|
||||||
@ -1582,7 +1582,7 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
CHECK (j_object == json({{"bar", {{"baz", 1}}}}));
|
CHECK (j_object == json({{"bar", {{"baz", 1}}}}));
|
||||||
|
|
||||||
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j)
|
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j) noexcept
|
||||||
{
|
{
|
||||||
return j != json(2);
|
return j != json(2);
|
||||||
});
|
});
|
||||||
@ -1601,7 +1601,7 @@ TEST_CASE("parser class")
|
|||||||
CHECK (j_filtered1.size() == 2);
|
CHECK (j_filtered1.size() == 2);
|
||||||
CHECK (j_filtered1 == json({1, {{"qux", "baz"}}}));
|
CHECK (j_filtered1 == json({1, {{"qux", "baz"}}}));
|
||||||
|
|
||||||
json j_filtered2 = json::parse(structured_array, [](int /*unused*/, json::parse_event_t e, const json& /*parsed*/)
|
json j_filtered2 = json::parse(structured_array, [](int /*unused*/, json::parse_event_t e, const json& /*parsed*/) noexcept
|
||||||
{
|
{
|
||||||
return e != json::parse_event_t::object_end;
|
return e != json::parse_event_t::object_end;
|
||||||
});
|
});
|
||||||
@ -1616,7 +1616,7 @@ TEST_CASE("parser class")
|
|||||||
SECTION("first closing event")
|
SECTION("first closing event")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/)
|
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
if (e == json::parse_event_t::object_end && first)
|
if (e == json::parse_event_t::object_end && first)
|
||||||
@ -1633,7 +1633,7 @@ TEST_CASE("parser class")
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/)
|
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
if (e == json::parse_event_t::array_end && first)
|
if (e == json::parse_event_t::array_end && first)
|
||||||
@ -1657,13 +1657,13 @@ TEST_CASE("parser class")
|
|||||||
// object and array is discarded only after the closing character
|
// object and array is discarded only after the closing character
|
||||||
// has been read
|
// has been read
|
||||||
|
|
||||||
json j_empty_object = json::parse("{}", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/)
|
json j_empty_object = json::parse("{}", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return e != json::parse_event_t::object_end;
|
return e != json::parse_event_t::object_end;
|
||||||
});
|
});
|
||||||
CHECK(j_empty_object == json());
|
CHECK(j_empty_object == json());
|
||||||
|
|
||||||
json j_empty_array = json::parse("[]", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/)
|
json j_empty_array = json::parse("[]", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return e != json::parse_event_t::array_end;
|
return e != json::parse_event_t::array_end;
|
||||||
});
|
});
|
||||||
@ -1731,7 +1731,7 @@ TEST_CASE("parser class")
|
|||||||
{
|
{
|
||||||
SECTION("parser with callback")
|
SECTION("parser with callback")
|
||||||
{
|
{
|
||||||
json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/)
|
json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -205,6 +205,14 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
{
|
{
|
||||||
for (size_t j = 0; j < j_values.size(); ++j)
|
for (size_t j = 0; j < j_values.size(); ++j)
|
||||||
{
|
{
|
||||||
|
// Skip comparing indicies 12 and 13, and 13 and 12 in C++20 pending fix
|
||||||
|
// See issue #3207
|
||||||
|
#if defined(JSON_HAS_CPP_20) || JSON_HAS_THREE_WAY_COMPARISON
|
||||||
|
if ((i == 12 && j == 13) || (i == 13 && j == 12))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
CAPTURE(i)
|
CAPTURE(i)
|
||||||
CAPTURE(j)
|
CAPTURE(j)
|
||||||
CAPTURE(j_values[i])
|
CAPTURE(j_values[i])
|
||||||
|
|||||||
@ -41,13 +41,6 @@ using nlohmann::json;
|
|||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <valarray>
|
#include <valarray>
|
||||||
|
|
||||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
|
||||||
#define JSON_HAS_CPP_17
|
|
||||||
#define JSON_HAS_CPP_14
|
|
||||||
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
|
|
||||||
#define JSON_HAS_CPP_14
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair
|
// NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
|
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
|
||||||
|
|||||||
@ -32,13 +32,6 @@ SOFTWARE.
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
|
||||||
#define JSON_HAS_CPP_17
|
|
||||||
#define JSON_HAS_CPP_14
|
|
||||||
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
|
|
||||||
#define JSON_HAS_CPP_14
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This test suite uses range for loops where values are copied. This is inefficient in usual code, but required to achieve 100% coverage.
|
// This test suite uses range for loops where values are copied. This is inefficient in usual code, but required to achieve 100% coverage.
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING_PUSH
|
DOCTEST_GCC_SUPPRESS_WARNING_PUSH
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wrange-loop-construct")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wrange-loop-construct")
|
||||||
|
|||||||
@ -42,10 +42,6 @@ using nlohmann::json;
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
|
||||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
|
||||||
#define JSON_HAS_CPP_17
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -42,70 +42,8 @@ using ordered_json = nlohmann::ordered_json;
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
|
||||||
#define JSON_HAS_CPP_17
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
|
|
||||||
#if defined(__cpp_lib_filesystem)
|
|
||||||
#define JSON_HAS_FILESYSTEM 1
|
|
||||||
#elif defined(__cpp_lib_experimental_filesystem)
|
|
||||||
#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
|
|
||||||
#elif !defined(__has_include)
|
|
||||||
#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
|
|
||||||
#elif __has_include(<filesystem>)
|
|
||||||
#define JSON_HAS_FILESYSTEM 1
|
|
||||||
#elif __has_include(<experimental/filesystem>)
|
|
||||||
#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
|
|
||||||
#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
|
|
||||||
#undef JSON_HAS_FILESYSTEM
|
|
||||||
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
|
|
||||||
#if defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)
|
|
||||||
#undef JSON_HAS_FILESYSTEM
|
|
||||||
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
|
|
||||||
#if defined(__clang_major__) && __clang_major__ < 7
|
|
||||||
#undef JSON_HAS_FILESYSTEM
|
|
||||||
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1940
|
|
||||||
#undef JSON_HAS_FILESYSTEM
|
|
||||||
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// no filesystem support before iOS 13
|
|
||||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|
|
||||||
#undef JSON_HAS_FILESYSTEM
|
|
||||||
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// no filesystem support before macOS Catalina
|
|
||||||
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|
|
||||||
#undef JSON_HAS_FILESYSTEM
|
|
||||||
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
||||||
#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef JSON_HAS_FILESYSTEM
|
|
||||||
#define JSON_HAS_FILESYSTEM 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
||||||
@ -271,7 +209,10 @@ std::string* sax_no_exception::error_string = nullptr;
|
|||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class my_allocator : public std::allocator<T>
|
class my_allocator : public std::allocator<T>
|
||||||
{};
|
{
|
||||||
|
public:
|
||||||
|
using std::allocator<T>::allocator;
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// for #3077
|
// for #3077
|
||||||
@ -338,7 +279,7 @@ TEST_CASE("regression tests 2")
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
json::parser_callback_t cb = [&](int /*level*/, json::parse_event_t event, json & parsed)
|
json::parser_callback_t cb = [&](int /*level*/, json::parse_event_t event, json & parsed) noexcept
|
||||||
{
|
{
|
||||||
// skip uninteresting events
|
// skip uninteresting events
|
||||||
if (event == json::parse_event_t::value && !parsed.is_primitive())
|
if (event == json::parse_event_t::value && !parsed.is_primitive())
|
||||||
@ -653,7 +594,7 @@ TEST_CASE("regression tests 2")
|
|||||||
#ifdef JSON_HAS_CPP_20
|
#ifdef JSON_HAS_CPP_20
|
||||||
SECTION("issue #2546 - parsing containers of std::byte")
|
SECTION("issue #2546 - parsing containers of std::byte")
|
||||||
{
|
{
|
||||||
const char DATA[] = R"("Hello, world!")";
|
const char DATA[] = R"("Hello, world!")"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||||
const auto s = std::as_bytes(std::span(DATA));
|
const auto s = std::as_bytes(std::span(DATA));
|
||||||
json j = json::parse(s);
|
json j = json::parse(s);
|
||||||
CHECK(j.dump() == "\"Hello, world!\"");
|
CHECK(j.dump() == "\"Hello, world!\"");
|
||||||
@ -807,7 +748,8 @@ TEST_CASE("regression tests 2")
|
|||||||
const auto j_path = j.get<nlohmann::detail::std_fs::path>();
|
const auto j_path = j.get<nlohmann::detail::std_fs::path>();
|
||||||
CHECK(j_path == text_path);
|
CHECK(j_path == text_path);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(nlohmann::detail::std_fs::path(json(1)), "[json.exception.type_error.302] type must be string, but is number", json::type_error);
|
// Disabled pending resolution of #3377
|
||||||
|
// CHECK_THROWS_WITH_AS(nlohmann::detail::std_fs::path(json(1)), "[json.exception.type_error.302] type must be string, but is number", json::type_error);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -835,6 +777,18 @@ TEST_CASE("regression tests 2")
|
|||||||
|
|
||||||
CHECK(j.dump() == "[1,4]");
|
CHECK(j.dump() == "[1,4]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("issue #3343 - json and ordered_json are not interchangable")
|
||||||
|
{
|
||||||
|
json::object_t jobj({ { "product", "one" } });
|
||||||
|
ordered_json::object_t ojobj({{"product", "one"}});
|
||||||
|
|
||||||
|
auto jit = jobj.begin();
|
||||||
|
auto ojit = ojobj.begin();
|
||||||
|
|
||||||
|
CHECK(jit->first == ojit->first);
|
||||||
|
CHECK(jit->second.get<std::string>() == ojit->second.get<std::string>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||||
|
|||||||
@ -1610,7 +1610,7 @@ TEST_CASE("UBJSON")
|
|||||||
CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
|
CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
|
||||||
|
|
||||||
json j;
|
json j;
|
||||||
nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)
|
nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@ -1624,7 +1624,7 @@ TEST_CASE("UBJSON")
|
|||||||
CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
|
CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
|
||||||
|
|
||||||
json j;
|
json j;
|
||||||
nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)
|
nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -59,6 +59,42 @@ class person_with_private_data
|
|||||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class person_with_private_data_2
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string name{};
|
||||||
|
int age = 0;
|
||||||
|
json metadata = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool operator==(const person_with_private_data_2& rhs) const
|
||||||
|
{
|
||||||
|
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
person_with_private_data_2() = default;
|
||||||
|
person_with_private_data_2(std::string name_, int age_, json metadata_)
|
||||||
|
: name(std::move(name_))
|
||||||
|
, age(age_)
|
||||||
|
, metadata(std::move(metadata_))
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
int getAge() const
|
||||||
|
{
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
json getMetadata() const
|
||||||
|
{
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(person_with_private_data_2, age, name, metadata)
|
||||||
|
};
|
||||||
|
|
||||||
class person_without_private_data_1
|
class person_without_private_data_1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -103,6 +139,41 @@ class person_without_private_data_2
|
|||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata)
|
||||||
|
|
||||||
|
class person_without_private_data_3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string name{};
|
||||||
|
int age = 0;
|
||||||
|
json metadata = nullptr;
|
||||||
|
|
||||||
|
bool operator==(const person_without_private_data_3& rhs) const
|
||||||
|
{
|
||||||
|
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
person_without_private_data_3() = default;
|
||||||
|
person_without_private_data_3(std::string name_, int age_, json metadata_)
|
||||||
|
: name(std::move(name_))
|
||||||
|
, age(age_)
|
||||||
|
, metadata(std::move(metadata_))
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
int getAge() const
|
||||||
|
{
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
json getMetadata() const
|
||||||
|
{
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(person_without_private_data_3, age, name, metadata)
|
||||||
|
|
||||||
class person_with_private_alphabet
|
class person_with_private_alphabet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -231,7 +302,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_with_public_alphabet, a, b, c, d, e, f
|
|||||||
|
|
||||||
} // namespace persons
|
} // namespace persons
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE", T,
|
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
|
||||||
persons::person_with_private_data,
|
persons::person_with_private_data,
|
||||||
persons::person_without_private_data_1,
|
persons::person_without_private_data_1,
|
||||||
persons::person_without_private_data_2)
|
persons::person_without_private_data_2)
|
||||||
@ -257,6 +328,40 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT", T,
|
||||||
|
persons::person_with_private_data_2,
|
||||||
|
persons::person_without_private_data_3)
|
||||||
|
{
|
||||||
|
SECTION("person with default values")
|
||||||
|
{
|
||||||
|
// serialization of default constructed object
|
||||||
|
T p0;
|
||||||
|
CHECK(json(p0).dump() == "{\"age\":0,\"metadata\":null,\"name\":\"\"}");
|
||||||
|
|
||||||
|
// serialization
|
||||||
|
T p1("Erik", 1, {{"haircuts", 2}});
|
||||||
|
CHECK(json(p1).dump() == "{\"age\":1,\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}");
|
||||||
|
|
||||||
|
// deserialization
|
||||||
|
auto p2 = json(p1).get<T>();
|
||||||
|
CHECK(p2 == p1);
|
||||||
|
|
||||||
|
// roundtrip
|
||||||
|
CHECK(T(json(p1)) == p1);
|
||||||
|
CHECK(json(T(json(p1))) == json(p1));
|
||||||
|
|
||||||
|
// check default value in case of missing field
|
||||||
|
json j = json(p1);
|
||||||
|
j.erase("name");
|
||||||
|
j.erase("age");
|
||||||
|
j.erase("metadata");
|
||||||
|
T p3 = j.get<T>();
|
||||||
|
CHECK(p3.getName() == "");
|
||||||
|
CHECK(p3.getAge() == 0);
|
||||||
|
CHECK(p3.getMetadata() == nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
|
TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
|
||||||
persons::person_with_private_alphabet,
|
persons::person_with_private_alphabet,
|
||||||
persons::person_with_public_alphabet)
|
persons::person_with_public_alphabet)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user