mirror of
https://github.com/nlohmann/json.git
synced 2026-10-07 15:07:13 +00:00
Compare commits
172
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66e72cc129 | ||
|
|
cf2af0396d | ||
|
|
44fba02ec2 | ||
|
|
42f8043413 | ||
|
|
606c1e710b | ||
|
|
fbacf1f1a8 | ||
|
|
173fbc0c90 | ||
|
|
2db0e307ca | ||
|
|
923917bb7d | ||
|
|
77730529ab | ||
|
|
e0c29a1dc4 | ||
|
|
93b772553f | ||
|
|
e4f4c767c0 | ||
|
|
1d49222f4e | ||
|
|
8b04885f59 | ||
|
|
d94a8d0a5a | ||
|
|
dfa17bd446 | ||
|
|
0b6a55ea6b | ||
|
|
5286c2843b | ||
|
|
3ba495ddf9 | ||
|
|
2739c0b0af | ||
|
|
471b35c5e8 | ||
|
|
e87813232f | ||
|
|
15b0cc0561 | ||
|
|
05afd8e8e0 | ||
|
|
c908630082 | ||
|
|
c99f99ccca | ||
|
|
268ef063d3 | ||
|
|
4068a5a4d8 | ||
|
|
e0ae5040dc | ||
|
|
f579e7e055 | ||
|
|
8f185c87f7 | ||
|
|
a43bfe645b | ||
|
|
f6b6aaf69f | ||
|
|
d62e3ec9c6 | ||
|
|
3cea705804 | ||
|
|
910fbb4b5c | ||
|
|
c8ec867991 | ||
|
|
2e06ccf0c7 | ||
|
|
f17207377b | ||
|
|
3b30446d1b | ||
|
|
960d3435a1 | ||
|
|
ceb1cdb774 | ||
|
|
80761cf255 | ||
|
|
eed512f1d5 | ||
|
|
3f672f036d | ||
|
|
83302ff69d | ||
|
|
4a93680068 | ||
|
|
1fdef286dc | ||
|
|
650f3c091e | ||
|
|
4dd4505e1c | ||
|
|
d3ba92d4fb | ||
|
|
89d6a7c2b5 | ||
|
|
95c8d2aa46 | ||
|
|
d38f5f111f | ||
|
|
057c86de8c | ||
|
|
448a90909e | ||
|
|
d9e4155ba1 | ||
|
|
7130880754 | ||
|
|
89bf08760f | ||
|
|
b1595c1b40 | ||
|
|
3d6d610fdc | ||
|
|
134b2f0efe | ||
|
|
dddb2d6e43 | ||
|
|
b59fc6c902 | ||
|
|
56cf446840 | ||
|
|
babae3f35d | ||
|
|
b3ce6fcce3 | ||
|
|
cff2af5966 | ||
|
|
ad248a3290 | ||
|
|
db73471df4 | ||
|
|
c6ac5c85c2 | ||
|
|
0e57b3fb28 | ||
|
|
d575be3e55 | ||
|
|
94c518f94d | ||
|
|
76ce7e2c84 | ||
|
|
5277335a9e | ||
|
|
05b6cd0892 | ||
|
|
95d10dab70 | ||
|
|
371a8a3d9f | ||
|
|
ae01d57694 | ||
|
|
6a757ca675 | ||
|
|
cb51f80e34 | ||
|
|
9d44e3f359 | ||
|
|
9d88ead578 | ||
|
|
414d378bb4 | ||
|
|
7e459c5366 | ||
|
|
0a97d94497 | ||
|
|
bee66ec810 | ||
|
|
1df24a0bd9 | ||
|
|
a279e6f4b9 | ||
|
|
b61c04bbe4 | ||
|
|
779ae7fffc | ||
|
|
a59d1f64e9 | ||
|
|
8db804ca8f | ||
|
|
a496c709f4 | ||
|
|
57bdb2f67f | ||
|
|
b6d6d4996a | ||
|
|
dcc81f43f0 | ||
|
|
467ccfd480 | ||
|
|
41233a5d41 | ||
|
|
383ce0b040 | ||
|
|
877241a51a | ||
|
|
d04f78864c | ||
|
|
51ee239b3c | ||
|
|
6e50766dc3 | ||
|
|
d4fab0971f | ||
|
|
eede67ca92 | ||
|
|
82b31f31b8 | ||
|
|
798f4c888a | ||
|
|
98258aa3af | ||
|
|
904c8c6710 | ||
|
|
1f0c3be6f3 | ||
|
|
c3b51addbf | ||
|
|
a91f6f489f | ||
|
|
9371f2b6c7 | ||
|
|
9deb721adc | ||
|
|
ecf9df7c45 | ||
|
|
b992e1f76a | ||
|
|
a7fa8d04e8 | ||
|
|
677507137b | ||
|
|
21d90fac1c | ||
|
|
e842f3a68f | ||
|
|
bc56ac6d9a | ||
|
|
bfb2b0cb48 | ||
|
|
8cccae029b | ||
|
|
c7e534d41e | ||
|
|
83d72fd7a7 | ||
|
|
da971a52c8 | ||
|
|
4c6a64507b | ||
|
|
c62aa8ac67 | ||
|
|
a7256deba3 | ||
|
|
3a4eddf4ac | ||
|
|
43e2d9c525 | ||
|
|
0650a48659 | ||
|
|
29bb5c48b8 | ||
|
|
e17e23a2b1 | ||
|
|
c2d7177d30 | ||
|
|
08dcdaf9b8 | ||
|
|
7dae258350 | ||
|
|
7da943c5c4 | ||
|
|
2d7024eed1 | ||
|
|
d71a494367 | ||
|
|
d9a71e7bc5 | ||
|
|
20d0723b67 | ||
|
|
06bebe2af6 | ||
|
|
723cf14be4 | ||
|
|
8c1b230277 | ||
|
|
061c30310e | ||
|
|
2f7d2548e1 | ||
|
|
ad73c78923 | ||
|
|
08e677ad61 | ||
|
|
d7c6c36979 | ||
|
|
cf352d4ef5 | ||
|
|
e96e2982a5 | ||
|
|
0a64e6c99b | ||
|
|
d8b8c2498f | ||
|
|
2fb66ba859 | ||
|
|
ab49a7b1bf | ||
|
|
154f240022 | ||
|
|
8d3280de1e | ||
|
|
118af5015e | ||
|
|
9b0b4ff26d | ||
|
|
694bfd1b4e | ||
|
|
ad82821c89 | ||
|
|
1bf0b1b6c2 | ||
|
|
b88e5f9107 | ||
|
|
d23803fd32 | ||
|
|
f1014c938a | ||
|
|
e91fdad877 | ||
|
|
9c71689715 | ||
|
|
44ec53c77b |
No files matched your search
@@ -205,9 +205,6 @@ API of the 3.x.y version is broken. This includes:
|
|||||||
- Changing access specifiers.
|
- Changing access specifiers.
|
||||||
- Changing default arguments.
|
- Changing default arguments.
|
||||||
|
|
||||||
What is and is not covered by this guarantee is described in the
|
|
||||||
[roadmap](https://json.nlohmann.me/community/roadmap/#api-stability).
|
|
||||||
|
|
||||||
Although these guidelines may seem restrictive, they are essential for maintaining the library’s utility.
|
Although these guidelines may seem restrictive, they are essential for maintaining the library’s utility.
|
||||||
|
|
||||||
Breaking changes may be introduced when they are guarded with a feature macro such as
|
Breaking changes may be introduced when they are guarded with a feature macro such as
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ only_commits:
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
# The Visual Studio 2017 jobs compile everything with /std:c++17, so they
|
|
||||||
# only build the C++17 variant of each test, split into two jobs each to
|
|
||||||
# stay below AppVeyor's 60-minute limit per job.
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
configuration: Debug
|
configuration: Debug
|
||||||
platform: x86
|
platform: x86
|
||||||
@@ -37,13 +34,7 @@ environment:
|
|||||||
configuration: Release
|
configuration: Release
|
||||||
platform: x86
|
platform: x86
|
||||||
CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX"
|
CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX"
|
||||||
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=0/2"
|
CMAKE_OPTIONS: ""
|
||||||
GENERATOR: Visual Studio 15 2017
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
|
||||||
configuration: Release
|
|
||||||
platform: x86
|
|
||||||
CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX"
|
|
||||||
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=1/2"
|
|
||||||
GENERATOR: Visual Studio 15 2017
|
GENERATOR: Visual Studio 15 2017
|
||||||
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||||
@@ -64,13 +55,7 @@ environment:
|
|||||||
configuration: Release
|
configuration: Release
|
||||||
platform: x64
|
platform: x64
|
||||||
CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX"
|
CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX"
|
||||||
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=0/2"
|
CMAKE_OPTIONS: ""
|
||||||
GENERATOR: Visual Studio 15 2017
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
|
||||||
configuration: Release
|
|
||||||
platform: x64
|
|
||||||
CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX"
|
|
||||||
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=1/2"
|
|
||||||
GENERATOR: Visual Studio 15 2017
|
GENERATOR: Visual Studio 15 2017
|
||||||
|
|
||||||
init:
|
init:
|
||||||
@@ -81,10 +66,15 @@ install:
|
|||||||
- if "%platform%"=="x86" set GENERATOR_PLATFORM=Win32
|
- if "%platform%"=="x86" set GENERATOR_PLATFORM=Win32
|
||||||
|
|
||||||
before_build:
|
before_build:
|
||||||
- cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On %CMAKE_OPTIONS%
|
- cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On "%CMAKE_OPTIONS%"
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- cmake --build . --config "%configuration%" --parallel 2
|
- cmake --build . --config "%configuration%" --parallel 2
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- ctest -C "%configuration%" --parallel 2 --output-on-failure
|
- if "%configuration%"=="Release" ctest -C "%configuration%" --parallel 2 --output-on-failure
|
||||||
|
# On Debug builds, skip test-unicode_all
|
||||||
|
# as it is extremely slow to run and cause
|
||||||
|
# occasional timeouts on AppVeyor.
|
||||||
|
# More info: https://github.com/nlohmann/json/pull/1570
|
||||||
|
- if "%configuration%"=="Debug" ctest --exclude-regex "test-unicode" -C "%configuration%" --parallel 2 --output-on-failure
|
||||||
+4
-3
@@ -51,12 +51,13 @@ labels:
|
|||||||
- "include/nlohmann/detail/view/.*"
|
- "include/nlohmann/detail/view/.*"
|
||||||
- "single_include/nlohmann/json_view\\.hpp"
|
- "single_include/nlohmann/json_view\\.hpp"
|
||||||
- "tests/src/unit-json_view.*"
|
- "tests/src/unit-json_view.*"
|
||||||
- "tests/src/fuzzer-parse_json_view\\.cpp"
|
- "tests/src/fuzzer-(parse_json_view|json_view_image)\\.cpp"
|
||||||
|
- "tests/benchmarks/json_view/.*"
|
||||||
- "tools/amalgamate/config_json_view\\.json"
|
- "tools/amalgamate/config_json_view\\.json"
|
||||||
- "docs/mkdocs/docs/features/json_view\\.md"
|
- "docs/mkdocs/docs/features/json_view\\.md"
|
||||||
- "docs/mkdocs/docs/api/basic_json_(document|view)/.*"
|
- "docs/mkdocs/docs/api/basic_json_(document|view)/.*"
|
||||||
- "docs/mkdocs/docs/api/(ordered_)?json_(document|view)\\.md"
|
- "docs/mkdocs/docs/api/(ordered_)?json_(editable_)?(document|view)\\.md"
|
||||||
- "docs/mkdocs/docs/examples/(basic_json_(document|view)__|(ordered_)?json_(document|view)).*"
|
- "docs/mkdocs/docs/examples/(basic_json_(document|view)__|(ordered_)?json_(editable_)?(document|view)).*"
|
||||||
- "tests/benchmarks/src/benchmarks_view\\.cpp"
|
- "tests/benchmarks/src/benchmarks_view\\.cpp"
|
||||||
|
|
||||||
- label: "aspect: json_view"
|
- label: "aspect: json_view"
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
name: "json_view benchmarks"
|
||||||
|
|
||||||
|
# On demand only: runs the comparison of json_view with yyjson, simdjson, and
|
||||||
|
# Boost.JSON (tests/benchmarks/json_view/compare.py) on GitHub-hosted runners,
|
||||||
|
# for numbers from x86-64 and AArch64 Linux. It runs when started by hand, or
|
||||||
|
# when a pull request gets the label "benchmark" (on both architectures, with
|
||||||
|
# GCC and the default settings). Shared runners are noisy: the results show
|
||||||
|
# where json_view stands, but published numbers need a quiet machine (see
|
||||||
|
# tests/benchmarks/json_view/README.md).
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [labeled]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
runner:
|
||||||
|
description: "Runner image"
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- ubuntu-24.04
|
||||||
|
- ubuntu-24.04-arm
|
||||||
|
default: ubuntu-24.04
|
||||||
|
compiler:
|
||||||
|
description: "Compiler"
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- g++
|
||||||
|
- clang++
|
||||||
|
default: g++
|
||||||
|
native:
|
||||||
|
description: "Compile for the runner's CPU (-march=native)"
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
rounds:
|
||||||
|
description: "Rounds of bench_view"
|
||||||
|
type: number
|
||||||
|
default: 30
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
compare:
|
||||||
|
if: github.event_name == 'workflow_dispatch' || github.event.label.name == 'benchmark'
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
runner: ${{ fromJSON(github.event_name == 'workflow_dispatch' && format('["{0}"]', inputs.runner) || '["ubuntu-24.04", "ubuntu-24.04-arm"]') }}
|
||||||
|
runs-on: ${{ matrix.runner }}
|
||||||
|
steps:
|
||||||
|
- name: Harden Runner
|
||||||
|
uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
|
||||||
|
with:
|
||||||
|
egress-policy: audit
|
||||||
|
|
||||||
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Download test data
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build -DJSON_BuildTests=On
|
||||||
|
cmake --build build --target download_test_data
|
||||||
|
|
||||||
|
- name: Run the comparison
|
||||||
|
env:
|
||||||
|
CXX: ${{ inputs.compiler || 'g++' }}
|
||||||
|
CC: ${{ inputs.compiler == 'clang++' && 'clang' || 'gcc' }}
|
||||||
|
ROUNDS: ${{ inputs.rounds || 30 }}
|
||||||
|
NATIVE: ${{ inputs.native && '--native' || '' }}
|
||||||
|
run: python3 tests/benchmarks/json_view/compare.py --data build/test_files --download --rounds "$ROUNDS" $NATIVE
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
|
run: cat tests/benchmarks/json_view/results/*.md >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
|
with:
|
||||||
|
name: json_view-benchmarks-${{ matrix.runner }}-${{ inputs.compiler || 'g++' }}
|
||||||
|
path: tests/benchmarks/json_view/results/
|
||||||
@@ -17,11 +17,11 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
macos-15:
|
macos-14:
|
||||||
runs-on: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
|
runs-on: macos-14 # https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
xcode: ['16.0', '16.1', '16.2', '16.3', '16.4', '26.0.1', '26.1.1', '26.2', '26.3']
|
xcode: ['15.0.1', '15.1', '15.2', '15.3', '15.4']
|
||||||
env:
|
env:
|
||||||
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
||||||
|
|
||||||
@@ -36,11 +36,11 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
run: cd build ; ctest -j 10 --output-on-failure
|
run: cd build ; ctest -j 10 --output-on-failure
|
||||||
|
|
||||||
macos-26:
|
macos-15:
|
||||||
runs-on: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
|
runs-on: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
xcode: ['26.4.1', '26.5', '26.6']
|
xcode: ['16.0', '16.1', '16.2', '16.3', '16.4', '26.0.1']
|
||||||
env:
|
env:
|
||||||
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
||||||
|
|
||||||
@@ -71,38 +71,3 @@ jobs:
|
|||||||
run: cmake --build build --parallel 10
|
run: cmake --build build --parallel 10
|
||||||
- name: Test
|
- name: Test
|
||||||
run: cd build ; ctest -j 10 --output-on-failure
|
run: cd build ; ctest -j 10 --output-on-failure
|
||||||
|
|
||||||
swiftpm:
|
|
||||||
runs-on: macos-15
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
- name: Check that Package.swift resolves without a deprecation warning
|
|
||||||
run: swift package dump-package
|
|
||||||
- name: Build the SwiftPM documentation example against this checkout
|
|
||||||
run: |
|
|
||||||
mkdir -p /tmp/json-swiftpm-consumer/Sources/MyLibrary
|
|
||||||
cp docs/mkdocs/docs/integration/swift/example.cpp /tmp/json-swiftpm-consumer/Sources/MyLibrary/example.cpp
|
|
||||||
cat > /tmp/json-swiftpm-consumer/Package.swift << EOF
|
|
||||||
// swift-tools-version: 5.9
|
|
||||||
import PackageDescription
|
|
||||||
|
|
||||||
let package = Package(
|
|
||||||
name: "MyPackage",
|
|
||||||
dependencies: [
|
|
||||||
.package(path: "${{ github.workspace }}")
|
|
||||||
],
|
|
||||||
targets: [
|
|
||||||
.target(
|
|
||||||
name: "MyLibrary",
|
|
||||||
dependencies: [
|
|
||||||
.product(name: "json", package: "json")
|
|
||||||
],
|
|
||||||
publicHeadersPath: "."
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
EOF
|
|
||||||
cd /tmp/json-swiftpm-consumer
|
|
||||||
swift build
|
|
||||||
@@ -107,7 +107,7 @@ jobs:
|
|||||||
container: ubuntu:24.04
|
container: ubuntu:24.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_delete_deprecated_functions, ci_test_no_thread_local]
|
target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_no_thread_local]
|
||||||
steps:
|
steps:
|
||||||
- name: Install build-essential
|
- name: Install build-essential
|
||||||
run: apt-get update ; apt-get install -y build-essential unzip wget git
|
run: apt-get update ; apt-get install -y build-essential unzip wget git
|
||||||
@@ -209,7 +209,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
# older GCC docker images (4, 5, 6) fail to check out code
|
# older GCC docker images (4, 5, 6) fail to check out code
|
||||||
compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', '16', 'latest']
|
compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', 'latest']
|
||||||
container: gcc:${{ matrix.compiler }}
|
container: gcc:${{ matrix.compiler }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build build --parallel 10
|
run: cmake --build build --parallel 10
|
||||||
- name: Test
|
- name: Test
|
||||||
run: cd build ; ctest -j 10 -C Debug --output-on-failure
|
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
|
||||||
|
|
||||||
clang-cl-12:
|
clang-cl-12:
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
@@ -195,7 +195,7 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build build --config Debug --parallel 10
|
run: cmake --build build --config Debug --parallel 10
|
||||||
- name: Test
|
- name: Test
|
||||||
run: cd build ; ctest -j 10 -C Debug --output-on-failure
|
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
|
||||||
|
|
||||||
ci_module_cpp20:
|
ci_module_cpp20:
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_comment": "Used by the ci_infer CMake target (#5715 item 4b). fail-on-issue makes CI fail on Infer findings; disable-issue-type is a type-level baseline for the ~174 pre-existing findings (all PULSE_UNNECESSARY_COPY*/PULSE_RESOURCE_LEAK/PULSE_CONST_REFABLE, mostly in test code) triaged in run https://github.com/nlohmann/json/actions/runs/35829411620 on commit 1054b2097, so CI fails only on a NEW issue type. Remove an entry here once its findings have been fixed or explicitly accepted.",
|
"_comment": "Used by the ci_infer CMake target (#5715 item 4b). fail-on-issue makes CI fail on Infer findings; disable-issue-type is a type-level baseline for the ~174 pre-existing findings (all PULSE_UNNECESSARY_COPY*/PULSE_RESOURCE_LEAK/PULSE_CONST_REFABLE, mostly in test code) triaged in run https://github.com/nlohmann/json/actions/runs/35829411620 on commit 1054b2097, so CI fails only on a NEW issue type. Remove an entry here once its findings have been fixed or explicitly accepted.",
|
||||||
"_comment_pulse": "Pulse stops exploring paths after pulse-max-disjuncts (default 20). With the default, basic_json::replace_value() (destroy + assert_invariant) exceeds the limit, Pulse loses the stored type, and reports false NULLPTR_DEREFERENCE findings for get_ptr() results in tests/src/unit-pointer_access.cpp.",
|
|
||||||
"pulse-max-disjuncts": 40,
|
|
||||||
"fail-on-issue": true,
|
"fail-on-issue": true,
|
||||||
"disable-issue-type": [
|
"disable-issue-type": [
|
||||||
"PULSE_UNNECESSARY_COPY_ASSIGNMENT",
|
"PULSE_UNNECESSARY_COPY_ASSIGNMENT",
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: json
|
||||||
|
Upstream-Contact: Niels Lohmann <mail@nlohmann.me>
|
||||||
|
Source: https://github.com/nlohmann/json
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
Files: include/nlohmann/thirdparty/hedley.hpp
|
||||||
|
Copyright: 2016-2021 Evan Nemerson <evan@nemerson.com>
|
||||||
|
License: CC0
|
||||||
|
|
||||||
|
Files: include/nlohmann/detail/meta/cpp_future.hpp
|
||||||
|
Copyright: 2013-2026 Niels Lohmann <https://nlohmann.me> and 2018 The Abseil Authors
|
||||||
|
License: MIT AND Apache-2.0
|
||||||
|
|
||||||
|
Files: tests/thirdparty/doctest/*
|
||||||
|
Copyright: 2016-2023 Viktor Kirilov
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
Files: tests/thirdparty/fifo_map/*
|
||||||
|
Copyright: 2015-2017 Niels Lohmann
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
Files: tests/thirdparty/imapdl/*
|
||||||
|
Copyright: 2017 Georg Sauthoff <mail@gms.tf>
|
||||||
|
License: GPL-3.0-only
|
||||||
|
|
||||||
|
Files: tools/amalgamate/*
|
||||||
|
Copyright: 2012 Erik Edlund <erik.edlund@32767.se>
|
||||||
|
License: BSD-3-Clause
|
||||||
|
|
||||||
|
Files: tools/gdb_pretty_printer/*
|
||||||
|
Copyright: 2020 Hannes Domani <https://github.com/ssbssa>
|
||||||
|
License: MIT
|
||||||
+3
-1
@@ -70,7 +70,10 @@ cc_library(
|
|||||||
"include/nlohmann/detail/view/builder.hpp",
|
"include/nlohmann/detail/view/builder.hpp",
|
||||||
"include/nlohmann/detail/view/compare.hpp",
|
"include/nlohmann/detail/view/compare.hpp",
|
||||||
"include/nlohmann/detail/view/document_data.hpp",
|
"include/nlohmann/detail/view/document_data.hpp",
|
||||||
|
"include/nlohmann/detail/view/edit.hpp",
|
||||||
|
"include/nlohmann/detail/view/edit_storage.hpp",
|
||||||
"include/nlohmann/detail/view/errors.hpp",
|
"include/nlohmann/detail/view/errors.hpp",
|
||||||
|
"include/nlohmann/detail/view/image.hpp",
|
||||||
"include/nlohmann/detail/view/input.hpp",
|
"include/nlohmann/detail/view/input.hpp",
|
||||||
"include/nlohmann/detail/view/iterator.hpp",
|
"include/nlohmann/detail/view/iterator.hpp",
|
||||||
"include/nlohmann/detail/view/lookup.hpp",
|
"include/nlohmann/detail/view/lookup.hpp",
|
||||||
@@ -102,7 +105,6 @@ cc_library(
|
|||||||
name = "singleheader-json",
|
name = "singleheader-json",
|
||||||
hdrs = [
|
hdrs = [
|
||||||
"single_include/nlohmann/json.hpp",
|
"single_include/nlohmann/json.hpp",
|
||||||
"single_include/nlohmann/json_fwd.hpp",
|
|
||||||
"single_include/nlohmann/json_view.hpp",
|
"single_include/nlohmann/json_view.hpp",
|
||||||
],
|
],
|
||||||
includes = ["single_include"],
|
includes = ["single_include"],
|
||||||
|
|||||||
+1
-1
@@ -10,5 +10,5 @@ title: "JSON for Modern C++"
|
|||||||
version: 3.12.0
|
version: 3.12.0
|
||||||
date-released: 2025-04-07
|
date-released: 2025-04-07
|
||||||
license: MIT
|
license: MIT
|
||||||
repository-code: "https://github.com/nlohmann/json"
|
repository-code: "https://github.com/nlohmann"
|
||||||
url: https://json.nlohmann.me
|
url: https://json.nlohmann.me
|
||||||
+1
-10
@@ -42,11 +42,8 @@ endif()
|
|||||||
## OPTIONS
|
## OPTIONS
|
||||||
##
|
##
|
||||||
|
|
||||||
# Build the tests by default only for the main project and only if the tests
|
|
||||||
# directory exists (the release archive json.tar.xz does not contain it).
|
|
||||||
# VERSION_GREATER_EQUAL is not available in older CMake (< 3.7)
|
# VERSION_GREATER_EQUAL is not available in older CMake (< 3.7)
|
||||||
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13)
|
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13))
|
||||||
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
|
|
||||||
set(JSON_BuildTests_INIT ON)
|
set(JSON_BuildTests_INIT ON)
|
||||||
else()
|
else()
|
||||||
set(JSON_BuildTests_INIT OFF)
|
set(JSON_BuildTests_INIT OFF)
|
||||||
@@ -65,7 +62,6 @@ option(JSON_MultipleHeaders "Use non-amalgamated version of the l
|
|||||||
option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF)
|
option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF)
|
||||||
option(JSON_StrictNulHandling "Build with strict NUL-byte handling enabled." OFF)
|
option(JSON_StrictNulHandling "Build with strict NUL-byte handling enabled." OFF)
|
||||||
option(JSON_StrictBinaryUTF8 "Build with UTF-8 checks in the CBOR, UBJSON, BJData, and BSON writers enabled." OFF)
|
option(JSON_StrictBinaryUTF8 "Build with UTF-8 checks in the CBOR, UBJSON, BJData, and BSON writers enabled." OFF)
|
||||||
option(JSON_DeleteDeprecatedFunctions "Delete the deprecated functions instead of only deprecating them." OFF)
|
|
||||||
|
|
||||||
if (JSON_CI)
|
if (JSON_CI)
|
||||||
include(ci)
|
include(ci)
|
||||||
@@ -127,10 +123,6 @@ if (JSON_StrictBinaryUTF8)
|
|||||||
message(STATUS "Strict UTF-8 checks in binary writers enabled (JSON_STRICT_BINARY_UTF8=1)")
|
message(STATUS "Strict UTF-8 checks in binary writers enabled (JSON_STRICT_BINARY_UTF8=1)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (JSON_DeleteDeprecatedFunctions)
|
|
||||||
message(STATUS "Deprecated functions are deleted (JSON_DELETE_DEPRECATED_FUNCTIONS=1)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (JSON_Diagnostic_Positions)
|
if (JSON_Diagnostic_Positions)
|
||||||
message(STATUS "Diagnostic positions enabled (JSON_DIAGNOSTIC_POSITIONS=1)")
|
message(STATUS "Diagnostic positions enabled (JSON_DIAGNOSTIC_POSITIONS=1)")
|
||||||
endif()
|
endif()
|
||||||
@@ -167,7 +159,6 @@ target_compile_definitions(
|
|||||||
$<$<BOOL:${JSON_LegacyDiscardedValueComparison}>:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1>
|
$<$<BOOL:${JSON_LegacyDiscardedValueComparison}>:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1>
|
||||||
$<$<BOOL:${JSON_StrictNulHandling}>:JSON_STRICT_NUL_HANDLING=1>
|
$<$<BOOL:${JSON_StrictNulHandling}>:JSON_STRICT_NUL_HANDLING=1>
|
||||||
$<$<BOOL:${JSON_StrictBinaryUTF8}>:JSON_STRICT_BINARY_UTF8=1>
|
$<$<BOOL:${JSON_StrictBinaryUTF8}>:JSON_STRICT_BINARY_UTF8=1>
|
||||||
$<$<BOOL:${JSON_DeleteDeprecatedFunctions}>:JSON_DELETE_DEPRECATED_FUNCTIONS=1>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
|
|||||||
@@ -196,19 +196,19 @@ Further documentation:
|
|||||||
|
|
||||||
## REUSE
|
## REUSE
|
||||||
|
|
||||||
### `REUSE.toml`
|
### `.reuse/dep5`
|
||||||
|
|
||||||
The file defines the licenses of certain third-party components in the repository. The root `Makefile` contains a target `reuse` that checks for compliance.
|
The file defines the licenses of certain third-party components in the repository. The root `Makefile` contains a target `reuse` that checks for compliance.
|
||||||
|
|
||||||
Further documentation:
|
Further documentation:
|
||||||
|
|
||||||
- [REUSE.toml](https://reuse.software/spec-3.3/#reusetoml)
|
- [DEP5](https://reuse.software/spec-3.2/#dep5-deprecated)
|
||||||
- [reuse command-line tool](https://pypi.org/project/reuse/)
|
- [reuse command-line tool](https://pypi.org/project/reuse/)
|
||||||
- [documentation of linting](https://reuse.readthedocs.io/en/stable/man/reuse-lint.html)
|
- [documentation of linting](https://reuse.readthedocs.io/en/stable/man/reuse-lint.html)
|
||||||
- [REUSE](http://reuse.software)
|
- [REUSE](http://reuse.software)
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> The filename `REUSE.toml` is predetermined by REUSE. Alternatively, a `.reuse/dep5` file (deprecated) can be used.
|
> The filename `.reuse/dep5` is predetermined by REUSE. Alternatively, a `REUSE.toml` file can be used.
|
||||||
|
|
||||||
### `.reuse/templates`
|
### `.reuse/templates`
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,6 @@
|
|||||||
# find GNU sed to use `-i` parameter
|
# find GNU sed to use `-i` parameter
|
||||||
SED:=$(shell command -v gsed || which sed)
|
SED:=$(shell command -v gsed || which sed)
|
||||||
|
|
||||||
# find GNU tar to use `--sort` and `--pax-option` parameters
|
|
||||||
TAR:=$(shell command -v gtar || which tar)
|
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# source files
|
# source files
|
||||||
@@ -184,8 +181,8 @@ ChangeLog.md:
|
|||||||
# archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>.
|
# archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>.
|
||||||
json.tar.xz:
|
json.tar.xz:
|
||||||
mkdir json
|
mkdir json
|
||||||
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include src/modules -type f) json
|
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include -type f) json
|
||||||
$(TAR) --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
|
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
|
rm -fr json
|
||||||
|
|
||||||
# We use `-X` to make the resulting ZIP file reproducible, see
|
# We use `-X` to make the resulting ZIP file reproducible, see
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import PackageDescription
|
|||||||
let package = Package(
|
let package = Package(
|
||||||
name: "nlohmann-json",
|
name: "nlohmann-json",
|
||||||
platforms: [
|
platforms: [
|
||||||
.iOS(.v12), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v9), .visionOS(.v1)
|
.iOS(.v12), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v4), .visionOS(.v1)
|
||||||
],
|
],
|
||||||
products: [
|
products: [
|
||||||
.library(name: "json", targets: ["json"])
|
.library(name: "json", targets: ["json"])
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
[](https://coveralls.io/github/nlohmann/json?branch=develop)
|
[](https://coveralls.io/github/nlohmann/json?branch=develop)
|
||||||
[](https://scan.coverity.com/projects/nlohmann-json)
|
[](https://scan.coverity.com/projects/nlohmann-json)
|
||||||
[](https://app.codacy.com/gh/nlohmann/json/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
[](https://app.codacy.com/gh/nlohmann/json/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
||||||
[](https://issues.oss-fuzz.com/issues?q=project:json)
|
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json)
|
||||||
[](https://wandbox.org/permlink/1mp10JbaANo6FUc7)
|
[](https://wandbox.org/permlink/1mp10JbaANo6FUc7)
|
||||||
[](https://json.nlohmann.me)
|
[](https://json.nlohmann.me)
|
||||||
[](https://raw.githubusercontent.com/nlohmann/json/develop/LICENSE.MIT)
|
[](https://raw.githubusercontent.com/nlohmann/json/develop/LICENSE.MIT)
|
||||||
@@ -1210,18 +1210,15 @@ language bindings, format converters, and the like. See the curated [Ecosystem](
|
|||||||
|
|
||||||
Though it's 2026 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
|
Though it's 2026 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
|
||||||
|
|
||||||
- GCC 4.8 - 16.2 (and possibly later)
|
- GCC 4.8 - 14.2 (and possibly later)
|
||||||
- Clang 3.4 - 22.1 (and possibly later)
|
- Clang 3.4 - 21.0 (and possibly later)
|
||||||
- Apple Clang 15.0 - 21.0 (and possibly later)
|
- Apple Clang 9.1 - 16.0 (and possibly later)
|
||||||
- Intel C++ Compiler Classic (icpc) 2021.10
|
- Intel C++ Compiler 17.0.2 (and possibly later)
|
||||||
- Intel oneAPI DPC++/C++ Compiler (icpx) 2025.3 (and possibly later)
|
- Nvidia CUDA Compiler 11.0.221 (and possibly later)
|
||||||
- NVIDIA CUDA Compiler (nvcc) 11.8 - 12.6 (and possibly later)
|
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
|
||||||
- NVIDIA HPC SDK C++ Compiler (nvc++) 25.5 (and possibly later)
|
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
|
||||||
- Microsoft Visual C++ 2015 / MSVC 19.0 (and possibly later)
|
- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)
|
||||||
- Microsoft Visual C++ 2017 / MSVC 19.16 (and possibly later)
|
- Microsoft Visual C++ 2022 / Build Tools 19.30.30709.0 (and possibly later)
|
||||||
- Microsoft Visual C++ 2019 / MSVC 19.29 (and possibly later)
|
|
||||||
- Microsoft Visual C++ 2022 / MSVC 19.44 (and possibly later)
|
|
||||||
- Microsoft Visual C++ 2026 / MSVC 19.51 (and possibly later)
|
|
||||||
|
|
||||||
I would be happy to learn about other compilers/versions.
|
I would be happy to learn about other compilers/versions.
|
||||||
|
|
||||||
@@ -1415,7 +1412,7 @@ The library is compliant to version 3.3 of the [**REUSE specification**](https:/
|
|||||||
|
|
||||||
- Every source file contains an SPDX copyright header.
|
- Every source file contains an SPDX copyright header.
|
||||||
- The full text of all licenses used in the repository can be found in the `LICENSES` folder.
|
- The full text of all licenses used in the repository can be found in the `LICENSES` folder.
|
||||||
- File `REUSE.toml` contains an overview of all files' copyrights and licenses.
|
- File `.reuse/dep5` contains an overview of all files' copyrights and licenses.
|
||||||
- Run `pipx run reuse lint` to verify the project's REUSE compliance and `pipx run reuse spdx` to generate a SPDX SBOM.
|
- Run `pipx run reuse lint` to verify the project's REUSE compliance and `pipx run reuse spdx` to generate a SPDX SBOM.
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|||||||
-52
@@ -1,52 +0,0 @@
|
|||||||
version = 1
|
|
||||||
SPDX-PackageName = "json"
|
|
||||||
SPDX-PackageSupplier = "Niels Lohmann <mail@nlohmann.me>"
|
|
||||||
SPDX-PackageDownloadLocation = "https://github.com/nlohmann/json"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me>"
|
|
||||||
SPDX-License-Identifier = "MIT"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "include/nlohmann/thirdparty/hedley.hpp"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2016-2021 Evan Nemerson <evan@nemerson.com>"
|
|
||||||
SPDX-License-Identifier = "CC0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "include/nlohmann/detail/meta/cpp_future.hpp"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me> and 2018 The Abseil Authors"
|
|
||||||
SPDX-License-Identifier = "MIT AND Apache-2.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tests/thirdparty/doctest/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2016-2023 Viktor Kirilov"
|
|
||||||
SPDX-License-Identifier = "MIT"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tests/thirdparty/fifo_map/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2015-2017 Niels Lohmann"
|
|
||||||
SPDX-License-Identifier = "MIT"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tests/thirdparty/imapdl/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2017 Georg Sauthoff <mail@gms.tf>"
|
|
||||||
SPDX-License-Identifier = "GPL-3.0-only"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tools/amalgamate/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2012 Erik Edlund <erik.edlund@32767.se>"
|
|
||||||
SPDX-License-Identifier = "BSD-3-Clause"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tools/gdb_pretty_printer/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2020 Hannes Domani <https://github.com/ssbssa>"
|
|
||||||
SPDX-License-Identifier = "MIT"
|
|
||||||
+8
-23
@@ -249,20 +249,6 @@ add_custom_target(ci_test_strict_nul_handling
|
|||||||
COMMENT "Compile and test with strict NUL-byte handling enabled"
|
COMMENT "Compile and test with strict NUL-byte handling enabled"
|
||||||
)
|
)
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Delete the deprecated functions.
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
add_custom_target(ci_test_delete_deprecated_functions
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
|
||||||
-DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_DeleteDeprecatedFunctions=ON
|
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_delete_deprecated_functions
|
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_delete_deprecated_functions
|
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_delete_deprecated_functions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
|
||||||
COMMENT "Compile and test with the deprecated functions deleted"
|
|
||||||
)
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Disable global UDLs.
|
# Disable global UDLs.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -376,7 +362,7 @@ add_custom_target(ci_test_coverage
|
|||||||
# Sanitizers.
|
# Sanitizers.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base -fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/cmake/clang_sanitizer_ignorelist.txt")
|
set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base")
|
||||||
|
|
||||||
add_custom_target(ci_test_clang_sanitizer
|
add_custom_target(ci_test_clang_sanitizer
|
||||||
COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND}
|
COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND}
|
||||||
@@ -459,14 +445,13 @@ add_custom_target(ci_test_single_header
|
|||||||
# Valgrind.
|
# Valgrind.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
# The Unicode test (~17M assertions) is too slow under Valgrind.
|
|
||||||
add_custom_target(ci_test_valgrind
|
add_custom_target(ci_test_valgrind
|
||||||
COMMAND CXX=${GCC_TOOL} ${CMAKE_COMMAND}
|
COMMAND CXX=${GCC_TOOL} ${CMAKE_COMMAND}
|
||||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||||
-DJSON_BuildTests=ON -DJSON_Valgrind=ON
|
-DJSON_BuildTests=ON -DJSON_Valgrind=ON
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_valgrind
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_valgrind
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_valgrind
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_valgrind
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_valgrind && ${CMAKE_CTEST_COMMAND} -L valgrind --exclude-regex "test-unicode" --parallel ${N} --output-on-failure
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_valgrind && ${CMAKE_CTEST_COMMAND} -L valgrind --parallel ${N} --output-on-failure
|
||||||
COMMENT "Compile and test with Valgrind"
|
COMMENT "Compile and test with Valgrind"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -723,7 +708,7 @@ ci_get_cmake(4.0.0 CMAKE_4_0_0_BINARY)
|
|||||||
# the tests require CMake 3.13 or later, so they are excluded for CMake 3.5.0
|
# the tests require CMake 3.13 or later, so they are excluded for CMake 3.5.0
|
||||||
set(JSON_CMAKE_FLAGS_3_5_0 JSON_Diagnostics JSON_Diagnostic_Positions JSON_GlobalUDLs JSON_ImplicitConversions JSON_DisableEnumSerialization
|
set(JSON_CMAKE_FLAGS_3_5_0 JSON_Diagnostics JSON_Diagnostic_Positions JSON_GlobalUDLs JSON_ImplicitConversions JSON_DisableEnumSerialization
|
||||||
JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind
|
JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind
|
||||||
JSON_StrictNulHandling JSON_StrictBinaryUTF8 JSON_DeleteDeprecatedFunctions)
|
JSON_StrictNulHandling JSON_StrictBinaryUTF8)
|
||||||
set(JSON_CMAKE_FLAGS_3_31_6 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
|
set(JSON_CMAKE_FLAGS_3_31_6 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
|
||||||
set(JSON_CMAKE_FLAGS_4_0_0 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
|
set(JSON_CMAKE_FLAGS_4_0_0 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
|
||||||
|
|
||||||
@@ -791,7 +776,7 @@ foreach(COMPILER g++-4.8 g++-4.9 g++-5 g++-6 g++-7 g++-8 g++-9 g++-10 g++-11 cla
|
|||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
|
||||||
${ADDITIONAL_FLAGS}
|
${ADDITIONAL_FLAGS}
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure
|
||||||
COMMENT "Compile and test with ${COMPILER}"
|
COMMENT "Compile and test with ${COMPILER}"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@@ -805,7 +790,7 @@ add_custom_target(ci_test_compiler_default
|
|||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_default
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_default
|
||||||
${ADDITIONAL_FLAGS}
|
${ADDITIONAL_FLAGS}
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_default --parallel ${N}
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_default --parallel ${N}
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_default && ${CMAKE_CTEST_COMMAND} --parallel ${N} -LE git_required --output-on-failure
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_default && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" -LE git_required --output-on-failure
|
||||||
COMMENT "Compile and test with default C++ compiler"
|
COMMENT "Compile and test with default C++ compiler"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -843,7 +828,7 @@ add_custom_target(ci_icpc
|
|||||||
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_icpc
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_icpc
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_icpc
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_icpc
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_icpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_icpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure
|
||||||
COMMENT "Compile and test with ICPC"
|
COMMENT "Compile and test with ICPC"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -854,7 +839,7 @@ add_custom_target(ci_icpx
|
|||||||
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_icpx
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_icpx
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_icpx
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_icpx
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_icpx && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_icpx && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure
|
||||||
COMMENT "Compile and test with ICPX (Intel oneAPI DPC++/C++)"
|
COMMENT "Compile and test with ICPX (Intel oneAPI DPC++/C++)"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -890,7 +875,7 @@ add_custom_target(ci_nvhpc
|
|||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_nvhpc
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_nvhpc
|
||||||
# the pipes are escaped so the surrounding shell passes them to ctest verbatim
|
# the pipes are escaped so the surrounding shell passes them to ctest verbatim
|
||||||
# instead of treating them as shell pipe operators
|
# instead of treating them as shell pipe operators
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_nvhpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-comparison_cpp20\\|test-comparison_legacy_cpp20\\|test-constructor1_cpp11\\|test-deserialization_cpp20" --output-on-failure
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_nvhpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode\\|test-comparison_cpp20\\|test-comparison_legacy_cpp20\\|test-constructor1_cpp11\\|test-deserialization_cpp20" --output-on-failure
|
||||||
COMMENT "Compile and test with NVIDIA HPC SDK (nvc++)"
|
COMMENT "Compile and test with NVIDIA HPC SDK (nvc++)"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
# Sanitizer ignore list for ci_test_clang_sanitizer (-fsanitize-ignorelist).
|
|
||||||
#
|
|
||||||
# libstdc++ 14's <format> declares `_Scanner(basic_string_view<_CharT>, size_t __nargs = -1)`, so every std::format
|
|
||||||
# call converts -1 to size_t, which -fsanitize=integer reports as implicit-integer-sign-change. This is
|
|
||||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119429, not a bug in this library. Only that check and only <format> are
|
|
||||||
# excluded, so implicit sign changes in the library and the tests are still reported.
|
|
||||||
[implicit-integer-sign-change]
|
|
||||||
src:*/include/c++/*/format
|
|
||||||
@@ -48,7 +48,6 @@ cc_library(
|
|||||||
name = "singleheader-json",
|
name = "singleheader-json",
|
||||||
hdrs = [
|
hdrs = [
|
||||||
"single_include/nlohmann/json.hpp",
|
"single_include/nlohmann/json.hpp",
|
||||||
"single_include/nlohmann/json_fwd.hpp",
|
|
||||||
"single_include/nlohmann/json_view.hpp",
|
"single_include/nlohmann/json_view.hpp",
|
||||||
],
|
],
|
||||||
includes = ["single_include"],
|
includes = ["single_include"],
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ if(MODE STREQUAL "undef")
|
|||||||
# recipe is self-contained and its output is byte-stable across reruns.
|
# recipe is self-contained and its output is byte-stable across reruns.
|
||||||
# The embedded SPDX tags below are part of the *generated* file's
|
# The embedded SPDX tags below are part of the *generated* file's
|
||||||
# content, not a REUSE header for this .cmake script itself (which is
|
# content, not a REUSE header for this .cmake script itself (which is
|
||||||
# already covered by the blanket path = "**" rule in REUSE.toml) -- keep
|
# already covered by the blanket "Files: *" rule in .reuse/dep5) -- keep
|
||||||
# them wrapped in REUSE-IgnoreStart/End so `reuse lint` does not try to
|
# them wrapped in REUSE-IgnoreStart/End so `reuse lint` does not try to
|
||||||
# parse "MIT\n")" as this file's own SPDX-License-Identifier value.
|
# parse "MIT\n")" as this file's own SPDX-License-Identifier value.
|
||||||
# REUSE-IgnoreStart
|
# REUSE-IgnoreStart
|
||||||
|
|||||||
+10
-3
@@ -131,19 +131,24 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_string', 'Meth
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_ubjson', 'Function', 'api/basic_json/to_ubjson/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_ubjson', 'Function', 'api/basic_json/to_ubjson/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value', 'Method', 'api/basic_json/value/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value', 'Method', 'api/basic_json/value/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value_t', 'Enum', 'api/basic_json/value_t/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value_t', 'Enum', 'api/basic_json/value_t/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::with_t', 'Type', 'api/basic_json/with_t/index.html');
|
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::~basic_json', 'Method', 'api/basic_json/~basic_json/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::~basic_json', 'Method', 'api/basic_json/~basic_json/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document', 'Class', 'api/basic_json_document/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document', 'Class', 'api/basic_json_document/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::basic_json_document', 'Constructor', 'api/basic_json_document/basic_json_document/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::basic_json_document', 'Constructor', 'api/basic_json_document/basic_json_document/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::accept', 'Function', 'api/basic_json_document/accept/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::accept', 'Function', 'api/basic_json_document/accept/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::erase', 'Method', 'api/basic_json_document/erase/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::insert', 'Method', 'api/basic_json_document/insert/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::is_discarded', 'Method', 'api/basic_json_document/is_discarded/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::is_discarded', 'Method', 'api/basic_json_document/is_discarded/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::load', 'Function', 'api/basic_json_document/load/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::memory_usage', 'Method', 'api/basic_json_document/memory_usage/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::memory_usage', 'Method', 'api/basic_json_document/memory_usage/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::node_count', 'Method', 'api/basic_json_document/node_count/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::node_count', 'Method', 'api/basic_json_document/node_count/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::owns_source', 'Method', 'api/basic_json_document/owns_source/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::owns_source', 'Method', 'api/basic_json_document/owns_source/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::parse', 'Function', 'api/basic_json_document/parse/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::parse', 'Function', 'api/basic_json_document/parse/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::parse_copy', 'Function', 'api/basic_json_document/parse_copy/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::parse_copy', 'Function', 'api/basic_json_document/parse_copy/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::push_back', 'Method', 'api/basic_json_document/push_back/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::read', 'Method', 'api/basic_json_document/read/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::read', 'Method', 'api/basic_json_document/read/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::root', 'Method', 'api/basic_json_document/root/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::root', 'Method', 'api/basic_json_document/root/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::save', 'Method', 'api/basic_json_document/save/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::set', 'Method', 'api/basic_json_document/set/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::shrink_to_fit', 'Method', 'api/basic_json_document/shrink_to_fit/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::shrink_to_fit', 'Method', 'api/basic_json_document/shrink_to_fit/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::source', 'Method', 'api/basic_json_document/source/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::source', 'Method', 'api/basic_json_document/source/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view', 'Class', 'api/basic_json_view/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view', 'Class', 'api/basic_json_view/index.html');
|
||||||
@@ -192,6 +197,8 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::type_name',
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::value', 'Method', 'api/basic_json_view/value/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::value', 'Method', 'api/basic_json_view/value/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'api/json/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'api/json/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('json_document', 'Class', 'api/json_document/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('json_document', 'Class', 'api/json_document/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('json_editable_document', 'Class', 'api/json_editable_document/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('json_editable_view', 'Class', 'api/json_editable_view/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('json_view', 'Class', 'api/json_view/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('json_view', 'Class', 'api/json_view/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer', 'Class', 'api/json_pointer/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer', 'Class', 'api/json_pointer/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::back', 'Method', 'api/json_pointer/back/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::back', 'Method', 'api/json_pointer/back/index.html');
|
||||||
@@ -231,6 +238,8 @@ INSERT INTO searchIndex(name, type, path) VALUES ('operator<<', 'Operator', 'api
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('operator>>', 'Operator', 'api/operator_gtgt/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('operator>>', 'Operator', 'api/operator_gtgt/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json', 'Class', 'api/ordered_json/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json', 'Class', 'api/ordered_json/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_document', 'Class', 'api/ordered_json_document/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_document', 'Class', 'api/ordered_json_document/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_editable_document', 'Class', 'api/ordered_json_editable_document/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_editable_view', 'Class', 'api/ordered_json_editable_view/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_view', 'Class', 'api/ordered_json_view/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_view', 'Class', 'api/ordered_json_view/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_map', 'Class', 'api/ordered_map/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_map', 'Class', 'api/ordered_map/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('std::formatter<basic_json>', 'Class', 'api/basic_json/std_formatter/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('std::formatter<basic_json>', 'Class', 'api/basic_json/std_formatter/index.html');
|
||||||
@@ -282,7 +291,6 @@ INSERT INTO searchIndex(name, type, path) VALUES ('Supported Macros', 'Guide', '
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'api/macros/json_assert/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'api/macros/json_assert/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_BRACE_INIT_COPY_SEMANTICS', 'Macro', 'api/macros/json_brace_init_copy_semantics/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_BRACE_INIT_COPY_SEMANTICS', 'Macro', 'api/macros/json_brace_init_copy_semantics/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'api/macros/json_throw_user/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'api/macros/json_throw_user/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DELETE_DEPRECATED_FUNCTIONS', 'Macro', 'api/macros/json_delete_deprecated_functions/index.html');
|
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'api/macros/json_diagnostics/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'api/macros/json_diagnostics/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTIC_POSITIONS', 'Macro', 'api/macros/json_diagnostic_positions/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTIC_POSITIONS', 'Macro', 'api/macros/json_diagnostic_positions/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_ENUM_SERIALIZATION', 'Macro', 'api/macros/json_disable_enum_serialization/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_ENUM_SERIALIZATION', 'Macro', 'api/macros/json_disable_enum_serialization/index.html');
|
||||||
@@ -313,7 +321,6 @@ INSERT INTO searchIndex(name, type, path) VALUES ('JSON_TRY_USER', 'Macro', 'api
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_GLOBAL_UDLS', 'Macro', 'api/macros/json_use_global_udls/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_GLOBAL_UDLS', 'Macro', 'api/macros/json_use_global_udls/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_IMPLICIT_CONVERSIONS', 'Macro', 'api/macros/json_use_implicit_conversions/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_IMPLICIT_CONVERSIONS', 'Macro', 'api/macros/json_use_implicit_conversions/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON', 'Macro', 'api/macros/json_use_legacy_discarded_value_comparison/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON', 'Macro', 'api/macros/json_use_legacy_discarded_value_comparison/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS', 'Macro', 'api/macros/json_use_objects_for_enum_keyed_maps/index.html');
|
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_SIMDUTF', 'Macro', 'api/macros/json_use_simdutf/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_SIMDUTF', 'Macro', 'api/macros/json_use_simdutf/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('Macros', 'Macro', 'api/macros/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('Macros', 'Macro', 'api/macros/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ enum class cbor_tag_handler_t
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
This enumeration is used in [`from_cbor`](from_cbor.md) and [`sax_parse`](sax_parse.md) to choose how to treat tags:
|
This enumeration is used in the [`from_cbor`](from_cbor.md) function to choose how to treat tags:
|
||||||
|
|
||||||
error
|
error
|
||||||
: report a parse error in case of a tag (the `from_cbor` overloads throw a `parse_error` exception by default)
|
: throw a `parse_error` exception in case of a tag
|
||||||
|
|
||||||
ignore
|
ignore
|
||||||
: ignore tags
|
: ignore tags
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ static basic_json diff(const basic_json& source,
|
|||||||
Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling
|
Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling
|
||||||
[`patch`](patch.md) function.
|
[`patch`](patch.md) function.
|
||||||
|
|
||||||
For two JSON values `source` and `target`, the following code always yields `#!cpp true`:
|
For two JSON values `source` and `target`, the following code yields always `#!cpp true`:
|
||||||
```cpp
|
```cpp
|
||||||
source.patch(diff(source, target)) == target;
|
source.patch(diff(source, target)) == target;
|
||||||
```
|
```
|
||||||
@@ -27,7 +27,7 @@ a JSON patch to convert the `source` to `target`
|
|||||||
|
|
||||||
## Exception safety
|
## Exception safety
|
||||||
|
|
||||||
Strong guarantee: `source` and `target` are never modified.
|
Strong guarantee: if an exception is thrown, there are no changes in the JSON value.
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
|
|||||||
@@ -120,12 +120,3 @@ Linear in the size of the input.
|
|||||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||||
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
|
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
|
||||||
- Added `error_handler` parameter in version 3.13.0.
|
- Added `error_handler` parameter in version 3.13.0.
|
||||||
|
|
||||||
!!! warning "Deprecation"
|
|
||||||
|
|
||||||
- Overload (2) replaces calls to `from_bjdata` with a pointer and a length as first two parameters, which has been
|
|
||||||
deprecated in version 3.13.0. This overload will be removed in version 4.0.0. Please replace all calls like
|
|
||||||
`#!cpp from_bjdata(ptr, len, ...);` with `#!cpp from_bjdata(ptr, ptr+len, ...);`.
|
|
||||||
|
|
||||||
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
|
|
||||||
function.
|
|
||||||
@@ -106,12 +106,3 @@ Linear in the size of the input.
|
|||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
- Added in version 3.13.0.
|
||||||
|
|
||||||
!!! warning "Deprecation"
|
|
||||||
|
|
||||||
- Overload (2) replaces calls to `from_bon8` with a pointer and a length as first two parameters, which has been
|
|
||||||
deprecated in version 3.13.0. This overload will be removed in version 4.0.0. Please replace all calls like
|
|
||||||
`#!cpp from_bon8(ptr, len, ...);` with `#!cpp from_bon8(ptr, ptr+len, ...);`.
|
|
||||||
|
|
||||||
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
|
|
||||||
function.
|
|
||||||
@@ -109,9 +109,6 @@ The class satisfies the following concept requirements:
|
|||||||
- **initializer_list_t** - type for initializer lists of `basic_json` values
|
- **initializer_list_t** - type for initializer lists of `basic_json` values
|
||||||
- [**input_format_t**](input_format_t.md) - type to choose the format to parse
|
- [**input_format_t**](input_format_t.md) - type to choose the format to parse
|
||||||
- [**json_sax_t**](../json_sax/index.md) - type for SAX events
|
- [**json_sax_t**](../json_sax/index.md) - type for SAX events
|
||||||
- [**with_object_t, with_array_t, with_string_t, with_boolean_t, with_integers_t, with_float_t, with_allocator_t,
|
|
||||||
with_json_serializer_t, with_binary_t, with_base_class_t**](with_t.md) - types to create a `basic_json` type with
|
|
||||||
one (or two) replaced template parameters
|
|
||||||
|
|
||||||
### Exceptions
|
### Exceptions
|
||||||
|
|
||||||
|
|||||||
@@ -56,10 +56,6 @@ This implementation does exactly follow this approach, as it uses double precisi
|
|||||||
smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally
|
smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally
|
||||||
and be serialized to `null`.
|
and be serialized to `null`.
|
||||||
|
|
||||||
During deserialization (from JSON text or any of the binary formats), a finite number that does not fit into
|
|
||||||
`number_float_t` is rejected with [`out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406), for
|
|
||||||
example a double-precision number in a binary format when `number_float_t` is `#!cpp float`.
|
|
||||||
|
|
||||||
### Storage
|
### Storage
|
||||||
|
|
||||||
Floating-point number values are stored directly inside a `basic_json` type.
|
Floating-point number values are stored directly inside a `basic_json` type.
|
||||||
|
|||||||
@@ -47,9 +47,8 @@ With the default values for `NumberIntegerType` (`std::int64_t`), the default va
|
|||||||
|
|
||||||
When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and
|
When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and
|
||||||
the minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of
|
the minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of
|
||||||
range will yield over/underflow when used in a constructor. During deserialization (from JSON text or any of the binary
|
range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers
|
||||||
formats), too large or small integer numbers will automatically be stored as [`number_unsigned_t`](number_unsigned_t.md)
|
will automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [`number_float_t`](number_float_t.md).
|
||||||
or [`number_float_t`](number_float_t.md).
|
|
||||||
|
|
||||||
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
|
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
|
||||||
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
|
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
|
||||||
|
|||||||
@@ -48,9 +48,8 @@ With the default values for `NumberUnsignedType` (`std::uint64_t`), the default
|
|||||||
|
|
||||||
When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and
|
When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and
|
||||||
the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow
|
the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow
|
||||||
when used in a constructor. During deserialization (from JSON text or any of the binary formats), too large or small
|
when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored
|
||||||
integer numbers will automatically be stored as [`number_integer_t`](number_integer_t.md) or
|
as [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_t.md).
|
||||||
[`number_float_t`](number_float_t.md).
|
|
||||||
|
|
||||||
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
|
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
|
||||||
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
|
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ static bool sax_parse(InputType&& i,
|
|||||||
input_format_t format = input_format_t::json,
|
input_format_t format = input_format_t::json,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool ignore_comments = false,
|
const bool ignore_comments = false,
|
||||||
const bool ignore_trailing_commas = false,
|
const bool ignore_trailing_commas = false);
|
||||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);
|
|
||||||
|
|
||||||
// (2)
|
// (2)
|
||||||
template<class IteratorType, class SAX, class SentinelType = IteratorType>
|
template<class IteratorType, class SAX, class SentinelType = IteratorType>
|
||||||
@@ -18,14 +17,13 @@ static bool sax_parse(IteratorType first, SentinelType last,
|
|||||||
input_format_t format = input_format_t::json,
|
input_format_t format = input_format_t::json,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool ignore_comments = false,
|
const bool ignore_comments = false,
|
||||||
const bool ignore_trailing_commas = false,
|
const bool ignore_trailing_commas = false);
|
||||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Read from input and generate SAX events
|
Read from input and generate SAX events
|
||||||
|
|
||||||
1. Read from a compatible input.
|
1. Read from a compatible input.
|
||||||
2. Read from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support).
|
2. Read from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support)
|
||||||
|
|
||||||
The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted
|
The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted
|
||||||
respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to
|
respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to
|
||||||
@@ -84,10 +82,6 @@ The SAX event lister must follow the interface of [`json_sax`](../json_sax/index
|
|||||||
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
|
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
|
||||||
(`#!cpp false`); (optional, `#!cpp false` by default)
|
(`#!cpp false`); (optional, `#!cpp false` by default)
|
||||||
|
|
||||||
`tag_handler` (in)
|
|
||||||
: how to handle CBOR tags; see [`cbor_tag_handler_t`](cbor_tag_handler_t.md). Ignored for formats other than CBOR
|
|
||||||
(optional, `cbor_tag_handler_t::error` by default).
|
|
||||||
|
|
||||||
`first` (in)
|
`first` (in)
|
||||||
: iterator to the start of a character range
|
: iterator to the start of a character range
|
||||||
|
|
||||||
@@ -143,7 +137,6 @@ A UTF-8 byte order mark is silently ignored.
|
|||||||
- Added in version 3.2.0.
|
- Added in version 3.2.0.
|
||||||
- Ignoring comments via `ignore_comments` added in version 3.9.0.
|
- Ignoring comments via `ignore_comments` added in version 3.9.0.
|
||||||
- Added `ignore_trailing_commas` in version 3.13.0.
|
- Added `ignore_trailing_commas` in version 3.13.0.
|
||||||
- Added `tag_handler` in version 3.13.0.
|
|
||||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||||
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
|
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
|
||||||
- `JSON_PRECISE_STREAM_POSITION` added in version 3.13.0 to optionally leave a `#!cpp std::istream` positioned right
|
- `JSON_PRECISE_STREAM_POSITION` added in version 3.13.0 to optionally leave a `#!cpp std::istream` positioned right
|
||||||
|
|||||||
@@ -68,8 +68,6 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
|||||||
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
||||||
not valid UTF-8 and `error_handler` is `strict` (the default only if
|
not valid UTF-8 and `error_handler` is `strict` (the default only if
|
||||||
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
|
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
|
||||||
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
|
|
||||||
discarded; example: `"cannot serialize discarded value to BJData"`
|
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
@@ -121,6 +119,4 @@ Linear in the size of the JSON value `j`.
|
|||||||
- BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
|
- BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
|
||||||
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
|
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
|
||||||
that is not valid UTF-8 unchanged, as before; `strict` (the default if
|
that is not valid UTF-8 unchanged, as before; `strict` (the default if
|
||||||
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
|
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
|
||||||
- Throws `type_error.321` for a discarded value since version 3.13.0; previously, a discarded value nested in an
|
|
||||||
array or object was silently skipped, producing invalid BJData.
|
|
||||||
@@ -58,9 +58,6 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
|||||||
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key is
|
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key is
|
||||||
not valid UTF-8 and `error_handler` is `strict` (the default only if
|
not valid UTF-8 and `error_handler` is `strict` (the default only if
|
||||||
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
|
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
|
||||||
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if a value nested in `j` is discarded
|
|
||||||
(the top-level value itself is covered by `type_error.317` above, since it must be an object); example:
|
|
||||||
`"cannot serialize discarded value to BSON"`
|
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
@@ -113,8 +110,6 @@ pass before anything is written.
|
|||||||
- Throws `out_of_range.412` and `out_of_range.415` since version 3.13.0.
|
- Throws `out_of_range.412` and `out_of_range.415` since version 3.13.0.
|
||||||
- Linear in the size of `j`, and no longer limited by the call stack for deeply nested values, since version 3.13.0.
|
- Linear in the size of `j`, and no longer limited by the call stack for deeply nested values, since version 3.13.0.
|
||||||
- `out_of_range.415` is now detected before anything is written, like the other exceptions above, since version 3.13.0.
|
- `out_of_range.415` is now detected before anything is written, like the other exceptions above, since version 3.13.0.
|
||||||
- Throws `type_error.321` for a discarded value nested in `j` since version 3.13.0; previously, it was silently
|
|
||||||
skipped, producing a document whose declared size did not match what was actually written.
|
|
||||||
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
|
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
|
||||||
that is not valid UTF-8 unchanged, as before; `strict` (the default if
|
that is not valid UTF-8 unchanged, as before; `strict` (the default if
|
||||||
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316` before anything
|
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316` before anything
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
|||||||
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
||||||
not valid UTF-8 and `error_handler` is `strict` (the default only if
|
not valid UTF-8 and `error_handler` is `strict` (the default only if
|
||||||
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
|
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
|
||||||
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
|
|
||||||
discarded; example: `"cannot serialize discarded value to CBOR"`
|
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
@@ -88,5 +86,3 @@ Linear in the size of the JSON value `j`.
|
|||||||
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
|
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
|
||||||
that is not valid UTF-8 unchanged, as before; `strict` (the default if
|
that is not valid UTF-8 unchanged, as before; `strict` (the default if
|
||||||
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
|
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
|
||||||
- Throws `type_error.321` for a discarded value since version 3.13.0; previously, a discarded value nested in an
|
|
||||||
array or object was silently skipped, producing invalid CBOR.
|
|
||||||
@@ -54,8 +54,6 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
|||||||
`"subtype 70000 is too large for the MessagePack ext type (max 255)"`
|
`"subtype 70000 is too large for the MessagePack ext type (max 255)"`
|
||||||
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
||||||
not valid UTF-8 and `error_handler` is `strict`
|
not valid UTF-8 and `error_handler` is `strict`
|
||||||
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
|
|
||||||
discarded; example: `"cannot serialize discarded value to MessagePack"`
|
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
@@ -110,5 +108,3 @@ Linear in the size of the JSON value `j`.
|
|||||||
- Fixed in version 3.13.0 to serialize `number_integer_t`/`number_unsigned_t` pairs of different width correctly;
|
- Fixed in version 3.13.0 to serialize `number_integer_t`/`number_unsigned_t` pairs of different width correctly;
|
||||||
before, integers could be serialized with the wrong value if `number_integer_t` was narrower than
|
before, integers could be serialized with the wrong value if `number_integer_t` was narrower than
|
||||||
`number_unsigned_t`.
|
`number_unsigned_t`.
|
||||||
- Throws `type_error.321` for a discarded value since version 3.13.0; previously, a discarded value nested in an
|
|
||||||
array or object was silently skipped, producing invalid MessagePack.
|
|
||||||
@@ -61,8 +61,6 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
|||||||
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
||||||
not valid UTF-8 and `error_handler` is `strict` (the default only if
|
not valid UTF-8 and `error_handler` is `strict` (the default only if
|
||||||
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
|
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
|
||||||
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
|
|
||||||
discarded; example: `"cannot serialize discarded value to UBJSON"`
|
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
@@ -114,5 +112,3 @@ Linear in the size of the JSON value `j`.
|
|||||||
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
|
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
|
||||||
that is not valid UTF-8 unchanged, as before; `strict` (the default if
|
that is not valid UTF-8 unchanged, as before; `strict` (the default if
|
||||||
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
|
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
|
||||||
- Throws `type_error.321` for a discarded value since version 3.13.0; previously, a discarded value nested in an
|
|
||||||
array or object was silently skipped, producing invalid UBJSON.
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
# <small>nlohmann::basic_json::</small>with_t
|
|
||||||
|
|
||||||
Member alias templates `with_object_t`, `with_array_t`, `with_string_t`, `with_boolean_t`, `with_integers_t`,
|
|
||||||
`with_float_t`, `with_allocator_t`, `with_json_serializer_t`, `with_binary_t`, and `with_base_class_t`.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
template<template<typename, typename, typename...> class ObjectType2>
|
|
||||||
using with_object_t = basic_json<ObjectType2, ArrayType, StringType, BooleanType,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
|
||||||
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<template<typename, typename...> class ArrayType2>
|
|
||||||
using with_array_t = basic_json<ObjectType, ArrayType2, StringType, BooleanType,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
|
||||||
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<class StringType2>
|
|
||||||
using with_string_t = basic_json<ObjectType, ArrayType, StringType2, BooleanType,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
|
||||||
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<class BooleanType2>
|
|
||||||
using with_boolean_t = basic_json<ObjectType, ArrayType, StringType, BooleanType2,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
|
||||||
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<class NumberIntegerType2, class NumberUnsignedType2>
|
|
||||||
using with_integers_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
|
|
||||||
NumberIntegerType2, NumberUnsignedType2, NumberFloatType,
|
|
||||||
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<class NumberFloatType2>
|
|
||||||
using with_float_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType2,
|
|
||||||
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<template<typename> class AllocatorType2>
|
|
||||||
using with_allocator_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
|
||||||
AllocatorType2, JSONSerializer, BinaryType, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<template<typename, typename = void> class JSONSerializer2>
|
|
||||||
using with_json_serializer_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
|
||||||
AllocatorType, JSONSerializer2, BinaryType, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<class BinaryType2>
|
|
||||||
using with_binary_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
|
||||||
AllocatorType, JSONSerializer, BinaryType2, CustomBaseClass>;
|
|
||||||
|
|
||||||
template<class CustomBaseClass2>
|
|
||||||
using with_base_class_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
|
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
|
||||||
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass2>;
|
|
||||||
```
|
|
||||||
|
|
||||||
These member alias templates make it easier to create a `basic_json` type that is identical to the current type except
|
|
||||||
for one (or, in the case of `with_integers_t`, two) of its [template parameters](index.md#template-parameters).
|
|
||||||
Spelling out all 11 template parameters of `basic_json` just to change a single one is verbose and error-prone; these
|
|
||||||
aliases only require the replacement type(s).
|
|
||||||
|
|
||||||
with_object_t<ObjectType2>
|
|
||||||
: replaces `ObjectType`
|
|
||||||
|
|
||||||
with_array_t<ArrayType2>
|
|
||||||
: replaces `ArrayType`
|
|
||||||
|
|
||||||
with_string_t<StringType2>
|
|
||||||
: replaces `StringType`
|
|
||||||
|
|
||||||
with_boolean_t<BooleanType2>
|
|
||||||
: replaces `BooleanType`
|
|
||||||
|
|
||||||
with_integers_t<NumberIntegerType2, NumberUnsignedType2>
|
|
||||||
: replaces both `NumberIntegerType` and `NumberUnsignedType`; the two are combined into a single alias because they
|
|
||||||
are usually changed together (for instance, when switching to fixed-width integer types)
|
|
||||||
|
|
||||||
with_float_t<NumberFloatType2>
|
|
||||||
: replaces `NumberFloatType`
|
|
||||||
|
|
||||||
with_allocator_t<AllocatorType2>
|
|
||||||
: replaces `AllocatorType`
|
|
||||||
|
|
||||||
with_json_serializer_t<JSONSerializer2>
|
|
||||||
: replaces `JSONSerializer`
|
|
||||||
|
|
||||||
with_binary_t<BinaryType2>
|
|
||||||
: replaces `BinaryType`
|
|
||||||
|
|
||||||
with_base_class_t<CustomBaseClass2>
|
|
||||||
: replaces `CustomBaseClass`; see also [`json_base_class_t`](json_base_class_t.md)
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
All other template parameters are kept unchanged, so the resulting type still uses, for instance, the same
|
|
||||||
`ObjectType` unless `with_object_t` itself is used.
|
|
||||||
|
|
||||||
The aliases are members of every `basic_json` specialization, including [`ordered_json`](../ordered_json.md), and the
|
|
||||||
type they produce is again a `basic_json` specialization. They can therefore be chained to replace several template
|
|
||||||
parameters at once:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
using my_json = nlohmann::json::with_integers_t<int, unsigned int>::with_float_t<float>;
|
|
||||||
using my_ordered_json = nlohmann::ordered_json::with_string_t<std::wstring>;
|
|
||||||
```
|
|
||||||
|
|
||||||
The result is the same type as spelling out all template parameters, so the order of the chained aliases does not
|
|
||||||
matter. For instance, `nlohmann::json::with_object_t<nlohmann::ordered_map>` is `nlohmann::ordered_json`.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
??? example
|
|
||||||
|
|
||||||
The following code shows how `with_object_t` can be used to create a JSON type that stores object elements in a
|
|
||||||
`std::map` and therefore keeps them sorted by key, unlike the default type which preserves insertion order
|
|
||||||
only when `nlohmann::ordered_json` is used.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
--8<-- "examples/with_t.cpp"
|
|
||||||
```
|
|
||||||
|
|
||||||
Output:
|
|
||||||
|
|
||||||
```json
|
|
||||||
--8<-- "examples/with_t.output"
|
|
||||||
```
|
|
||||||
|
|
||||||
## See also
|
|
||||||
|
|
||||||
- [basic_json](index.md#template-parameters) - the template parameters that can be replaced
|
|
||||||
- [json_base_class_t](json_base_class_t.md) - the type used for `CustomBaseClass`
|
|
||||||
|
|
||||||
## Version history
|
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
# <small>nlohmann::basic_json_document::</small>erase
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// (1)
|
||||||
|
std::size_t erase(view_type object, string_view_t key);
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
template<typename I>
|
||||||
|
void erase(view_type array, I idx);
|
||||||
|
|
||||||
|
// (3)
|
||||||
|
std::size_t erase(const json_pointer& ptr);
|
||||||
|
```
|
||||||
|
|
||||||
|
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
|
||||||
|
has `erase`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
|
||||||
|
|
||||||
|
1. Removes every member of `object` whose key is `key` (see [Notes](#notes) on duplicate keys) and returns how many
|
||||||
|
were removed; `#!cpp 0` if `object` has no member with this key.
|
||||||
|
2. Removes the element at index `idx` of `array`, which must already exist (`#!cpp idx < array.size()`).
|
||||||
|
3. Removes the value the JSON pointer `ptr` refers to, relative to [`root()`](root.md), and returns how many values
|
||||||
|
were removed: the *parent* of the target must already exist, and the target itself is removed as in 1. (an object
|
||||||
|
member; `#!cpp 0` or more) or 2. (an array element; always `#!cpp 1`). `ptr` must not be empty -- [`root()`](root.md)
|
||||||
|
itself cannot be erased.
|
||||||
|
|
||||||
|
## Template parameters
|
||||||
|
|
||||||
|
`I`
|
||||||
|
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
|
||||||
|
`idx` do not participate in overload resolution).
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`object` (in)
|
||||||
|
: the object to remove a member of
|
||||||
|
|
||||||
|
`array` (in)
|
||||||
|
: the array to remove an element of
|
||||||
|
|
||||||
|
`key` (in)
|
||||||
|
: the key of the member(s) to remove
|
||||||
|
|
||||||
|
`idx` (in)
|
||||||
|
: the index of the element to remove; a negative value throws (see [Exceptions](#exceptions))
|
||||||
|
|
||||||
|
`ptr` (in)
|
||||||
|
: a JSON pointer to the value to remove, relative to `root()`
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
1. the number of removed members (`#!cpp 0` if `object` had none with this `key`)
|
||||||
|
2. (nothing)
|
||||||
|
3. the number of removed values (`#!cpp 0` or more for an object member, always `#!cpp 1` for an array element)
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
1. Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if `object` is not an object -- the
|
||||||
|
same message [`BasicJsonType::erase`](../basic_json/erase.md) throws for the same type.
|
||||||
|
2. Throws `type_error.307` if `array` is not an array. Throws
|
||||||
|
[`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is negative, or if
|
||||||
|
`#!cpp idx >= array.size()`.
|
||||||
|
3. Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) ("JSON pointer has no parent")
|
||||||
|
if `ptr` is empty. Throws what [`at`](../basic_json_view/at.md) throws (overload 3) for resolving `ptr`'s parent.
|
||||||
|
For the last reference token itself: if the parent is an array, throws what 2. throws for an index that is out of
|
||||||
|
range, or, for a token that is not a valid array index,
|
||||||
|
[`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) (a leading `#!cpp '0'`),
|
||||||
|
[`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) (not a number),
|
||||||
|
[`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) (too large for `size_type`), or
|
||||||
|
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) (an empty token); otherwise (an
|
||||||
|
object, or a primitive value the pointer's parent resolves to) throws what 1. throws.
|
||||||
|
|
||||||
|
Every overload also throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view
|
||||||
|
does not belong to this document") if `object`/`array` is a [discarded](../basic_json_view/is_discarded.md) view or a
|
||||||
|
view of a *different* document (overloads 1-2 only; overload 3 always starts from this document's own
|
||||||
|
[`root()`](root.md)).
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
1. Linear in the number of members of `object`.
|
||||||
|
2. Linear in the number of elements of `array` at or after `idx` (they move one slot over).
|
||||||
|
3. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
||||||
|
that level or the index into the array (as [`at`](../basic_json_view/at.md)), plus the complexity of 1. or 2. for
|
||||||
|
the last token.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
!!! info "Duplicate keys"
|
||||||
|
|
||||||
|
Overload 1. removes *every* member with `key`, not just the first -- unlike [`set`](set.md), which assigns the
|
||||||
|
first occurrence and drops the rest. This is why it returns a count rather than a single view: there may be
|
||||||
|
more than one member removed, or none.
|
||||||
|
|
||||||
|
Like [`set`](set.md) and [`push_back`](push_back.md), `erase` never moves an element's *value*: a view still
|
||||||
|
referring to a removed member or element keeps showing what it last held (see [Edits](index.md#edits)) -- it just no
|
||||||
|
longer appears when `array`/`object` is read, dumped, or iterated. Removing an element of `array` (2.) does shift the
|
||||||
|
*links* to the elements after it, the same way `insert`, `set`, or `push_back` on the same array would; any iterator
|
||||||
|
already taken over `array`/`object` is invalidated by an erase, since it was walking the old layout.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below drops a deprecated field and a decommissioned entry from a configuration document -- using all
|
||||||
|
three overloads -- and shows what stays intact that would not with a plain `json`/`ordered_json` value: the order
|
||||||
|
of the fields around the ones removed, and the exact spelling of a number that was never touched.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_document__erase.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_document__erase.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [insert](insert.md) - insert an element into an array
|
||||||
|
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||||
|
- [push_back](push_back.md) - append to an array
|
||||||
|
- [root](root.md) - the view of the root value, the starting point of overload 3
|
||||||
|
- [`BasicJsonType::erase`](../basic_json/erase.md) - the corresponding function of `basic_json`
|
||||||
|
- [Edits](index.md#edits) - what an edit guarantees, for every overload
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType, bool Editable = false>
|
||||||
class basic_json_document;
|
class basic_json_document;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -19,6 +19,11 @@ it (a copy, or an rvalue `#!cpp std::string` that was moved in); see [`owns_sour
|
|||||||
is move-only: copying a document would either duplicate a potentially large index and text, or leave two documents
|
is move-only: copying a document would either duplicate a potentially large index and text, or leave two documents
|
||||||
claiming to borrow the same buffer, so it is disabled.
|
claiming to borrow the same buffer, so it is disabled.
|
||||||
|
|
||||||
|
With `#!cpp Editable == true`, the document also offers [`set`](set.md), [`push_back`](push_back.md),
|
||||||
|
[`insert`](insert.md), and [`erase`](erase.md) to change values in place, see [Edits](#edits) below. The source text
|
||||||
|
itself is never written; a read-only document (`#!cpp Editable == false`, the default) does not carry any of the
|
||||||
|
bookkeeping edits need, and calling any of them on one fails to compile (`#!cpp static_assert`).
|
||||||
|
|
||||||
## Template parameters
|
## Template parameters
|
||||||
|
|
||||||
`BasicJsonType`
|
`BasicJsonType`
|
||||||
@@ -26,23 +31,37 @@ claiming to borrow the same buffer, so it is disabled.
|
|||||||
[`ordered_json`](../ordered_json.md). Only 64-bit `number_integer_t`/`number_unsigned_t` types are supported; this
|
[`ordered_json`](../ordered_json.md). Only 64-bit `number_integer_t`/`number_unsigned_t` types are supported; this
|
||||||
is checked with a `static_assert`.
|
is checked with a `static_assert`.
|
||||||
|
|
||||||
|
`Editable`
|
||||||
|
: whether the document supports [`set`](set.md), [`push_back`](push_back.md), [`insert`](insert.md), and
|
||||||
|
[`erase`](erase.md) (optional, `#!cpp false` by default). See [Edits](#edits) below.
|
||||||
|
|
||||||
## Specializations
|
## Specializations
|
||||||
|
|
||||||
- [**json_document**](../json_document.md) - documents of the default specialization [`json`](../json.md)
|
- [**json_document**](../json_document.md) - read-only documents of the default specialization [`json`](../json.md)
|
||||||
- [**ordered_json_document**](../ordered_json_document.md) - documents of [`ordered_json`](../ordered_json.md)
|
- [**ordered_json_document**](../ordered_json_document.md) - read-only documents of
|
||||||
|
[`ordered_json`](../ordered_json.md)
|
||||||
|
- [**json_editable_document**](../json_editable_document.md) - editable documents of [`json`](../json.md)
|
||||||
|
- [**ordered_json_editable_document**](../ordered_json_editable_document.md) - editable documents of
|
||||||
|
[`ordered_json`](../ordered_json.md)
|
||||||
|
|
||||||
## Member types
|
## Member types
|
||||||
|
|
||||||
- **view_type** - the type of view returned by [`root()`](root.md) (`#!cpp basic_json_view<BasicJsonType>`)
|
- **view_type** - the type of view returned by [`root()`](root.md) (`#!cpp basic_json_view<BasicJsonType, Editable>`)
|
||||||
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md)
|
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md)
|
||||||
|
|
||||||
## Member functions
|
## Member functions
|
||||||
|
|
||||||
- [(constructor)](basic_json_document.md)
|
- [(constructor)](basic_json_document.md)
|
||||||
|
|
||||||
|
### Parsing
|
||||||
|
|
||||||
- [**parse**](parse.md) (_static_) - deserialize from a compatible input, borrowing or owning it as appropriate
|
- [**parse**](parse.md) (_static_) - deserialize from a compatible input, borrowing or owning it as appropriate
|
||||||
- [**parse_copy**](parse_copy.md) (_static_) - deserialize a copy of a compatible input
|
- [**parse_copy**](parse_copy.md) (_static_) - deserialize a copy of a compatible input
|
||||||
- [**accept**](accept.md) (_static_) - check whether the input is valid JSON
|
- [**accept**](accept.md) (_static_) - check whether the input is valid JSON
|
||||||
- [**read**](read.md) - (re-)parse into this document, reusing its memory
|
- [**read**](read.md) - (re-)parse into this document, reusing its memory
|
||||||
|
|
||||||
|
### Access
|
||||||
|
|
||||||
- [**root**](root.md) - the view of the root value
|
- [**root**](root.md) - the view of the root value
|
||||||
- [**is_discarded**](is_discarded.md) - return whether the last parse failed
|
- [**is_discarded**](is_discarded.md) - return whether the last parse failed
|
||||||
- [**source**](source.md) - the parsed text
|
- [**source**](source.md) - the parsed text
|
||||||
@@ -51,6 +70,49 @@ claiming to borrow the same buffer, so it is disabled.
|
|||||||
- [**memory_usage**](memory_usage.md) - the number of bytes held by the document
|
- [**memory_usage**](memory_usage.md) - the number of bytes held by the document
|
||||||
- [**shrink_to_fit**](shrink_to_fit.md) - release unused index capacity
|
- [**shrink_to_fit**](shrink_to_fit.md) - release unused index capacity
|
||||||
|
|
||||||
|
### Images
|
||||||
|
|
||||||
|
- [**save**](save.md) - the document as an image that `load()` reads without parsing
|
||||||
|
- [**load**](load.md) (_static_) - read an image written by `save()`
|
||||||
|
|
||||||
|
### Edits
|
||||||
|
|
||||||
|
- [**set**](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers
|
||||||
|
to (`#!cpp Editable` documents only)
|
||||||
|
- [**push_back**](push_back.md) - append to an array (`#!cpp Editable` documents only)
|
||||||
|
- [**insert**](insert.md) - insert an element into an array before a given position (`#!cpp Editable` documents only)
|
||||||
|
- [**erase**](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||||
|
(`#!cpp Editable` documents only)
|
||||||
|
|
||||||
|
## Edits
|
||||||
|
|
||||||
|
An editable document (`#!cpp Editable == true`) can be changed after parsing, with [`set`](set.md),
|
||||||
|
[`push_back`](push_back.md), [`insert`](insert.md), and [`erase`](erase.md);
|
||||||
|
[`json_editable_document`](../json_editable_document.md) and
|
||||||
|
[`ordered_json_editable_document`](../ordered_json_editable_document.md) are the corresponding specializations. A few
|
||||||
|
points apply to every edit:
|
||||||
|
|
||||||
|
- **The source text is never written**, and the parsed index never moves: every value keeps the node it was parsed
|
||||||
|
into, so [views](../basic_json_view/index.md) taken before an edit stay valid, including
|
||||||
|
[`root()`](root.md). New values (and the element sequences of an edited array/object) go to storage owned by the
|
||||||
|
document, allocated on demand.
|
||||||
|
- **A view keeps referring to the same value.** After [`set`](set.md) replaces the value a view refers to, that view
|
||||||
|
sees the new value; a view of a value that a later edit replaces or drops keeps showing what it last held. An edit
|
||||||
|
of an array or object, however, **invalidates the iterators taken over it** (its members may now live in a
|
||||||
|
different sequence), and a string obtained with [`get_string()`](../basic_json_view/get_string.md) stays valid even
|
||||||
|
as further edits happen (earlier buffers of edited text are kept alive, not overwritten).
|
||||||
|
- **Values are accepted three ways:** a [`basic_json_view`](../basic_json_view/index.md) of *any* document
|
||||||
|
(read-only or editable; it is copied, nothing is shared with the source document), a `BasicJsonType` value, or
|
||||||
|
anything `BasicJsonType` can be constructed from (numbers, strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
|
||||||
|
- [`dump()`](../basic_json_view/dump.md) writes an edited document with members in document order, new members at
|
||||||
|
the end, and, with [`number_format::source`](../basic_json_view/number_format.md), keeps the spelling of every
|
||||||
|
number that was not itself edited -- see [Editing a document](../../features/json_view.md#editing-a-document) for
|
||||||
|
why this matters.
|
||||||
|
- [`read()`](read.md) discards all edits, [`shrink_to_fit()`](shrink_to_fit.md) does not move the node index once
|
||||||
|
there are edits, and [`memory_usage()`](memory_usage.md) includes the memory edits use.
|
||||||
|
[`source_offset()`](../basic_json_view/source_offset.md) of a value introduced by an edit is
|
||||||
|
`#!cpp static_cast<std::size_t>(-1)`, the same value it reports for a decoded string.
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
# <small>nlohmann::basic_json_document::</small>insert
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template<typename I, typename V>
|
||||||
|
view_type insert(view_type array, I idx, V&& value);
|
||||||
|
```
|
||||||
|
|
||||||
|
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
|
||||||
|
has `insert`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
|
||||||
|
|
||||||
|
Inserts `value` into `array` as a new element before position `idx`, which must not be past the end
|
||||||
|
(`#!cpp idx <= array.size()`; `#!cpp idx == array.size()` appends, like [`push_back`](push_back.md)). Unlike
|
||||||
|
[`push_back`](push_back.md), a [null](../basic_json_view/is_null.md) `array` does *not* first become an empty array:
|
||||||
|
`array` must already be an array.
|
||||||
|
|
||||||
|
`value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any* document -- read-only or
|
||||||
|
editable, and it does not have to be `array`'s own document -- which is copied so that nothing is shared with the
|
||||||
|
source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers,
|
||||||
|
strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
|
||||||
|
|
||||||
|
## Template parameters
|
||||||
|
|
||||||
|
`I`
|
||||||
|
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
|
||||||
|
`idx` do not participate in overload resolution).
|
||||||
|
|
||||||
|
`V`
|
||||||
|
: the type of `value`, deduced; see above for what is accepted.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`array` (in)
|
||||||
|
: the array to insert into
|
||||||
|
|
||||||
|
`idx` (in)
|
||||||
|
: the position to insert `value` before; a negative value throws (see [Exceptions](#exceptions))
|
||||||
|
|
||||||
|
`value` (in)
|
||||||
|
: the value to insert
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
a view of the new element, now holding `value`
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
|
||||||
|
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
|
||||||
|
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
|
||||||
|
for the encoding that is not reclaimed. A failure of a later allocation -- while `array` switches from its parsed
|
||||||
|
layout to a growable block, or while that block grows, see [Notes](#notes) -- can still leave `array` already
|
||||||
|
switched to that layout even though `value` itself was not inserted.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if `array` is not an array -- the same
|
||||||
|
message [`BasicJsonType::insert`](../basic_json/insert.md) throws for the same type; a null `array` throws this too
|
||||||
|
(see above). Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is negative,
|
||||||
|
or if `#!cpp idx > array.size()`. Throws
|
||||||
|
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
|
||||||
|
document") if `array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a *different* document.
|
||||||
|
Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
|
||||||
|
[discarded](../basic_json_view/is_discarded.md) view or a [discarded](../basic_json/is_discarded.md) `BasicJsonType`
|
||||||
|
value, and [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or contains) a
|
||||||
|
binary value -- `BasicJsonType` can hold one, but a `json_document` cannot. Throws
|
||||||
|
[`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `value` is (or contains) a string that is
|
||||||
|
not valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the number of elements of `array` at or after `idx` (they move one slot over), plus time linear in the
|
||||||
|
size of `value` to encode it into the document's storage (constant for a scalar, linear in the number of nested
|
||||||
|
values for an array or object): like [`push_back`](push_back.md), the elements of `array` move to a growable block
|
||||||
|
of links the first time it is inserted into (or [`set`](set.md)/[`push_back`](push_back.md) on), and that block
|
||||||
|
grows in amortized constant time; inserting before the end within that block still shifts every later element.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Like [`set`](set.md) on a member or an element, `insert` never moves an existing *element's value* -- only where
|
||||||
|
`array`'s *links* to its elements live -- so a view of an existing element of `array` stays valid across an
|
||||||
|
`insert`, and keeps referring to the same element even though its index shifts. Any iterator already taken over
|
||||||
|
`array` is invalidated, since it was walking the old layout. See [Edits](index.md#edits) for what stays valid across
|
||||||
|
an edit in general.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below inserts a step into the middle of a deployment plan, without touching the steps that come
|
||||||
|
after it, and shows that a view taken before the insert keeps referring to the same element even though its
|
||||||
|
index shifts -- something a plain `json`/`ordered_json` array, or its `std::vector`-based storage, has no
|
||||||
|
equivalent for.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_document__insert.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_document__insert.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [push_back](push_back.md) - append to an array
|
||||||
|
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||||
|
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||||
|
- [`BasicJsonType::insert`](../basic_json/insert.md) - the corresponding function of `basic_json`
|
||||||
|
- [Edits](index.md#edits) - what an edit guarantees, for every overload
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
# <small>nlohmann::basic_json_document::</small>load
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// (1)
|
||||||
|
static basic_json_document load(const std::uint8_t* image, std::size_t size,
|
||||||
|
const image_check check = image_check::full);
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
static basic_json_document load(const std::vector<std::uint8_t>& image,
|
||||||
|
const image_check check = image_check::full);
|
||||||
|
|
||||||
|
// (3)
|
||||||
|
static basic_json_document load(std::vector<std::uint8_t>&& image,
|
||||||
|
const image_check check = image_check::full);
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Reads an image [`save()`](save.md) wrote, from a pointer and a byte count. The image is **borrowed**: `image`
|
||||||
|
must stay alive and unchanged for as long as the returned document, and any view taken from it, is used.
|
||||||
|
2. Reads an image from a `#!cpp std::vector`. Also **borrowed** -- equivalent to overload 1 called with
|
||||||
|
`#!cpp image.data()` and `#!cpp image.size()`.
|
||||||
|
3. Reads an image, keeping the vector instead of copying it: `image` is moved into the document (no copy), which
|
||||||
|
then owns it for as long as it needs the text and the decoded strings. [`owns_source()`](owns_source.md) is
|
||||||
|
`#!cpp true` afterward.
|
||||||
|
|
||||||
|
In every overload, the node index is copied into storage the document itself owns -- so that it is properly aligned,
|
||||||
|
and, for an [editable](index.md#edits) document, can be edited -- while the text and the decoded strings stay in
|
||||||
|
`image`. The hash indexes [large objects](../../features/json_view.md) use for lookup are rebuilt, exactly as after
|
||||||
|
parsing.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`image` (in)
|
||||||
|
: the image [`save()`](save.md) wrote (overloads 1 and 2), or one to take ownership of (overload 3)
|
||||||
|
|
||||||
|
`size` (in)
|
||||||
|
: the number of bytes at `image` (overload 1)
|
||||||
|
|
||||||
|
`check` (in)
|
||||||
|
: how thoroughly to validate `image` before trusting it; see [`image_check`](#image_check) below (optional,
|
||||||
|
`#!cpp image_check::full` by default)
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
The document read from the image.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Overloads 1 and 2 give the strong guarantee: `image` is only read, never written, so a thrown exception leaves the
|
||||||
|
caller's buffer untouched.
|
||||||
|
|
||||||
|
Overload 3 moves `image` into the document *before* validating it, so that a good image is kept without a copy. If
|
||||||
|
loading then fails, the partially built document -- and the vector now inside it -- is discarded along with the
|
||||||
|
exception, and `image` itself is left **empty**, not restored to what was passed in. Move a copy in instead, or
|
||||||
|
validate with overload 2 first, if the original vector must survive a failed load.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
On a big-endian target, throws [`type_error.320`](../../home/exceptions.md#jsonexceptiontype_error320) -- the same
|
||||||
|
exception [`save()`](save.md#exceptions) throws there, since the image format is little-endian only.
|
||||||
|
|
||||||
|
Otherwise throws [`parse_error.116`](../../home/exceptions.md#jsonexceptionparse_error116) if `image` is not one
|
||||||
|
`save()` could have written, or fails the requested `check`:
|
||||||
|
|
||||||
|
| message | when |
|
||||||
|
|------------------------|------------------------------------------------------------------------------------------------------|
|
||||||
|
| `too short` | `image` is `#!cpp nullptr`, or `size` is smaller than the 64-byte header |
|
||||||
|
| `unknown format` | the header's magic bytes or version do not match, or a reserved header field is not zero |
|
||||||
|
| `sizes out of range` | the node count, text size, or decoded-string size the header describes does not fit `size`, or the `#!cpp '\0'` after the text or after the decoded strings is missing |
|
||||||
|
| `the check failed` | `check` is not `#!cpp image_check::none`, and the image fails it -- see [`image_check`](#image_check) |
|
||||||
|
|
||||||
|
!!! failure "Example messages"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.116] parse error: invalid json_document image: too short
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.116] parse error: invalid json_document image: unknown format
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.116] parse error: invalid json_document image: sizes out of range
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.116] parse error: invalid json_document image: the check failed
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the number of nodes, which are always copied into the document. With `#!cpp check == image_check::full`,
|
||||||
|
additionally linear in the combined length of the text and the decoded strings; `#!cpp image_check::bounds` and
|
||||||
|
`#!cpp image_check::none` do not read them.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
**The `image_check` modes.**
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using image_check = detail::view::image_check;
|
||||||
|
|
||||||
|
enum class image_check
|
||||||
|
{
|
||||||
|
full,
|
||||||
|
bounds,
|
||||||
|
none
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
How thoroughly `load()` validates `image` before trusting it.
|
||||||
|
|
||||||
|
| value | checks | guarantees |
|
||||||
|
|----------|--------------------------------------------------------------------------------------------------------------|------------|
|
||||||
|
| `full` | everything the parser itself guarantees: structure and bounds; that every string is valid UTF-8 (and, for a string still in the source text, that it contains no quote, backslash, or control character); and that every number token is well-formed and matches the value stored for it | reading and serializing a checked image is safe and always produces valid JSON, exactly as for a parsed document |
|
||||||
|
| `bounds` | structure and bounds only -- that every offset and count in the node index stays inside the image | reading and serializing stay memory-safe, but a crafted image can hold strings that are not valid UTF-8 or that serialize to invalid JSON ([`dump()`](../basic_json_view/dump.md) writes them unchanged or throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316)), and numbers whose values differ from their text |
|
||||||
|
| `none` | nothing | images from a trusted source only -- reading a damaged image is undefined behavior |
|
||||||
|
|
||||||
|
`full` is the default and the right choice for an image from anything you do not fully control -- a file, a cache
|
||||||
|
shared with other processes, a peer on the network. `bounds` skips scanning the text and the decoded strings, so it
|
||||||
|
fits a cache your own process just wrote and reads straight back, where damage would mean a bug or a hardware fault
|
||||||
|
rather than adversarial input; it still cannot crash or read out of bounds. `none` skips validation entirely and
|
||||||
|
should only be used for an image you trust as much as your own memory.
|
||||||
|
|
||||||
|
**Lifetime.** Overloads 1 and 2 borrow `image`: it must stay alive and byte-for-byte unchanged for as long as the
|
||||||
|
returned document, and any [view](../basic_json_view/index.md) taken from it, is used -- exactly like a document
|
||||||
|
[`parse()`](parse.md) borrowed its input for. Overload 3 avoids this by keeping the vector itself; see
|
||||||
|
[`owns_source`](owns_source.md).
|
||||||
|
|
||||||
|
!!! warning "Experimental"
|
||||||
|
|
||||||
|
The image format is versioned but not yet stable, and may change in an incompatible way before it is declared
|
||||||
|
stable; `load()` already rejects an image written by a different format version with `parse_error.116`
|
||||||
|
("unknown format"). Use images to cache a document within one build of the library, or to hand one to another
|
||||||
|
process running the *same* build on the *same* (little-endian) machine -- not as a long-term storage format.
|
||||||
|
|
||||||
|
**What `image_check::bounds` does not guarantee.** A bounds-checked image can never make `load()`,
|
||||||
|
[`root()`](root.md), element access, or [`materialize()`](../basic_json_view/materialize.md) read outside the image,
|
||||||
|
so those stay safe on a damaged one. It does *not* guarantee that the image describes valid JSON: a string
|
||||||
|
that a `full` check would have rejected can make [`dump()`](../basic_json_view/dump.md) write invalid UTF-8 or invalid
|
||||||
|
JSON, or throw `type_error.316`, and a number can read back with a value that does not match how it is spelled.
|
||||||
|
Reserve `bounds` for images you already trust to be well-formed, and use it only to skip the extra scan.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example "Caching a document, ownership, and a rejected image"
|
||||||
|
|
||||||
|
The example below saves a parsed document as an image, checks that `load()` reproduces the original
|
||||||
|
[`dump()`](../basic_json_view/dump.md) without parsing, and shows the difference between
|
||||||
|
`load(std::move(image))` (owned) and `load(image)` (borrowed). It then damages one byte of the image and shows
|
||||||
|
`image_check::full` rejecting it with `parse_error.116`, while `image_check::bounds` -- meant for a cache the
|
||||||
|
process already trusts -- still reads it without going out of bounds.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_document__load.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_document__load.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [save](save.md) - write the document as an image
|
||||||
|
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
|
||||||
|
- [parse](parse.md) - deserialize from JSON text instead of an image
|
||||||
|
- [Images](../../features/json_view.md#images) - why and when to use images
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -132,6 +132,7 @@ integer type becomes a floating-point value.
|
|||||||
- [accept](accept.md) - check whether the input is valid JSON
|
- [accept](accept.md) - check whether the input is valid JSON
|
||||||
- [read](read.md) - (re-)parse into this document, reusing its memory
|
- [read](read.md) - (re-)parse into this document, reusing its memory
|
||||||
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
|
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
|
||||||
|
- [load](load.md) - read a document from an image instead of parsing JSON text
|
||||||
- [`BasicJsonType::parse`](../basic_json/parse.md) - the corresponding function of `basic_json`
|
- [`BasicJsonType::parse`](../basic_json/parse.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# <small>nlohmann::basic_json_document::</small>push_back
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template<typename V>
|
||||||
|
view_type push_back(view_type array, V&& value);
|
||||||
|
```
|
||||||
|
|
||||||
|
Appends `value` as a new last element of `array`. A [null](../basic_json_view/is_null.md) `array` first becomes an
|
||||||
|
empty array, the same way [`set`](set.md) turns a null `object` into an empty object.
|
||||||
|
|
||||||
|
`value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any* document -- read-only or
|
||||||
|
editable, and it does not have to be `array`'s own document -- which is copied so that nothing is shared with the
|
||||||
|
source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers,
|
||||||
|
strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
|
||||||
|
|
||||||
|
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
|
||||||
|
has `push_back`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
|
||||||
|
|
||||||
|
## Template parameters
|
||||||
|
|
||||||
|
`V`
|
||||||
|
: the type of `value`, deduced; see above for what is accepted.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`array` (in)
|
||||||
|
: the array (or null value) to append to
|
||||||
|
|
||||||
|
`value` (in)
|
||||||
|
: the value to append
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
a view of the new last element of `array`, now holding `value`
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
|
||||||
|
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
|
||||||
|
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
|
||||||
|
for the encoding that is not reclaimed. A failure of a later allocation -- while `array` switches from its parsed
|
||||||
|
layout to a growable block, or while that block grows, see [Notes](#notes) -- can still leave a partial effect, such
|
||||||
|
as a null `array` argument already turned into an empty array even though `value` itself was not appended.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) if `array` is neither an array nor
|
||||||
|
null -- the same message [`BasicJsonType::push_back`](../basic_json/push_back.md) throws for the same type. Throws
|
||||||
|
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
|
||||||
|
document") if `array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a *different* document.
|
||||||
|
Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
|
||||||
|
[discarded](../basic_json_view/is_discarded.md) view or a [discarded](../basic_json/is_discarded.md) `BasicJsonType`
|
||||||
|
value, and [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or contains) a
|
||||||
|
binary value -- `BasicJsonType` can hold one, but a `json_document` cannot. Throws
|
||||||
|
[`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `value` is (or contains) a string that is
|
||||||
|
not valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Amortized constant, plus time linear in the size of `value` to encode it into the document's storage (constant for
|
||||||
|
a scalar, linear in the number of nested values for an array or object): the elements of `array` move to a growable
|
||||||
|
block of links the first time it is appended to (or [`set`](set.md) on), and that block itself grows -- doubling its
|
||||||
|
capacity, so the cost of growing it amortizes to constant per element -- only once it runs out of room. See
|
||||||
|
[Notes](#notes).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Like [`set`](set.md) on a member or an element, `push_back` never moves an existing element itself -- only where
|
||||||
|
`array`'s *links* to its elements live -- so a view of an existing element of `array` stays valid across a
|
||||||
|
`push_back`, but any iterator already taken over `array` is invalidated, since it was walking the old layout. See
|
||||||
|
[Edits](index.md#edits) for what stays valid across an edit in general.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below appends records to an array one at a time, as they might arrive from a stream of events,
|
||||||
|
without ever building a `BasicJsonType` value for the array or for the records already in it, and shows that a
|
||||||
|
view taken from an earlier `push_back` still refers to the same element once later ones have run.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_document__push_back.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_document__push_back.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||||
|
- [insert](insert.md) - insert an element into an array before a given position
|
||||||
|
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||||
|
- [root](root.md) - the view of the root value
|
||||||
|
- [`BasicJsonType::push_back`](../basic_json/push_back.md) - the corresponding function of `basic_json`
|
||||||
|
- [Edits](index.md#edits) - what an edit guarantees, for every overload
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -75,6 +75,7 @@ many documents of similar size should therefore keep one document and call `read
|
|||||||
|
|
||||||
- [parse](parse.md) - deserialize from a compatible input
|
- [parse](parse.md) - deserialize from a compatible input
|
||||||
- [root](root.md) - the view of the root value
|
- [root](root.md) - the view of the root value
|
||||||
|
- [load](load.md) - read a document from an image instead of parsing JSON text
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
# <small>nlohmann::basic_json_document::</small>save
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::vector<std::uint8_t> save() const;
|
||||||
|
```
|
||||||
|
|
||||||
|
Writes the document as an *image*: a byte buffer that [`load`](load.md) reads back without parsing. The image holds
|
||||||
|
the node index, the source text (plus, for an edited document, the number tokens edits wrote), and the decoded
|
||||||
|
strings (plus the strings edits wrote) -- everything [`root()`](root.md) needs, with nothing left to parse.
|
||||||
|
|
||||||
|
An edited document is written in its *current* state, with its values in document order, the way the library's own
|
||||||
|
parser would have produced them for that JSON text: a member [`set`](set.md) added goes at the end, an
|
||||||
|
[`erase`](erase.md)d member leaves no trace, and a float that is not finite (NaN or positive/negative infinity)
|
||||||
|
becomes null, the same substitution [`dump()`](../basic_json_view/dump.md) makes. The same document always saves to
|
||||||
|
the same bytes -- also across `BasicJsonType` and `#!cpp Editable`, since the image reflects document order and
|
||||||
|
values only, not which specialization produced them.
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
The image, as a `#!cpp std::vector<std::uint8_t>`. Pass it, or a pointer to its data together with its size, to
|
||||||
|
[`load`](load.md) to read the document back.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong guarantee: `save()` does not modify `#!cpp *this` (it is `#!cpp const`), so if it throws, the document is left
|
||||||
|
exactly as it was, and the partially built image is discarded with the exception.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
Throws [`type_error.320`](../../home/exceptions.md#jsonexceptiontype_error320) if the document is
|
||||||
|
[discarded](is_discarded.md) -- a default-constructed document, or one a failed [`parse()`](parse.md)/
|
||||||
|
[`read()`](read.md) with `allow_exceptions == false` left discarded.
|
||||||
|
|
||||||
|
On a big-endian target, throws `type_error.320` with a different message instead: the image format is little-endian
|
||||||
|
only (see [Notes](#notes)).
|
||||||
|
|
||||||
|
Throws [`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the node count, the text, or
|
||||||
|
the decoded strings of the image would individually reach 4 GiB -- the same 32-bit offsets
|
||||||
|
[`parse()`](parse.md#exceptions) and, for edits, [`set`](set.md)/[`push_back`](push_back.md) are already limited to.
|
||||||
|
|
||||||
|
!!! failure "Example messages"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.320] cannot save a discarded json_document
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.type_error.320] json_document images need a little-endian target
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the size of the document: the number of nodes, plus the length of the text and the decoded strings that end
|
||||||
|
up in the image.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
**Format.** The image begins with a 64-byte header (the magic bytes `#!cpp "NJVI"`, a version number, the node count,
|
||||||
|
and the sizes of the text and the decoded strings, all little-endian), followed by the nodes
|
||||||
|
([16 bytes each](../../home/architecture.md#node-index-of-json-views)), the text and a `#!cpp '\0'`, and the decoded
|
||||||
|
strings and a `#!cpp '\0'`. [`load`](load.md) checks the header, and the sizes it describes, before reading anything
|
||||||
|
else -- see [`load`'s Exceptions](load.md#exceptions).
|
||||||
|
|
||||||
|
!!! warning "Experimental"
|
||||||
|
|
||||||
|
The image format is versioned but not yet stable: it may change in an incompatible way before it is declared
|
||||||
|
stable. Use images to cache a document within one build of the library, or to hand one to another process running
|
||||||
|
the *same* build on the *same* (little-endian) machine -- not as a long-term storage format. Keep the original
|
||||||
|
JSON text if you need to read a saved document back with a future library version.
|
||||||
|
|
||||||
|
**Little-endian only.** The image is written as raw little-endian bytes, with no byte-swapping. `save()` (and
|
||||||
|
[`load`](load.md)) throw `type_error.320` on a big-endian target rather than silently produce bytes a big-endian
|
||||||
|
reader could not interpret correctly.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example "Caching a parsed document as an image"
|
||||||
|
|
||||||
|
The example below saves a parsed configuration as an image -- the way a service might cache one to answer later
|
||||||
|
requests without parsing the text again -- and confirms that loading it back gives exactly the same result as
|
||||||
|
parsing did, and that saving is deterministic.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_document__save.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_document__save.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [load](load.md) - read an image written by `save()`
|
||||||
|
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
|
||||||
|
- [`basic_json_view::dump`](../basic_json_view/dump.md) - serialize the document to JSON text instead of an image
|
||||||
|
- [Images](../../features/json_view.md#images) - why and when to use images
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
# <small>nlohmann::basic_json_document::</small>set
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// (1)
|
||||||
|
template<typename V>
|
||||||
|
view_type set(view_type target, V&& value);
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
template<typename V>
|
||||||
|
view_type set(view_type object, string_view_t key, V&& value);
|
||||||
|
|
||||||
|
// (3)
|
||||||
|
template<typename I, typename V>
|
||||||
|
view_type set(view_type array, I idx, V&& value);
|
||||||
|
|
||||||
|
// (4)
|
||||||
|
template<typename V>
|
||||||
|
view_type set(const json_pointer& ptr, V&& value);
|
||||||
|
```
|
||||||
|
|
||||||
|
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
|
||||||
|
has `set`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
|
||||||
|
|
||||||
|
1. Replaces the value `target` refers to with `value`.
|
||||||
|
2. Sets the member `key` of the object `object` to `value`: assigns it if `object` already has a member with this
|
||||||
|
key -- the first one, should the key occur more than once, and the later duplicates are then dropped (see the
|
||||||
|
[Notes](#notes) below) -- or appends a new member at the end otherwise. A [null](../basic_json_view/is_null.md)
|
||||||
|
`object` first becomes an empty object.
|
||||||
|
3. Assigns `value` to the element at index `idx` of the array `array`, which must already exist (`#!cpp idx <
|
||||||
|
array.size()`).
|
||||||
|
4. Sets the value the JSON pointer `ptr` refers to, relative to [`root()`](root.md), to `value`. The *parent* of the
|
||||||
|
target must already exist: an object member is set as in 2. (added if it does not exist yet), an array element is
|
||||||
|
assigned as in 3., and a last reference token of `#!cpp "-"`, or equal to the size of the array, appends `value`
|
||||||
|
instead, exactly as [`push_back`](push_back.md) would. An empty `ptr` sets [`root()`](root.md) itself, as in 1.
|
||||||
|
|
||||||
|
In every overload, `value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any*
|
||||||
|
document -- read-only or editable, and it does not have to be `target`'s/`object`'s/`array`'s own document -- which
|
||||||
|
is copied so that nothing is shared with the source document afterward; a `BasicJsonType` value; or anything
|
||||||
|
`BasicJsonType` can be constructed from (numbers, strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
|
||||||
|
|
||||||
|
## Template parameters
|
||||||
|
|
||||||
|
`V`
|
||||||
|
: the type of `value`, deduced; see above for what is accepted.
|
||||||
|
|
||||||
|
`I`
|
||||||
|
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
|
||||||
|
`idx` do not participate in overload resolution).
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`target` (in)
|
||||||
|
: the value to replace
|
||||||
|
|
||||||
|
`object` (in)
|
||||||
|
: the object (or null value) whose member to set
|
||||||
|
|
||||||
|
`array` (in)
|
||||||
|
: the array whose element to assign
|
||||||
|
|
||||||
|
`key` (in)
|
||||||
|
: the key of the member to set
|
||||||
|
|
||||||
|
`idx` (in)
|
||||||
|
: the index of the element to assign; a negative value throws (see [Exceptions](#exceptions))
|
||||||
|
|
||||||
|
`ptr` (in)
|
||||||
|
: a JSON pointer to the value to set, relative to `root()`
|
||||||
|
|
||||||
|
`value` (in)
|
||||||
|
: the new value
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
1. a view of `target`, now holding `value`
|
||||||
|
2. a view of the member `key` of `object`, now holding `value`
|
||||||
|
3. a view of the element `idx` of `array`, now holding `value`
|
||||||
|
4. a view of the value `ptr` refers to, now holding `value`
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
|
||||||
|
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
|
||||||
|
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
|
||||||
|
for the encoding that is not reclaimed. A failure of a later allocation -- while an edited array or object switches
|
||||||
|
from its parsed layout to a growable block, see [Notes](#notes) -- can still leave a partial effect, such as a
|
||||||
|
[null](../basic_json_view/is_null.md) `object`/`array` argument already turned into an empty object/array even
|
||||||
|
though `value` itself was not linked in.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
1. Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
|
||||||
|
[discarded](../basic_json_view/is_discarded.md) view, or a [discarded](../basic_json/is_discarded.md)
|
||||||
|
`BasicJsonType` value (e.g. `#!cpp BasicJsonType(value_t::discarded)`) -- an object or array `value`, of either
|
||||||
|
kind, is fine and is encoded as a whole subtree.
|
||||||
|
2. Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if `object` is neither an object
|
||||||
|
nor null -- the same message [`operator[]`](../basic_json_view/operator%5B%5D.md) throws for a string argument on
|
||||||
|
such a value. Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `key` is not
|
||||||
|
valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
|
||||||
|
Also throws what 1. throws for `value`.
|
||||||
|
3. Throws `type_error.305` if `array` is not an array -- the same message `operator[]` throws for a numeric argument
|
||||||
|
on such a value. Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is
|
||||||
|
negative, or if `#!cpp idx >= array.size()`. Also throws what 1. throws for `value`.
|
||||||
|
4. Throws what [`at`](../basic_json_view/at.md) throws (overload 3) for resolving `ptr`'s parent, except that a
|
||||||
|
missing object member or an array index equal to the array's size at the very last reference token is not an
|
||||||
|
error there (it becomes a new member or an appended element) instead of
|
||||||
|
[`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403)/[`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402).
|
||||||
|
For the last reference token itself: if the parent is an object (or a primitive value, where it throws
|
||||||
|
`type_error.305`), throws what 2. throws; if the parent is an array, throws what 3. throws for an index that is
|
||||||
|
out of range, or, for a token that is not a valid array index,
|
||||||
|
[`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) (a leading `#!cpp '0'`),
|
||||||
|
[`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) (not a number),
|
||||||
|
[`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) (too large for `size_type`), or
|
||||||
|
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) (an empty token). Also throws what 1.
|
||||||
|
throws for `value`.
|
||||||
|
|
||||||
|
Every overload also throws [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or
|
||||||
|
contains) a binary value -- `BasicJsonType` can hold one, but a `json_document` cannot -- and
|
||||||
|
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
|
||||||
|
document") if `target`/`object`/`array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a
|
||||||
|
*different* document (overloads 1-3 only; overload 4 always starts from this document's own [`root()`](root.md)).
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
1. Linear in the size of `value` (encoding it into the document's storage): constant for a scalar, linear in the
|
||||||
|
number of nested values for an array or object. If `target` is itself an array or object that spans more than one
|
||||||
|
node in its parent's original, unedited layout, and `value` is a scalar, replacing it additionally costs time
|
||||||
|
linear in the number of elements of that parent, the *first* time -- see [Notes](#notes).
|
||||||
|
2. Linear in the number of members of `object`, to find an existing member with `key`, plus the complexity of 1. for
|
||||||
|
`value`.
|
||||||
|
3. Constant, plus the complexity of 1. for `value`.
|
||||||
|
4. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
||||||
|
that level or the index into the array (as [`at`](../basic_json_view/at.md)), plus the complexity of 2. or 3. for
|
||||||
|
the last token.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
!!! info "Duplicate keys"
|
||||||
|
|
||||||
|
If `object` already has more than one member with `key` (2.), the *first* one is assigned `value` and every
|
||||||
|
later member with the same key is removed -- so that a lookup, an iteration, and
|
||||||
|
[`materialize()`](../basic_json_view/materialize.md) of `object` afterward all agree on a single value for
|
||||||
|
`key`, the same way [`operator[]`](../basic_json_view/operator%5B%5D.md) already picks the first occurrence of a
|
||||||
|
duplicate key for reading. See the [Notes on duplicate keys](../basic_json_view/operator%5B%5D.md#notes) of
|
||||||
|
`operator[]`.
|
||||||
|
|
||||||
|
Setting a member (2.) or an element (3., through 4.) of an array or object whose elements have not been edited
|
||||||
|
before switches it from its parsed layout to a growable block holding links to its elements; a later
|
||||||
|
[`push_back`](push_back.md) or `set` on the same container reuses that block, growing it (amortized constant time)
|
||||||
|
only once it runs out of room. This never moves an element itself -- only where the container's *links* to its
|
||||||
|
elements live -- so a view of an element stays valid, but any iterator already taken over the container is
|
||||||
|
invalidated, since it was walking the old layout. See [Edits](index.md#edits) for what stays valid across an edit in
|
||||||
|
general.
|
||||||
|
|
||||||
|
The same switch happens, for the same reason, when overload 1. replaces a multi-node array/object value with a
|
||||||
|
scalar: the *parent's* element sequence is what has to switch to links, not `target` itself, because the parent
|
||||||
|
originally stepped over `target`'s whole subtree by its node count, which no longer applies once `target` is a
|
||||||
|
one-node scalar.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example "Example: (1)/(2)/(3)/(4) replace a value, set a member, assign an element, set via a JSON pointer"
|
||||||
|
|
||||||
|
The example below edits a small configuration document -- replacing a value, adding an object member, assigning
|
||||||
|
an array element, and reaching a field through a JSON pointer -- and shows what
|
||||||
|
[`dump()`](../basic_json_view/dump.md) preserves that is lost once the same edits are made on a `BasicJsonType`
|
||||||
|
value instead: the order object members were written in, and the exact spelling of a number that was never
|
||||||
|
touched.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_document__set.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_document__set.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [push_back](push_back.md) - append to an array
|
||||||
|
- [insert](insert.md) - insert an element into an array
|
||||||
|
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||||
|
- [root](root.md) - the view of the root value, the starting point of overload 4
|
||||||
|
- [`basic_json_view::dump`](../basic_json_view/dump.md) - serialize the document, keeping an untouched number's
|
||||||
|
spelling with `#!cpp number_format::source`
|
||||||
|
- [Edits](index.md#edits) - what an edit guarantees, for every overload
|
||||||
|
- [Editing a document](../../features/json_view.md#editing-a-document) - why editable documents keep the source
|
||||||
|
text's order and number spelling
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType, bool Editable = false>
|
||||||
class basic_json_view;
|
class basic_json_view;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -27,16 +27,30 @@ subtree on demand. [`operator[]`](operator%5B%5D.md), [`at`](at.md), [`contains`
|
|||||||
[`operator!=`](operator_ne.md) compare two views, or a view and a `BasicJsonType` value, without ever building a
|
[`operator!=`](operator_ne.md) compare two views, or a view and a `BasicJsonType` value, without ever building a
|
||||||
`BasicJsonType` value for a view; no ordering comparison (`#!cpp operator<`) is provided.
|
`BasicJsonType` value for a view; no ordering comparison (`#!cpp operator<`) is provided.
|
||||||
|
|
||||||
|
`basic_json_view` itself is always read-only -- it never has a `set` or `push_back` of its own. A view of an
|
||||||
|
**editable** document (`#!cpp Editable == true`) sees every edit made through
|
||||||
|
[`basic_json_document::set`](../basic_json_document/set.md) and
|
||||||
|
[`basic_json_document::push_back`](../basic_json_document/push_back.md): once a value is changed, every view that
|
||||||
|
still refers to it -- including ones taken before the change -- reads the new value. See
|
||||||
|
[Edits](../basic_json_document/index.md#edits).
|
||||||
|
|
||||||
## Template parameters
|
## Template parameters
|
||||||
|
|
||||||
`BasicJsonType`
|
`BasicJsonType`
|
||||||
: a specialization of [`basic_json`](../basic_json/index.md), matching the
|
: a specialization of [`basic_json`](../basic_json/index.md), matching the
|
||||||
[`basic_json_document`](../basic_json_document/index.md) the view was taken from.
|
[`basic_json_document`](../basic_json_document/index.md) the view was taken from.
|
||||||
|
|
||||||
|
`Editable`
|
||||||
|
: whether the view is of an editable document, matching the [`basic_json_document`](../basic_json_document/index.md)
|
||||||
|
it was taken from (optional, `#!cpp false` by default). See [Edits](../basic_json_document/index.md#edits).
|
||||||
|
|
||||||
## Specializations
|
## Specializations
|
||||||
|
|
||||||
- [**json_view**](../json_view.md) - views of a [`json_document`](../json_document.md)
|
- [**json_view**](../json_view.md) - views of a [`json_document`](../json_document.md)
|
||||||
- [**ordered_json_view**](../ordered_json_view.md) - views of an [`ordered_json_document`](../ordered_json_document.md)
|
- [**ordered_json_view**](../ordered_json_view.md) - views of an [`ordered_json_document`](../ordered_json_document.md)
|
||||||
|
- [**json_editable_view**](../json_editable_view.md) - views of a [`json_editable_document`](../json_editable_document.md)
|
||||||
|
- [**ordered_json_editable_view**](../ordered_json_editable_view.md) - views of an
|
||||||
|
[`ordered_json_editable_document`](../ordered_json_editable_document.md)
|
||||||
|
|
||||||
## Member types
|
## Member types
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# <small>nlohmann::</small>json_editable_document
|
||||||
|
|
||||||
|
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using json_editable_document = basic_json_document<json, true>;
|
||||||
|
```
|
||||||
|
|
||||||
|
This type is an **editable** [`basic_json_document`](basic_json_document/index.md) of the default
|
||||||
|
[`json`](json.md) specialization: in addition to everything [`json_document`](json_document.md) offers,
|
||||||
|
[`set`](basic_json_document/set.md) and [`push_back`](basic_json_document/push_back.md) change values after
|
||||||
|
parsing, without ever rewriting the source text -- see [Edits](basic_json_document/index.md#edits) and
|
||||||
|
[Editing a document](../features/json_view.md#editing-a-document).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below patches two fields of a small configuration document -- changing one and adding another --
|
||||||
|
and dumps it back out with the member order and the spelling of the untouched number preserved, something a
|
||||||
|
plain [`json`](json.md) value cannot do.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/json_editable_document.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/json_editable_document.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [json_editable_view](json_editable_view.md) - a view of a value of a `json_editable_document`
|
||||||
|
- [json_document](json_document.md) - the read-only document this type adds edits to
|
||||||
|
- [ordered_json_editable_document](ordered_json_editable_document.md) - the corresponding editable document for
|
||||||
|
`ordered_json`
|
||||||
|
- [Edits](basic_json_document/index.md#edits) - what an edit guarantees
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Since version 3.13.0.
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# <small>nlohmann::</small>json_editable_view
|
||||||
|
|
||||||
|
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using json_editable_view = basic_json_view<json, true>;
|
||||||
|
```
|
||||||
|
|
||||||
|
This type is a [`basic_json_view`](basic_json_view/index.md) of a value of a
|
||||||
|
[`json_editable_document`](json_editable_document.md). It offers the same read-only interface as
|
||||||
|
[`json_view`](json_view.md); what is different is what it can be a view *of* -- a value that
|
||||||
|
[`set`](basic_json_document/set.md) and [`push_back`](basic_json_document/push_back.md) can change, with every view
|
||||||
|
still referring to it seeing the change, see [Edits](basic_json_document/index.md#edits).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below is the same as [`json_editable_document`'s](json_editable_document.md): every view read back
|
||||||
|
out of the document -- `#!cpp doc.root()` and the views nested under it -- sees the edits made through `set`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/json_editable_document.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/json_editable_document.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [json_editable_document](json_editable_document.md) - the document type this view refers into
|
||||||
|
- [json_view](json_view.md) - the corresponding read-only view
|
||||||
|
- [ordered_json_editable_view](ordered_json_editable_view.md) - the corresponding view for
|
||||||
|
`ordered_json_editable_document`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Since version 3.13.0.
|
||||||
@@ -60,13 +60,6 @@ header. See also the [macro overview page](../../features/macros.md).
|
|||||||
- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums
|
- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums
|
||||||
- [**JSON_DISABLE_TUPLE_REFERENCE_CONVERSION**](json_disable_tuple_reference_conversion.md) - switch off conversion from a one-element tuple of a JSON reference
|
- [**JSON_DISABLE_TUPLE_REFERENCE_CONVERSION**](json_disable_tuple_reference_conversion.md) - switch off conversion from a one-element tuple of a JSON reference
|
||||||
- [**JSON_USE_IMPLICIT_CONVERSIONS**](json_use_implicit_conversions.md) - control implicit conversions
|
- [**JSON_USE_IMPLICIT_CONVERSIONS**](json_use_implicit_conversions.md) - control implicit conversions
|
||||||
- [**JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS**](json_use_objects_for_enum_keyed_maps.md) - opt in to storing maps with enum
|
|
||||||
keys as objects
|
|
||||||
|
|
||||||
## Deprecated functions
|
|
||||||
|
|
||||||
- [**JSON_DELETE_DEPRECATED_FUNCTIONS**](json_delete_deprecated_functions.md) - opt in to deleting the deprecated
|
|
||||||
functions ahead of their removal in version 4.0.0
|
|
||||||
|
|
||||||
## Comparison behavior
|
## Comparison behavior
|
||||||
|
|
||||||
|
|||||||
@@ -50,11 +50,9 @@ The default value is `0` (disabled — existing behavior is preserved).
|
|||||||
```
|
```
|
||||||
|
|
||||||
Code that relies on these producing arrays must use `json::array()` instead (see below). Lists with more than one
|
Code that relies on these producing arrays must use `json::array()` instead (see below). Lists with more than one
|
||||||
element, and a single `[string, value]` pair *written as a braced list*, such as `{{"key", "value"}}`, which still
|
element, and a single `[string, value]` pair such as `{{"key", "value"}}`, which still creates an object, are not
|
||||||
creates an object, are not affected. This exception is based on how the pair is written, not on the shape of its
|
affected. The library's own conversions are not affected either: for example, `std::tuple<int>{5}` still becomes
|
||||||
value: an existing JSON value that happens to be a two-element array with a string as its first element, such as
|
`[5]`.
|
||||||
`json arr = {"key", 42};`, is still copied by `json j{arr};` rather than turned into an object. The library's own
|
|
||||||
conversions are not affected either: for example, `std::tuple<int>{5}` still becomes `[5]`.
|
|
||||||
|
|
||||||
!!! note "ABI compatibility"
|
!!! note "ABI compatibility"
|
||||||
|
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
# JSON_DELETE_DEPRECATED_FUNCTIONS
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_DELETE_DEPRECATED_FUNCTIONS /* value */
|
|
||||||
```
|
|
||||||
|
|
||||||
When defined to `1`, all [deprecated functions](../../community/roadmap.md#removal-of-deprecated-functions) of the
|
|
||||||
library are declared as deleted (`= delete`) instead of only being marked as deprecated. Code that still calls one of
|
|
||||||
them no longer compiles. This way, you can find all calls that need to be replaced before version 4.0.0 removes these
|
|
||||||
functions; the [migration guide](../../integration/migration_guide.md#replace-deprecated-functions) describes how.
|
|
||||||
|
|
||||||
A deleted function, unlike a removed one, still takes part in overload resolution. A call that would select it
|
|
||||||
therefore fails to compile instead of silently selecting another overload. This matters for the deprecated
|
|
||||||
`from_*(ptr, len)` overloads of [`from_cbor`](../basic_json/from_cbor.md), [`from_msgpack`](../basic_json/from_msgpack.md),
|
|
||||||
[`from_ubjson`](../basic_json/from_ubjson.md), [`from_bjdata`](../basic_json/from_bjdata.md),
|
|
||||||
[`from_bon8`](../basic_json/from_bon8.md), and [`from_bson`](../basic_json/from_bson.md): without them, a call like
|
|
||||||
`from_cbor(ptr, len)` would compile, read `ptr` as a NUL-terminated string, and convert `len` to the `strict` parameter.
|
|
||||||
|
|
||||||
The macro does not affect the deprecated legacy comparison of discarded values, which is controlled by
|
|
||||||
[`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](json_use_legacy_discarded_value_comparison.md).
|
|
||||||
|
|
||||||
## Default definition
|
|
||||||
|
|
||||||
The default value is `0` (disabled, the deprecated functions can still be called, and the compiler warns about it).
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_DELETE_DEPRECATED_FUNCTIONS 0
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
!!! info "CMake option"
|
|
||||||
|
|
||||||
The macro can also be set with the CMake option
|
|
||||||
[`JSON_DeleteDeprecatedFunctions`](../../integration/cmake.md#json_deletedeprecatedfunctions) (`OFF` by default).
|
|
||||||
|
|
||||||
!!! warning "Opt-in only"
|
|
||||||
|
|
||||||
This macro must be defined **before** including `<nlohmann/json.hpp>`. Defining it after the include has no
|
|
||||||
effect. Define it for the whole project to avoid different declarations of the same class in different
|
|
||||||
translation units.
|
|
||||||
|
|
||||||
!!! note "ABI compatibility"
|
|
||||||
|
|
||||||
The macro only turns calls that compile into calls that do not; it does not change the layout or the behavior of
|
|
||||||
any type. Its value is therefore not encoded in the [namespace](../../features/namespace.md).
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
??? example "Example: default behavior (macro not defined)"
|
|
||||||
|
|
||||||
Without the macro, the deprecated overload is called, and the compiler warns about it:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
const std::vector<std::uint8_t> v = {0x82, 0x01, 0x02};
|
|
||||||
auto j = json::from_cbor(v.data(), v.size());
|
|
||||||
// warning: 'from_cbor' is deprecated: Since 3.8.0; use from_cbor(ptr, ptr + len)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
??? example "Example: deleted deprecated functions (macro defined to 1)"
|
|
||||||
|
|
||||||
With the macro, the call does not compile:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_DELETE_DEPRECATED_FUNCTIONS 1
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
const std::vector<std::uint8_t> v = {0x82, 0x01, 0x02};
|
|
||||||
auto j = json::from_cbor(v.data(), v.size());
|
|
||||||
// error: call to deleted function 'from_cbor'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## See also
|
|
||||||
|
|
||||||
- [Roadmap: removal of deprecated functions](../../community/roadmap.md#removal-of-deprecated-functions) - the
|
|
||||||
deprecated functions and the version they were deprecated in
|
|
||||||
- [Migration guide: replace deprecated functions](../../integration/migration_guide.md#replace-deprecated-functions) -
|
|
||||||
how to replace each deprecated function
|
|
||||||
|
|
||||||
## Version history
|
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
|
||||||
- Planned to be removed in version 4.0.0, which removes the deprecated functions. The deprecated `from_*(ptr, len)`
|
|
||||||
overloads stay deleted in version 4.0.0.
|
|
||||||
@@ -112,4 +112,3 @@ The default value is `0` (disabled — existing behavior is preserved).
|
|||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
- Added in version 3.13.0.
|
||||||
- Planned to become the default (with the macro removed) in version 4.0.0.
|
|
||||||
@@ -44,7 +44,7 @@ By default, implicit conversions are enabled.
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example: implicit and explicit conversions"
|
??? example "Example: implicit conversion"
|
||||||
|
|
||||||
This is an example for an implicit conversion:
|
This is an example for an implicit conversion:
|
||||||
|
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
# JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS /* value */
|
|
||||||
```
|
|
||||||
|
|
||||||
When defined to `1`, maps whose keys are enums (such as `std::map<E, T>` or `std::unordered_map<E, T>`) are stored as
|
|
||||||
JSON objects, using the enum's own conversion for the keys. By default, they are stored as arrays of `[key, value]`
|
|
||||||
pairs.
|
|
||||||
|
|
||||||
## Default definition
|
|
||||||
|
|
||||||
The default value is `0` (disabled — existing behavior is preserved).
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 0
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
!!! note "Background"
|
|
||||||
|
|
||||||
JSON object keys are strings, so a map is only stored as an object if its keys can be converted to a string type.
|
|
||||||
Enums are not, even if [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) maps them to strings, so a
|
|
||||||
map with enum keys becomes an array of `[key, value]` pairs:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[["stopped", "aa"], ["completed", "bb"]]
|
|
||||||
```
|
|
||||||
|
|
||||||
With this macro, the same map becomes an object
|
|
||||||
(see [#4378](https://github.com/nlohmann/json/issues/4378)):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"completed": "bb", "stopped": "aa"}
|
|
||||||
```
|
|
||||||
|
|
||||||
!!! note "Maps with non-unique keys"
|
|
||||||
|
|
||||||
Maps that allow duplicate keys, such as `std::multimap<E, T>` or `std::unordered_multimap<E, T>`, are not affected
|
|
||||||
by the macro and are still stored as arrays of `[key, value]` pairs, as an object cannot hold duplicate keys.
|
|
||||||
|
|
||||||
!!! note "Reading"
|
|
||||||
|
|
||||||
Reading is not affected by the macro: a map with enum keys can always be read from both an array of pairs and an
|
|
||||||
object. For the latter, each key is converted to the enum with its `from_json` function, e.g., the one defined by
|
|
||||||
[`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md). Data written without the macro can therefore
|
|
||||||
still be read after enabling it.
|
|
||||||
|
|
||||||
!!! warning "Keys must serialize to distinct strings"
|
|
||||||
|
|
||||||
Each key is converted with the enum's `to_json` function. If a key is not converted to a string (for instance, an
|
|
||||||
enum without [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md), which is stored as an integer, or an
|
|
||||||
enumerator mapped to `nullptr`), [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) is thrown.
|
|
||||||
If two keys are converted to the same string (for instance, because
|
|
||||||
[`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) maps an unlisted enumerator to the first entry),
|
|
||||||
[`type_error.318`](../../home/exceptions.md#jsonexceptiontype_error318) is thrown. In both cases, the target value
|
|
||||||
is not changed.
|
|
||||||
|
|
||||||
!!! warning "Opt-in only"
|
|
||||||
|
|
||||||
This macro must be defined **before** including `<nlohmann/json.hpp>`. Defining it after the include has no effect.
|
|
||||||
|
|
||||||
!!! note "ABI compatibility"
|
|
||||||
|
|
||||||
The value of this macro is encoded in the [namespace](../../features/namespace.md) (tag `_ekmo`), resulting in
|
|
||||||
distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program
|
|
||||||
without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
??? example "Example: default behavior (macro not defined)"
|
|
||||||
|
|
||||||
Without the macro, a map with enum keys is stored as an array of pairs:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#include <map>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
enum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };
|
|
||||||
|
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState, {
|
|
||||||
{TS_STOPPED, "stopped"},
|
|
||||||
{TS_RUNNING, "running"},
|
|
||||||
{TS_COMPLETED, "completed"},
|
|
||||||
})
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
std::map<TaskState, std::string> m = {{TS_STOPPED, "aa"}, {TS_COMPLETED, "bb"}};
|
|
||||||
|
|
||||||
json j = m;
|
|
||||||
// j is [["stopped","aa"],["completed","bb"]]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
??? example "Example: objects for enum-keyed maps (macro defined to 1)"
|
|
||||||
|
|
||||||
With the macro, the same map is stored as an object:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 1
|
|
||||||
#include <map>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
enum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };
|
|
||||||
|
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState, {
|
|
||||||
{TS_STOPPED, "stopped"},
|
|
||||||
{TS_RUNNING, "running"},
|
|
||||||
{TS_COMPLETED, "completed"},
|
|
||||||
})
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
std::map<TaskState, std::string> m = {{TS_STOPPED, "aa"}, {TS_COMPLETED, "bb"}};
|
|
||||||
|
|
||||||
json j = m;
|
|
||||||
// j is {"completed":"bb","stopped":"aa"}
|
|
||||||
|
|
||||||
auto m2 = j.get<std::map<TaskState, std::string>>();
|
|
||||||
// m2 == m
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## See also
|
|
||||||
|
|
||||||
- [Specializing enum conversion](../../features/enum_conversion.md)
|
|
||||||
- [**NLOHMANN_JSON_SERIALIZE_ENUM**](nlohmann_json_serialize_enum.md) - serialize/deserialize an enum
|
|
||||||
- [**NLOHMANN_JSON_SERIALIZE_ENUM_STRICT**](nlohmann_json_serialize_enum_strict.md) - serialize/deserialize an enum with
|
|
||||||
exceptions
|
|
||||||
|
|
||||||
## Version history
|
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
|
||||||
@@ -41,9 +41,6 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
conversion. Select this default pair carefully. See example 1 below.
|
conversion. Select this default pair carefully. See example 1 below.
|
||||||
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
||||||
list will be returned when converting to or from JSON. See example 2 below.
|
list will be returned when converting to or from JSON. See example 2 below.
|
||||||
- Maps with enum keys (e.g., `std::map<ENUM_TYPE, T>`) are stored as arrays of `[key, value]` pairs by default.
|
|
||||||
Define [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md) to store them as objects
|
|
||||||
with the converted keys. Such maps can be read from both forms.
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -83,7 +80,6 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
- [Specializing enum conversion](../../features/enum_conversion.md)
|
- [Specializing enum conversion](../../features/enum_conversion.md)
|
||||||
- [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](./nlohmann_json_serialize_enum_strict.md)
|
- [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](./nlohmann_json_serialize_enum_strict.md)
|
||||||
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
|
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
|
||||||
- [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md)
|
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
`"enum value out of range for <type>"`.
|
`"enum value out of range for <type>"`.
|
||||||
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
||||||
list will be returned when converting to or from JSON. See example 2 below.
|
list will be returned when converting to or from JSON. See example 2 below.
|
||||||
- Maps with enum keys (e.g., `std::map<ENUM_TYPE, T>`) are stored as arrays of `[key, value]` pairs by default.
|
|
||||||
Define [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md) to store them as objects
|
|
||||||
with the converted keys. Such maps can be read from both forms.
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -102,7 +99,6 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
- [Specializing enum conversion](../../features/enum_conversion.md)
|
- [Specializing enum conversion](../../features/enum_conversion.md)
|
||||||
- [`NLOHMANN_JSON_SERIALIZE_ENUM`](./nlohmann_json_serialize_enum.md)
|
- [`NLOHMANN_JSON_SERIALIZE_ENUM`](./nlohmann_json_serialize_enum.md)
|
||||||
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
|
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
|
||||||
- [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md)
|
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# <small>nlohmann::</small>ordered_json_editable_document
|
||||||
|
|
||||||
|
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using ordered_json_editable_document = basic_json_document<ordered_json, true>;
|
||||||
|
```
|
||||||
|
|
||||||
|
This type is an **editable** [`basic_json_document`](basic_json_document/index.md) of the
|
||||||
|
[`ordered_json`](ordered_json.md) specialization: [`set`](basic_json_document/set.md) and
|
||||||
|
[`push_back`](basic_json_document/push_back.md) change values after parsing, as for
|
||||||
|
[`json_editable_document`](json_editable_document.md), and
|
||||||
|
[`materialize()`](basic_json_view/materialize.md) preserves the document order of object members -- including
|
||||||
|
members [`set`](basic_json_document/set.md) added -- instead of sorting them like
|
||||||
|
[`json_editable_document`](json_editable_document.md) does.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below edits a document with `set`, then shows that `materialize()` keeps the member order of the
|
||||||
|
source text (with the new member at the end) for `ordered_json_editable_document`, where it would sort the
|
||||||
|
members alphabetically for [`json_editable_document`](json_editable_document.md).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/ordered_json_editable_document.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/ordered_json_editable_document.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [ordered_json_editable_view](ordered_json_editable_view.md) - a view of a value of an
|
||||||
|
`ordered_json_editable_document`
|
||||||
|
- [ordered_json_document](ordered_json_document.md) - the read-only document this type adds edits to
|
||||||
|
- [json_editable_document](json_editable_document.md) - the corresponding editable document for the default `json`
|
||||||
|
specialization
|
||||||
|
- [Object Order](../features/object_order.md)
|
||||||
|
- [Edits](basic_json_document/index.md#edits) - what an edit guarantees
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Since version 3.13.0.
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# <small>nlohmann::</small>ordered_json_editable_view
|
||||||
|
|
||||||
|
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using ordered_json_editable_view = basic_json_view<ordered_json, true>;
|
||||||
|
```
|
||||||
|
|
||||||
|
This type is a [`basic_json_view`](basic_json_view/index.md) of a value of an
|
||||||
|
[`ordered_json_editable_document`](ordered_json_editable_document.md), the corresponding view for
|
||||||
|
[`ordered_json_view`](ordered_json_view.md) the way [`json_editable_view`](json_editable_view.md) is for
|
||||||
|
[`json_view`](json_view.md).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below is the same as [`ordered_json_editable_document`'s](ordered_json_editable_document.md): the
|
||||||
|
views `set` returns see the document's member order preserved on `materialize()`, unlike for a
|
||||||
|
[`json_editable_document`](json_editable_document.md).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/ordered_json_editable_document.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/ordered_json_editable_document.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [ordered_json_editable_document](ordered_json_editable_document.md) - the document type this view refers into
|
||||||
|
- [ordered_json_view](ordered_json_view.md) - the corresponding read-only view
|
||||||
|
- [json_editable_view](json_editable_view.md) - the corresponding view for `json_editable_document`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Since version 3.13.0.
|
||||||
@@ -21,18 +21,17 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
|
|||||||
|
|
||||||
| Compiler | Architecture | Operating System | CI |
|
| Compiler | Architecture | Operating System | CI |
|
||||||
|----------------------------------------------|--------------|-----------------------------------|-----------|
|
|----------------------------------------------|--------------|-----------------------------------|-----------|
|
||||||
|
| AppleClang 15.0.0.15000040; Xcode 15.0.1 | arm64 | macOS 14.7.2 (Sonoma) | GitHub |
|
||||||
|
| AppleClang 15.0.0.15000100; Xcode 15.1 | arm64 | macOS 14.7.2 (Sonoma) | GitHub |
|
||||||
|
| AppleClang 15.0.0.15000100; Xcode 15.2 | arm64 | macOS 14.7.2 (Sonoma) | GitHub |
|
||||||
|
| AppleClang 15.0.0.15000309; Xcode 15.3 | arm64 | macOS 14.7.2 (Sonoma) | GitHub |
|
||||||
|
| AppleClang 15.0.0.15000309; Xcode 15.4 | arm64 | macOS 14.7.2 (Sonoma) | GitHub |
|
||||||
| AppleClang 16.0.0.16000026; Xcode 16 | arm64 | macOS 15.2 (Sequoia) | GitHub |
|
| AppleClang 16.0.0.16000026; Xcode 16 | arm64 | macOS 15.2 (Sequoia) | GitHub |
|
||||||
| AppleClang 16.0.0.16000026; Xcode 16.1 | arm64 | macOS 15.2 (Sequoia) | GitHub |
|
| AppleClang 16.0.0.16000026; Xcode 16.1 | arm64 | macOS 15.2 (Sequoia) | GitHub |
|
||||||
| AppleClang 16.0.0.16000026; Xcode 16.2 | arm64 | macOS 15.2 (Sequoia) | GitHub |
|
| AppleClang 16.0.0.16000026; Xcode 16.2 | arm64 | macOS 15.2 (Sequoia) | GitHub |
|
||||||
| AppleClang 17.0.0.17000013; Xcode 16.3 | arm64 | macOS 15.5 (Sequoia) | GitHub |
|
| AppleClang 17.0.0.17000013; Xcode 16.3 | arm64 | macOS 15.5 (Sequoia) | GitHub |
|
||||||
| AppleClang 17.0.0.17000013; Xcode 16.4 | arm64 | macOS 15.5 (Sequoia) | GitHub |
|
| AppleClang 17.0.0.17000013; Xcode 16.4 | arm64 | macOS 15.5 (Sequoia) | GitHub |
|
||||||
| AppleClang 17.0.0.17000319; Xcode 26.0.1 | arm64 | macOS 15.5 (Sequoia) | GitHub |
|
| AppleClang 17.0.0.17000319; Xcode 26.0.1 | arm64 | macOS 15.5 (Sequoia) | GitHub |
|
||||||
| AppleClang 17.0.0.17000404; Xcode 26.1.1 | arm64 | macOS 15.7.9 (Sequoia) | GitHub |
|
|
||||||
| AppleClang 17.0.0.17000603; Xcode 26.2 | arm64 | macOS 15.7.9 (Sequoia) | GitHub |
|
|
||||||
| AppleClang 17.0.0.17000604; Xcode 26.3 | arm64 | macOS 15.7.9 (Sequoia) | GitHub |
|
|
||||||
| AppleClang 21.0.0.21000099; Xcode 26.4.1 | arm64 | macOS 26.6.2 (Tahoe) | GitHub |
|
|
||||||
| AppleClang 21.0.0.21000101; Xcode 26.5 | arm64 | macOS 26.6.2 (Tahoe) | GitHub |
|
|
||||||
| AppleClang 21.0.0.21000101; Xcode 26.6 | arm64 | macOS 26.6.2 (Tahoe) | GitHub |
|
|
||||||
| Clang 3.4.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
| Clang 3.4.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||||
| Clang 3.5.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
| Clang 3.5.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||||
| Clang 3.6.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
| Clang 3.6.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||||
@@ -90,7 +89,7 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
|
|||||||
| GNU 13.3.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
| GNU 13.3.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||||
| GNU 14.2.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
| GNU 14.2.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||||
| GNU 15.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
| GNU 15.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||||
| GNU 16.2.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
| GNU 16.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||||
| GNU 16.1.0 | arm64 | Ubuntu 24.04 | GitHub |
|
| GNU 16.1.0 | arm64 | Ubuntu 24.04 | GitHub |
|
||||||
| icpc (ICC) 2021.10.0 20230609 | x86_64 | Ubuntu 22.04 LTS | GitHub |
|
| icpc (ICC) 2021.10.0 20230609 | x86_64 | Ubuntu 22.04 LTS | GitHub |
|
||||||
| icpx (Intel oneAPI DPC++/C++) 2025.3.2 | x86_64 | Ubuntu 24.04 LTS | GitHub |
|
| icpx (Intel oneAPI DPC++/C++) 2025.3.2 | x86_64 | Ubuntu 24.04 LTS | GitHub |
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ work items are tracked in the [GitHub milestones](https://github.com/nlohmann/js
|
|||||||
|
|
||||||
## What the project will not do
|
## What the project will not do
|
||||||
|
|
||||||
- **Break the public API of version 3.x.** See [API stability](#api-stability) for what this covers.
|
- **Break the public API of version 3.x.** See the
|
||||||
|
[contribution guidelines](https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md#break-the-public-api)
|
||||||
|
for what counts as a breaking change.
|
||||||
- **Require a newer C++ standard than C++11.**
|
- **Require a newer C++ standard than C++11.**
|
||||||
- **Break JSON conformance** or enable non-standard extensions by default.
|
- **Break JSON conformance** or enable non-standard extensions by default.
|
||||||
- **Add dependencies** or require a build step. The library remains header-only, and the single header
|
- **Add dependencies** or require a build step. The library remains header-only, and the single header
|
||||||
@@ -33,32 +35,6 @@ work items are tracked in the [GitHub milestones](https://github.com/nlohmann/js
|
|||||||
- **Trade simplicity for speed or memory efficiency.** Performance improvements are welcome, but the library is not
|
- **Trade simplicity for speed or memory efficiency.** Performance improvements are welcome, but the library is not
|
||||||
meant to compete with the fastest JSON libraries, see [Design goals](../home/design_goals.md).
|
meant to compete with the fastest JSON libraries, see [Design goals](../home/design_goals.md).
|
||||||
|
|
||||||
## API stability
|
|
||||||
|
|
||||||
Releases follow [semantic versioning](https://semver.org): a minor or patch release of version 3.x does not break code
|
|
||||||
that uses the public API. In particular, a 3.x release does not:
|
|
||||||
|
|
||||||
- change the signature of a function (its parameter types, return type, number of parameters, or the const-ness of a
|
|
||||||
member function);
|
|
||||||
- remove or rename a function or class;
|
|
||||||
- change which exceptions a function throws, or the [exception ids](../home/exceptions.md);
|
|
||||||
- change access specifiers or default arguments.
|
|
||||||
|
|
||||||
Exceptions to these rules, for instance when fixing a bug requires changing the exception a function throws, are
|
|
||||||
documented in the [release notes](../home/releases.md).
|
|
||||||
|
|
||||||
The following are **not** part of the public API and may change in any release, including patch releases:
|
|
||||||
|
|
||||||
- The text of exception messages returned by `what()`. Use the [exception id](../home/exceptions.md) to tell errors
|
|
||||||
apart.
|
|
||||||
- The ABI, including `sizeof(basic_json)` and the memory layout of its values. Recompile your code when you upgrade the
|
|
||||||
library. The [versioned inline namespace](../features/namespace.md) turns mixing versions into a link error.
|
|
||||||
- Everything in namespace `nlohmann::detail`, and macros and type traits that are not documented in the
|
|
||||||
[API reference](../api/basic_json/index.md).
|
|
||||||
|
|
||||||
Changes that would break the public API are only added behind a macro whose default keeps the 3.x behavior, see
|
|
||||||
[Version 4.0](#version-40).
|
|
||||||
|
|
||||||
## Version 4.0
|
## Version 4.0
|
||||||
|
|
||||||
There is no release date for version 4.0 yet. Proposals that need a major version, for instance stricter type
|
There is no release date for version 4.0 yet. Proposals that need a major version, for instance stricter type
|
||||||
@@ -88,8 +64,6 @@ The following macros guard changes that are planned to become the default in ver
|
|||||||
| [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) | `0` | `1`: reading from a stream does not consume the character after a number | – | 3.13.0 |
|
| [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) | `0` | `1`: reading from a stream does not consume the character after a number | – | 3.13.0 |
|
||||||
| [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) | `0` | `1`: a NUL byte in the input is a parse error instead of the end of input | [`JSON_StrictNulHandling`](../integration/cmake.md#json_strictnulhandling) | 3.13.0 |
|
| [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) | `0` | `1`: a NUL byte in the input is a parse error instead of the end of input | [`JSON_StrictNulHandling`](../integration/cmake.md#json_strictnulhandling) | 3.13.0 |
|
||||||
| [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) | `0` | `1`: `to_cbor`, `to_ubjson`, `to_bjdata`, and `to_bson` throw for strings that are not valid UTF-8 by default | [`JSON_StrictBinaryUTF8`](../integration/cmake.md#json_strictbinaryutf8) | 3.13.0 |
|
| [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) | `0` | `1`: `to_cbor`, `to_ubjson`, `to_bjdata`, and `to_bson` throw for strings that are not valid UTF-8 by default | [`JSON_StrictBinaryUTF8`](../integration/cmake.md#json_strictbinaryutf8) | 3.13.0 |
|
||||||
| [`JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`](../api/macros/json_disable_tuple_reference_conversion.md) | `0` | `1`: a `basic_json` value can no longer be created from a one-element tuple of a reference to it, such as `std::forward_as_tuple(j)`| [`JSON_DisableTupleReferenceConversion`](../integration/cmake.md#json_disabletuplereferenceconversion) | 3.13.0 |
|
|
||||||
| [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) | `0` | removed: the deprecated functions are removed (see below); the `from_*(ptr, len)` overloads stay deleted | [`JSON_DeleteDeprecatedFunctions`](../integration/cmake.md#json_deletedeprecatedfunctions) | 3.13.0 |
|
|
||||||
|
|
||||||
For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:
|
For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:
|
||||||
|
|
||||||
@@ -101,8 +75,6 @@ For example, the following makes a 3.x release behave like version 4.0 with resp
|
|||||||
#define JSON_PRECISE_STREAM_POSITION 1
|
#define JSON_PRECISE_STREAM_POSITION 1
|
||||||
#define JSON_STRICT_NUL_HANDLING 1
|
#define JSON_STRICT_NUL_HANDLING 1
|
||||||
#define JSON_STRICT_BINARY_UTF8 1
|
#define JSON_STRICT_BINARY_UTF8 1
|
||||||
#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 1
|
|
||||||
#define JSON_DELETE_DEPRECATED_FUNCTIONS 1
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -112,13 +84,8 @@ way to achieve this.
|
|||||||
### Removal of deprecated functions
|
### Removal of deprecated functions
|
||||||
|
|
||||||
Version 4.0 will remove all deprecated functions. Compiling with deprecation warnings enabled shows which of them your
|
Version 4.0 will remove all deprecated functions. Compiling with deprecation warnings enabled shows which of them your
|
||||||
code still uses. Defining [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) to
|
code still uses. The [migration guide](../integration/migration_guide.md#replace-deprecated-functions) shows how to
|
||||||
`1` turns these warnings into errors, as the deprecated functions are then deleted. The
|
replace each of them.
|
||||||
[migration guide](../integration/migration_guide.md#replace-deprecated-functions) shows how to replace each of them.
|
|
||||||
|
|
||||||
The `from_*` overloads taking a pointer and a length are not removed in version 4.0, but stay deleted. Without them, a
|
|
||||||
call like `from_cbor(ptr, len)` would still compile: it would read `ptr` as a NUL-terminated string and convert `len`
|
|
||||||
to the `strict` parameter.
|
|
||||||
|
|
||||||
| Deprecated | Since | Migration |
|
| Deprecated | Since | Migration |
|
||||||
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------------------------------------------------------------------|
|
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------------------------------------------------------------------|
|
||||||
@@ -130,7 +97,6 @@ to the `strict` parameter.
|
|||||||
| [`json_pointer::operator string_t`](../api/json_pointer/operator_string_t.md) | 3.11.0 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
| [`json_pointer::operator string_t`](../api/json_pointer/operator_string_t.md) | 3.11.0 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
||||||
| [`json_pointer`](../api/json_pointer/index.md) with a `basic_json` type as template argument, and the overloads of `value`, `contains`, `operator[]`, and `at` accepting such a pointer | 3.11.0 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
| [`json_pointer`](../api/json_pointer/index.md) with a `basic_json` type as template argument, and the overloads of `value`, `contains`, `operator[]`, and `at` accepting such a pointer | 3.11.0 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
||||||
| Comparing a [`json_pointer`](../api/json_pointer/index.md) with a string via [`operator==`](../api/json_pointer/operator_eq.md) or [`operator!=`](../api/json_pointer/operator_ne.md) | 3.11.2 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
| Comparing a [`json_pointer`](../api/json_pointer/index.md) with a string via [`operator==`](../api/json_pointer/operator_eq.md) or [`operator!=`](../api/json_pointer/operator_ne.md) | 3.11.2 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
||||||
| [`from_bjdata`](../api/basic_json/from_bjdata.md) and [`from_bon8`](../api/basic_json/from_bon8.md) with `(ptr, len)` | 3.13.0 | [Parsing](../integration/migration_guide.md#parsing) |
|
|
||||||
|
|
||||||
The deprecated legacy comparison of discarded values is controlled by a macro and therefore listed in the table above.
|
The deprecated legacy comparison of discarded values is controlled by a macro and therefore listed in the table above.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
using json_editable_document = nlohmann::json_editable_document;
|
||||||
|
using json_editable_view = nlohmann::json_editable_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a deprecated field is dropped from a configuration file, and a
|
||||||
|
// decommissioned replica is removed from the list -- "price" keeps its
|
||||||
|
// trailing zero, and the fields around the removed ones keep their order
|
||||||
|
const std::string text = R"({
|
||||||
|
"name": "cache",
|
||||||
|
"legacy_host": "db0",
|
||||||
|
"host": "db1",
|
||||||
|
"price": 19.90,
|
||||||
|
"replicas": ["db2", "db3", "db4"]
|
||||||
|
})";
|
||||||
|
|
||||||
|
json_editable_document doc = json_editable_document::parse(text);
|
||||||
|
|
||||||
|
doc.erase(doc.root(), "legacy_host"); // (1) an object member
|
||||||
|
doc.erase(doc.root()["replicas"], 1); // (2) an array element ("db3")
|
||||||
|
const std::size_t removed = doc.erase(json::json_pointer("/replicas/0")); // (3) via a JSON pointer
|
||||||
|
|
||||||
|
std::cout << removed << '\n';
|
||||||
|
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||||
|
|
||||||
|
// the same edits on a plain json value: object_t is a std::map, so
|
||||||
|
// parsing already sorted the keys, and dump() rewrites every number to
|
||||||
|
// its shortest form, even "price", which was never touched
|
||||||
|
json plain = json::parse(text);
|
||||||
|
plain.erase("legacy_host");
|
||||||
|
plain["replicas"].erase(1);
|
||||||
|
plain["replicas"].erase(0);
|
||||||
|
std::cout << plain.dump(2) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
1
|
||||||
|
{
|
||||||
|
"name": "cache",
|
||||||
|
"host": "db1",
|
||||||
|
"price": 19.90,
|
||||||
|
"replicas": [
|
||||||
|
"db4"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
"host": "db1",
|
||||||
|
"name": "cache",
|
||||||
|
"price": 19.9,
|
||||||
|
"replicas": [
|
||||||
|
"db4"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
using json_editable_document = nlohmann::json_editable_document;
|
||||||
|
using json_editable_view = nlohmann::json_editable_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a deployment plan -- "budget" is written with a trailing zero that has
|
||||||
|
// no effect on its value
|
||||||
|
const std::string text = R"({
|
||||||
|
"release": "2026.09",
|
||||||
|
"steps": ["build", "test", "deploy"],
|
||||||
|
"budget": 19.90
|
||||||
|
})";
|
||||||
|
|
||||||
|
json_editable_document doc = json_editable_document::parse(text);
|
||||||
|
|
||||||
|
const std::size_t deploy_index = 2;
|
||||||
|
const auto deploy = doc.root()["steps"][deploy_index]; // held across the insert
|
||||||
|
|
||||||
|
doc.insert(doc.root()["steps"], deploy_index, "smoke-test"); // insert before "deploy"
|
||||||
|
|
||||||
|
// the held view still refers to "deploy", even though its index moved
|
||||||
|
// from 2 to 3, and nothing else in the document was touched
|
||||||
|
std::cout << deploy.dump() << '\n';
|
||||||
|
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||||
|
|
||||||
|
// the same edit on a plain json value: an index held from before the
|
||||||
|
// insert now refers to whatever moved into that slot, and dump()
|
||||||
|
// rewrites "budget" to its shortest form even though it was never
|
||||||
|
// touched
|
||||||
|
json plain = json::parse(text);
|
||||||
|
plain["steps"].insert(plain["steps"].begin() + static_cast<std::ptrdiff_t>(deploy_index), "smoke-test");
|
||||||
|
std::cout << plain["steps"][deploy_index].dump() << '\n';
|
||||||
|
std::cout << plain.dump(2) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"deploy"
|
||||||
|
{
|
||||||
|
"release": "2026.09",
|
||||||
|
"steps": [
|
||||||
|
"build",
|
||||||
|
"test",
|
||||||
|
"smoke-test",
|
||||||
|
"deploy"
|
||||||
|
],
|
||||||
|
"budget": 19.90
|
||||||
|
}
|
||||||
|
|
||||||
|
"smoke-test"
|
||||||
|
{
|
||||||
|
"budget": 19.9,
|
||||||
|
"release": "2026.09",
|
||||||
|
"steps": [
|
||||||
|
"build",
|
||||||
|
"test",
|
||||||
|
"smoke-test",
|
||||||
|
"deploy"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using image_check = json_document::image_check;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::cout << std::boolalpha;
|
||||||
|
|
||||||
|
// the image of a parsed document -- as if read back from a cache file or
|
||||||
|
// received from another process running the same build of the library
|
||||||
|
const std::string text = R"({"name": "cache", "note": "caf\u00e9", "replicas": ["db2", "db3"]})";
|
||||||
|
const json_document parsed = json_document::parse(text);
|
||||||
|
const std::vector<std::uint8_t> image = parsed.save();
|
||||||
|
|
||||||
|
// (1)/(2) load() needs no parsing, yet dumps exactly what parsing did
|
||||||
|
const json_document borrowed = json_document::load(image);
|
||||||
|
std::cout << (borrowed.root().dump() == parsed.root().dump()) << '\n';
|
||||||
|
std::cout << borrowed.owns_source() << '\n'; // borrowed: still points into `image`
|
||||||
|
|
||||||
|
// (3) load(std::move(image)) keeps the vector instead of copying it
|
||||||
|
std::vector<std::uint8_t> to_move = image;
|
||||||
|
const json_document owned = json_document::load(std::move(to_move));
|
||||||
|
std::cout << owned.owns_source() << '\n';
|
||||||
|
|
||||||
|
// a damaged image -- the last byte of the decoded string "note" holds
|
||||||
|
// (an escape sequence, so it was unescaped into the document's own
|
||||||
|
// buffer), flipped, as storage or transport corruption might do
|
||||||
|
std::vector<std::uint8_t> damaged = image;
|
||||||
|
damaged[damaged.size() - 2] = 0xFF;
|
||||||
|
|
||||||
|
// image_check::full inspects strings and numbers, so it catches the damage
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<void>(json_document::load(damaged, image_check::full));
|
||||||
|
}
|
||||||
|
catch (const json::parse_error& e)
|
||||||
|
{
|
||||||
|
std::cout << e.id << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
// image_check::bounds only checks structure and bounds, so a cache the
|
||||||
|
// process already trusts loads without the extra scan -- reading a value
|
||||||
|
// the damage did not touch is still safe
|
||||||
|
const json_document trusted = json_document::load(damaged, image_check::bounds);
|
||||||
|
std::cout << trusted.root()["name"].get<std::string>() << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
true
|
||||||
|
false
|
||||||
|
true
|
||||||
|
116
|
||||||
|
cache
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
using json_editable_document = nlohmann::json_editable_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// "events" starts out null -- the first push_back() turns it into an
|
||||||
|
// array, exactly like set() turns a null object member into an object
|
||||||
|
json_editable_document doc = json_editable_document::parse(R"({"source": "sensor-1", "events": null})");
|
||||||
|
|
||||||
|
const auto first = doc.push_back(doc.root()["events"], json{{"type", "start"}, {"t", 0}});
|
||||||
|
for (int t = 1; t <= 3; ++t)
|
||||||
|
{
|
||||||
|
doc.push_back(doc.root()["events"], json{{"type", "tick"}, {"t", t}});
|
||||||
|
}
|
||||||
|
|
||||||
|
// push_back() never moves an existing element: a view taken from an
|
||||||
|
// earlier call still refers to the same element after later ones
|
||||||
|
std::cout << first.dump() << '\n';
|
||||||
|
std::cout << doc.root()["events"].size() << '\n';
|
||||||
|
std::cout << doc.root().dump(2) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{"t":0,"type":"start"}
|
||||||
|
4
|
||||||
|
{
|
||||||
|
"source": "sensor-1",
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"t": 0,
|
||||||
|
"type": "start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": 1,
|
||||||
|
"type": "tick"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": 2,
|
||||||
|
"type": "tick"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": 3,
|
||||||
|
"type": "tick"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::cout << std::boolalpha;
|
||||||
|
|
||||||
|
// a configuration a service parses once and then caches as an image, so
|
||||||
|
// that later requests can load() it instead of parsing the text again
|
||||||
|
const std::string text = R"({"name": "cache", "host": "db1", "port": 6379, "replicas": ["db2", "db3"]})";
|
||||||
|
const json_document config = json_document::parse(text);
|
||||||
|
|
||||||
|
// save() turns the parsed document into a byte buffer: a 64-byte header,
|
||||||
|
// the node index, the source text, and the decoded strings
|
||||||
|
const std::vector<std::uint8_t> image = config.save();
|
||||||
|
std::cout << image.size() << '\n';
|
||||||
|
|
||||||
|
// the same document always saves to the same bytes
|
||||||
|
std::cout << (image == json_document::parse(text).save()) << '\n';
|
||||||
|
|
||||||
|
// loading the image back needs no parsing, yet dumps exactly what
|
||||||
|
// parsing the text produced
|
||||||
|
const json_document reloaded = json_document::load(image);
|
||||||
|
std::cout << (reloaded.root().dump() == config.root().dump()) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
316
|
||||||
|
true
|
||||||
|
true
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
using json_editable_document = nlohmann::json_editable_document;
|
||||||
|
using json_editable_view = nlohmann::json_editable_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a configuration file, as it might be read from disk -- "price" is
|
||||||
|
// written with a trailing zero that has no effect on its value
|
||||||
|
const std::string text = R"({
|
||||||
|
"name": "cache",
|
||||||
|
"host": "db1",
|
||||||
|
"port": 6379,
|
||||||
|
"price": 19.90,
|
||||||
|
"replicas": ["db2", "db3"],
|
||||||
|
"timeout": 30
|
||||||
|
})";
|
||||||
|
|
||||||
|
json_editable_document doc = json_editable_document::parse(text);
|
||||||
|
|
||||||
|
doc.set(doc.root()["port"], 6380); // (1) replace a value
|
||||||
|
doc.set(doc.root(), "region", "us-east"); // (2) add a member
|
||||||
|
doc.set(doc.root()["replicas"], 0, "db4"); // (3) assign an element
|
||||||
|
doc.set(json::json_pointer("/timeout"), 45); // (4) via a JSON pointer
|
||||||
|
|
||||||
|
// members stay in document order (the new one at the end), and a number
|
||||||
|
// that was not itself edited keeps its exact spelling
|
||||||
|
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||||
|
|
||||||
|
// the same edits on a plain json value: object_t is a std::map, so
|
||||||
|
// parsing already sorted the keys, and dump() rewrites every number to
|
||||||
|
// its shortest form, even "price", which was never touched
|
||||||
|
json plain = json::parse(text);
|
||||||
|
plain["port"] = 6380;
|
||||||
|
plain["region"] = "us-east";
|
||||||
|
plain["replicas"][0] = "db4";
|
||||||
|
plain[json::json_pointer("/timeout")] = 45;
|
||||||
|
std::cout << plain.dump(2) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "cache",
|
||||||
|
"host": "db1",
|
||||||
|
"port": 6380,
|
||||||
|
"price": 19.90,
|
||||||
|
"replicas": [
|
||||||
|
"db4",
|
||||||
|
"db3"
|
||||||
|
],
|
||||||
|
"timeout": 45,
|
||||||
|
"region": "us-east"
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
"host": "db1",
|
||||||
|
"name": "cache",
|
||||||
|
"port": 6380,
|
||||||
|
"price": 19.9,
|
||||||
|
"region": "us-east",
|
||||||
|
"replicas": [
|
||||||
|
"db4",
|
||||||
|
"db3"
|
||||||
|
],
|
||||||
|
"timeout": 45
|
||||||
|
}
|
||||||
@@ -13,7 +13,19 @@ class visitor_adaptor_with_metadata
|
|||||||
void do_visit(const Ptr& ptr, const Fnc& fnc) const;
|
void do_visit(const Ptr& ptr, const Fnc& fnc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
using json = nlohmann::json::with_base_class_t<visitor_adaptor_with_metadata>;
|
using json = nlohmann::basic_json <
|
||||||
|
std::map,
|
||||||
|
std::vector,
|
||||||
|
std::string,
|
||||||
|
bool,
|
||||||
|
std::int64_t,
|
||||||
|
std::uint64_t,
|
||||||
|
double,
|
||||||
|
std::allocator,
|
||||||
|
nlohmann::adl_serializer,
|
||||||
|
std::vector<std::uint8_t>,
|
||||||
|
visitor_adaptor_with_metadata
|
||||||
|
>;
|
||||||
|
|
||||||
template <class Fnc>
|
template <class Fnc>
|
||||||
void visitor_adaptor_with_metadata::visit(const Fnc& fnc) const
|
void visitor_adaptor_with_metadata::visit(const Fnc& fnc) const
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
using json_editable_document = nlohmann::json_editable_document;
|
||||||
|
using json_editable_view = nlohmann::json_editable_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a configuration file, as it might be read from disk
|
||||||
|
const std::string text = R"({"name": "cache", "host": "db1", "port": 6379, "price": 19.90})";
|
||||||
|
std::cout << text << "\n\n";
|
||||||
|
|
||||||
|
// patch two fields -- "price" is never touched
|
||||||
|
json_editable_document doc = json_editable_document::parse(text);
|
||||||
|
doc.set(doc.root(), "host", "db2");
|
||||||
|
doc.set(doc.root(), "retries", 3);
|
||||||
|
|
||||||
|
// member order (the new member at the end) and the untouched number's
|
||||||
|
// exact spelling survive
|
||||||
|
std::cout << doc.root().dump(-1, ' ', false, json_editable_view::number_format::source) << '\n';
|
||||||
|
|
||||||
|
// the same patch on a plain json value: keys are sorted (object_t is a
|
||||||
|
// std::map), and "price" is rewritten even though the patch never
|
||||||
|
// touched it
|
||||||
|
json plain = json::parse(text);
|
||||||
|
plain["host"] = "db2";
|
||||||
|
plain["retries"] = 3;
|
||||||
|
std::cout << plain.dump() << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{"name": "cache", "host": "db1", "port": 6379, "price": 19.90}
|
||||||
|
|
||||||
|
{"name":"cache","host":"db2","port":6379,"price":19.90,"retries":3}
|
||||||
|
{"host":"db2","name":"cache","port":6379,"price":19.9,"retries":3}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using ordered_json_editable_document = nlohmann::ordered_json_editable_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// ordered_json_editable_document is basic_json_document<nlohmann::ordered_json, true>
|
||||||
|
ordered_json_editable_document doc = ordered_json_editable_document::parse(R"({"z": 1, "a": 2, "m": 3})");
|
||||||
|
doc.set(doc.root(), "b", 4); // set() always appends a new member at the end
|
||||||
|
|
||||||
|
// materialize() preserves the document order (with "b" at the end),
|
||||||
|
// instead of sorting the keys the way json_editable_document does
|
||||||
|
std::cout << doc.root().materialize().dump() << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"z":1,"a":2,"m":3,"b":4}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
// a JSON type that stores objects in a std::map (which keeps keys sorted)
|
|
||||||
// instead of the default ordered associative container
|
|
||||||
using sorted_json = nlohmann::json::with_object_t<std::map>;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
sorted_json j;
|
|
||||||
j["c"] = 1;
|
|
||||||
j["a"] = 2;
|
|
||||||
j["b"] = 3;
|
|
||||||
|
|
||||||
// keys are sorted, because std::map is used to store the object
|
|
||||||
std::cout << j.dump() << std::endl;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"a":2,"b":3,"c":1}
|
|
||||||
@@ -131,7 +131,6 @@ The library maps CBOR types to JSON value types as follows:
|
|||||||
| Byte string | binary | 0x59 |
|
| Byte string | binary | 0x59 |
|
||||||
| Byte string | binary | 0x5A |
|
| Byte string | binary | 0x5A |
|
||||||
| Byte string | binary | 0x5B |
|
| Byte string | binary | 0x5B |
|
||||||
| Byte string | binary | 0x5F |
|
|
||||||
| UTF-8 string | string | 0x60..0x77 |
|
| UTF-8 string | string | 0x60..0x77 |
|
||||||
| UTF-8 string | string | 0x78 |
|
| UTF-8 string | string | 0x78 |
|
||||||
| UTF-8 string | string | 0x79 |
|
| UTF-8 string | string | 0x79 |
|
||||||
@@ -157,9 +156,6 @@ The library maps CBOR types to JSON value types as follows:
|
|||||||
| Single-Precision Float | number_float | 0xFA |
|
| Single-Precision Float | number_float | 0xFA |
|
||||||
| Double-Precision Float | number_float | 0xFB |
|
| Double-Precision Float | number_float | 0xFB |
|
||||||
|
|
||||||
Indefinite-length UTF-8 strings (0x7F) and byte strings (0x5F) are supported. Each chunk must be a definite-length
|
|
||||||
string of the same major type, as required by [RFC 8949, Section 3.2.3](https://www.rfc-editor.org/rfc/rfc8949.html#section-3.2.3).
|
|
||||||
|
|
||||||
!!! warning "Incomplete mapping"
|
!!! warning "Incomplete mapping"
|
||||||
|
|
||||||
The mapping is **incomplete** in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors:
|
The mapping is **incomplete** in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors:
|
||||||
@@ -172,9 +168,9 @@ string of the same major type, as required by [RFC 8949, Section 3.2.3](https://
|
|||||||
!!! warning "Negative integer overflow"
|
!!! warning "Negative integer overflow"
|
||||||
|
|
||||||
CBOR negative integers (major type 1) are decoded as `-1 - n`. If the encoded magnitude `n` is too large for the
|
CBOR negative integers (major type 1) are decoded as `-1 - n`. If the encoded magnitude `n` is too large for the
|
||||||
result to fit into `number_integer_t` (`std::int64_t` by default), the result is stored as `number_float_t`, like
|
result to fit into `number_integer_t` (`std::int64_t` by default), parsing fails with a
|
||||||
a too small integer in JSON text. For example, `-18446744073709551616` (`0x3B` followed by eight `0xFF` bytes) is
|
[`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) exception rather than overflowing
|
||||||
stored as `-1.8446744073709552e+19`.
|
silently.
|
||||||
|
|
||||||
!!! warning "Object keys"
|
!!! warning "Object keys"
|
||||||
|
|
||||||
|
|||||||
@@ -58,23 +58,6 @@ assert(jPi.get<TaskState>() == TS_INVALID );
|
|||||||
--8<-- "examples/nlohmann_json_serialize_enum.output"
|
--8<-- "examples/nlohmann_json_serialize_enum.output"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maps with enum keys
|
|
||||||
|
|
||||||
By default, maps with enum keys, such as `std::map<TaskState, std::string>`, are stored as arrays of `[key, value]`
|
|
||||||
pairs, because JSON object keys must be strings. Define
|
|
||||||
[`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md) before including the
|
|
||||||
library to store them as objects, with the keys converted by the enum's `to_json()` function:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::map<TaskState, std::string> m = {{TS_STOPPED, "aa"}, {TS_COMPLETED, "bb"}};
|
|
||||||
|
|
||||||
json j = m;
|
|
||||||
// default: [["stopped","aa"],["completed","bb"]]
|
|
||||||
// with JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS: {"completed":"bb","stopped":"aa"}
|
|
||||||
```
|
|
||||||
|
|
||||||
Either form can be read back, with or without the macro.
|
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
Just as in [Arbitrary Type Conversions](arbitrary_types.md) above,
|
Just as in [Arbitrary Type Conversions](arbitrary_types.md) above,
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ C++ types, and finally serialize it again.
|
|||||||
[parsing untrusted input](parsing/untrusted_input.md).
|
[parsing untrusted input](parsing/untrusted_input.md).
|
||||||
- [Zero-copy JSON views](json_view.md) — read a JSON text through a flat index instead of building a `json` tree;
|
- [Zero-copy JSON views](json_view.md) — read a JSON text through a flat index instead of building a `json` tree;
|
||||||
strings and numbers stay in the input and are only decoded when needed.
|
strings and numbers stay in the input and are only decoded when needed.
|
||||||
|
[Editable documents](json_view.md#editing-a-document) can also be modified, and [images](json_view.md#images) load a
|
||||||
|
parsed document again without parsing it.
|
||||||
- [Comments](comments.md) and [trailing commas](trailing_commas.md) — opt-in relaxations of the JSON grammar.
|
- [Comments](comments.md) and [trailing commas](trailing_commas.md) — opt-in relaxations of the JSON grammar.
|
||||||
|
|
||||||
## Accessing and modifying values
|
## Accessing and modifying values
|
||||||
|
|||||||
@@ -187,14 +187,129 @@ a number to its parsed `#!cpp double`/`#!cpp int64_t` value.
|
|||||||
[`operator<<`](../api/basic_json_view/operator_ltlt.md) writes a view to a stream the way `basic_json`'s does, using
|
[`operator<<`](../api/basic_json_view/operator_ltlt.md) writes a view to a stream the way `basic_json`'s does, using
|
||||||
the stream's `width`/`fill` for indentation.
|
the stream's `width`/`fill` for indentation.
|
||||||
|
|
||||||
|
## Editing a document
|
||||||
|
|
||||||
|
Everything above is read-only: a `json_document`/`json_view` lets you look at a parsed text without copying it, but
|
||||||
|
not change it. [`basic_json_document<BasicJsonType, true>`](../api/basic_json_document/index.md) -- more conveniently
|
||||||
|
spelled [`json_editable_document`](../api/json_editable_document.md) or
|
||||||
|
[`ordered_json_editable_document`](../api/ordered_json_editable_document.md) -- also lets you
|
||||||
|
[`set`](../api/basic_json_document/set.md) a value, [`push_back`](../api/basic_json_document/push_back.md) onto or
|
||||||
|
[`insert`](../api/basic_json_document/insert.md) into an array, and [`erase`](../api/basic_json_document/erase.md)
|
||||||
|
an object member or an array element, still without ever building a `basic_json` tree for parts you do not touch.
|
||||||
|
|
||||||
|
`#!cpp Editable` defaults to `#!cpp false`, so `json_document`/`ordered_json_document` are unaffected -- they carry
|
||||||
|
none of the bookkeeping edits need, and calling `set`/`push_back`/`insert`/`erase` on one is a compile error, not a
|
||||||
|
runtime one.
|
||||||
|
|
||||||
|
### Why: editing without reformatting
|
||||||
|
|
||||||
|
The `#!cpp 19.90` price from [above](#writing-a-view-back) is exactly the kind of value that makes editing a `json`
|
||||||
|
or `ordered_json` value in place lossy. Say you parse a configuration file, patch one field, and write it back:
|
||||||
|
|
||||||
|
- **`json`** re-sorts every key on the way in (`object_t` is a `#!cpp std::map`) and rewrites every number to its
|
||||||
|
shortest round-trip form on the way out -- a one-field patch turns into a diff that reorders the whole file and
|
||||||
|
rewrites `#!cpp 19.90` to `#!cpp 19.9`.
|
||||||
|
- **`ordered_json`** keeps the key order, but still rewrites every number the same way: parsing has already reduced
|
||||||
|
it to a `#!cpp double`/`#!cpp int64_t`, and there is no way back to how it was spelled in the source text.
|
||||||
|
|
||||||
|
An editable document keeps both. [`dump()`](../api/basic_json_view/dump.md) of an edited document writes members in
|
||||||
|
document order -- a member [`set`](../api/basic_json_document/set.md) added goes at the end, exactly where it was
|
||||||
|
inserted, and an [`erase`](../api/basic_json_document/erase.md)d member simply leaves a gap: everything around it
|
||||||
|
keeps its place -- and [`number_format::source`](../api/basic_json_view/number_format.md) keeps the exact spelling
|
||||||
|
of every number an edit did not itself touch; a number an edit *did* touch is written the way
|
||||||
|
[`BasicJsonType::dump()`](../api/basic_json/dump.md) would write it, since there is no source spelling for a brand
|
||||||
|
new value.
|
||||||
|
|
||||||
|
??? example "Example: patch a configuration, keeping member order and number spellings"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/json_editable_document.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/json_editable_document.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
### What stays valid, and what an edit costs
|
||||||
|
|
||||||
|
The source text itself is **never written**, and the parsed index never moves -- a value keeps the node it was
|
||||||
|
parsed into for as long as it is not itself replaced. So every [view](../api/basic_json_view/index.md) taken before
|
||||||
|
an edit, including a previously obtained [`root()`](../api/basic_json_document/root.md), stays valid and, if it
|
||||||
|
still refers to the edited value, sees the edit; a view of a value a later edit drops or replaces just keeps showing
|
||||||
|
what it last held. New values go to storage the document allocates and owns on demand. The one thing an edit does
|
||||||
|
invalidate is the **iterators** taken over an edited array or object: the first time one of its elements is set,
|
||||||
|
appended to, inserted into, or erased, its elements move from the parsed, fixed layout to a growable block of links
|
||||||
|
so that [`push_back`](../api/basic_json_document/push_back.md) can later grow it in amortized constant time --
|
||||||
|
existing elements are not touched, but an iterator that was walking the old layout no longer matches. A string
|
||||||
|
obtained with
|
||||||
|
[`get_string()`](../api/basic_json_view/get_string.md) is unaffected either way and stays valid across further
|
||||||
|
edits. See [`basic_json_document`'s Edits](../api/basic_json_document/index.md#edits) for the details, and
|
||||||
|
[`set`'s Exception safety](../api/basic_json_document/set.md#exception-safety) for what an edit guarantees if it
|
||||||
|
throws (the *basic* guarantee, not the strong one `dump()` and the read-only functions provide). How edits are kept in
|
||||||
|
the index is described in the [architecture overview](../home/architecture.md#node-index-of-json-views).
|
||||||
|
|
||||||
|
## Images
|
||||||
|
|
||||||
|
[`save()`](../api/basic_json_document/save.md) writes a document as an *image*: a byte buffer that
|
||||||
|
[`load()`](../api/basic_json_document/load.md) reads back into a document without parsing -- no lexing, no building
|
||||||
|
the node index, nothing but copying the nodes and pointing the text and the decoded strings at the image. Where
|
||||||
|
[`parse_copy()`](../api/basic_json_document/parse_copy.md) still has to scan the whole input,
|
||||||
|
[`load()`](../api/basic_json_document/load.md) turns that scan into a copy of the node index alone.
|
||||||
|
|
||||||
|
**Why.** A document that is parsed once and then read many times -- a configuration loaded at startup, a template
|
||||||
|
rendered on every request, a large reference dataset a worker process needs in memory -- pays for parsing once but
|
||||||
|
can amortize [`save()`](../api/basic_json_document/save.md)'s cost across every later load. That makes images useful
|
||||||
|
for a cache: save a document the first time it is parsed (to a file, a shared-memory segment, an in-process cache),
|
||||||
|
and [`load()`](../api/basic_json_document/load.md) it on every later use instead of parsing the source text again.
|
||||||
|
They are just as useful for handing a parsed document to another process (or a forked worker) running the same build
|
||||||
|
of the library, since [`load()`](../api/basic_json_document/load.md) turns the transfer into a copy of the node index
|
||||||
|
plus pointers into the received bytes, not a re-parse.
|
||||||
|
|
||||||
|
**Choosing a check.** [`load()`](../api/basic_json_document/load.md) takes an
|
||||||
|
[`image_check`](../api/basic_json_document/load.md#image_check) that trades validation against speed:
|
||||||
|
`image_check::full` (the default) checks everything the parser itself guarantees, so a checked image is exactly as
|
||||||
|
safe to read and serialize as a freshly parsed document -- the right choice whenever the image did not come straight
|
||||||
|
from this process's own [`save()`](../api/basic_json_document/save.md), such as a file or a network peer.
|
||||||
|
`image_check::bounds` only checks structure and bounds -- cheaper, since it skips scanning the text and the decoded
|
||||||
|
strings -- and fits a cache the process trusts, one it wrote and reads back itself. `image_check::none` skips
|
||||||
|
validation entirely, for an image trusted as much as the process's own memory. See
|
||||||
|
[`load()`'s Notes](../api/basic_json_document/load.md#notes) for exactly what each level does and does not guarantee.
|
||||||
|
|
||||||
|
??? example "Example: cache a parsed configuration as an image"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_document__save.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_document__save.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! warning "Experimental"
|
||||||
|
|
||||||
|
The image format is versioned but not yet stable, and may change in an incompatible way before it is declared
|
||||||
|
stable. It is little-endian only, and tied to the library build that wrote it -- use it to cache a document or to
|
||||||
|
hand one to another process running the *same* build, not as a long-term storage format; keep the original JSON
|
||||||
|
text if a saved document needs to be readable by a future library version.
|
||||||
|
|
||||||
|
The idea of a document you can read without parsing comes from zero-copy formats such as
|
||||||
|
[FlatBuffers](https://github.com/google/flatbuffers) and [YaFF](https://github.com/yandex/yaff); the check
|
||||||
|
[`load()`](../api/basic_json_document/load.md) runs follows the idea of FlatBuffers' Verifier. No code is taken from
|
||||||
|
either.
|
||||||
|
|
||||||
## Choosing between `json`, `ordered_json`, the SAX interface, and `json_view`
|
## Choosing between `json`, `ordered_json`, the SAX interface, and `json_view`
|
||||||
|
|
||||||
| | [`json`](../api/json.md) / [`ordered_json`](../api/ordered_json.md) | [SAX interface](parsing/sax_interface.md) | [`json_document`](../api/json_document.md) / [`json_view`](../api/json_view.md) |
|
| | [`json`](../api/json.md) / [`ordered_json`](../api/ordered_json.md) | [SAX interface](parsing/sax_interface.md) | [`json_document`](../api/json_document.md) / [`json_view`](../api/json_view.md) | [`json_editable_document`](../api/json_editable_document.md) / [`json_editable_view`](../api/json_editable_view.md) |
|
||||||
|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| **Ownership** | owns every value | owns nothing; you decide what to keep, in your handler | borrows or owns the *text*; the index is always owned by the document |
|
| **Ownership** | owns every value | owns nothing; you decide what to keep, in your handler | borrows or owns the *text*; the index is always owned by the document | same as `json_document`; edits go to storage the document owns |
|
||||||
| **Mutability** | freely mutable | not applicable (a one-shot event stream) | read-only |
|
| **Mutability** | freely mutable | not applicable (a one-shot event stream) | read-only | [`set`](../api/basic_json_document/set.md)/[`push_back`](../api/basic_json_document/push_back.md)/[`insert`](../api/basic_json_document/insert.md)/[`erase`](../api/basic_json_document/erase.md) edit in place; the source text is never rewritten |
|
||||||
| **What you get** | a full tree you can read, write, and keep as long as you like | a sequence of callbacks; whatever your handler builds from them | a flat index plus, on demand, [`materialize()`](../api/basic_json_view/materialize.md)d `json`/`ordered_json` values for the parts you actually use |
|
| **What you get** | a full tree you can read, write, and keep as long as you like | a sequence of callbacks; whatever your handler builds from them | a flat index plus, on demand, [`materialize()`](../api/basic_json_view/materialize.md)d `json`/`ordered_json` values for the parts you actually use | the same, plus [`dump()`](../api/basic_json_view/dump.md) of an edited document that keeps the member order and, with [`number_format::source`](../api/basic_json_view/number_format.md), the spelling of every untouched number |
|
||||||
| **Typical use** | general-purpose JSON handling: config, request/response bodies you build or modify, anything you hold onto | validating or projecting a text into your own data structure without ever holding the whole thing as JSON | large or high-volume input where you only need part of it, or need it repeatedly, and can keep the source text (or a copy) alive for as long as the document lives |
|
| **Typical use** | general-purpose JSON handling: config, request/response bodies you build or modify, anything you hold onto | validating or projecting a text into your own data structure without ever holding the whole thing as JSON | large or high-volume input where you only need part of it, or need it repeatedly, and can keep the source text (or a copy) alive for as long as the document lives | a document you read, patch a few fields of, and write back -- a configuration file, for instance -- where the rest of it should come back exactly as it was |
|
||||||
|
| **Caching/reload** | not applicable -- re-parse, or roll your own serialization | not applicable | [`save()`](../api/basic_json_document/save.md)/[`load()`](../api/basic_json_document/load.md): cache the parsed index as an image and reload it without parsing | same, saving the document's current -- possibly edited -- state |
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -23,17 +23,6 @@ This macro overrides [`#!cpp catch`](https://en.cppreference.com/w/cpp/language/
|
|||||||
|
|
||||||
See [full documentation of `JSON_CATCH_USER(exception)`](../api/macros/json_throw_user.md).
|
See [full documentation of `JSON_CATCH_USER(exception)`](../api/macros/json_throw_user.md).
|
||||||
|
|
||||||
## `JSON_DELETE_DEPRECATED_FUNCTIONS`
|
|
||||||
|
|
||||||
When defined to `1`, all deprecated functions are declared as deleted instead of only being marked as deprecated, so
|
|
||||||
code that still calls them no longer compiles. This way, you can find all calls that need to be replaced before version
|
|
||||||
4.0.0 removes these functions.
|
|
||||||
|
|
||||||
The macro can also be set with the CMake option
|
|
||||||
[`JSON_DeleteDeprecatedFunctions`](../integration/cmake.md#json_deletedeprecatedfunctions) (`OFF` by default).
|
|
||||||
|
|
||||||
See [full documentation of `JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md).
|
|
||||||
|
|
||||||
## `JSON_DIAGNOSTICS`
|
## `JSON_DIAGNOSTICS`
|
||||||
|
|
||||||
This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable
|
This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable
|
||||||
@@ -97,8 +86,7 @@ See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json
|
|||||||
## `JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`
|
## `JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`
|
||||||
|
|
||||||
When defined to `1`, a JSON value can no longer be created from a one-element `std::tuple` holding a reference to a JSON
|
When defined to `1`, a JSON value can no longer be created from a one-element `std::tuple` holding a reference to a JSON
|
||||||
value, such as the result of `std::forward_as_tuple(j)`. This lets `std::tuple` convert such tuples element-wise. This
|
value, such as the result of `std::forward_as_tuple(j)`. This lets `std::tuple` convert such tuples element-wise.
|
||||||
is planned to become the default in version 4.0.0.
|
|
||||||
|
|
||||||
See [full documentation of `JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`](../api/macros/json_disable_tuple_reference_conversion.md).
|
See [full documentation of `JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`](../api/macros/json_disable_tuple_reference_conversion.md).
|
||||||
|
|
||||||
@@ -210,13 +198,6 @@ default.
|
|||||||
|
|
||||||
See [full documentation of `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md).
|
See [full documentation of `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md).
|
||||||
|
|
||||||
## `JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`
|
|
||||||
|
|
||||||
When defined to `1`, maps with enum keys (e.g., `std::map<E, T>`) are stored as objects, using the enum's conversion for
|
|
||||||
the keys, instead of arrays of `[key, value]` pairs. It is switched off (`0`) by default.
|
|
||||||
|
|
||||||
See [full documentation of `JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md).
|
|
||||||
|
|
||||||
## `JSON_USE_SIMDUTF`
|
## `JSON_USE_SIMDUTF`
|
||||||
|
|
||||||
When defined, UTF-8 validation of JSON strings read from contiguous byte input is delegated to the
|
When defined, UTF-8 validation of JSON strings read from contiguous byte input is delegated to the
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ The complete default namespace name is derived as follows:
|
|||||||
- [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) defined non-zero appends `_psp`.
|
- [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) defined non-zero appends `_psp`.
|
||||||
- [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) defined non-zero appends `_snul`.
|
- [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) defined non-zero appends `_snul`.
|
||||||
- [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) defined non-zero appends `_sbu8`.
|
- [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) defined non-zero appends `_sbu8`.
|
||||||
- [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md) defined non-zero
|
|
||||||
appends `_ekmo`.
|
|
||||||
- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by
|
- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by
|
||||||
underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component)
|
underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component)
|
||||||
below.
|
below.
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ always use the scalar path regardless of this macro.
|
|||||||
|
|
||||||
Parsing always produces SAX events internally; [`parse`](../api/basic_json/parse.md) simply feeds them to a consumer
|
Parsing always produces SAX events internally; [`parse`](../api/basic_json/parse.md) simply feeds them to a consumer
|
||||||
that builds a complete `basic_json` value tree (a DOM) in memory. For documents too large to comfortably hold as
|
that builds a complete `basic_json` value tree (a DOM) in memory. For documents too large to comfortably hold as
|
||||||
a DOM, three alternatives avoid building it:
|
a DOM, two alternatives avoid building it:
|
||||||
|
|
||||||
- Implement the [SAX interface](parsing/sax_interface.md) directly and pass it to
|
- Implement the [SAX interface](parsing/sax_interface.md) directly and pass it to
|
||||||
[`sax_parse`](../api/basic_json/sax_parse.md); only the parts of the input you choose to keep ever become
|
[`sax_parse`](../api/basic_json/sax_parse.md); only the parts of the input you choose to keep ever become
|
||||||
@@ -64,12 +64,6 @@ a DOM, three alternatives avoid building it:
|
|||||||
discard finished elements as soon as they are handled, so memory usage stays bounded by one element (plus the
|
discard finished elements as soon as they are handled, so memory usage stays bounded by one element (plus the
|
||||||
unparsed remainder of the input) instead of the whole document -- see the [recipe for streaming a large homogeneous
|
unparsed remainder of the input) instead of the whole document -- see the [recipe for streaming a large homogeneous
|
||||||
array](parsing/parser_callbacks.md#recipe-streaming-a-large-homogeneous-array).
|
array](parsing/parser_callbacks.md#recipe-streaming-a-large-homogeneous-array).
|
||||||
- Parse into a [`json_document`](json_view.md) (`#!cpp <nlohmann/json_view.hpp>`) instead of a `basic_json`. It keeps
|
|
||||||
the input text and builds a flat index of 16 bytes per value; strings and numbers are not copied, but read from the
|
|
||||||
text when needed. Read-only [views](../api/basic_json_view/index.md) give the familiar element access, and only the
|
|
||||||
parts you [`materialize()`](../api/basic_json_view/materialize.md) become `basic_json` values. A document that
|
|
||||||
borrows the text instead of owning a copy needs the text to outlive it; see
|
|
||||||
[choosing between `json`, the SAX interface, and `json_view`](json_view.md#choosing-between-json-ordered_json-the-sax-interface-and-json_view).
|
|
||||||
|
|
||||||
If the data is naturally record-oriented, consider [JSON Lines](parsing/json_lines.md) instead of one large JSON
|
If the data is naturally record-oriented, consider [JSON Lines](parsing/json_lines.md) instead of one large JSON
|
||||||
document: reading and parsing it line by line with `#!cpp std::getline` means only one line's value is ever in memory
|
document: reading and parsing it line by line with `#!cpp std::getline` means only one line's value is ever in memory
|
||||||
@@ -215,7 +209,6 @@ those headers are then never processed by the compiler at all.
|
|||||||
- [Architecture](../home/architecture.md) - how input adapters, the lexer, and the serializer fit together
|
- [Architecture](../home/architecture.md) - how input adapters, the lexer, and the serializer fit together
|
||||||
- [Parsing](parsing/index.md) - the available parsing functions and inputs
|
- [Parsing](parsing/index.md) - the available parsing functions and inputs
|
||||||
- [SAX interface](parsing/sax_interface.md) - parse without building a DOM
|
- [SAX interface](parsing/sax_interface.md) - parse without building a DOM
|
||||||
- [Zero-copy JSON views](json_view.md) - parse into a flat index of the text and read it without building a DOM
|
|
||||||
- [Binary formats](binary_formats/index.md) - compact alternatives to JSON text
|
- [Binary formats](binary_formats/index.md) - compact alternatives to JSON text
|
||||||
- [Object Order](object_order.md) - `json` vs. `ordered_json` and other `ObjectType` choices
|
- [Object Order](object_order.md) - `json` vs. `ordered_json` and other `ObjectType` choices
|
||||||
- [Template Parameter Requirements](types/template_parameters.md) - custom container and allocator types
|
- [Template Parameter Requirements](types/template_parameters.md) - custom container and allocator types
|
||||||
|
|||||||
@@ -194,8 +194,8 @@ packet-beta
|
|||||||
|
|
||||||
| Bytes | Field | Type | Contents |
|
| Bytes | Field | Type | Contents |
|
||||||
|-------|---------|------------|-------------------------------------------------------------------------------------------------------------------------------|
|
|-------|---------|------------|-------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| 0 | `kind` | `uint8_t` | the type, numbered as [`value_t`](../api/basic_json/value_t.md): 0 null, 1 object, 2 array, 3 string, 4 boolean, 5 signed integer, 6 unsigned integer, 7 float |
|
| 0 | `kind` | `uint8_t` | the type, numbered as [`value_t`](../api/basic_json/value_t.md): 0 null, 1 object, 2 array, 3 string, 4 boolean, 5 signed integer, 6 unsigned integer, 7 float; 10 for a link (see below) |
|
||||||
| 1 | `flags` | `uint8_t` | bits 0-1: where a string's bytes are (0: the source text, 1: the buffer of decoded strings, for strings with escapes); bit 2: the value of a boolean |
|
| 1 | `flags` | `uint8_t` | bits 0-1: where a string's bytes (or a number's token) are (0: the source text, 1: the buffer of decoded strings, for strings with escapes, 2: the edit buffer); bit 2: the value of a boolean; bits 3 and 4: moved and new (see below) |
|
||||||
| 2-3 | `extra` | `uint16_t` | numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their hash index (1-based), or 0; otherwise 0 |
|
| 2-3 | `extra` | `uint16_t` | numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their hash index (1-based), or 0; otherwise 0 |
|
||||||
| 4-7 | `off` | `uint32_t` | where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object |
|
| 4-7 | `off` | `uint32_t` | where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object |
|
||||||
| 8-11 | `len` | `uint32_t` | strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements |
|
| 8-11 | `len` | `uint32_t` | strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements |
|
||||||
@@ -244,6 +244,29 @@ flowchart LR
|
|||||||
All `flags` are 0. The integer's bytes 8-15 hold its value, 1; its `extra` says it has one digit. The float's `extra`
|
All `flags` are 0. The integer's bytes 8-15 hold its value, 1; its `extra` says it has one digit. The float's `extra`
|
||||||
says it has one integer and one fraction digit, and its `len` is that of the token `2.5`.
|
says it has one integer and one fraction digit, and its `len` is that of the token `2.5`.
|
||||||
|
|
||||||
|
Editable documents ([`json_editable_document`](../api/json_editable_document.md),
|
||||||
|
[`detail/view/edit.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/view/edit.hpp) and
|
||||||
|
[`detail/view/edit_storage.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/view/edit_storage.hpp))
|
||||||
|
never write the source text and never move or resize the parsed index, so views stay valid while the document is
|
||||||
|
edited:
|
||||||
|
|
||||||
|
- A new scalar is written over its node. Its text (a string, or the token of a number as `dump()` writes it) goes to
|
||||||
|
the edit buffer, which `flags` bits 0-1 then name.
|
||||||
|
- An array or object whose elements change gets the flag *moved* (bit 3): its elements then live in a separate
|
||||||
|
sequence (a header node, then the entries), whose number is in `off`. The entries are links (`kind` 10), whose bytes
|
||||||
|
8-15 hold the address of the value's node, so values never move.
|
||||||
|
- A node written by an edit gets the flag *new* (bit 4): it has no position in the source text.
|
||||||
|
- Views of read-only documents compile without any of this: how views walk the index is a template parameter
|
||||||
|
(`navigation<Editable>`).
|
||||||
|
|
||||||
|
Images ([`save`](../api/basic_json_document/save.md) and [`load`](../api/basic_json_document/load.md),
|
||||||
|
[`detail/view/image.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/view/image.hpp)) store
|
||||||
|
the nodes as they are: a 64-byte header (the magic bytes `NJVI`, a format version, the sizes, and reserved bytes that
|
||||||
|
must be zero), the nodes, the text, and the decoded strings. An edited document is first written in document order, as
|
||||||
|
the parser would have written it (without links), and the numbers of the hash indexes are cleared, since `load`
|
||||||
|
rebuilds the indexes. So a change of the node layout is a change of the image format: it must raise `image_version`,
|
||||||
|
and `load` then rejects images of other versions (`parse_error.116`) instead of misreading them.
|
||||||
|
|
||||||
## Input adapters
|
## Input adapters
|
||||||
|
|
||||||
Input is read via **input adapters** that abstract a source. Every input adapter provides this interface:
|
Input is read via **input adapters** that abstract a source. Every input adapter provides this interface:
|
||||||
|
|||||||
@@ -331,6 +331,9 @@ An unexpected byte was read in a [binary format](../features/binary_formats/inde
|
|||||||
[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1
|
[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
|
[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: negative integer overflow
|
||||||
|
```
|
||||||
|
```
|
||||||
[json.exception.parse_error.112] parse error at byte 5: syntax error while parsing BSON document: document size 6 does not match the number of bytes read (5)
|
[json.exception.parse_error.112] parse error at byte 5: syntax error while parsing BSON document: document size 6 does not match the number of bytes read (5)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -388,6 +391,23 @@ A UBJSON high-precision number could not be parsed.
|
|||||||
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A
|
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### json.exception.parse_error.116
|
||||||
|
|
||||||
|
[`basic_json_document::load()`](../api/basic_json_document/load.md) rejected an
|
||||||
|
[image](../features/json_view.md#images): either the bytes are not one [`save()`](../api/basic_json_document/save.md)
|
||||||
|
could have written (too short, an unknown magic number or format version, or sizes that do not fit the buffer), or
|
||||||
|
they are, but fail the requested [`image_check`](../api/basic_json_document/load.md#image_check).
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.parse_error.116] parse error: invalid json_document image: the check failed
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
This exception was added in version 3.13.0, together with [images](../features/json_view.md#images).
|
||||||
|
|
||||||
## Iterator errors
|
## Iterator errors
|
||||||
|
|
||||||
This exception is thrown if iterators passed to a library function do not match
|
This exception is thrown if iterators passed to a library function do not match
|
||||||
@@ -596,9 +616,6 @@ During implicit or explicit value conversion, the JSON type must be compatible w
|
|||||||
[json.exception.type_error.302] type must be string, but is object
|
[json.exception.type_error.302] type must be string, but is object
|
||||||
```
|
```
|
||||||
|
|
||||||
This exception is also thrown with [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md)
|
|
||||||
if a key of a map with enum keys is not converted to a string, for instance, because the enum is stored as an integer.
|
|
||||||
|
|
||||||
### json.exception.type_error.303
|
### json.exception.type_error.303
|
||||||
|
|
||||||
To retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`.
|
To retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`.
|
||||||
@@ -791,32 +808,43 @@ The dynamic type of the object cannot be represented in the requested serializat
|
|||||||
|
|
||||||
Encapsulate the JSON value in an object. That is, instead of serializing `#!json true`, serialize `#!json {"value": true}`
|
Encapsulate the JSON value in an object. That is, instead of serializing `#!json true`, serialize `#!json {"value": true}`
|
||||||
|
|
||||||
### json.exception.type_error.318
|
### json.exception.type_error.319
|
||||||
|
|
||||||
With [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md), a map with enum
|
[`basic_json_document::set`](../api/basic_json_document/set.md) and
|
||||||
keys is stored as an object. This exception is thrown if two of its keys are converted to the same string, so one of the
|
[`basic_json_document::push_back`](../api/basic_json_document/push_back.md) can store any `basic_json` value except
|
||||||
entries would be lost. This happens, for instance, if [`NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md)
|
a binary one: a `json_document` has no representation for [binary values](../features/binary_values.md), which only
|
||||||
does not list an enumerator and it is therefore converted like the first listed one.
|
ever arise from parsing a binary format or from an explicit [`json::binary`](../api/basic_json/binary.md) value, not
|
||||||
|
from JSON text.
|
||||||
|
|
||||||
!!! failure "Example message"
|
!!! failure "Example message"
|
||||||
|
|
||||||
```
|
```
|
||||||
[json.exception.type_error.318] duplicate object key 'red'
|
[json.exception.type_error.319] cannot store a binary value in a json_document
|
||||||
```
|
```
|
||||||
|
|
||||||
### json.exception.type_error.321
|
!!! note
|
||||||
|
|
||||||
A discarded value (one created by [`parse()`](../api/basic_json/parse.md) with a callback that returns `false` for the
|
This exception was added in version 3.13.0, together with editable [`json_document`s](../features/json_view.md).
|
||||||
value, or by default-constructing a [`basic_json`](../api/basic_json/index.md) with
|
|
||||||
[`value_t::discarded`](../api/basic_json/value_t.md)) was passed to a binary serialization function, either directly or
|
|
||||||
nested in an array or object. There is no way to represent a discarded value in CBOR, MessagePack, UBJSON, BJData, or BSON.
|
|
||||||
|
|
||||||
!!! failure "Example message"
|
### json.exception.type_error.320
|
||||||
|
|
||||||
|
[`basic_json_document::save()`](../api/basic_json_document/save.md) cannot write an
|
||||||
|
[image](../features/json_view.md#images) of a [discarded](../api/basic_json_document/is_discarded.md) document.
|
||||||
|
[`save()`](../api/basic_json_document/save.md) and [`load()`](../api/basic_json_document/load.md) also throw this
|
||||||
|
exception on a big-endian target, since the image format is little-endian only.
|
||||||
|
|
||||||
|
!!! failure "Example messages"
|
||||||
|
|
||||||
Serializing `#!json [1, 2]` to CBOR, where the second element was discarded by a parser callback:
|
|
||||||
```
|
```
|
||||||
[json.exception.type_error.321] cannot serialize discarded value to CBOR
|
[json.exception.type_error.320] cannot save a discarded json_document
|
||||||
```
|
```
|
||||||
|
```
|
||||||
|
[json.exception.type_error.320] json_document images need a little-endian target
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
This exception was added in version 3.13.0, together with [images](../features/json_view.md#images).
|
||||||
|
|
||||||
## Out of range
|
## Out of range
|
||||||
|
|
||||||
@@ -890,18 +918,13 @@ The JSON Patch operations 'remove' and 'add' cannot be applied to the root eleme
|
|||||||
|
|
||||||
### json.exception.out_of_range.406
|
### json.exception.out_of_range.406
|
||||||
|
|
||||||
A parsed number could not be stored without changing it to NaN or INF. For the binary formats, this happens when a
|
A parsed number could not be stored as without changing it to NaN or INF.
|
||||||
finite floating-point number does not fit into [`number_float_t`](../api/basic_json/number_float_t.md), for example a
|
|
||||||
double-precision number when `number_float_t` is `#!cpp float`.
|
|
||||||
|
|
||||||
!!! failure "Example messages"
|
!!! failure "Example message"
|
||||||
|
|
||||||
```
|
```
|
||||||
number overflow parsing '10E1000'
|
number overflow parsing '10E1000'
|
||||||
```
|
```
|
||||||
```
|
|
||||||
[json.exception.out_of_range.406] syntax error while parsing CBOR value: number overflow
|
|
||||||
```
|
|
||||||
|
|
||||||
### json.exception.out_of_range.407
|
### json.exception.out_of_range.407
|
||||||
|
|
||||||
@@ -1047,13 +1070,24 @@ MessagePack's ext type and BSON's binary subtype are each stored in a single byt
|
|||||||
|
|
||||||
[`basic_json_document::parse()`](../api/basic_json_document/parse.md) and the other parsing functions of
|
[`basic_json_document::parse()`](../api/basic_json_document/parse.md) and the other parsing functions of
|
||||||
[`basic_json_document`](../api/basic_json_document/index.md) index a value's position in the source text in 32 bits,
|
[`basic_json_document`](../api/basic_json_document/index.md) index a value's position in the source text in 32 bits,
|
||||||
so they do not support an input of 4 GiB or more.
|
so they do not support an input of 4 GiB or more. The same 32-bit limit applies to an **editable** document's own
|
||||||
|
storage: [`set`](../api/basic_json_document/set.md) and [`push_back`](../api/basic_json_document/push_back.md) throw
|
||||||
|
this exception once the strings and number tokens written by edits reach 4 GiB in total, or once more than
|
||||||
|
4294967295 arrays/objects have had an element set or appended to them. The same limit applies to an
|
||||||
|
[image](../features/json_view.md#images): [`save()`](../api/basic_json_document/save.md) throws it if the node
|
||||||
|
count, the text, or the decoded strings it would write would individually reach 4 GiB.
|
||||||
|
|
||||||
!!! failure "Example message"
|
!!! failure "Example messages"
|
||||||
|
|
||||||
```
|
```
|
||||||
[json.exception.out_of_range.416] input of 4 GiB or more is not supported by json_document
|
[json.exception.out_of_range.416] input of 4 GiB or more is not supported by json_document
|
||||||
```
|
```
|
||||||
|
```
|
||||||
|
[json.exception.out_of_range.416] edits of 4 GiB or more are not supported by json_document
|
||||||
|
```
|
||||||
|
```
|
||||||
|
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document
|
||||||
|
```
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
|
|||||||
@@ -126,18 +126,12 @@ automatically download a release as a dependency at configure time.
|
|||||||
|
|
||||||
### `JSON_BuildTests`
|
### `JSON_BuildTests`
|
||||||
|
|
||||||
Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project and the `tests` directory exists (the release archive `json.tar.xz` does not contain it). That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.
|
Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.
|
||||||
|
|
||||||
### `JSON_CI`
|
### `JSON_CI`
|
||||||
|
|
||||||
Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default.
|
Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default.
|
||||||
|
|
||||||
### `JSON_DeleteDeprecatedFunctions`
|
|
||||||
|
|
||||||
Delete the deprecated functions instead of only deprecating them by defining the macro
|
|
||||||
[`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md). This option is `OFF` by
|
|
||||||
default.
|
|
||||||
|
|
||||||
### `JSON_Diagnostics`
|
### `JSON_Diagnostics`
|
||||||
|
|
||||||
Enable [extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This option is `OFF` by default.
|
Enable [extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This option is `OFF` by default.
|
||||||
|
|||||||
@@ -14,13 +14,6 @@ deprecations are annotated with
|
|||||||
[`HEDLEY_DEPRECATED_FOR`](https://nemequ.github.io/hedley/api-reference.html#HEDLEY_DEPRECATED_FOR) to report which
|
[`HEDLEY_DEPRECATED_FOR`](https://nemequ.github.io/hedley/api-reference.html#HEDLEY_DEPRECATED_FOR) to report which
|
||||||
function to use instead.
|
function to use instead.
|
||||||
|
|
||||||
!!! tip "Find all calls of deprecated functions"
|
|
||||||
|
|
||||||
Define [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) to `1` (or set the
|
|
||||||
CMake option [`JSON_DeleteDeprecatedFunctions`](cmake.md#json_deletedeprecatedfunctions)) to delete all deprecated
|
|
||||||
functions. Every remaining call then fails to compile, even if deprecation warnings are disabled, so your code is
|
|
||||||
ready for version 4.0.0 once it compiles with the macro.
|
|
||||||
|
|
||||||
### Parsing
|
### Parsing
|
||||||
|
|
||||||
- Function `friend std::istream& operator<<(basic_json&, std::istream&)` is deprecated since 3.0.0. Please use
|
- Function `friend std::istream& operator<<(basic_json&, std::istream&)` is deprecated since 3.0.0. Please use
|
||||||
@@ -48,10 +41,8 @@ function to use instead.
|
|||||||
[`from_ubjson`](../api/basic_json/from_ubjson.md), and [`from_bson`](../api/basic_json/from_bson.md)) via initializer
|
[`from_ubjson`](../api/basic_json/from_ubjson.md), and [`from_bson`](../api/basic_json/from_bson.md)) via initializer
|
||||||
lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call `from_cbor(ptr, ptr+len)` instead of
|
lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call `from_cbor(ptr, ptr+len)` instead of
|
||||||
`from_cbor({ptr, len})`. Likewise, passing a pointer and a length as two separate arguments to `from_cbor`,
|
`from_cbor({ptr, len})`. Likewise, passing a pointer and a length as two separate arguments to `from_cbor`,
|
||||||
`from_msgpack`, `from_ubjson`, and `from_bson` is deprecated since 3.8.0, and to
|
`from_msgpack`, `from_ubjson`, and `from_bson` is deprecated since 3.8.0; call `from_cbor(ptr, ptr+len)` instead of
|
||||||
[`from_bjdata`](../api/basic_json/from_bjdata.md) and [`from_bon8`](../api/basic_json/from_bon8.md) since 3.13.0; call
|
`from_cbor(ptr, len)`.
|
||||||
`from_cbor(ptr, ptr+len)` instead of `from_cbor(ptr, len)`. These overloads will not be removed in version 4.0.0, but
|
|
||||||
deleted, so a call like `from_cbor(ptr, len)` cannot compile and convert `len` to the `strict` parameter.
|
|
||||||
|
|
||||||
=== "Deprecated"
|
=== "Deprecated"
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -233,19 +233,24 @@ nav:
|
|||||||
- 'update': api/basic_json/update.md
|
- 'update': api/basic_json/update.md
|
||||||
- 'value': api/basic_json/value.md
|
- 'value': api/basic_json/value.md
|
||||||
- 'value_t': api/basic_json/value_t.md
|
- 'value_t': api/basic_json/value_t.md
|
||||||
- 'with_t': api/basic_json/with_t.md
|
|
||||||
- basic_json_document:
|
- basic_json_document:
|
||||||
- 'Overview': api/basic_json_document/index.md
|
- 'Overview': api/basic_json_document/index.md
|
||||||
- '(Constructor)': api/basic_json_document/basic_json_document.md
|
- '(Constructor)': api/basic_json_document/basic_json_document.md
|
||||||
- 'accept': api/basic_json_document/accept.md
|
- 'accept': api/basic_json_document/accept.md
|
||||||
|
- 'erase': api/basic_json_document/erase.md
|
||||||
|
- 'insert': api/basic_json_document/insert.md
|
||||||
- 'is_discarded': api/basic_json_document/is_discarded.md
|
- 'is_discarded': api/basic_json_document/is_discarded.md
|
||||||
|
- 'load': api/basic_json_document/load.md
|
||||||
- 'memory_usage': api/basic_json_document/memory_usage.md
|
- 'memory_usage': api/basic_json_document/memory_usage.md
|
||||||
- 'node_count': api/basic_json_document/node_count.md
|
- 'node_count': api/basic_json_document/node_count.md
|
||||||
- 'owns_source': api/basic_json_document/owns_source.md
|
- 'owns_source': api/basic_json_document/owns_source.md
|
||||||
- 'parse': api/basic_json_document/parse.md
|
- 'parse': api/basic_json_document/parse.md
|
||||||
- 'parse_copy': api/basic_json_document/parse_copy.md
|
- 'parse_copy': api/basic_json_document/parse_copy.md
|
||||||
|
- 'push_back': api/basic_json_document/push_back.md
|
||||||
- 'read': api/basic_json_document/read.md
|
- 'read': api/basic_json_document/read.md
|
||||||
- 'root': api/basic_json_document/root.md
|
- 'root': api/basic_json_document/root.md
|
||||||
|
- 'save': api/basic_json_document/save.md
|
||||||
|
- 'set': api/basic_json_document/set.md
|
||||||
- 'shrink_to_fit': api/basic_json_document/shrink_to_fit.md
|
- 'shrink_to_fit': api/basic_json_document/shrink_to_fit.md
|
||||||
- 'source': api/basic_json_document/source.md
|
- 'source': api/basic_json_document/source.md
|
||||||
- basic_json_view:
|
- basic_json_view:
|
||||||
@@ -308,6 +313,8 @@ nav:
|
|||||||
- 'to_json': api/adl_serializer/to_json.md
|
- 'to_json': api/adl_serializer/to_json.md
|
||||||
- 'json': api/json.md
|
- 'json': api/json.md
|
||||||
- 'json_document': api/json_document.md
|
- 'json_document': api/json_document.md
|
||||||
|
- 'json_editable_document': api/json_editable_document.md
|
||||||
|
- 'json_editable_view': api/json_editable_view.md
|
||||||
- json_pointer:
|
- json_pointer:
|
||||||
- 'Overview': api/json_pointer/index.md
|
- 'Overview': api/json_pointer/index.md
|
||||||
- '(Constructor)': api/json_pointer/json_pointer.md
|
- '(Constructor)': api/json_pointer/json_pointer.md
|
||||||
@@ -349,6 +356,8 @@ nav:
|
|||||||
- 'operator""_json_pointer': api/operator_literal_json_pointer.md
|
- 'operator""_json_pointer': api/operator_literal_json_pointer.md
|
||||||
- 'ordered_json': api/ordered_json.md
|
- 'ordered_json': api/ordered_json.md
|
||||||
- 'ordered_json_document': api/ordered_json_document.md
|
- 'ordered_json_document': api/ordered_json_document.md
|
||||||
|
- 'ordered_json_editable_document': api/ordered_json_editable_document.md
|
||||||
|
- 'ordered_json_editable_view': api/ordered_json_editable_view.md
|
||||||
- 'ordered_json_view': api/ordered_json_view.md
|
- 'ordered_json_view': api/ordered_json_view.md
|
||||||
- 'ordered_map': api/ordered_map.md
|
- 'ordered_map': api/ordered_map.md
|
||||||
- macros:
|
- macros:
|
||||||
@@ -357,7 +366,6 @@ nav:
|
|||||||
- 'JSON_BRACE_INIT_COPY_SEMANTICS': api/macros/json_brace_init_copy_semantics.md
|
- 'JSON_BRACE_INIT_COPY_SEMANTICS': api/macros/json_brace_init_copy_semantics.md
|
||||||
- 'JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER': api/macros/json_throw_user.md
|
- 'JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER': api/macros/json_throw_user.md
|
||||||
- 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md
|
- 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md
|
||||||
- 'JSON_DELETE_DEPRECATED_FUNCTIONS': api/macros/json_delete_deprecated_functions.md
|
|
||||||
- 'JSON_DIAGNOSTIC_POSITIONS': api/macros/json_diagnostic_positions.md
|
- 'JSON_DIAGNOSTIC_POSITIONS': api/macros/json_diagnostic_positions.md
|
||||||
- 'JSON_DISABLE_ENUM_SERIALIZATION': api/macros/json_disable_enum_serialization.md
|
- 'JSON_DISABLE_ENUM_SERIALIZATION': api/macros/json_disable_enum_serialization.md
|
||||||
- 'JSON_DISABLE_TUPLE_REFERENCE_CONVERSION': api/macros/json_disable_tuple_reference_conversion.md
|
- 'JSON_DISABLE_TUPLE_REFERENCE_CONVERSION': api/macros/json_disable_tuple_reference_conversion.md
|
||||||
@@ -379,7 +387,6 @@ nav:
|
|||||||
- 'JSON_USE_GLOBAL_UDLS': api/macros/json_use_global_udls.md
|
- 'JSON_USE_GLOBAL_UDLS': api/macros/json_use_global_udls.md
|
||||||
- 'JSON_USE_IMPLICIT_CONVERSIONS': api/macros/json_use_implicit_conversions.md
|
- 'JSON_USE_IMPLICIT_CONVERSIONS': api/macros/json_use_implicit_conversions.md
|
||||||
- 'JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON': api/macros/json_use_legacy_discarded_value_comparison.md
|
- 'JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON': api/macros/json_use_legacy_discarded_value_comparison.md
|
||||||
- 'JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS': api/macros/json_use_objects_for_enum_keyed_maps.md
|
|
||||||
- 'JSON_USE_SIMDUTF': api/macros/json_use_simdutf.md
|
- 'JSON_USE_SIMDUTF': api/macros/json_use_simdutf.md
|
||||||
- 'JSON_VIEW_NO_SIMD': api/macros/json_view_no_simd.md
|
- 'JSON_VIEW_NO_SIMD': api/macros/json_view_no_simd.md
|
||||||
- 'JSON_VIEW_USE_SSSE3': api/macros/json_view_use_ssse3.md
|
- 'JSON_VIEW_USE_SSSE3': api/macros/json_view_use_ssse3.md
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ mkdocs-material==9.7.7 # theme for mkdocs
|
|||||||
mkdocs-material-extensions==1.3.1 # extensions
|
mkdocs-material-extensions==1.3.1 # extensions
|
||||||
mkdocs-minify-plugin==0.8.0 # plugin "minify"
|
mkdocs-minify-plugin==0.8.0 # plugin "minify"
|
||||||
mkdocs-redirects==1.2.3 # plugin "redirects"
|
mkdocs-redirects==1.2.3 # plugin "redirects"
|
||||||
mkdocs-htmlproofer-plugin==1.6.0 # plugin "htmlproofer"
|
mkdocs-htmlproofer-plugin==1.5.0 # plugin "htmlproofer"
|
||||||
mkdocs-llmstxt==0.5.0 # plugin "llmstxt"
|
mkdocs-llmstxt==0.5.0 # plugin "llmstxt"
|
||||||
|
|
||||||
PyYAML==6.0.3 # linter
|
PyYAML==6.0.3 # linter
|
||||||
+3
-3
@@ -1454,9 +1454,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
"integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
|
|||||||
@@ -50,10 +50,6 @@
|
|||||||
#define JSON_STRICT_BINARY_UTF8 0
|
#define JSON_STRICT_BINARY_UTF8 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
||||||
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
|
||||||
#else
|
#else
|
||||||
@@ -96,20 +92,14 @@
|
|||||||
#define NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8
|
#define NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS _ekmo
|
|
||||||
#else
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
||||||
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Construct the namespace ABI tags component
|
// Construct the namespace ABI tags component
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h) json_abi ## a ## b ## c ## d ## e ## f ## g ## h
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g) json_abi ## a ## b ## c ## d ## e ## f ## g
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h) \
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g) \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h)
|
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g)
|
||||||
|
|
||||||
#define NLOHMANN_JSON_ABI_TAGS \
|
#define NLOHMANN_JSON_ABI_TAGS \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
||||||
@@ -119,8 +109,7 @@
|
|||||||
NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS, \
|
NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS, \
|
||||||
NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION, \
|
NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION, \
|
||||||
NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING, \
|
NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING, \
|
||||||
NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8, \
|
NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8)
|
||||||
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS)
|
|
||||||
|
|
||||||
// Construct the namespace version component
|
// Construct the namespace version component
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ inline void from_json(const BasicJsonType& j, EnumType& e)
|
|||||||
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
||||||
value_type val;
|
value_type val;
|
||||||
get_arithmetic_value(j, val);
|
get_arithmetic_value(j, val);
|
||||||
e = static_cast<EnumType>(bool_aware_static_cast<underlying_type>(val));
|
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
@@ -530,40 +530,11 @@ void from_json_pair_array_to_map(const BasicJsonType& j, MapType& m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read a map with enum keys from an object, using the enum's own from_json for
|
|
||||||
// the keys (e.g., from NLOHMANN_JSON_SERIALIZE_ENUM); this is the form written
|
|
||||||
// with JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
||||||
template<typename BasicJsonType, typename Map>
|
|
||||||
inline bool from_json_enum_keyed_object(const BasicJsonType& j, Map& m, std::true_type /*key is enum*/)
|
|
||||||
{
|
|
||||||
if (!j.is_object())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m.clear();
|
|
||||||
for (const auto& p : *j.template get_ptr<const typename BasicJsonType::object_t*>())
|
|
||||||
{
|
|
||||||
m.emplace(BasicJsonType(p.first).template get<typename Map::key_type>(), p.second.template get<typename Map::mapped_type>());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename BasicJsonType, typename Map>
|
|
||||||
inline bool from_json_enum_keyed_object(const BasicJsonType& /*j*/, Map& /*m*/, std::false_type /*key is enum*/)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
||||||
typename = enable_if_t < !std::is_constructible <
|
typename = enable_if_t < !std::is_constructible <
|
||||||
typename BasicJsonType::string_t, Key >::value >>
|
typename BasicJsonType::string_t, Key >::value >>
|
||||||
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
|
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(modernize-type-traits) we use C++11
|
|
||||||
if (from_json_enum_keyed_object(j, m, std::is_enum<Key> {}))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
from_json_pair_array_to_map(j, m);
|
from_json_pair_array_to_map(j, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,11 +543,6 @@ template < typename BasicJsonType, typename Key, typename Value, typename Hash,
|
|||||||
typename BasicJsonType::string_t, Key >::value >>
|
typename BasicJsonType::string_t, Key >::value >>
|
||||||
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
|
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(modernize-type-traits) we use C++11
|
|
||||||
if (from_json_enum_keyed_object(j, m, std::is_enum<Key> {}))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
from_json_pair_array_to_map(j, m);
|
from_json_pair_array_to_map(j, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -329,8 +329,8 @@ boundaries compute_boundaries(FloatType value)
|
|||||||
//
|
//
|
||||||
// -e <= 60 or e >= -60 := alpha
|
// -e <= 60 or e >= -60 := alpha
|
||||||
|
|
||||||
JSON_INLINE_VARIABLE constexpr int kAlpha = -60;
|
constexpr int kAlpha = -60;
|
||||||
JSON_INLINE_VARIABLE constexpr int kGamma = -32;
|
constexpr int kGamma = -32;
|
||||||
|
|
||||||
struct cached_power // c = f * 2^e ~= 10^k
|
struct cached_power // c = f * 2^e ~= 10^k
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <optional> // optional
|
#include <optional> // optional
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <algorithm> // copy
|
||||||
#include <iterator> // begin, end
|
#include <iterator> // begin, end
|
||||||
#include <memory> // allocator_traits
|
#include <memory> // allocator_traits
|
||||||
#include <string> // basic_string, char_traits
|
#include <string> // basic_string, char_traits
|
||||||
@@ -22,7 +23,6 @@
|
|||||||
#include <valarray> // valarray
|
#include <valarray> // valarray
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
|
||||||
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
#include <nlohmann/detail/meta/std_fs.hpp>
|
#include <nlohmann/detail/meta/std_fs.hpp>
|
||||||
@@ -38,14 +38,10 @@ namespace detail
|
|||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note all external_constructor<>::construct functions need to store the new
|
* Note all external_constructor<>::construct functions need to call
|
||||||
* value with j.replace_value(), which destroys the old one to avoid a memory
|
* j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
|
||||||
* leak in case j contains an allocated value (e.g., a string). See bug issue
|
* allocated value (e.g., a string). See bug issue
|
||||||
* https://github.com/nlohmann/json/issues/2865 for more information.
|
* https://github.com/nlohmann/json/issues/2865 for more information.
|
||||||
*
|
|
||||||
* A value that has to be allocated is created before the old one is destroyed:
|
|
||||||
* were it the other way around, an exception while creating the new value would
|
|
||||||
* leave j with the type of the new value, but the pointer to the destroyed old one.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<value_t> struct external_constructor;
|
template<value_t> struct external_constructor;
|
||||||
@@ -56,7 +52,10 @@ struct external_constructor<value_t::boolean>
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
|
static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
|
||||||
{
|
{
|
||||||
j.replace_value(value_t::boolean, b);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
|
j.m_data.m_type = value_t::boolean;
|
||||||
|
j.m_data.m_value = b;
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,15 +65,19 @@ struct external_constructor<value_t::string>
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
|
static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(s);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::string, value);
|
j.m_data.m_type = value_t::string;
|
||||||
|
j.m_data.m_value = s;
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
|
static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(std::move(s));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::string, value);
|
j.m_data.m_type = value_t::string;
|
||||||
|
j.m_data.m_value = std::move(s);
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename CompatibleStringType,
|
template < typename BasicJsonType, typename CompatibleStringType,
|
||||||
@@ -82,8 +85,10 @@ struct external_constructor<value_t::string>
|
|||||||
int > = 0 >
|
int > = 0 >
|
||||||
static void construct(BasicJsonType& j, const CompatibleStringType& str)
|
static void construct(BasicJsonType& j, const CompatibleStringType& str)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(j.template create<typename BasicJsonType::string_t>(str));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::string, value);
|
j.m_data.m_type = value_t::string;
|
||||||
|
j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,15 +98,19 @@ struct external_constructor<value_t::binary>
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
|
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(b);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::binary, value);
|
j.m_data.m_type = value_t::binary;
|
||||||
|
j.m_data.m_value = typename BasicJsonType::binary_t(b);
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
|
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(std::move(b));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::binary, value);
|
j.m_data.m_type = value_t::binary;
|
||||||
|
j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,7 +120,10 @@ struct external_constructor<value_t::number_float>
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
|
static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
|
||||||
{
|
{
|
||||||
j.replace_value(value_t::number_float, val);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
|
j.m_data.m_type = value_t::number_float;
|
||||||
|
j.m_data.m_value = val;
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,7 +133,10 @@ struct external_constructor<value_t::number_unsigned>
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
|
static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
|
||||||
{
|
{
|
||||||
j.replace_value(value_t::number_unsigned, val);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
|
j.m_data.m_type = value_t::number_unsigned;
|
||||||
|
j.m_data.m_value = val;
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -131,7 +146,10 @@ struct external_constructor<value_t::number_integer>
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
|
static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
|
||||||
{
|
{
|
||||||
j.replace_value(value_t::number_integer, val);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
|
j.m_data.m_type = value_t::number_integer;
|
||||||
|
j.m_data.m_value = val;
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,15 +159,21 @@ struct external_constructor<value_t::array>
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
|
static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(arr);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::array, value);
|
j.m_data.m_type = value_t::array;
|
||||||
|
j.m_data.m_value = arr;
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
|
static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(std::move(arr));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::array, value);
|
j.m_data.m_type = value_t::array;
|
||||||
|
j.m_data.m_value = std::move(arr);
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename CompatibleArrayType,
|
template < typename BasicJsonType, typename CompatibleArrayType,
|
||||||
@@ -163,23 +187,39 @@ struct external_constructor<value_t::array>
|
|||||||
using std::begin;
|
using std::begin;
|
||||||
using std::end;
|
using std::end;
|
||||||
|
|
||||||
const typename BasicJsonType::json_value value(j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr)));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::array, value);
|
j.m_data.m_type = value_t::array;
|
||||||
|
j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, const std::vector<bool>& arr)
|
static void construct(BasicJsonType& j, const std::vector<bool>& arr)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(j.template create<typename BasicJsonType::array_t>(arr.begin(), arr.end()));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::array, value);
|
j.m_data.m_type = value_t::array;
|
||||||
|
j.m_data.m_value = value_t::array;
|
||||||
|
j.m_data.m_value.array->reserve(arr.size());
|
||||||
|
for (const bool x : arr)
|
||||||
|
{
|
||||||
|
j.m_data.m_value.array->push_back(x);
|
||||||
|
j.set_parent(j.m_data.m_value.array->back());
|
||||||
|
}
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T,
|
||||||
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
||||||
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
|
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(j.template create<typename BasicJsonType::array_t>(std::begin(arr), std::end(arr)));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::array, value);
|
j.m_data.m_type = value_t::array;
|
||||||
|
j.m_data.m_value = value_t::array;
|
||||||
|
j.m_data.m_value.array->resize(arr.size());
|
||||||
|
std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if JSON_HAS_RANGE_VIEW_CONVERSION
|
#if JSON_HAS_RANGE_VIEW_CONVERSION
|
||||||
@@ -187,15 +227,18 @@ struct external_constructor<value_t::array>
|
|||||||
enable_if_t<is_compatible_range_view<std::remove_cvref_t<CompatibleArrayType>>::value, int> = 0>
|
enable_if_t<is_compatible_range_view<std::remove_cvref_t<CompatibleArrayType>>::value, int> = 0>
|
||||||
static void construct(BasicJsonType& j, CompatibleArrayType && arr)
|
static void construct(BasicJsonType& j, CompatibleArrayType && arr)
|
||||||
{
|
{
|
||||||
// no range constructor: a view's begin() and end() may have different
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
// types, and the view may only be iterable once
|
j.m_data.m_type = value_t::array;
|
||||||
typename BasicJsonType::array_t elements;
|
j.m_data.m_value = value_t::array;
|
||||||
for (auto&& x : std::forward<CompatibleArrayType>(arr))
|
for (auto&& x : std::forward<CompatibleArrayType>(arr))
|
||||||
{
|
{
|
||||||
elements.push_back(x);
|
j.m_data.m_value.array->push_back(x);
|
||||||
}
|
}
|
||||||
const typename BasicJsonType::json_value value(std::move(elements));
|
// set the parents only once all elements are in place: a push_back
|
||||||
j.replace_value(value_t::array, value);
|
// that reallocates moves the earlier elements, which does not keep
|
||||||
|
// their parent pointers
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -206,15 +249,21 @@ struct external_constructor<value_t::object>
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(obj);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::object, value);
|
j.m_data.m_type = value_t::object;
|
||||||
|
j.m_data.m_value = obj;
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
||||||
{
|
{
|
||||||
const typename BasicJsonType::json_value value(std::move(obj));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::object, value);
|
j.m_data.m_type = value_t::object;
|
||||||
|
j.m_data.m_value = std::move(obj);
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename CompatibleObjectType,
|
template < typename BasicJsonType, typename CompatibleObjectType,
|
||||||
@@ -224,8 +273,11 @@ struct external_constructor<value_t::object>
|
|||||||
using std::begin;
|
using std::begin;
|
||||||
using std::end;
|
using std::end;
|
||||||
|
|
||||||
const typename BasicJsonType::json_value value(j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj)));
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
j.replace_value(value_t::object, value);
|
j.m_data.m_type = value_t::object;
|
||||||
|
j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -234,20 +286,9 @@ struct external_constructor<value_t::object>
|
|||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
// whether storing the value of a std::optional<T> cannot throw; MSVC 2017
|
|
||||||
// evaluates std::is_nothrow_assignable as true even if T's to_json throws, so
|
|
||||||
// the exception would call std::terminate (#5642)
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1920
|
|
||||||
template<typename BasicJsonType, typename T>
|
|
||||||
using is_nothrow_optional_to_json = std::false_type;
|
|
||||||
#else
|
|
||||||
template<typename BasicJsonType, typename T>
|
|
||||||
using is_nothrow_optional_to_json = std::is_nothrow_assignable<BasicJsonType&, const T&>;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T,
|
||||||
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
||||||
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(is_nothrow_optional_to_json<BasicJsonType, T>::value)
|
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(std::is_nothrow_assignable<BasicJsonType&, const T&>::value)
|
||||||
{
|
{
|
||||||
if (opt.has_value())
|
if (opt.has_value())
|
||||||
{
|
{
|
||||||
@@ -323,7 +364,7 @@ inline void to_json(BasicJsonType& j, EnumType e) noexcept
|
|||||||
{
|
{
|
||||||
using underlying_type = typename std::underlying_type<EnumType>::type;
|
using underlying_type = typename std::underlying_type<EnumType>::type;
|
||||||
static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;
|
static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;
|
||||||
external_constructor<integral_value_t>::construct(j, bool_aware_static_cast<underlying_type>(e));
|
external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
@@ -343,9 +384,6 @@ template < typename BasicJsonType, typename CompatibleArrayType,
|
|||||||
!is_basic_json<CompatibleArrayType>::value
|
!is_basic_json<CompatibleArrayType>::value
|
||||||
#if JSON_HAS_RANGE_VIEW_CONVERSION
|
#if JSON_HAS_RANGE_VIEW_CONVERSION
|
||||||
&& !is_compatible_range_view<CompatibleArrayType>::value
|
&& !is_compatible_range_view<CompatibleArrayType>::value
|
||||||
#endif
|
|
||||||
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
||||||
&& !is_enum_keyed_map<CompatibleArrayType>::value
|
|
||||||
#endif
|
#endif
|
||||||
,
|
,
|
||||||
int > = 0 >
|
int > = 0 >
|
||||||
@@ -400,33 +438,6 @@ inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
|
|||||||
external_constructor<value_t::object>::construct(j, obj);
|
external_constructor<value_t::object>::construct(j, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
|
||||||
// store a map with enum keys as an object, using the enum's own to_json for the
|
|
||||||
// keys (e.g., from NLOHMANN_JSON_SERIALIZE_ENUM); without the macro, such maps
|
|
||||||
// are stored as arrays of [key, value] pairs
|
|
||||||
template < typename BasicJsonType, typename EnumKeyedMap,
|
|
||||||
enable_if_t < is_enum_keyed_map<EnumKeyedMap>::value&& !is_basic_json<EnumKeyedMap>::value, int > = 0 >
|
|
||||||
inline void to_json(BasicJsonType& j, const EnumKeyedMap& map)
|
|
||||||
{
|
|
||||||
typename BasicJsonType::object_t obj;
|
|
||||||
for (const auto& p : map)
|
|
||||||
{
|
|
||||||
BasicJsonType key = p.first;
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!key.is_string()))
|
|
||||||
{
|
|
||||||
JSON_THROW(type_error::create(302, concat("type must be string, but is ", key.type_name()), &key));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& key_string = *key.template get_ptr<typename BasicJsonType::string_t*>();
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!obj.emplace(key_string, BasicJsonType(p.second)).second))
|
|
||||||
{
|
|
||||||
JSON_THROW(type_error::create(318, concat("duplicate object key '", key_string, "'"), &key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
external_constructor<value_t::object>::construct(j, std::move(obj));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -221,7 +221,7 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
// scan functions
|
// scan functions
|
||||||
/////////////////////
|
/////////////////////
|
||||||
|
|
||||||
/// contiguous input: try to decode the 4 hex digits following `\\u`
|
/// contiguous input: try to decode the 4 hex digits following `\u`
|
||||||
/// directly from the input buffer via hex_codepoint(), instead of 4 calls
|
/// directly from the input buffer via hex_codepoint(), instead of 4 calls
|
||||||
/// to get(). On success, advances the adapter and the position counters
|
/// to get(). On success, advances the adapter and the position counters
|
||||||
/// exactly as those 4 get() calls would (a hex digit is never '\n', so
|
/// exactly as those 4 get() calls would (a hex digit is never '\n', so
|
||||||
@@ -2070,39 +2070,6 @@ scan_number_done:
|
|||||||
// read the next character and ignore whitespace
|
// read the next character and ignore whitespace
|
||||||
skip_whitespace();
|
skip_whitespace();
|
||||||
|
|
||||||
return scan_after_whitespace();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief scan the next token when the caller expects a separator (':' or
|
|
||||||
',') most of the time
|
|
||||||
|
|
||||||
After an object key the next token is almost always ':', after a value
|
|
||||||
inside an object or array almost always ','. Testing for that character
|
|
||||||
first is a compare and a well-predicted branch, where the switch in
|
|
||||||
scan_after_whitespace() is an indirect jump through a table. Anything else
|
|
||||||
goes through the switch, so the result is the same as scan()'s.
|
|
||||||
|
|
||||||
May only be called after scan() has run once (the BOM check is skipped).
|
|
||||||
*/
|
|
||||||
token_type scan_expecting(token_type expected_type)
|
|
||||||
{
|
|
||||||
JSON_ASSERT(expected_type == token_type::name_separator || expected_type == token_type::value_separator);
|
|
||||||
JSON_ASSERT(position.chars_read_total > 0);
|
|
||||||
const char_int_type expected_char = static_cast<unsigned char>((expected_type == token_type::name_separator) ? ':' : ',');
|
|
||||||
skip_whitespace();
|
|
||||||
if (JSON_HEDLEY_LIKELY(current == expected_char))
|
|
||||||
{
|
|
||||||
return expected_type;
|
|
||||||
}
|
|
||||||
return scan_after_whitespace();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// the part of scan() after the leading whitespace: skip comments and
|
|
||||||
/// scan the token that starts with current
|
|
||||||
token_type scan_after_whitespace()
|
|
||||||
{
|
|
||||||
// ignore comments
|
// ignore comments
|
||||||
while (ignore_comments && current == '/')
|
while (ignore_comments && current == '/')
|
||||||
{
|
{
|
||||||
@@ -2182,6 +2149,7 @@ scan_number_done:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
/// input adapter
|
/// input adapter
|
||||||
InputAdapterType ia;
|
InputAdapterType ia;
|
||||||
|
|
||||||
|
|||||||
Loaded 100 of 185 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user