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:
|
||||
schedule:
|
||||
- cron: '0 19 * * 1'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
|
||||
3
.github/workflows/macos.yml
vendored
3
.github/workflows/macos.yml
vendored
@ -7,6 +7,7 @@ on:
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
xcode:
|
||||
@ -37,7 +38,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- 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
|
||||
run: cmake --build build --parallel 10
|
||||
- name: test
|
||||
|
||||
1
.github/workflows/ubuntu.yml
vendored
1
.github/workflows/ubuntu.yml
vendored
@ -7,6 +7,7 @@ on:
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
ci_test_clang:
|
||||
|
||||
41
.github/workflows/windows.yml
vendored
41
.github/workflows/windows.yml
vendored
@ -7,6 +7,7 @@ on:
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
mingw:
|
||||
@ -64,7 +65,7 @@ jobs:
|
||||
run: cd build ; ctest -j 10 -C Release --output-on-failure
|
||||
|
||||
msvc2019:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Debug, Release]
|
||||
@ -84,7 +85,7 @@ jobs:
|
||||
run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure
|
||||
|
||||
msvc2019_latest:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@ -95,8 +96,40 @@ jobs:
|
||||
- name: test
|
||||
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:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
strategy:
|
||||
matrix:
|
||||
version: [11, 12]
|
||||
@ -113,7 +146,7 @@ jobs:
|
||||
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
|
||||
|
||||
clang-cl-11:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
strategy:
|
||||
matrix:
|
||||
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."
|
||||
authors:
|
||||
authors:
|
||||
- family-names: Lohmann
|
||||
given-names: Niels
|
||||
orcid: https://orcid.org/0000-0001-9037-795X
|
||||
@ -8,7 +8,7 @@ authors:
|
||||
website: https://nlohmann.me
|
||||
title: "JSON for Modern C++"
|
||||
version: 3.10.5
|
||||
date-released: 2022
|
||||
date-released: 2022-01-03
|
||||
license: MIT
|
||||
repository-code: "https://github.com/nlohmann"
|
||||
url: https://json.nlohmann.me
|
||||
|
||||
@ -19,6 +19,7 @@ endif()
|
||||
## INCLUDE
|
||||
##
|
||||
##
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
|
||||
include(ExternalProject)
|
||||
|
||||
##
|
||||
@ -30,7 +31,13 @@ if (POLICY CMP0077)
|
||||
cmake_policy(SET CMP0077 NEW)
|
||||
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_Diagnostics "Use extended diagnostic messages." OFF)
|
||||
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)
|
||||
|
||||
if (JSON_CI)
|
||||
include(cmake/ci.cmake)
|
||||
include(ci)
|
||||
endif ()
|
||||
|
||||
##
|
||||
|
||||
36
Makefile
36
Makefile
@ -4,9 +4,6 @@
|
||||
# configuration
|
||||
##########################################################################
|
||||
|
||||
# directory to recent compiler binaries
|
||||
COMPILER_DIR=/usr/local/opt/llvm/bin
|
||||
|
||||
# find GNU sed to use `-i` parameter
|
||||
SED:=$(shell command -v gsed || which sed)
|
||||
|
||||
@ -62,6 +59,7 @@ run_benchmarks:
|
||||
cd cmake-build-benchmarks ; ninja
|
||||
cd cmake-build-benchmarks ; ./json_benchmarks
|
||||
|
||||
|
||||
##########################################################################
|
||||
# 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
|
||||
open cmake-build-pvs-studio/pvs/index.html
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Code format and source amalgamation
|
||||
##########################################################################
|
||||
@ -203,20 +202,29 @@ ChangeLog.md:
|
||||
# Release files
|
||||
##########################################################################
|
||||
|
||||
# Create the files for a release and add signatures and hashes. We use `-X` to make the resulting ZIP file
|
||||
# reproducible, see <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
|
||||
# Create a tar.gz archive that contains sufficient files to be used as CMake project (e.g., using FetchContent). The
|
||||
# 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
|
||||
mkdir release_files
|
||||
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) meson.build LICENSE.MIT
|
||||
gpg --armor --detach-sig include.zip
|
||||
mv include.zip include.zip.asc release_files
|
||||
gpg --armor --detach-sig $(AMALGAMATED_FILE)
|
||||
gpg --armor --detach-sig json.tar.xz
|
||||
cp $(AMALGAMATED_FILE) release_files
|
||||
mv $(AMALGAMATED_FILE).asc release_files
|
||||
cd release_files ; shasum -a 256 json.hpp > hashes.txt
|
||||
cd release_files ; shasum -a 256 include.zip >> hashes.txt
|
||||
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 include.zip json.tar.xz > hashes.txt
|
||||
|
||||
|
||||
##########################################################################
|
||||
@ -225,12 +233,12 @@ release:
|
||||
|
||||
# clean up
|
||||
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 cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64
|
||||
rm -fr cmake-build-benchmarks cmake-build-pedantic fuzz-testing cmake-build-clang-analyze cmake-build-pvs-studio cmake-build-infer cmake_build
|
||||
rm -fr cmake-build-benchmarks fuzz-testing cmake-build-pvs-studio release_files
|
||||
$(MAKE) clean -Cdoc
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Thirdparty code
|
||||
##########################################################################
|
||||
|
||||
28
README.md
28
README.md
@ -10,7 +10,7 @@
|
||||
[](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://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://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).
|
||||
|
||||
: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.
|
||||
|
||||
@ -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++ 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++ 2022 / Build Tools 19.30.30709.0 (and possibly later)
|
||||
|
||||
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 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 17 2022 MSVC 19.30.30709.0 (Build Engine version 17.0.31804.368 for .NET Framework) | Windows-10.0.20348 | GitHub Actions |
|
||||
|
||||
|
||||
## Integration
|
||||
@ -1183,29 +1185,20 @@ target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||
|
||||
Since CMake v3.11,
|
||||
[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:
|
||||
```cmake
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(json
|
||||
GIT_REPOSITORY https://github.com/nlohmann/json.git
|
||||
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()
|
||||
FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.10.5/json.tar.xz)
|
||||
FetchContent_MakeAvailable(json)
|
||||
|
||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||
```
|
||||
|
||||
**Note**: The repository https://github.com/nlohmann/json download size is huge.
|
||||
It contains all the dataset used for the benchmarks. 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
|
||||
**Note**: It is recommended to use the URL approach described above which is supported as of version 3.10.0. See
|
||||
<https://json.nlohmann.me/integration/cmake/#fetchcontent> for more information.
|
||||
|
||||
#### 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)
|
||||
- [**cppcheck**](http://cppcheck.sourceforge.net) for static analysis
|
||||
- [**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
|
||||
- [**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
|
||||
- [**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
|
||||
- [**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))
|
||||
- [**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
|
||||
|
||||
@ -23,7 +23,7 @@ if(NOT benchmark_POPULATED)
|
||||
endif()
|
||||
|
||||
# download test data
|
||||
include(${CMAKE_SOURCE_DIR}/../cmake/download_test_data.cmake)
|
||||
include(download_test_data)
|
||||
|
||||
# benchmark binary
|
||||
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}")
|
||||
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)
|
||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}")
|
||||
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.
|
||||
# -Wreserved-identifier See https://github.com/onqtam/doctest/issues/536.
|
||||
|
||||
set(CLANG_CXXFLAGS "-std=c++11 \
|
||||
-Werror \
|
||||
-Weverything \
|
||||
-Wno-c++98-compat \
|
||||
-Wno-c++98-compat-pedantic \
|
||||
-Wno-deprecated-declarations \
|
||||
-Wno-extra-semi-stmt \
|
||||
-Wno-padded \
|
||||
-Wno-covered-switch-default \
|
||||
-Wno-weak-vtables \
|
||||
-Wno-reserved-identifier \
|
||||
")
|
||||
set(CLANG_CXXFLAGS
|
||||
-Werror
|
||||
-Weverything
|
||||
-Wno-c++98-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-deprecated-declarations
|
||||
-Wno-extra-semi-stmt
|
||||
-Wno-padded
|
||||
-Wno-covered-switch-default
|
||||
-Wno-weak-vtables
|
||||
-Wno-reserved-identifier
|
||||
)
|
||||
|
||||
# Warning flags determined for GCC 12.0 (experimental) with https://github.com/nlohmann/gcc_flags:
|
||||
# Ignored GCC warnings:
|
||||
# -Wno-abi-tag We do not care about ABI tags.
|
||||
# -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-templates The library uses templates.
|
||||
|
||||
set(GCC_CXXFLAGS "-std=c++11 \
|
||||
-pedantic \
|
||||
-Werror \
|
||||
--all-warnings \
|
||||
--extra-warnings \
|
||||
-W \
|
||||
-WNSObject-attribute \
|
||||
-Wno-abi-tag \
|
||||
-Waddress \
|
||||
-Waddress-of-packed-member \
|
||||
-Wno-aggregate-return \
|
||||
-Waggressive-loop-optimizations \
|
||||
-Waligned-new=all \
|
||||
-Wall \
|
||||
-Walloc-zero \
|
||||
-Walloca \
|
||||
-Wanalyzer-double-fclose \
|
||||
-Wanalyzer-double-free \
|
||||
-Wanalyzer-exposure-through-output-file \
|
||||
-Wanalyzer-file-leak \
|
||||
-Wanalyzer-free-of-non-heap \
|
||||
-Wanalyzer-malloc-leak \
|
||||
-Wanalyzer-mismatching-deallocation \
|
||||
-Wanalyzer-null-argument \
|
||||
-Wanalyzer-null-dereference \
|
||||
-Wanalyzer-possible-null-argument \
|
||||
-Wanalyzer-possible-null-dereference \
|
||||
-Wanalyzer-shift-count-negative \
|
||||
-Wanalyzer-shift-count-overflow \
|
||||
-Wanalyzer-stale-setjmp-buffer \
|
||||
-Wanalyzer-tainted-array-index \
|
||||
-Wanalyzer-too-complex \
|
||||
-Wanalyzer-unsafe-call-within-signal-handler \
|
||||
-Wanalyzer-use-after-free \
|
||||
-Wanalyzer-use-of-pointer-in-stale-stack-frame \
|
||||
-Wanalyzer-write-to-const \
|
||||
-Wanalyzer-write-to-string-literal \
|
||||
-Warith-conversion \
|
||||
-Warray-bounds \
|
||||
-Warray-bounds=2 \
|
||||
-Warray-parameter=2 \
|
||||
-Wattribute-alias=2 \
|
||||
-Wattribute-warning \
|
||||
-Wattributes \
|
||||
-Wbool-compare \
|
||||
-Wbool-operation \
|
||||
-Wbuiltin-declaration-mismatch \
|
||||
-Wbuiltin-macro-redefined \
|
||||
-Wc++0x-compat \
|
||||
-Wc++11-compat \
|
||||
-Wc++14-compat \
|
||||
-Wc++17-compat \
|
||||
-Wc++1z-compat \
|
||||
-Wc++20-compat \
|
||||
-Wc++2a-compat \
|
||||
-Wcannot-profile \
|
||||
-Wcast-align \
|
||||
-Wcast-align=strict \
|
||||
-Wcast-function-type \
|
||||
-Wcast-qual \
|
||||
-Wcatch-value=3 \
|
||||
-Wchar-subscripts \
|
||||
-Wclass-conversion \
|
||||
-Wclass-memaccess \
|
||||
-Wclobbered \
|
||||
-Wcomma-subscript \
|
||||
-Wcomment \
|
||||
-Wcomments \
|
||||
-Wconditionally-supported \
|
||||
-Wconversion \
|
||||
-Wconversion-null \
|
||||
-Wcoverage-mismatch \
|
||||
-Wcpp \
|
||||
-Wctad-maybe-unsupported \
|
||||
-Wctor-dtor-privacy \
|
||||
-Wdangling-else \
|
||||
-Wdate-time \
|
||||
-Wdelete-incomplete \
|
||||
-Wdelete-non-virtual-dtor \
|
||||
-Wdeprecated \
|
||||
-Wdeprecated-copy \
|
||||
-Wdeprecated-copy-dtor \
|
||||
-Wdeprecated-declarations \
|
||||
-Wdeprecated-enum-enum-conversion \
|
||||
-Wdeprecated-enum-float-conversion \
|
||||
-Wdisabled-optimization \
|
||||
-Wdiv-by-zero \
|
||||
-Wdouble-promotion \
|
||||
-Wduplicated-branches \
|
||||
-Wduplicated-cond \
|
||||
-Weffc++ \
|
||||
-Wempty-body \
|
||||
-Wendif-labels \
|
||||
-Wenum-compare \
|
||||
-Wenum-conversion \
|
||||
-Wexpansion-to-defined \
|
||||
-Wextra \
|
||||
-Wextra-semi \
|
||||
-Wfloat-conversion \
|
||||
-Wfloat-equal \
|
||||
-Wformat-contains-nul \
|
||||
-Wformat-diag \
|
||||
-Wformat-extra-args \
|
||||
-Wformat-nonliteral \
|
||||
-Wformat-overflow=2 \
|
||||
-Wformat-security \
|
||||
-Wformat-signedness \
|
||||
-Wformat-truncation=2 \
|
||||
-Wformat-y2k \
|
||||
-Wformat-zero-length \
|
||||
-Wformat=2 \
|
||||
-Wframe-address \
|
||||
-Wfree-nonheap-object \
|
||||
-Whsa \
|
||||
-Wif-not-aligned \
|
||||
-Wignored-attributes \
|
||||
-Wignored-qualifiers \
|
||||
-Wimplicit-fallthrough=5 \
|
||||
-Winaccessible-base \
|
||||
-Winherited-variadic-ctor \
|
||||
-Winit-list-lifetime \
|
||||
-Winit-self \
|
||||
-Winline \
|
||||
-Wint-in-bool-context \
|
||||
-Wint-to-pointer-cast \
|
||||
-Winvalid-memory-model \
|
||||
-Winvalid-offsetof \
|
||||
-Winvalid-pch \
|
||||
-Wliteral-suffix \
|
||||
-Wlogical-not-parentheses \
|
||||
-Wlogical-op \
|
||||
-Wno-long-long \
|
||||
-Wlto-type-mismatch \
|
||||
-Wmain \
|
||||
-Wmaybe-uninitialized \
|
||||
-Wmemset-elt-size \
|
||||
-Wmemset-transposed-args \
|
||||
-Wmisleading-indentation \
|
||||
-Wmismatched-dealloc \
|
||||
-Wmismatched-new-delete \
|
||||
-Wmismatched-tags \
|
||||
-Wmissing-attributes \
|
||||
-Wmissing-braces \
|
||||
-Wmissing-declarations \
|
||||
-Wmissing-field-initializers \
|
||||
-Wmissing-include-dirs \
|
||||
-Wmissing-profile \
|
||||
-Wmultichar \
|
||||
-Wmultiple-inheritance \
|
||||
-Wmultistatement-macros \
|
||||
-Wno-namespaces \
|
||||
-Wnarrowing \
|
||||
-Wnoexcept \
|
||||
-Wnoexcept-type \
|
||||
-Wnon-template-friend \
|
||||
-Wnon-virtual-dtor \
|
||||
-Wnonnull \
|
||||
-Wnonnull-compare \
|
||||
-Wnormalized=nfkc \
|
||||
-Wnull-dereference \
|
||||
-Wodr \
|
||||
-Wold-style-cast \
|
||||
-Wopenmp-simd \
|
||||
-Woverflow \
|
||||
-Woverlength-strings \
|
||||
-Woverloaded-virtual \
|
||||
-Wpacked \
|
||||
-Wpacked-bitfield-compat \
|
||||
-Wpacked-not-aligned \
|
||||
-Wno-padded \
|
||||
-Wparentheses \
|
||||
-Wpedantic \
|
||||
-Wpessimizing-move \
|
||||
-Wplacement-new=2 \
|
||||
-Wpmf-conversions \
|
||||
-Wpointer-arith \
|
||||
-Wpointer-compare \
|
||||
-Wpragmas \
|
||||
-Wprio-ctor-dtor \
|
||||
-Wpsabi \
|
||||
-Wrange-loop-construct \
|
||||
-Wredundant-decls \
|
||||
-Wredundant-move \
|
||||
-Wredundant-tags \
|
||||
-Wregister \
|
||||
-Wreorder \
|
||||
-Wrestrict \
|
||||
-Wreturn-local-addr \
|
||||
-Wreturn-type \
|
||||
-Wscalar-storage-order \
|
||||
-Wsequence-point \
|
||||
-Wshadow=compatible-local \
|
||||
-Wshadow=global \
|
||||
-Wshadow=local \
|
||||
-Wshift-count-negative \
|
||||
-Wshift-count-overflow \
|
||||
-Wshift-negative-value \
|
||||
-Wshift-overflow=2 \
|
||||
-Wsign-compare \
|
||||
-Wsign-conversion \
|
||||
-Wsign-promo \
|
||||
-Wsized-deallocation \
|
||||
-Wsizeof-array-argument \
|
||||
-Wsizeof-array-div \
|
||||
-Wsizeof-pointer-div \
|
||||
-Wsizeof-pointer-memaccess \
|
||||
-Wstack-protector \
|
||||
-Wstrict-aliasing \
|
||||
-Wstrict-aliasing=3 \
|
||||
-Wstrict-null-sentinel \
|
||||
-Wstrict-overflow \
|
||||
-Wstrict-overflow=5 \
|
||||
-Wstring-compare \
|
||||
-Wstringop-overflow=4 \
|
||||
-Wstringop-overread \
|
||||
-Wstringop-truncation \
|
||||
-Wsubobject-linkage \
|
||||
-Wsuggest-attribute=cold \
|
||||
-Wsuggest-attribute=const \
|
||||
-Wsuggest-attribute=format \
|
||||
-Wsuggest-attribute=malloc \
|
||||
-Wsuggest-attribute=noreturn \
|
||||
-Wsuggest-attribute=pure \
|
||||
-Wsuggest-final-methods \
|
||||
-Wsuggest-final-types \
|
||||
-Wsuggest-override \
|
||||
-Wswitch \
|
||||
-Wswitch-bool \
|
||||
-Wswitch-default \
|
||||
-Wswitch-enum \
|
||||
-Wswitch-outside-range \
|
||||
-Wswitch-unreachable \
|
||||
-Wsync-nand \
|
||||
-Wsynth \
|
||||
-Wno-system-headers \
|
||||
-Wtautological-compare \
|
||||
-Wno-templates \
|
||||
-Wterminate \
|
||||
-Wtrampolines \
|
||||
-Wtrigraphs \
|
||||
-Wtsan \
|
||||
-Wtype-limits \
|
||||
-Wundef \
|
||||
-Wuninitialized \
|
||||
-Wunknown-pragmas \
|
||||
-Wunreachable-code \
|
||||
-Wunsafe-loop-optimizations \
|
||||
-Wunused \
|
||||
-Wunused-but-set-parameter \
|
||||
-Wunused-but-set-variable \
|
||||
-Wunused-const-variable=2 \
|
||||
-Wunused-function \
|
||||
-Wunused-label \
|
||||
-Wunused-local-typedefs \
|
||||
-Wunused-macros \
|
||||
-Wunused-parameter \
|
||||
-Wunused-result \
|
||||
-Wunused-value \
|
||||
-Wunused-variable \
|
||||
-Wuseless-cast \
|
||||
-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 \
|
||||
")
|
||||
set(GCC_CXXFLAGS
|
||||
-pedantic
|
||||
-Werror
|
||||
--all-warnings
|
||||
--extra-warnings
|
||||
-W
|
||||
-WNSObject-attribute
|
||||
-Wno-abi-tag
|
||||
-Waddress
|
||||
-Waddress-of-packed-member
|
||||
-Wno-aggregate-return
|
||||
-Waggressive-loop-optimizations
|
||||
-Waligned-new=all
|
||||
-Wall
|
||||
-Walloc-zero
|
||||
-Walloca
|
||||
-Wanalyzer-double-fclose
|
||||
-Wanalyzer-double-free
|
||||
-Wanalyzer-exposure-through-output-file
|
||||
-Wanalyzer-file-leak
|
||||
-Wanalyzer-free-of-non-heap
|
||||
-Wanalyzer-malloc-leak
|
||||
-Wanalyzer-mismatching-deallocation
|
||||
-Wanalyzer-null-argument
|
||||
-Wanalyzer-null-dereference
|
||||
-Wanalyzer-possible-null-argument
|
||||
-Wanalyzer-possible-null-dereference
|
||||
-Wanalyzer-shift-count-negative
|
||||
-Wanalyzer-shift-count-overflow
|
||||
-Wanalyzer-stale-setjmp-buffer
|
||||
-Wanalyzer-tainted-allocation-size
|
||||
-Wanalyzer-tainted-array-index
|
||||
-Wanalyzer-tainted-divisor
|
||||
-Wanalyzer-tainted-offset
|
||||
-Wanalyzer-tainted-size
|
||||
-Wanalyzer-too-complex
|
||||
-Wanalyzer-unsafe-call-within-signal-handler
|
||||
-Wanalyzer-use-after-free
|
||||
-Wanalyzer-use-of-pointer-in-stale-stack-frame
|
||||
-Wanalyzer-use-of-uninitialized-value
|
||||
-Wanalyzer-write-to-const
|
||||
-Wanalyzer-write-to-string-literal
|
||||
-Warith-conversion
|
||||
-Warray-bounds
|
||||
-Warray-bounds=2
|
||||
-Warray-compare
|
||||
-Warray-parameter=2
|
||||
-Wattribute-alias=2
|
||||
-Wattribute-warning
|
||||
-Wattributes
|
||||
-Wbool-compare
|
||||
-Wbool-operation
|
||||
-Wbuiltin-declaration-mismatch
|
||||
-Wbuiltin-macro-redefined
|
||||
-Wc++0x-compat
|
||||
-Wc++11-compat
|
||||
-Wc++11-extensions
|
||||
-Wc++14-compat
|
||||
-Wc++14-extensions
|
||||
-Wc++17-compat
|
||||
-Wc++17-extensions
|
||||
-Wc++1z-compat
|
||||
-Wc++20-compat
|
||||
-Wc++20-extensions
|
||||
-Wc++23-extensions
|
||||
-Wc++2a-compat
|
||||
-Wcannot-profile
|
||||
-Wcast-align
|
||||
-Wcast-align=strict
|
||||
-Wcast-function-type
|
||||
-Wcast-qual
|
||||
-Wcatch-value=3
|
||||
-Wchar-subscripts
|
||||
-Wclass-conversion
|
||||
-Wclass-memaccess
|
||||
-Wclobbered
|
||||
-Wcomma-subscript
|
||||
-Wcomment
|
||||
-Wcomments
|
||||
-Wconditionally-supported
|
||||
-Wconversion
|
||||
-Wconversion-null
|
||||
-Wcoverage-invalid-line-number
|
||||
-Wcoverage-mismatch
|
||||
-Wcpp
|
||||
-Wctad-maybe-unsupported
|
||||
-Wctor-dtor-privacy
|
||||
-Wdangling-else
|
||||
-Wdate-time
|
||||
-Wdelete-incomplete
|
||||
-Wdelete-non-virtual-dtor
|
||||
-Wdeprecated
|
||||
-Wdeprecated-copy
|
||||
-Wdeprecated-copy-dtor
|
||||
-Wdeprecated-declarations
|
||||
-Wdeprecated-enum-enum-conversion
|
||||
-Wdeprecated-enum-float-conversion
|
||||
-Wdisabled-optimization
|
||||
-Wdiv-by-zero
|
||||
-Wdouble-promotion
|
||||
-Wduplicated-branches
|
||||
-Wduplicated-cond
|
||||
-Weffc++
|
||||
-Wempty-body
|
||||
-Wendif-labels
|
||||
-Wenum-compare
|
||||
-Wenum-conversion
|
||||
-Wexceptions
|
||||
-Wexpansion-to-defined
|
||||
-Wextra
|
||||
-Wextra-semi
|
||||
-Wfloat-conversion
|
||||
-Wfloat-equal
|
||||
-Wformat-diag
|
||||
-Wformat-overflow=2
|
||||
-Wformat-signedness
|
||||
-Wformat-truncation=2
|
||||
-Wformat=2
|
||||
-Wframe-address
|
||||
-Wfree-nonheap-object
|
||||
-Whsa
|
||||
-Wif-not-aligned
|
||||
-Wignored-attributes
|
||||
-Wignored-qualifiers
|
||||
-Wimplicit-fallthrough=5
|
||||
-Winaccessible-base
|
||||
-Winfinite-recursion
|
||||
-Winherited-variadic-ctor
|
||||
-Winit-list-lifetime
|
||||
-Winit-self
|
||||
-Winline
|
||||
-Wint-in-bool-context
|
||||
-Wint-to-pointer-cast
|
||||
-Winterference-size
|
||||
-Winvalid-imported-macros
|
||||
-Winvalid-memory-model
|
||||
-Winvalid-offsetof
|
||||
-Winvalid-pch
|
||||
-Wliteral-suffix
|
||||
-Wlogical-not-parentheses
|
||||
-Wlogical-op
|
||||
-Wno-long-long
|
||||
-Wlto-type-mismatch
|
||||
-Wmain
|
||||
-Wmaybe-uninitialized
|
||||
-Wmemset-elt-size
|
||||
-Wmemset-transposed-args
|
||||
-Wmisleading-indentation
|
||||
-Wmismatched-dealloc
|
||||
-Wmismatched-new-delete
|
||||
-Wmismatched-tags
|
||||
-Wmissing-attributes
|
||||
-Wmissing-braces
|
||||
-Wmissing-declarations
|
||||
-Wmissing-field-initializers
|
||||
-Wmissing-include-dirs
|
||||
-Wmissing-profile
|
||||
-Wmissing-requires
|
||||
-Wmultichar
|
||||
-Wmultiple-inheritance
|
||||
-Wmultistatement-macros
|
||||
-Wno-namespaces
|
||||
-Wnarrowing
|
||||
-Wnoexcept
|
||||
-Wnoexcept-type
|
||||
-Wnon-template-friend
|
||||
-Wnon-virtual-dtor
|
||||
-Wnonnull
|
||||
-Wnonnull-compare
|
||||
-Wnormalized=nfkc
|
||||
-Wnull-dereference
|
||||
-Wodr
|
||||
-Wold-style-cast
|
||||
-Wopenacc-parallelism
|
||||
-Wopenmp-simd
|
||||
-Woverflow
|
||||
-Woverlength-strings
|
||||
-Woverloaded-virtual
|
||||
-Wpacked
|
||||
-Wpacked-bitfield-compat
|
||||
-Wpacked-not-aligned
|
||||
-Wno-padded
|
||||
-Wparentheses
|
||||
-Wpedantic
|
||||
-Wpessimizing-move
|
||||
-Wplacement-new=2
|
||||
-Wpmf-conversions
|
||||
-Wpointer-arith
|
||||
-Wpointer-compare
|
||||
-Wpragmas
|
||||
-Wprio-ctor-dtor
|
||||
-Wpsabi
|
||||
-Wrange-loop-construct
|
||||
-Wredundant-decls
|
||||
-Wredundant-move
|
||||
-Wredundant-tags
|
||||
-Wregister
|
||||
-Wreorder
|
||||
-Wrestrict
|
||||
-Wreturn-local-addr
|
||||
-Wreturn-type
|
||||
-Wscalar-storage-order
|
||||
-Wsequence-point
|
||||
-Wshadow=compatible-local
|
||||
-Wshadow=global
|
||||
-Wshadow=local
|
||||
-Wshift-count-negative
|
||||
-Wshift-count-overflow
|
||||
-Wshift-negative-value
|
||||
-Wshift-overflow=2
|
||||
-Wsign-compare
|
||||
-Wsign-conversion
|
||||
-Wsign-promo
|
||||
-Wsized-deallocation
|
||||
-Wsizeof-array-argument
|
||||
-Wsizeof-array-div
|
||||
-Wsizeof-pointer-div
|
||||
-Wsizeof-pointer-memaccess
|
||||
-Wstack-protector
|
||||
-Wstrict-aliasing
|
||||
-Wstrict-aliasing=3
|
||||
-Wstrict-null-sentinel
|
||||
-Wstrict-overflow
|
||||
-Wstrict-overflow=5
|
||||
-Wstring-compare
|
||||
-Wstringop-overflow=4
|
||||
-Wstringop-overread
|
||||
-Wstringop-truncation
|
||||
-Wsubobject-linkage
|
||||
-Wsuggest-attribute=cold
|
||||
-Wsuggest-attribute=const
|
||||
-Wsuggest-attribute=format
|
||||
-Wsuggest-attribute=malloc
|
||||
-Wsuggest-attribute=noreturn
|
||||
-Wsuggest-attribute=pure
|
||||
-Wsuggest-final-methods
|
||||
-Wsuggest-final-types
|
||||
-Wsuggest-override
|
||||
-Wswitch
|
||||
-Wswitch-bool
|
||||
-Wswitch-default
|
||||
-Wswitch-enum
|
||||
-Wswitch-outside-range
|
||||
-Wswitch-unreachable
|
||||
-Wsync-nand
|
||||
-Wsynth
|
||||
-Wno-system-headers
|
||||
-Wtautological-compare
|
||||
-Wno-templates
|
||||
-Wterminate
|
||||
-Wtrampolines
|
||||
-Wtrigraphs
|
||||
-Wtsan
|
||||
-Wtype-limits
|
||||
-Wundef
|
||||
-Wuninitialized
|
||||
-Wunknown-pragmas
|
||||
-Wunreachable-code
|
||||
-Wunsafe-loop-optimizations
|
||||
-Wunused
|
||||
-Wunused-but-set-parameter
|
||||
-Wunused-but-set-variable
|
||||
-Wunused-const-variable=2
|
||||
-Wunused-function
|
||||
-Wunused-label
|
||||
-Wunused-local-typedefs
|
||||
-Wunused-macros
|
||||
-Wunused-parameter
|
||||
-Wunused-result
|
||||
-Wunused-value
|
||||
-Wunused-variable
|
||||
-Wuseless-cast
|
||||
-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
|
||||
COMMAND CXX=${GCC_TOOL} CXXFLAGS=${GCC_CXXFLAGS} ${CMAKE_COMMAND}
|
||||
COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND}
|
||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||
-DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON
|
||||
-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
|
||||
COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXXFLAGS} ${CMAKE_COMMAND}
|
||||
COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND}
|
||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||
-DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON
|
||||
-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)
|
||||
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_CXX_STANDARD=${CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
||||
-DJSON_TestStandards=${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 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}
|
||||
COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}
|
||||
COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND}
|
||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||
-DCMAKE_CXX_STANDARD=${CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||
-DJSON_BuildTests=ON
|
||||
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
||||
-DJSON_TestStandards=${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 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
|
||||
###############################################################################
|
||||
|
||||
if (APPLE)
|
||||
set(CMAKE_310_BINARY ${PROJECT_BINARY_DIR}/cmake-3.1.0-Darwin64/CMake.app/Contents/bin/cmake)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_310_BINARY}
|
||||
COMMAND wget https://github.com/Kitware/CMake/releases/download/v3.1.0/cmake-3.1.0-Darwin64.tar.gz
|
||||
COMMAND tar xfz cmake-3.1.0-Darwin64.tar.gz
|
||||
COMMAND rm cmake-3.1.0-Darwin64.tar.gz
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
COMMENT "Download CMake 3.1.0"
|
||||
)
|
||||
else()
|
||||
set(CMAKE_310_BINARY ${PROJECT_BINARY_DIR}/cmake-3.1.0-Linux-x86_64/bin/cmake)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_310_BINARY}
|
||||
COMMAND wget https://github.com/Kitware/CMake/releases/download/v3.1.0/cmake-3.1.0-Linux-x86_64.tar.gz
|
||||
COMMAND tar xfz cmake-3.1.0-Linux-x86_64.tar.gz
|
||||
COMMAND rm cmake-3.1.0-Linux-x86_64.tar.gz
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
COMMENT "Download CMake 3.1.0"
|
||||
)
|
||||
endif()
|
||||
function(ci_get_cmake version var)
|
||||
if (APPLE)
|
||||
set(${var} ${PROJECT_BINARY_DIR}/cmake-${version}-Darwin64/CMake.app/Contents/bin/cmake)
|
||||
add_custom_command(
|
||||
OUTPUT ${${var}}
|
||||
COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-Darwin64.tar.gz
|
||||
COMMAND tar xfz cmake-${version}-Darwin64.tar.gz
|
||||
COMMAND rm cmake-${version}-Darwin64.tar.gz
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
COMMENT "Download CMake ${version}"
|
||||
)
|
||||
else()
|
||||
set(${var} ${PROJECT_BINARY_DIR}/cmake-${version}-Linux-x86_64/bin/cmake)
|
||||
add_custom_command(
|
||||
OUTPUT ${${var}}
|
||||
COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-Linux-x86_64.tar.gz
|
||||
COMMAND tar xfz cmake-${version}-Linux-x86_64.tar.gz
|
||||
COMMAND rm cmake-${version}-Linux-x86_64.tar.gz
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
COMMENT "Download CMake ${version}"
|
||||
)
|
||||
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})
|
||||
string(TOLOWER "ci_cmake_flag_${JSON_CMAKE_FLAG}" JSON_CMAKE_FLAG_TARGET)
|
||||
add_custom_target("${JSON_CMAKE_FLAG_TARGET}"
|
||||
COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${CMAKE_VERSION})"
|
||||
set(JSON_CMAKE_FLAGS_3_1_0 "JSON_Install;JSON_MultipleHeaders;JSON_ImplicitConversions;JSON_Valgrind;JSON_Diagnostics;JSON_SystemInclude")
|
||||
set(JSON_CMAKE_FLAGS_3_13_0 "JSON_BuildTests")
|
||||
|
||||
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}
|
||||
-Werror=dev
|
||||
-D${JSON_CMAKE_FLAG}=ON
|
||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}
|
||||
-D${flag}=ON
|
||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${flag_target}
|
||||
)
|
||||
add_custom_target("${JSON_CMAKE_FLAG_TARGET}_31"
|
||||
COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake 3.1)"
|
||||
COMMAND mkdir ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}_31
|
||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}_31 && ${CMAKE_310_BINARY}
|
||||
-Werror=dev ${PROJECT_SOURCE_DIR}
|
||||
-D${JSON_CMAKE_FLAG}=ON
|
||||
-DCMAKE_CXX_COMPILE_FEATURES="cxx_range_for" -DCMAKE_CXX_FLAGS="-std=gnu++11"
|
||||
DEPENDS ${CMAKE_310_BINARY}
|
||||
add_custom_target(${flag_target}_${min_version_var}
|
||||
COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${min_version})"
|
||||
COMMAND mkdir -pv ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var}
|
||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var}
|
||||
&& ${cmake_binary} -Werror=dev ${PROJECT_SOURCE_DIR} -D${flag}=ON
|
||||
DEPENDS ${cmake_binary}
|
||||
)
|
||||
list(APPEND JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGET} ${JSON_CMAKE_FLAG_TARGET}_31)
|
||||
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_TARGETS ${JSON_CMAKE_FLAG_TARGET} ${flag_target}_${min_version_var})
|
||||
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()
|
||||
|
||||
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"
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [json_pointer](../json_pointer/index.md) - type to represent JSON Pointers
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 2.0.0.
|
||||
|
||||
@ -29,6 +29,7 @@ are the base for JSON patches.
|
||||
|
||||
## 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)
|
||||
|
||||
## 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.
|
||||
|
||||
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_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(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_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
|
||||
|
||||
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
|
||||
|
||||
The `to_json`/`from_json` functions for the `person` struct above can be created with:
|
||||
|
||||
|
||||
```cpp
|
||||
namespace ns {
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Here is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed:
|
||||
|
||||
|
||||
```cpp
|
||||
namespace ns {
|
||||
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;
|
||||
int housenumber;
|
||||
int postcode;
|
||||
|
||||
|
||||
public:
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)
|
||||
};
|
||||
|
||||
@ -1,19 +1,123 @@
|
||||
# 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
|
||||
// a JSON value
|
||||
json j_original = R"({
|
||||
"baz": ["one", "two", "three"],
|
||||
"foo": "bar"
|
||||
})"_json;
|
||||
json::json_pointer p = "/nested/one";
|
||||
```
|
||||
|
||||
// access members with a JSON pointer (RFC 6901)
|
||||
j_original["/baz/1"_json_pointer];
|
||||
// "two"
|
||||
Furthermore, a user-defined string literal can be used to achieve the same result:
|
||||
|
||||
```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
|
||||
|
||||
- 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)`
|
||||
|
||||
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)`
|
||||
|
||||
This macro overrides `#!cpp catch` calls inside the library. The argument is the type of the exception to catch. As of
|
||||
version 3.8.0, the library only catches `std::out_of_range` 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.
|
||||
This macro overrides [`#!cpp catch`](https://en.cppreference.com/w/cpp/language/try_catch) calls inside the library.
|
||||
The argument is the type of the exception to catch. As of version 3.8.0, the library only catches `std::out_of_range`
|
||||
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.
|
||||
|
||||
!!! 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`
|
||||
|
||||
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
|
||||
`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`
|
||||
|
||||
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
|
||||
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`
|
||||
|
||||
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.
|
||||
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`
|
||||
|
||||
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
|
||||
`#!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`.
|
||||
|
||||
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
|
||||
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`
|
||||
|
||||
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.
|
||||
|
||||
!!! info "Default behavior"
|
||||
|
||||
By default, the macro is not defined.
|
||||
|
||||
```cpp
|
||||
#undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK
|
||||
```
|
||||
|
||||
## `JSON_THROW_USER(exception)`
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
## `JSON_TRY_USER`
|
||||
|
||||
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.
|
||||
|
||||
## `JSON_USE_IMPLICIT_CONVERSIONS`
|
||||
@ -84,12 +192,12 @@ When defined to `0`, implicit conversions are switched off. By default, implicit
|
||||
??? example
|
||||
|
||||
This is an example for an implicit conversion:
|
||||
|
||||
|
||||
```cpp
|
||||
json j = "Hello, world!";
|
||||
std::string s = j;
|
||||
```
|
||||
|
||||
|
||||
When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be
|
||||
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
|
||||
sets `JSON_USE_IMPLICIT_CONVERSIONS` accordingly.
|
||||
|
||||
!!! info "Default behavior"
|
||||
|
||||
```cpp
|
||||
#define JSON_USE_IMPLICIT_CONVERSIONS 1
|
||||
```
|
||||
|
||||
## `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
|
||||
@ -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.
|
||||
|
||||
## `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...)`
|
||||
|
||||
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.
|
||||
|
||||
## `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, ...)`
|
||||
|
||||
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.
|
||||
|
||||
## Default behavior: sort keys
|
||||
|
||||
The default type `nlohmann::json` uses a `std::map` to store JSON objects, and thus stores object keys **sorted alphabetically**.
|
||||
|
||||
??? 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).
|
||||
|
||||
??? 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)).
|
||||
|
||||
### 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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
# CMakeLists.txt
|
||||
find_package(nlohmann_json 3.2.0 REQUIRED)
|
||||
...
|
||||
add_library(foo ...)
|
||||
...
|
||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||
```
|
||||
!!! example
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
# 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 "")
|
||||
!!! example
|
||||
|
||||
# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
|
||||
# unintended consequences that will break the build. It's generally
|
||||
# discouraged (although not necessarily well documented as such) to use
|
||||
# include(...) for pulling in other CMake projects anyways.
|
||||
add_subdirectory(nlohmann_json)
|
||||
...
|
||||
add_library(foo ...)
|
||||
...
|
||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||
```
|
||||
```cmake title="CMakeLists.txt"
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(ExampleProject LANGUAGES CXX)
|
||||
|
||||
### 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,
|
||||
[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
|
||||
be used to automatically download the repository as a dependency at configure type.
|
||||
add_executable(example example.cpp)
|
||||
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
|
||||
```
|
||||
|
||||
Example:
|
||||
```cmake
|
||||
include(FetchContent)
|
||||
!!! note
|
||||
|
||||
FetchContent_Declare(json
|
||||
GIT_REPOSITORY https://github.com/nlohmann/json
|
||||
GIT_TAG v3.7.3)
|
||||
Do not use `#!cmake include(nlohmann_json/CMakeLists.txt)`, since that carries with it unintended consequences that
|
||||
will break the build. It is generally discouraged (although not necessarily well documented as such) to use
|
||||
`#!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
|
||||
|
||||
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
|
||||
# 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()
|
||||
...
|
||||
```
|
||||
!!! example
|
||||
|
||||
`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
|
||||
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << json::meta() << std::endl;
|
||||
std::cout << std::setw(4) << json::meta() << std::endl;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
# 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
|
||||
#include <nlohmann/json.hpp>
|
||||
@ -9,6 +10,9 @@
|
||||
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"
|
||||
```
|
||||
|
||||
When executed, this program should create output similar to
|
||||
|
||||
```json
|
||||
--8<-- "../../examples/meta.output"
|
||||
```
|
||||
|
||||
## Homebrew
|
||||
|
||||
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:
|
||||
|
||||
=== "example.cpp"
|
||||
|
||||
```cpp
|
||||
--8<-- "integration/example.cpp"
|
||||
```
|
||||
```cpp title="example.cpp"
|
||||
--8<-- "integration/example.cpp"
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
:material-update: The [formula](https://formulae.brew.sh/formula/nlohmann-json) is updated automatically.
|
||||
|
||||
## 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.
|
||||
@ -64,24 +70,17 @@ If you are using [Conan](https://www.conan.io/) to manage your dependencies, mer
|
||||
|
||||
1. Create the following files:
|
||||
|
||||
=== "Conanfile.txt"
|
||||
|
||||
```ini
|
||||
--8<-- "integration/conan/Conanfile.txt"
|
||||
```
|
||||
```ini title="Conanfile.txt"
|
||||
--8<-- "integration/conan/Conanfile.txt"
|
||||
```
|
||||
|
||||
=== "CMakeLists.txt"
|
||||
|
||||
```cmake
|
||||
--8<-- "integration/conan/CMakeLists.txt"
|
||||
```
|
||||
|
||||
=== "example.cpp"
|
||||
|
||||
```cpp
|
||||
--8<-- "integration/conan/example.cpp"
|
||||
```
|
||||
```cmake title="CMakeLists.txt"
|
||||
--8<-- "integration/conan/CMakeLists.txt"
|
||||
```
|
||||
|
||||
```cpp title="example.cpp"
|
||||
--8<-- "integration/conan/example.cpp"
|
||||
```
|
||||
|
||||
2. Build:
|
||||
|
||||
@ -93,6 +92,8 @@ If you are using [Conan](https://www.conan.io/) to manage your dependencies, mer
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
:material-update: The [package](https://conan.io/center/nlohmann_json) is updated automatically.
|
||||
|
||||
## 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.
|
||||
@ -113,17 +114,13 @@ If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project fo
|
||||
|
||||
1. Create the following files:
|
||||
|
||||
=== "CMakeLists.txt"
|
||||
|
||||
```cmake
|
||||
--8<-- "integration/vcpkg/CMakeLists.txt"
|
||||
```
|
||||
|
||||
=== "example.cpp"
|
||||
|
||||
```cpp
|
||||
--8<-- "integration/vcpkg/example.cpp"
|
||||
```
|
||||
```cmake title="CMakeLists.txt"
|
||||
--8<-- "integration/vcpkg/CMakeLists.txt"
|
||||
```
|
||||
|
||||
```cpp title="example.cpp"
|
||||
--8<-- "integration/vcpkg/example.cpp"
|
||||
```
|
||||
|
||||
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`).
|
||||
|
||||
:material-update: cget reads directly from the [GitHub repository](https://github.com/nlohmann/json) and is always up-to-date.
|
||||
|
||||
## 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).
|
||||
@ -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.
|
||||
|
||||
:material-update: The [package](https://packages.msys2.org/base/mingw-w64-nlohmann-json) is updated automatically.
|
||||
|
||||
## 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.
|
||||
|
||||
:material-update: The [package](https://ports.macports.org/port/nlohmann-json/) is updated automatically.
|
||||
|
||||
## 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.
|
||||
|
||||
:material-update: The [package](https://cppget.org/nlohmann-json) is updated automatically.
|
||||
|
||||
## 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.
|
||||
|
||||
:material-update: wsjcpp reads directly from the [GitHub repository](https://github.com/nlohmann/json) and is always up-to-date.
|
||||
|
||||
## 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:
|
||||
|
||||
@ -464,7 +464,8 @@ void from_json(const BasicJsonType& j, std_fs::path& p)
|
||||
{
|
||||
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*>();
|
||||
}
|
||||
|
||||
@ -352,7 +352,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
@brief post-increment (it++)
|
||||
@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;
|
||||
++(*this);
|
||||
@ -403,7 +403,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
@brief post-decrement (it--)
|
||||
@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;
|
||||
--(*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) {}
|
||||
|
||||
/// 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));
|
||||
}
|
||||
@ -60,7 +60,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
|
||||
}
|
||||
|
||||
/// 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));
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ class primitive_iterator_t
|
||||
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;
|
||||
++m_it;
|
||||
@ -100,7 +100,7 @@ class primitive_iterator_t
|
||||
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;
|
||||
--m_it;
|
||||
|
||||
@ -97,6 +97,15 @@
|
||||
#define JSON_HAS_FILESYSTEM 0
|
||||
#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
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
@ -334,6 +343,7 @@
|
||||
|
||||
#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_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
|
||||
|
||||
/*!
|
||||
@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 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
|
||||
@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 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
|
||||
// allows to call any std function as if (e.g. with begin):
|
||||
|
||||
@ -8,19 +8,23 @@
|
||||
// clean up
|
||||
#undef JSON_ASSERT
|
||||
#undef JSON_INTERNAL_CATCH
|
||||
#undef JSON_CATCH
|
||||
#undef JSON_THROW
|
||||
#undef JSON_TRY
|
||||
#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
|
||||
#undef JSON_EXPLICIT
|
||||
#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>
|
||||
|
||||
@ -147,8 +147,12 @@ struct static_const
|
||||
static constexpr T value{};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
|
||||
#ifndef JSON_HAS_CPP_17
|
||||
|
||||
template<typename T>
|
||||
constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace nlohmann
|
||||
|
||||
@ -1872,6 +1872,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
template < typename ValueType, typename std::enable_if <
|
||||
detail::conjunction <
|
||||
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, typename string_t::value_type>>,
|
||||
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`
|
||||
// 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>
|
||||
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
||||
: 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} {}
|
||||
|
||||
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
|
||||
|
||||
@ -2394,6 +2394,15 @@ using is_detected_convertible =
|
||||
#define JSON_HAS_FILESYSTEM 0
|
||||
#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
|
||||
#if defined(__clang__)
|
||||
#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_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
|
||||
@ -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 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
|
||||
@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 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
|
||||
// allows to call any std function as if (e.g. with begin):
|
||||
@ -3173,8 +3191,12 @@ struct static_const
|
||||
static constexpr T value{};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
|
||||
#ifndef JSON_HAS_CPP_17
|
||||
|
||||
template<typename T>
|
||||
constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace nlohmann
|
||||
@ -4257,7 +4279,8 @@ void from_json(const BasicJsonType& j, std_fs::path& p)
|
||||
{
|
||||
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*>();
|
||||
}
|
||||
@ -11299,7 +11322,7 @@ class primitive_iterator_t
|
||||
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;
|
||||
++m_it;
|
||||
@ -11312,7 +11335,7 @@ class primitive_iterator_t
|
||||
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;
|
||||
--m_it;
|
||||
@ -11719,7 +11742,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
@brief post-increment (it++)
|
||||
@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;
|
||||
++(*this);
|
||||
@ -11770,7 +11793,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
@brief post-decrement (it--)
|
||||
@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;
|
||||
--(*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) {}
|
||||
|
||||
/// 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));
|
||||
}
|
||||
@ -12170,7 +12193,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
|
||||
}
|
||||
|
||||
/// 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));
|
||||
}
|
||||
@ -17057,11 +17080,12 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
||||
|
||||
// Explicit constructors instead of `using Container::Container`
|
||||
// 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>
|
||||
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
||||
: 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} {}
|
||||
|
||||
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 <
|
||||
detail::conjunction <
|
||||
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, typename string_t::value_type>>,
|
||||
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
|
||||
#undef JSON_ASSERT
|
||||
#undef JSON_INTERNAL_CATCH
|
||||
#undef JSON_CATCH
|
||||
#undef JSON_THROW
|
||||
#undef JSON_TRY
|
||||
#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
|
||||
#undef JSON_EXPLICIT
|
||||
#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>
|
||||
|
||||
|
||||
|
||||
@ -1,163 +1,131 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
option(JSON_Valgrind "Execute test suite with Valgrind." OFF)
|
||||
option(JSON_FastTests "Skip expensive/slow tests." OFF)
|
||||
|
||||
# download test data
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/download_test_data.cmake)
|
||||
set(JSON_TestStandards "" CACHE STRING "The list of standards to test explicitly.")
|
||||
|
||||
# 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)
|
||||
include(test)
|
||||
|
||||
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)
|
||||
#############################################################################
|
||||
# override standard support
|
||||
#############################################################################
|
||||
|
||||
# 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()
|
||||
|
||||
#############################################################################
|
||||
# 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
|
||||
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)
|
||||
endif()
|
||||
# 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)
|
||||
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)
|
||||
string(REGEX REPLACE "unit-([^$]+)" "test-\\1" testcase ${file_basename})
|
||||
#############################################################################
|
||||
# test_main library with shared code to speed up build and common settings
|
||||
#############################################################################
|
||||
|
||||
add_executable(${testcase} $<TARGET_OBJECTS:doctest_main> ${file})
|
||||
target_compile_definitions(${testcase} PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
|
||||
target_compile_options(${testcase} PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
||||
)
|
||||
target_include_directories(${testcase} PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
|
||||
target_link_libraries(${testcase} PRIVATE ${NLOHMANN_JSON_TARGET_NAME})
|
||||
add_library(test_main OBJECT src/unit.cpp)
|
||||
target_compile_definitions(test_main PUBLIC
|
||||
DOCTEST_CONFIG_SUPER_FAST_ASSERTS
|
||||
JSON_TEST_KEEP_MACROS
|
||||
)
|
||||
target_compile_features(test_main PRIVATE cxx_std_11)
|
||||
target_compile_options(test_main PUBLIC
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
||||
# 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
|
||||
if (compiler_supports_cpp_17)
|
||||
file(READ ${file} FILE_CONTENT)
|
||||
string(FIND "${FILE_CONTENT}" "JSON_HAS_CPP_17" CPP_17_FOUND)
|
||||
if(NOT ${CPP_17_FOUND} EQUAL -1)
|
||||
add_executable(${testcase}_cpp17 $<TARGET_OBJECTS:doctest_main> ${file})
|
||||
target_compile_definitions(${testcase}_cpp17 PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
|
||||
target_compile_options(${testcase}_cpp17 PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
||||
$<$<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)
|
||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
||||
)
|
||||
target_include_directories(test_main PUBLIC
|
||||
thirdparty/doctest
|
||||
thirdparty/fifo_map
|
||||
${PROJECT_BINARY_DIR}/include
|
||||
)
|
||||
target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME})
|
||||
|
||||
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
|
||||
target_link_libraries(${testcase}_cpp17 PRIVATE stdc++fs)
|
||||
endif()
|
||||
#############################################################################
|
||||
# define test- and standard-specific build settings
|
||||
#############################################################################
|
||||
|
||||
if (JSON_FastTests)
|
||||
add_test(NAME "${testcase}_cpp17"
|
||||
COMMAND ${testcase}_cpp17 ${DOCTEST_TEST_FILTER}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
else()
|
||||
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 (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
|
||||
json_test_set_test_options(all CXX_STANDARDS 17 LINK_LIBRARIES stdc++fs)
|
||||
endif()
|
||||
|
||||
if (JSON_FastTests)
|
||||
add_test(NAME "${testcase}"
|
||||
COMMAND ${testcase} ${DOCTEST_TEST_FILTER}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
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()
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
# avoid stack overflow, see https://github.com/nlohmann/json/issues/2955
|
||||
json_test_set_test_options("test-cbor;test-msgpack;test-ubjson" LINK_OPTIONS /STACK:4000000)
|
||||
endif()
|
||||
|
||||
# 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")
|
||||
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")
|
||||
# disabled due to https://github.com/nlohmann/json/discussions/2824
|
||||
#target_compile_options(test-disabled_exceptions PUBLIC /EH)
|
||||
#target_compile_definitions(test-disabled_exceptions PUBLIC _HAS_EXCEPTIONS=0)
|
||||
#json_test_set_test_options(test-disabled_exceptions COMPILE_DEFINITIONS _HAS_EXCEPTIONS=0 COMPILE_OPTIONS /EH)
|
||||
endif()
|
||||
|
||||
# avoid stack overflow, see https://github.com/nlohmann/json/issues/2955
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
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")
|
||||
#############################################################################
|
||||
# add unit tests
|
||||
#############################################################################
|
||||
|
||||
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()
|
||||
|
||||
# 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
|
||||
#############################################################################
|
||||
@ -170,4 +138,5 @@ endif()
|
||||
|
||||
add_subdirectory(cmake_add_subdirectory)
|
||||
add_subdirectory(cmake_fetch_content)
|
||||
add_subdirectory(cmake_fetch_content2)
|
||||
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>
|
||||
struct bad_allocator : std::allocator<T>
|
||||
{
|
||||
using std::allocator<T>::allocator;
|
||||
|
||||
template<class... Args>
|
||||
void construct(T* /*unused*/, Args&& ... /*unused*/)
|
||||
{
|
||||
|
||||
@ -37,7 +37,7 @@ SOFTWARE.
|
||||
|
||||
/* forward declarations */
|
||||
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);
|
||||
|
||||
/*
|
||||
@ -104,12 +104,12 @@ class alt_string
|
||||
}
|
||||
|
||||
template <typename op_type>
|
||||
bool operator<(const op_type& op) const
|
||||
bool operator<(const op_type& op) const noexcept
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -152,7 +152,7 @@ class alt_string
|
||||
private:
|
||||
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)
|
||||
@ -172,7 +172,7 @@ using alt_json = nlohmann::basic_json <
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1609,7 +1609,7 @@ TEST_CASE("CBOR")
|
||||
|
||||
// callback to set binary_seen to true if a binary value was seen
|
||||
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())
|
||||
{
|
||||
|
||||
@ -33,6 +33,12 @@ SOFTWARE.
|
||||
#include <nlohmann/json.hpp>
|
||||
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")
|
||||
{
|
||||
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);
|
||||
|
||||
// 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;
|
||||
};
|
||||
@ -1499,7 +1499,7 @@ TEST_CASE("parser class")
|
||||
|
||||
// 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;
|
||||
};
|
||||
@ -1538,14 +1538,14 @@ TEST_CASE("parser class")
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
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;
|
||||
});
|
||||
@ -1555,7 +1555,7 @@ TEST_CASE("parser class")
|
||||
|
||||
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;
|
||||
});
|
||||
@ -1563,7 +1563,7 @@ TEST_CASE("parser class")
|
||||
// the top-level object will be discarded, leaving a 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;
|
||||
});
|
||||
@ -1574,7 +1574,7 @@ TEST_CASE("parser class")
|
||||
|
||||
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
|
||||
return j != json(2);
|
||||
@ -1582,7 +1582,7 @@ TEST_CASE("parser class")
|
||||
|
||||
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);
|
||||
});
|
||||
@ -1601,7 +1601,7 @@ TEST_CASE("parser class")
|
||||
CHECK (j_filtered1.size() == 2);
|
||||
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;
|
||||
});
|
||||
@ -1616,7 +1616,7 @@ TEST_CASE("parser class")
|
||||
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;
|
||||
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;
|
||||
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
|
||||
// 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;
|
||||
});
|
||||
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;
|
||||
});
|
||||
@ -1731,7 +1731,7 @@ TEST_CASE("parser class")
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
@ -205,6 +205,14 @@ TEST_CASE("lexicographical comparison operators")
|
||||
{
|
||||
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(j)
|
||||
CAPTURE(j_values[i])
|
||||
|
||||
@ -41,13 +41,6 @@ using nlohmann::json;
|
||||
#include <unordered_set>
|
||||
#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
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
|
||||
|
||||
@ -32,13 +32,6 @@ SOFTWARE.
|
||||
#include <nlohmann/json.hpp>
|
||||
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.
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_PUSH
|
||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wrange-loop-construct")
|
||||
|
||||
@ -42,10 +42,6 @@ using nlohmann::json;
|
||||
#include <cstdio>
|
||||
#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
|
||||
#include <variant>
|
||||
#endif
|
||||
|
||||
@ -42,70 +42,8 @@ using ordered_json = nlohmann::ordered_json;
|
||||
#include <type_traits>
|
||||
#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
|
||||
#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
|
||||
|
||||
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
||||
@ -271,7 +209,10 @@ std::string* sax_no_exception::error_string = nullptr;
|
||||
|
||||
template<class T>
|
||||
class my_allocator : public std::allocator<T>
|
||||
{};
|
||||
{
|
||||
public:
|
||||
using std::allocator<T>::allocator;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
if (event == json::parse_event_t::value && !parsed.is_primitive())
|
||||
@ -653,7 +594,7 @@ TEST_CASE("regression tests 2")
|
||||
#ifdef JSON_HAS_CPP_20
|
||||
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));
|
||||
json j = json::parse(s);
|
||||
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>();
|
||||
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
|
||||
|
||||
@ -835,6 +777,18 @@ TEST_CASE("regression tests 2")
|
||||
|
||||
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
|
||||
|
||||
@ -1610,7 +1610,7 @@ TEST_CASE("UBJSON")
|
||||
CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
|
||||
|
||||
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;
|
||||
});
|
||||
@ -1624,7 +1624,7 @@ TEST_CASE("UBJSON")
|
||||
CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
@ -59,6 +59,42 @@ class person_with_private_data
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -103,6 +139,41 @@ class person_without_private_data_2
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -231,7 +302,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_with_public_alphabet, a, b, c, d, e, f
|
||||
|
||||
} // 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_without_private_data_1,
|
||||
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,
|
||||
persons::person_with_private_alphabet,
|
||||
persons::person_with_public_alphabet)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user