mirror of
https://github.com/nlohmann/json.git
synced 2026-10-07 06:57:14 +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
@@ -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,7 +66,7 @@ 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
|
||||||
|
|||||||
+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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -68,8 +68,12 @@ cc_library(
|
|||||||
"include/nlohmann/detail/string_utils.hpp",
|
"include/nlohmann/detail/string_utils.hpp",
|
||||||
"include/nlohmann/detail/value_t.hpp",
|
"include/nlohmann/detail/value_t.hpp",
|
||||||
"include/nlohmann/detail/view/builder.hpp",
|
"include/nlohmann/detail/view/builder.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",
|
||||||
@@ -78,8 +82,11 @@ cc_library(
|
|||||||
"include/nlohmann/detail/view/materialize.hpp",
|
"include/nlohmann/detail/view/materialize.hpp",
|
||||||
"include/nlohmann/detail/view/node.hpp",
|
"include/nlohmann/detail/view/node.hpp",
|
||||||
"include/nlohmann/detail/view/number.hpp",
|
"include/nlohmann/detail/view/number.hpp",
|
||||||
|
"include/nlohmann/detail/view/object_index.hpp",
|
||||||
"include/nlohmann/detail/view/pointer.hpp",
|
"include/nlohmann/detail/view/pointer.hpp",
|
||||||
"include/nlohmann/detail/view/scan.hpp",
|
"include/nlohmann/detail/view/scan.hpp",
|
||||||
|
"include/nlohmann/detail/view/serializer.hpp",
|
||||||
|
"include/nlohmann/detail/view/simd.hpp",
|
||||||
"include/nlohmann/detail/view/string_ref.hpp",
|
"include/nlohmann/detail/view/string_ref.hpp",
|
||||||
"include/nlohmann/detail/view/value.hpp",
|
"include/nlohmann/detail/view/value.hpp",
|
||||||
"include/nlohmann/json.hpp",
|
"include/nlohmann/json.hpp",
|
||||||
|
|||||||
@@ -62,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)
|
||||||
@@ -124,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()
|
||||||
@@ -164,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(
|
||||||
|
|||||||
@@ -1404,6 +1404,7 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I
|
|||||||
- The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
|
- The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
|
||||||
- The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright © 2021 The fast_float authors
|
- The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright © 2021 The fast_float authors
|
||||||
- The view's parser (`<nlohmann/json_view.hpp>`) contains techniques and code adapted from [yyjson](https://github.com/ibireme/yyjson) by YaoYuan, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above): table-driven decoding of `\u` escapes and fixed-offset unrolled checks.
|
- The view's parser (`<nlohmann/json_view.hpp>`) contains techniques and code adapted from [yyjson](https://github.com/ibireme/yyjson) by YaoYuan, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above): table-driven decoding of `\u` escapes and fixed-offset unrolled checks.
|
||||||
|
- The view's parser (`<nlohmann/json_view.hpp>`) validates non-ASCII strings with the vector UTF-8 check of [simdjson](https://github.com/simdjson/simdjson) by Daniel Lemire, Geoff Langdale, John Keiser, and contributors (its "lookup4" algorithm and tables, after J. Keiser and D. Lemire, "Validating UTF-8 In Less Than One Instruction Per Byte", 2021), which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here) and the Apache 2.0 License. Copyright © 2018-2025 The simdjson authors
|
||||||
|
|
||||||
<img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
|
<img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
|
||||||
|
|
||||||
|
|||||||
+2
-16
@@ -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}
|
||||||
@@ -722,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})
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
+17
-2
@@ -135,14 +135,20 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::~basic_json', 'Me
|
|||||||
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');
|
||||||
@@ -154,6 +160,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::cbegin', 'Me
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::cend', 'Method', 'api/basic_json_view/cend/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::cend', 'Method', 'api/basic_json_view/cend/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::contains', 'Method', 'api/basic_json_view/contains/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::contains', 'Method', 'api/basic_json_view/contains/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::count', 'Method', 'api/basic_json_view/count/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::count', 'Method', 'api/basic_json_view/count/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::dump', 'Method', 'api/basic_json_view/dump/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::empty', 'Method', 'api/basic_json_view/empty/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::empty', 'Method', 'api/basic_json_view/empty/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::end', 'Method', 'api/basic_json_view/end/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::end', 'Method', 'api/basic_json_view/end/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::find', 'Method', 'api/basic_json_view/find/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::find', 'Method', 'api/basic_json_view/find/index.html');
|
||||||
@@ -176,9 +183,13 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_string',
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_structured', 'Method', 'api/basic_json_view/is_structured/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_structured', 'Method', 'api/basic_json_view/is_structured/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::items', 'Method', 'api/basic_json_view/items/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::items', 'Method', 'api/basic_json_view/items/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::materialize', 'Method', 'api/basic_json_view/materialize/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::materialize', 'Method', 'api/basic_json_view/materialize/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::number_format', 'Enum', 'api/basic_json_view/number_format/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::number_token', 'Method', 'api/basic_json_view/number_token/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::number_token', 'Method', 'api/basic_json_view/number_token/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator bool', 'Method', 'api/basic_json_view/operator_bool/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator bool', 'Method', 'api/basic_json_view/operator_bool/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator<<', 'Operator', 'api/basic_json_view/operator_ltlt/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator[]', 'Operator', 'api/basic_json_view/operator[]/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator[]', 'Operator', 'api/basic_json_view/operator[]/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator==', 'Operator', 'api/basic_json_view/operator_eq/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator!=', 'Operator', 'api/basic_json_view/operator_ne/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::size', 'Method', 'api/basic_json_view/size/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::size', 'Method', 'api/basic_json_view/size/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::source_offset', 'Method', 'api/basic_json_view/source_offset/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::source_offset', 'Method', 'api/basic_json_view/source_offset/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::type', 'Method', 'api/basic_json_view/type/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::type', 'Method', 'api/basic_json_view/type/index.html');
|
||||||
@@ -186,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');
|
||||||
@@ -225,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');
|
||||||
@@ -276,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');
|
||||||
@@ -307,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');
|
||||||
@@ -343,3 +356,5 @@ INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_SERIALIZE_ENUM_
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MAJOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MAJOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MINOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MINOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_PATCH', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_PATCH', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_VIEW_NO_SIMD', 'Macro', 'api/macros/json_view_no_simd/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_VIEW_USE_SSSE3', 'Macro', 'api/macros/json_view_use_ssse3/index.html');
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ Binary values are serialized as an object containing two keys:
|
|||||||
|
|
||||||
- [to_string](to_string.md) returns a string representation of a JSON value
|
- [to_string](to_string.md) returns a string representation of a JSON value
|
||||||
- [operator<<](../operator_ltlt.md) serialize to stream
|
- [operator<<](../operator_ltlt.md) serialize to stream
|
||||||
|
- [`basic_json_view::dump`](../basic_json_view/dump.md) the corresponding function of `basic_json_view`, serializing
|
||||||
|
directly from a flat index without building a `basic_json` value
|
||||||
- [Serialization](../../features/serialization.md) - the serialization article
|
- [Serialization](../../features/serialization.md) - the serialization article
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|||||||
@@ -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.
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -171,6 +171,8 @@ Linear.
|
|||||||
|
|
||||||
- [operator!=](operator_ne.md) compare for inequality
|
- [operator!=](operator_ne.md) compare for inequality
|
||||||
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20)
|
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20)
|
||||||
|
- [basic_json_view::operator==](../basic_json_view/operator_eq.md) - the same comparison on a zero-copy view, without
|
||||||
|
building a `basic_json` value for it
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ Linear.
|
|||||||
|
|
||||||
- [operator==](operator_eq.md) comparison: equal
|
- [operator==](operator_eq.md) comparison: equal
|
||||||
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20)
|
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20)
|
||||||
|
- [basic_json_view::operator!=](../basic_json_view/operator_ne.md) - the same comparison on a zero-copy view, without
|
||||||
|
building a `basic_json` value for it
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
|
||||||
@@ -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.
|
||||||
@@ -49,6 +49,11 @@ whether or not the new parse succeeds; take fresh views from [`root()`](root.md)
|
|||||||
`input` is borrowed or owned by the same rules as [`parse()`](parse.md#notes); a document can borrow on one call and
|
`input` is borrowed or owned by the same rules as [`parse()`](parse.md#notes); a document can borrow on one call and
|
||||||
own on the next, since ownership is decided freshly each time.
|
own on the next, since ownership is decided freshly each time.
|
||||||
|
|
||||||
|
Reusing a document matters most for large inputs: the operating system provides the memory of a fresh node index one
|
||||||
|
page at a time, and every page costs a page fault the first time it is written. On x86-64 Linux (4 KiB pages), parsing
|
||||||
|
a 55 MB document into a reused document took about 40 % less time than parsing it into a fresh one. Programs that parse
|
||||||
|
many documents of similar size should therefore keep one document and call `read()`.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example
|
??? example
|
||||||
@@ -70,6 +75,7 @@ own on the next, since ownership is decided freshly each time.
|
|||||||
|
|
||||||
- [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.
|
||||||
@@ -74,6 +74,8 @@ None of these exceptions carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics
|
|||||||
1. Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
1. Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
another, in document order, stopping at the first match. Each comparison first checks the key's length --
|
another, in document order, stopping at the first match. Each comparison first checks the key's length --
|
||||||
already known from the index, without reading the key bytes -- before comparing its content.
|
already known from the index, without reading the key bytes -- before comparing its content.
|
||||||
|
Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time
|
||||||
|
on average.
|
||||||
2. Linear in `idx`: elements are skipped one at a time from the first one, since they are not a fixed size in the
|
2. Linear in `idx`: elements are skipped one at a time from the first one, since they are not a fixed size in the
|
||||||
index (unlike `BasicJsonType`'s array, which is random-access).
|
index (unlike `BasicJsonType`'s array, which is random-access).
|
||||||
3. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
3. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ No-throw guarantee: this function never throws exceptions.
|
|||||||
1. Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
1. Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
||||||
known from the index, without reading the key bytes -- before comparing its content.
|
known from the index, without reading the key bytes -- before comparing its content.
|
||||||
|
Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time
|
||||||
|
on average.
|
||||||
2. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
2. 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 for [`operator[]`](operator[].md#complexity) and
|
that level or the index into the array -- as for [`operator[]`](operator[].md#complexity) and
|
||||||
[`at`](at.md#complexity) with a JSON pointer.
|
[`at`](at.md#complexity) with a JSON pointer.
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ No-throw guarantee: this function never throws exceptions.
|
|||||||
Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
||||||
known from the index, without reading the key bytes -- before comparing its content.
|
known from the index, without reading the key bytes -- before comparing its content.
|
||||||
|
Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time on
|
||||||
|
average.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>dump
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
string_t dump(const int indent = -1,
|
||||||
|
const char indent_char = ' ',
|
||||||
|
const bool ensure_ascii = false,
|
||||||
|
const number_format numbers = number_format::shortest) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
Serializes this value (and its subtree) directly from the flat index, without ever building a `BasicJsonType` value
|
||||||
|
first. With the default `#!cpp numbers == number_format::shortest`, the result is the same string
|
||||||
|
[`BasicJsonType::dump`](../basic_json/dump.md) would produce for the value
|
||||||
|
[`BasicJsonType::parse()`](../basic_json/parse.md) builds from the same source text, called with the same `indent`,
|
||||||
|
`indent_char`, and `ensure_ascii` -- except that members of an object appear in document order rather than sorted by
|
||||||
|
key, and *every* occurrence of a repeated key is written rather than only the last one (see
|
||||||
|
[Notes on duplicate keys](operator[].md#notes)). For a `json_view` (whose `BasicJsonType` is not ordered), this means
|
||||||
|
`dump()` can print an object's members in a different order than [`materialize()`](materialize.md)`.dump()` of the
|
||||||
|
same subtree.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`indent` (in)
|
||||||
|
: If `indent` is nonnegative, array elements and object members are pretty-printed with that indent level. An
|
||||||
|
indent level of `0` only inserts newlines. `-1` (the default) selects the most compact representation.
|
||||||
|
|
||||||
|
`indent_char` (in)
|
||||||
|
: The character used for indentation if `indent` is greater than `0`. The default is ` ` (space).
|
||||||
|
|
||||||
|
`ensure_ascii` (in)
|
||||||
|
: If `ensure_ascii` is `#!cpp true`, all non-ASCII characters in the output are escaped with `\uXXXX` sequences, and
|
||||||
|
the result consists of ASCII characters only.
|
||||||
|
|
||||||
|
`numbers` (in)
|
||||||
|
: how to write numbers, see [`number_format`](number_format.md): `shortest` (the default) writes them the way
|
||||||
|
[`BasicJsonType::dump`](../basic_json/dump.md) would; `source` copies every number exactly as it appears in the
|
||||||
|
source text.
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
string containing the serialization of this value, or `#!cpp "<discarded>"` if the view is
|
||||||
|
[discarded](is_discarded.md).
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
May throw `#!cpp std::bad_alloc` if allocating the output string fails. Unlike
|
||||||
|
[`BasicJsonType::dump`](../basic_json/dump.md), there is no `error_handler` parameter and no
|
||||||
|
[`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316): the view only ever holds text the parser
|
||||||
|
already validated as UTF-8, so there is nothing to replace or ignore.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the size of the output text.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
The walk over the subtree is iterative, so the nesting depth it can write is limited by available memory only, not by
|
||||||
|
the call stack -- as for [`materialize()`](materialize.md).
|
||||||
|
|
||||||
|
Strings are escaped by the same rules as [`BasicJsonType::dump`](../basic_json/dump.md). With
|
||||||
|
`#!cpp numbers == number_format::shortest`, floats are written with the library's shortest round-trip conversion,
|
||||||
|
exactly as [`BasicJsonType::dump`](../basic_json/dump.md) would (e.g. `#!cpp 1.5`, `#!cpp 100.0`, `#!cpp 1e+100`), and
|
||||||
|
integers are copied from the source text -- already canonical in JSON, so this matches their shortest form too --
|
||||||
|
except that `#!cpp -0` is written as `#!cpp 0`, the way [`BasicJsonType::parse()`](../basic_json/parse.md) reads it.
|
||||||
|
`#!cpp number_format::source` copies every number exactly as written in the source text instead, with no exception
|
||||||
|
for `#!cpp -0` -- `#!cpp 1.50`, `#!cpp 1E2`, `#!cpp -0.0`, `#!cpp -0`, or all digits of an integer literal with more
|
||||||
|
digits than any number type holds (such a literal is itself classified as a float, see
|
||||||
|
[What is different](../../features/json_view.md#what-is-different)) -- something `BasicJsonType` cannot do, since
|
||||||
|
parsing already reduces every number to its parsed value.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below forwards a single record out of a larger batch, and re-serializes a configuration file, both
|
||||||
|
without ever building a `BasicJsonType` value for the surrounding array or for the parts of it that were not
|
||||||
|
needed. It also shows that [`materialize()`](materialize.md)`.dump()` of the configuration sorts its keys, where
|
||||||
|
`dump()` on the view keeps the order they appear in the source text.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__dump.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__dump.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [`number_format`](number_format.md) - how `dump()` writes numbers
|
||||||
|
- [operator<<](operator_ltlt.md) - serialize this value to a stream
|
||||||
|
- [materialize](materialize.md) - build a `BasicJsonType` value, e.g. to use `BasicJsonType::dump`'s `error_handler`
|
||||||
|
- [`BasicJsonType::dump`](../basic_json/dump.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -28,6 +28,8 @@ No-throw guarantee: this function never throws exceptions.
|
|||||||
Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
||||||
known from the index, without reading the key bytes -- before comparing its content.
|
known from the index, without reading the key bytes -- before comparing its content.
|
||||||
|
Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time on
|
||||||
|
average.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -20,11 +20,19 @@ Moving the document itself does not invalidate its views: the index is heap-allo
|
|||||||
`basic_json_document` object.
|
`basic_json_document` object.
|
||||||
|
|
||||||
`basic_json_view` provides the read-only part of the `BasicJsonType` interface: the type-inspection functions, element
|
`basic_json_view` provides the read-only part of the `BasicJsonType` interface: the type-inspection functions, element
|
||||||
access, lookup, iteration, and conversion -- [`get<T>()`](get.md), [`get_string()`](get_string.md),
|
access, lookup, iteration, conversion, and comparison -- [`get<T>()`](get.md), [`get_string()`](get_string.md),
|
||||||
[`number_token()`](number_token.md), and [`materialize()`](materialize.md) to build the `BasicJsonType` value of a
|
[`number_token()`](number_token.md), and [`materialize()`](materialize.md) to build the `BasicJsonType` value of a
|
||||||
subtree on demand. [`operator[]`](operator%5B%5D.md), [`at`](at.md), [`contains`](contains.md), and
|
subtree on demand. [`operator[]`](operator%5B%5D.md), [`at`](at.md), [`contains`](contains.md), and
|
||||||
[`value`](value.md) also accept a [`json_pointer`](../json_pointer/index.md). It does not (yet) provide `dump()` or
|
[`value`](value.md) also accept a [`json_pointer`](../json_pointer/index.md). [`operator==`](operator_eq.md) and
|
||||||
comparison.
|
[`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.
|
||||||
|
|
||||||
|
`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
|
||||||
|
|
||||||
@@ -32,10 +40,17 @@ comparison.
|
|||||||
: 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
|
||||||
|
|
||||||
@@ -47,6 +62,7 @@ comparison.
|
|||||||
- **iterator**, **const_iterator** - a forward iterator over the elements of an array or the member values of an
|
- **iterator**, **const_iterator** - a forward iterator over the elements of an array or the member values of an
|
||||||
object, in document order; both names refer to the same type, since a view is always read-only
|
object, in document order; both names refer to the same type, since a view is always read-only
|
||||||
- **item** - a (key, value) pair produced by [`items()`](items.md)
|
- **item** - a (key, value) pair produced by [`items()`](items.md)
|
||||||
|
- [**number_format**](number_format.md) - how [`dump()`](dump.md) writes numbers
|
||||||
|
|
||||||
## Member functions
|
## Member functions
|
||||||
|
|
||||||
@@ -106,6 +122,16 @@ comparison.
|
|||||||
- [**number_token**](number_token.md) - get a number's token text without a copy
|
- [**number_token**](number_token.md) - get a number's token text without a copy
|
||||||
- [**materialize**](materialize.md) - build the `BasicJsonType` value of this subtree
|
- [**materialize**](materialize.md) - build the `BasicJsonType` value of this subtree
|
||||||
|
|
||||||
|
### Comparison
|
||||||
|
|
||||||
|
- [**operator==**](operator_eq.md) - comparison: equal
|
||||||
|
- [**operator!=**](operator_ne.md) - comparison: not equal
|
||||||
|
|
||||||
|
### Serialization
|
||||||
|
|
||||||
|
- [**dump**](dump.md) - serialize to a JSON-formatted string
|
||||||
|
- [**operator<<**](operator_ltlt.md) - serialize to stream
|
||||||
|
|
||||||
### Source access
|
### Source access
|
||||||
|
|
||||||
- [**source_offset**](source_offset.md) - byte offset of this value in the document's source text
|
- [**source_offset**](source_offset.md) - byte offset of this value in the document's source text
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>number_format
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
enum class number_format {
|
||||||
|
shortest,
|
||||||
|
source
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
This enumeration is used in [`dump`](dump.md) to choose how numbers are written. Two values are differentiated:
|
||||||
|
|
||||||
|
shortest
|
||||||
|
: integers are copied from the source text -- already canonical in JSON -- except that `#!cpp -0` becomes
|
||||||
|
`#!cpp 0`, the way [`BasicJsonType::parse()`](../basic_json/parse.md) reads it; floats are written with the
|
||||||
|
library's shortest round-trip conversion, exactly as [`BasicJsonType::dump()`](../basic_json/dump.md) would (e.g.
|
||||||
|
`#!cpp 1.5`, `#!cpp 100.0`, `#!cpp 1e+100`)
|
||||||
|
|
||||||
|
source
|
||||||
|
: every number is copied exactly as it appears in the source text -- `#!cpp 1.50`, `#!cpp 1E2`, `#!cpp -0`, all
|
||||||
|
digits of an integer literal with more digits than any number type holds -- something `BasicJsonType` cannot do,
|
||||||
|
since parsing already reduces every number to its parsed value
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below writes back a price list received from a supplier: with `number_format::shortest` (the
|
||||||
|
default), a trailing zero and scientific notation are normalized away and a long account number that overflows
|
||||||
|
every number type is rounded, the same way `#!cpp materialize().dump()` (or `basic_json::dump()`) would;
|
||||||
|
`number_format::source` keeps every number exactly as it was written in the source text instead.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__number_format.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__number_format.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [dump](dump.md) - serialize to a JSON-formatted string
|
||||||
|
- [number_token](number_token.md) - get a single number's token text without dumping the whole value
|
||||||
|
- [`BasicJsonType::error_handler_t`](../basic_json/error_handler_t.md) - the analogous enumeration for
|
||||||
|
`BasicJsonType::dump`'s decoding-error behavior
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -76,6 +76,8 @@ None of these exceptions carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics
|
|||||||
another, in document order, stopping at the first match. Each comparison first checks the key's length --
|
another, in document order, stopping at the first match. Each comparison first checks the key's length --
|
||||||
already known from the index, without reading the key bytes -- before comparing its content, so a key of a
|
already known from the index, without reading the key bytes -- before comparing its content, so a key of a
|
||||||
different length than `key` is rejected without touching the source text.
|
different length than `key` is rejected without touching the source text.
|
||||||
|
Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time
|
||||||
|
on average.
|
||||||
2. Linear in `idx`: elements are skipped one at a time from the first one, since they are not a fixed size in the
|
2. Linear in `idx`: elements are skipped one at a time from the first one, since they are not a fixed size in the
|
||||||
index (unlike `BasicJsonType`'s array, which is random-access).
|
index (unlike `BasicJsonType`'s array, which is random-access).
|
||||||
3. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
3. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>operator==
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// (1)
|
||||||
|
bool operator==(const basic_json_view& lhs, const basic_json_view& rhs);
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
bool operator==(const basic_json_view& lhs, const BasicJsonType& rhs);
|
||||||
|
bool operator==(const BasicJsonType& lhs, const basic_json_view& rhs);
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Compares two views for equality: whether the values [`BasicJsonType::parse()`](../basic_json/parse.md) would
|
||||||
|
produce for `lhs` and `rhs` are equal, according to `BasicJsonType`'s [`operator==`](../basic_json/operator_eq.md).
|
||||||
|
2. Compares a view and a `BasicJsonType` value for equality, in either order: whether the value `parse()` would
|
||||||
|
produce for the view and the other operand are equal, according to `BasicJsonType`'s
|
||||||
|
[`operator==`](../basic_json/operator_eq.md).
|
||||||
|
|
||||||
|
Neither overload builds a `BasicJsonType` value for a view to do the comparison (see [Notes](#notes) below). Numbers
|
||||||
|
compare by value across their types (`#!cpp 1 == 1.0`), and an object compares by its members, with duplicate keys
|
||||||
|
resolved exactly as `parse()` resolves them -- the last value, at the position of the first occurrence of the key.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`lhs` (in)
|
||||||
|
: first value to consider
|
||||||
|
|
||||||
|
`rhs` (in)
|
||||||
|
: second value to consider
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
whether the values `lhs` and `rhs` are equal
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong exception safety: if an exception is thrown, there are no changes to either operand, or to the document(s) a
|
||||||
|
view refers to.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
May throw `#!cpp std::bad_alloc`. Unlike the other comparison and most other `basic_json_view` functions,
|
||||||
|
`operator==` is not `#!cpp noexcept`: resolving an object's members needs a temporary array to sort them by key (see
|
||||||
|
[Complexity](#complexity) below), and that allocation can fail.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the size of the compared values: every number, string, array element, and object member is visited at most
|
||||||
|
once, and the walk is iterative, so the nesting depth it can compare is limited by available memory only, not by the
|
||||||
|
call stack (as for [`materialize()`](materialize.md)). Resolving an object's members takes an additional O(n log n)
|
||||||
|
in the number of members at that level, since they are sorted by key to detect and resolve duplicates before being
|
||||||
|
compared. Two arrays of different [`size()`](size.md) are rejected without visiting either one's elements.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Only a single number, boolean, or `#!cpp null` value is ever materialized into a `BasicJsonType`, to reuse its
|
||||||
|
`operator==` -- for numbers, so that values written differently in the source text but equal in value (e.g. an
|
||||||
|
integer and a floating-point literal) still compare equal, following the same rules `BasicJsonType` does for special
|
||||||
|
values such as `#!cpp NaN`. Constructing one of these scalars never allocates. Strings are compared directly, without
|
||||||
|
allocating, either from the source text on both sides or, for overload 2, against `BasicJsonType`'s own string.
|
||||||
|
Arrays and objects are never materialized at all; only their elements or members are visited, one pair at a time.
|
||||||
|
|
||||||
|
!!! info "How objects are compared"
|
||||||
|
|
||||||
|
For a [`json_view`](../json_view.md) (`BasicJsonType::object_t` is `#!cpp std::map`), members are compared by
|
||||||
|
key, regardless of the order they appear in the source text. For an
|
||||||
|
[`ordered_json_view`](../ordered_json_view.md) (`object_t` is `ordered_map`), they are compared in the order
|
||||||
|
they occur, so the very same two objects with their members reordered can compare equal as `json_view`s but not
|
||||||
|
as `ordered_json_view`s. This is exactly how [`json`](../json.md) and [`ordered_json`](../ordered_json.md)
|
||||||
|
compare, see ["Comparing different `basic_json` specializations"](../basic_json/operator_eq.md#notes).
|
||||||
|
|
||||||
|
!!! info "Discarded views"
|
||||||
|
|
||||||
|
A [discarded](is_discarded.md) view compares the same way a discarded `BasicJsonType` value does, which is
|
||||||
|
governed by
|
||||||
|
[`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../macros/json_use_legacy_discarded_value_comparison.md): by
|
||||||
|
default, a discarded view is never equal to anything, not even another discarded view.
|
||||||
|
|
||||||
|
No ordering comparison (`#!cpp operator<`) is provided for `basic_json_view`; [`materialize()`](materialize.md) is
|
||||||
|
the way to get a `BasicJsonType` value that supports it.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below checks whether a newly received configuration differs from the previous one, and whether a
|
||||||
|
received document matches what a test expects -- directly on views, without ever materializing a `BasicJsonType`
|
||||||
|
value for either side.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__operator_eq.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__operator_eq.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [operator!=](operator_ne.md) - compare for inequality
|
||||||
|
- [materialize](materialize.md) - build a `BasicJsonType` value, e.g. to keep comparing after the document is gone
|
||||||
|
- [`BasicJsonType::operator==`](../basic_json/operator_eq.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>operator<<
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::ostream& operator<<(std::ostream& o, const basic_json_view& v);
|
||||||
|
```
|
||||||
|
|
||||||
|
Not available when [`JSON_NO_IO`](../macros/json_no_io.md) is defined.
|
||||||
|
|
||||||
|
Serializes the given view `v` to the output stream `o`, using [`dump`](dump.md) -- exactly as
|
||||||
|
`#!cpp operator<<(std::ostream&, const basic_json&)` does for a `basic_json` value.
|
||||||
|
|
||||||
|
- The indentation of the output can be controlled with the member variable `width` of the output stream `o`. For
|
||||||
|
instance, using the manipulator `std::setw(4)` on `o` sets the indentation level to `4`, and the serialization
|
||||||
|
result is the same as calling `#!cpp v.dump(4)`. A `width` of `0` or less (the default) selects the most compact
|
||||||
|
representation, as `#!cpp v.dump(-1)` does.
|
||||||
|
- The indentation character can be controlled with the member variable `fill` of the output stream `o`. For instance,
|
||||||
|
the manipulator `std::setfill('\t')` sets indentation to use a tab character rather than the default space
|
||||||
|
character.
|
||||||
|
- As for `basic_json`, `o`'s `width` is reset to `0` after this call, whether or not it was greater than `0` before.
|
||||||
|
|
||||||
|
Numbers are always written as `#!cpp v.dump()` writes them by default, i.e. as with
|
||||||
|
[`number_format::shortest`](number_format.md); there is no way to select `#!cpp number_format::source` through the
|
||||||
|
stream.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`o` (in, out)
|
||||||
|
: stream to write to
|
||||||
|
|
||||||
|
`v` (in)
|
||||||
|
: view to serialize
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
the stream `o`
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
May throw `#!cpp std::bad_alloc`, propagated from [`dump`](dump.md#exceptions). Unlike
|
||||||
|
`#!cpp operator<<(std::ostream&, const basic_json&)`, there is no UTF-8 decoding step that could throw
|
||||||
|
[`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316), and no `error_handler` to choose between --
|
||||||
|
see the [Exceptions](dump.md#exceptions) of `dump`.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear, as [`dump`](dump.md#complexity).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below writes one record out of a larger batch straight to a log stream -- compact for a one-line
|
||||||
|
entry, and pretty-printed with `std::setw`/`std::setfill` for a readable dump -- without ever building a
|
||||||
|
`BasicJsonType` value for the record, or for the rest of the batch.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__operator_ltlt.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__operator_ltlt.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [dump](dump.md) - serialize to a JSON-formatted string
|
||||||
|
- [`operator<<(std::ostream&)`](../operator_ltlt.md) - the corresponding operator for `basic_json`
|
||||||
|
- [`JSON_NO_IO`](../macros/json_no_io.md) - switch off functions relying on certain C++ I/O headers
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>operator!=
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// (1)
|
||||||
|
bool operator!=(const basic_json_view& lhs, const basic_json_view& rhs);
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
bool operator!=(const basic_json_view& lhs, const BasicJsonType& rhs);
|
||||||
|
bool operator!=(const BasicJsonType& lhs, const basic_json_view& rhs);
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Compares two views for inequality. Returns `#!cpp !(lhs == rhs)`, see [operator==](operator_eq.md).
|
||||||
|
2. Compares a view and a `BasicJsonType` value for inequality, in either order. Returns `#!cpp !(lhs == rhs)` (or,
|
||||||
|
for the reversed order, `#!cpp !(rhs == lhs)`), see [operator==](operator_eq.md).
|
||||||
|
|
||||||
|
Since `operator!=` is defined as the negation of [`operator==`](operator_eq.md), it follows the same rules for
|
||||||
|
special cases: for instance, since a [discarded](is_discarded.md) view is never equal to anything by default (see
|
||||||
|
[operator=='s Notes](operator_eq.md#notes)), it is never *unequal* to anything either -- `#!cpp discarded != discarded`
|
||||||
|
is also `#!cpp false`, exactly as for a discarded `BasicJsonType` value.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`lhs` (in)
|
||||||
|
: first value to consider
|
||||||
|
|
||||||
|
`rhs` (in)
|
||||||
|
: second value to consider
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
whether the values `lhs` and `rhs` are not equal
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong exception safety: if an exception is thrown, there are no changes to either operand, or to the document(s) a
|
||||||
|
view refers to.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
May throw `#!cpp std::bad_alloc`, propagated from [`operator==`](operator_eq.md#exceptions). Unlike most other
|
||||||
|
`basic_json_view` functions, `operator!=` is not `#!cpp noexcept`.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear, as [`operator==`](operator_eq.md#complexity).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
See the [Notes](operator_eq.md#notes) of `operator==` -- in particular for how an object's members are compared
|
||||||
|
(order matters for [`ordered_json_view`](../ordered_json_view.md) but not for [`json_view`](../json_view.md)) and
|
||||||
|
for how discarded views compare.
|
||||||
|
|
||||||
|
No ordering comparison (`#!cpp operator<`) is provided for `basic_json_view`; [`materialize()`](materialize.md) is
|
||||||
|
the way to get a `BasicJsonType` value that supports it.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below asserts, as a test would, that a received document differs from an unwanted value, and shows
|
||||||
|
that -- as for [`json`](../json.md)/[`ordered_json`](../ordered_json.md) -- reordering an object's members is
|
||||||
|
detected as a difference for an `ordered_json_view` but not for a `json_view`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__operator_ne.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__operator_ne.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [operator==](operator_eq.md) - compare for equality
|
||||||
|
- [materialize](materialize.md) - build a `BasicJsonType` value, e.g. to keep comparing after the document is gone
|
||||||
|
- [`BasicJsonType::operator!=`](../basic_json/operator_ne.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -70,6 +70,8 @@ None of these exceptions carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics
|
|||||||
1. Linear in the number of members: as for [`operator[]`](operator[].md#complexity), members are compared one after
|
1. Linear in the number of members: as for [`operator[]`](operator[].md#complexity), members are compared one after
|
||||||
another, in document order, stopping at the first match. Plus the complexity of converting the found member to
|
another, in document order, stopping at the first match. Plus the complexity of converting the found member to
|
||||||
`T` (see [`get`](get.md)).
|
`T` (see [`get`](get.md)).
|
||||||
|
Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time
|
||||||
|
on average.
|
||||||
2. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
2. 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 for the [`operator[]`](operator[].md#complexity) and
|
that level or the index into the array -- as for the [`operator[]`](operator[].md#complexity) and
|
||||||
[`at`](at.md#complexity) overloads that take a JSON pointer. Plus the complexity of converting the resolved value
|
[`at`](at.md#complexity) overloads that take a JSON pointer. Plus the complexity of converting the resolved value
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -37,6 +37,8 @@ header. See also the [macro overview page](../../features/macros.md).
|
|||||||
- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers
|
- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers
|
||||||
- [**JSON_USE_GLOBAL_UDLS**](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace
|
- [**JSON_USE_GLOBAL_UDLS**](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace
|
||||||
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
|
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
|
||||||
|
- [**JSON_VIEW_NO_SIMD**](json_view_no_simd.md) - use only portable code in the parser of `json_view.hpp`
|
||||||
|
- [**JSON_VIEW_USE_SSSE3**](json_view_use_ssse3.md) - validate non-ASCII strings with SSSE3 in the parser of `json_view.hpp`
|
||||||
|
|
||||||
## Library version
|
## Library version
|
||||||
|
|
||||||
@@ -58,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
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# JSON_VIEW_NO_SIMD
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_VIEW_NO_SIMD
|
||||||
|
```
|
||||||
|
|
||||||
|
When defined, the parser of [`basic_json_document`](../basic_json_document/index.md) (`<nlohmann/json_view.hpp>`)
|
||||||
|
uses only portable C++ to scan strings. By default, it scans long runs of string bytes 16 at a time with NEON on
|
||||||
|
AArch64 (with GCC and Clang) and SSE2 on x86-64, which are part of the baseline instruction sets of these
|
||||||
|
architectures, and validates non-ASCII text with NEON (or SSSE3, see
|
||||||
|
[`JSON_VIEW_USE_SSSE3`](json_view_use_ssse3.md)).
|
||||||
|
|
||||||
|
The same input is accepted or rejected either way, with the same values, and errors are reported the same way; only
|
||||||
|
the speed differs. The macro exists for platforms whose compilers lack the intrinsics headers, and to test the portable
|
||||||
|
code.
|
||||||
|
|
||||||
|
!!! warning "Define consistently"
|
||||||
|
|
||||||
|
The macro selects between two definitions of the same inline functions. It must therefore be defined identically for
|
||||||
|
**every** translation unit that includes `<nlohmann/json_view.hpp>`; prefer a compile definition on the target.
|
||||||
|
|
||||||
|
## Default definition
|
||||||
|
|
||||||
|
By default, `#!cpp JSON_VIEW_NO_SIMD` is not defined, and the vector code is used where available.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#undef JSON_VIEW_NO_SIMD
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The code below uses the portable string scanning of the view.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_VIEW_NO_SIMD
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [JSON_VIEW_USE_SSSE3](json_view_use_ssse3.md) - validate non-ASCII strings with SSSE3 on x86-64
|
||||||
|
- [json_view](../../features/json_view.md) - the zero-copy view
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# JSON_VIEW_USE_SSSE3
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_VIEW_USE_SSSE3
|
||||||
|
```
|
||||||
|
|
||||||
|
When defined on x86-64, the parser of [`basic_json_document`](../basic_json_document/index.md)
|
||||||
|
(`<nlohmann/json_view.hpp>`) validates non-ASCII text in strings with SSSE3 without asking the CPU first.
|
||||||
|
|
||||||
|
By default, the parser checks once at run time whether the CPU has SSSE3 (all x86-64 CPUs since about 2011 have it)
|
||||||
|
and then validates non-ASCII text 16 bytes at a time, using the "lookup4" algorithm of
|
||||||
|
[simdjson](https://github.com/simdjson/simdjson); on CPUs without SSSE3, it validates one UTF-8 sequence at a time.
|
||||||
|
The vector check is compiled for SSSE3 with a function attribute (GCC 4.9 and later, Clang), so this needs no compiler
|
||||||
|
option. With MSVC, the check uses `__cpuid`. On AArch64, the vector check uses NEON and is always on.
|
||||||
|
|
||||||
|
Define the macro only together with a compiler option that enables SSSE3 (e.g. `-mssse3`, or `-march=` with a CPU that
|
||||||
|
has it), and only for programs that run on such CPUs. It saves the check of the CPU, which costs little. The same
|
||||||
|
input is accepted or rejected either way; only the speed of non-ASCII text differs.
|
||||||
|
|
||||||
|
!!! warning "Define consistently"
|
||||||
|
|
||||||
|
The macro selects between two definitions of the same inline functions. It must therefore be defined identically,
|
||||||
|
with the same compiler options, for **every** translation unit that includes `<nlohmann/json_view.hpp>`; mixing
|
||||||
|
translation units that define it with ones that do not is an ODR violation. Prefer a compile definition on the
|
||||||
|
target.
|
||||||
|
|
||||||
|
## Default definition
|
||||||
|
|
||||||
|
By default, `#!cpp JSON_VIEW_USE_SSSE3` is not defined.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#undef JSON_VIEW_USE_SSSE3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
With CMake, for a program that only runs on CPUs with SSSE3:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
target_compile_definitions(your_target PRIVATE JSON_VIEW_USE_SSSE3)
|
||||||
|
target_compile_options(your_target PRIVATE -mssse3)
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [JSON_VIEW_NO_SIMD](json_view_no_simd.md) - use only portable code in the view's parser
|
||||||
|
- [JSON_USE_SIMDUTF](json_use_simdutf.md) - validate UTF-8 with simdutf in `basic_json`'s parser
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ Linear.
|
|||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [dump](basic_json/dump.md) - serialize to a JSON-formatted string
|
- [dump](basic_json/dump.md) - serialize to a JSON-formatted string
|
||||||
|
- [`basic_json_view::operator<<`](basic_json_view/operator_ltlt.md) - the corresponding operator for
|
||||||
|
`basic_json_view`
|
||||||
- [Serialization](../features/serialization.md) - the serialization article
|
- [Serialization](../features/serialization.md) - the serialization article
|
||||||
|
|
||||||
## 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 |
|
||||||
|
|||||||
@@ -64,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:
|
||||||
|
|
||||||
@@ -77,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>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -88,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 |
|
||||||
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------------------------------------------------------------------|
|
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------------------------------------------------------------------|
|
||||||
@@ -106,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
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using json_view = nlohmann::json_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a large batch of sensor readings -- forward just the one that changed,
|
||||||
|
// without ever building a basic_json value for the batch or for the
|
||||||
|
// readings that are not needed
|
||||||
|
const json_document batch = json_document::parse(R"(
|
||||||
|
[{"id": 1, "temp": 21.5}, {"id": 2, "temp": 87.3}, {"id": 3, "temp": 21.7}]
|
||||||
|
)");
|
||||||
|
const json_view readings = batch.root();
|
||||||
|
std::cout << readings[1].dump() << '\n';
|
||||||
|
|
||||||
|
// a configuration file -- dump() on the view keeps the member order of
|
||||||
|
// the source text; a json value's object_t is std::map, so
|
||||||
|
// materialize().dump() of the very same view sorts the keys instead
|
||||||
|
const json_document config = json_document::parse(
|
||||||
|
R"({"name": "cache", "host": "db1", "port": 6379, "timeout": 30})");
|
||||||
|
std::cout << config.root().dump(2) << "\n\n";
|
||||||
|
std::cout << config.root().materialize().dump(2) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{"id":2,"temp":87.3}
|
||||||
|
{
|
||||||
|
"name": "cache",
|
||||||
|
"host": "db1",
|
||||||
|
"port": 6379,
|
||||||
|
"timeout": 30
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
"host": "db1",
|
||||||
|
"name": "cache",
|
||||||
|
"port": 6379,
|
||||||
|
"timeout": 30
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using json_view = nlohmann::json_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a price list received from a supplier feed -- prices and account
|
||||||
|
// numbers must be forwarded exactly, e.g. into an invoice
|
||||||
|
const json_document doc = json_document::parse(R"(
|
||||||
|
[{"sku": "A1", "price": 19.90, "account_id": 12345678901234567890123456},
|
||||||
|
{"sku": "A2", "price": 1E2, "account_id": 98765432109876543210987654}]
|
||||||
|
)");
|
||||||
|
const json_view list = doc.root();
|
||||||
|
|
||||||
|
// number_format::shortest (the default) writes numbers the way
|
||||||
|
// basic_json::dump() would: "19.90" becomes "19.9", "1E2" becomes
|
||||||
|
// "100.0", and each account number -- far beyond any 64-bit integer --
|
||||||
|
// is rounded to the nearest double, exactly as materialize().dump()
|
||||||
|
// (or a plain nlohmann::json) would round it
|
||||||
|
std::cout << list.dump() << '\n';
|
||||||
|
|
||||||
|
// number_format::source copies every number exactly as it was written
|
||||||
|
// in the source text instead -- something basic_json cannot do at all,
|
||||||
|
// since parsing already reduces every number to its parsed value
|
||||||
|
std::cout << list.dump(-1, ' ', false, json_view::number_format::source) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
[{"sku":"A1","price":19.9,"account_id":1.2345678901234568e+25},{"sku":"A2","price":100.0,"account_id":9.876543210987655e+25}]
|
||||||
|
[{"sku":"A1","price":19.90,"account_id":12345678901234567890123456},{"sku":"A2","price":1E2,"account_id":98765432109876543210987654}]
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// two snapshots of a polled configuration endpoint -- compare them
|
||||||
|
// directly as views, without ever building a nlohmann::json value for
|
||||||
|
// either one
|
||||||
|
const json_document previous = json_document::parse(
|
||||||
|
R"({"name": "cache", "port": 6379, "timeout": 30})");
|
||||||
|
const json_document current = json_document::parse(
|
||||||
|
R"({"port": 6379.0, "timeout": 30, "name": "cache"})");
|
||||||
|
|
||||||
|
// same members, reordered, and 6379 written as a float -- operator==
|
||||||
|
// treats them the same way BasicJsonType::operator== would
|
||||||
|
std::cout << std::boolalpha << (previous.root() == current.root()) << '\n';
|
||||||
|
|
||||||
|
// an actually changed value is detected the same way
|
||||||
|
const json_document changed = json_document::parse(
|
||||||
|
R"({"name": "cache", "port": 6380, "timeout": 30})");
|
||||||
|
std::cout << (previous.root() == changed.root()) << '\n';
|
||||||
|
|
||||||
|
// comparing a view directly against an expected json value -- handy in a
|
||||||
|
// test, without materializing the received document at all
|
||||||
|
const json expected = {{"name", "cache"}, {"port", 6379}, {"timeout", 30}};
|
||||||
|
std::cout << (previous.root() == expected) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
true
|
||||||
|
false
|
||||||
|
true
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using json_view = nlohmann::json_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// one order out of a large incoming batch -- write it straight to a log
|
||||||
|
// stream without ever building a basic_json value for it, or for the
|
||||||
|
// rest of the batch
|
||||||
|
const json_document doc = json_document::parse(R"(
|
||||||
|
[{"id": 1, "item": "cable"}, {"id": 2, "item": "adapter"}]
|
||||||
|
)");
|
||||||
|
const json_view orders = doc.root();
|
||||||
|
|
||||||
|
// compact, for a one-line log entry
|
||||||
|
std::cout << orders[1] << '\n';
|
||||||
|
|
||||||
|
// std::setw sets the indentation level, exactly as for basic_json
|
||||||
|
std::cout << std::setw(2) << orders[1] << "\n\n";
|
||||||
|
|
||||||
|
// std::setfill changes the indentation character
|
||||||
|
std::cout << std::setw(1) << std::setfill('\t') << orders[1] << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{"id":2,"item":"adapter"}
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"item": "adapter"
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"item": "adapter"
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using ordered_json_document = nlohmann::ordered_json_document;
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// assert, as a test would, that a received document differs from an
|
||||||
|
// unwanted shape -- without ever materializing it into a json value just
|
||||||
|
// to compare
|
||||||
|
const json_document received = json_document::parse(
|
||||||
|
R"({"status": "ok", "code": 200})");
|
||||||
|
const json unwanted = {{"status", "error"}, {"code", 500}};
|
||||||
|
std::cout << std::boolalpha << (received.root() != unwanted) << '\n';
|
||||||
|
|
||||||
|
// json (std::map) compares object members regardless of order ...
|
||||||
|
const json_document a = json_document::parse(R"({"a": 1, "b": 2})");
|
||||||
|
const json_document b = json_document::parse(R"({"b": 2, "a": 1})");
|
||||||
|
std::cout << (a.root() != b.root()) << '\n';
|
||||||
|
|
||||||
|
// ... but ordered_json (ordered_map) compares them in the order they
|
||||||
|
// appear, so the very same reordering is detected as a difference
|
||||||
|
const ordered_json_document oa = ordered_json_document::parse(R"({"a": 1, "b": 2})");
|
||||||
|
const ordered_json_document ob = ordered_json_document::parse(R"({"b": 2, "a": 1})");
|
||||||
|
std::cout << (oa.root() != ob.root()) << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
true
|
||||||
|
false
|
||||||
|
true
|
||||||
@@ -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}
|
||||||
@@ -168,9 +168,9 @@ The library maps CBOR types to JSON value types as follows:
|
|||||||
!!! 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
|
||||||
|
|||||||
@@ -139,8 +139,12 @@ whenever any of the other conditions above was not met.
|
|||||||
element access and lookup functions never carry the JSON Pointer path `JSON_DIAGNOSTICS` would otherwise add: the
|
element access and lookup functions never carry the JSON Pointer path `JSON_DIAGNOSTICS` would otherwise add: the
|
||||||
view has no `basic_json` value to point at, so the exception is created without one, regardless of how
|
view has no `basic_json` value to point at, so the exception is created without one, regardless of how
|
||||||
`BasicJsonType` was built.
|
`BasicJsonType` was built.
|
||||||
- **`dump()` and comparison are not (yet) provided** by `basic_json_view`. For now,
|
- **Ordering comparisons are not provided** by `basic_json_view` -- there is no `#!cpp operator<`.
|
||||||
[`materialize()`](../api/basic_json_view/materialize.md) is the way to get a value you can do those things with.
|
[`operator==`](../api/basic_json_view/operator_eq.md) and [`operator!=`](../api/basic_json_view/operator_ne.md) are
|
||||||
|
provided, though: two views, or a view and a `BasicJsonType` value, compare equal exactly when
|
||||||
|
[`materialize()`](../api/basic_json_view/materialize.md) or [`parse()`](../api/basic_json/parse.md) would produce
|
||||||
|
equal values for them, without ever building a tree to do it. For ordering, too,
|
||||||
|
[`materialize()`](../api/basic_json_view/materialize.md) is the way to get a value you can compare.
|
||||||
|
|
||||||
## Getting values out without copying
|
## Getting values out without copying
|
||||||
|
|
||||||
@@ -166,14 +170,146 @@ Two conversions never copy at all:
|
|||||||
|
|
||||||
Both results are only valid as long as the view -- and, for a string with no escapes, the borrowed source text -- is.
|
Both results are only valid as long as the view -- and, for a string with no escapes, the borrowed source text -- is.
|
||||||
|
|
||||||
|
## Writing a view back
|
||||||
|
|
||||||
|
[`dump()`](../api/basic_json_view/dump.md) serializes a view directly from the flat index, without ever building a
|
||||||
|
`basic_json` value. An object's members are written in document order, not sorted by key, and *every* occurrence of a
|
||||||
|
repeated key is written, not only the last one -- the same two ways [iteration](#what-is-different) already differs
|
||||||
|
from a [`materialize()`](../api/basic_json_view/materialize.md)d value, see above. `#!cpp materialize().dump()` gives
|
||||||
|
a different result in both respects for a `json_view`.
|
||||||
|
|
||||||
|
By default, numbers are written the way [`basic_json::dump()`](../api/basic_json/dump.md) would.
|
||||||
|
[`number_format::source`](../api/basic_json_view/number_format.md) instead copies every number exactly as it was
|
||||||
|
written in the source text -- a price like `#!cpp 19.90`, a long order or account ID with more digits than any number
|
||||||
|
type holds, or a high-precision coordinate -- something `basic_json` cannot do at all, since parsing already reduces
|
||||||
|
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
|
||||||
|
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,9 +194,9 @@ 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; 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 |
|
||||||
| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself |
|
| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself |
|
||||||
@@ -211,6 +211,11 @@ packet-beta
|
|||||||
subtree is `next` nodes further for an array or object, and the next node otherwise (`document_data::after`). Views
|
subtree is `next` nodes further for an array or object, and the next node otherwise (`document_data::after`). Views
|
||||||
step from element to element this way and skip whole subtrees in constant time.
|
step from element to element this way and skip whole subtrees in constant time.
|
||||||
- **Offsets** are 32 bits wide, so a document is limited to 4 GiB (`out_of_range.416`).
|
- **Offsets** are 32 bits wide, so a document is limited to 4 GiB (`out_of_range.416`).
|
||||||
|
- **Large objects** (128 members or more) get a hash index after parsing
|
||||||
|
([`detail/view/object_index.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/view/object_index.hpp)):
|
||||||
|
an open-addressing table whose slots hold the distance from the object's node to a key's node, so that a lookup does
|
||||||
|
not compare every key. The object's `extra` holds the number of its table. Only 65,535 tables fit into `extra`;
|
||||||
|
objects beyond them are searched linearly.
|
||||||
|
|
||||||
For example, `#!json {"a": [1, 2.5]}` becomes five nodes. Each node's elements follow it, and `next` leads from an
|
For example, `#!json {"a": [1, 2.5]}` becomes five nodes. Each node's elements follow it, and `next` leads from an
|
||||||
array or object past its subtree:
|
array or object past its subtree:
|
||||||
@@ -239,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
|
||||||
|
|
||||||
|
|||||||
@@ -25,3 +25,5 @@ The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Eva
|
|||||||
The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright © 2021 The fast_float authors
|
The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright © 2021 The fast_float authors
|
||||||
|
|
||||||
The view's parser (`<nlohmann/json_view.hpp>`) contains techniques and code adapted from [yyjson](https://github.com/ibireme/yyjson) by YaoYuan, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above): table-driven decoding of `\u` escapes and fixed-offset unrolled checks.
|
The view's parser (`<nlohmann/json_view.hpp>`) contains techniques and code adapted from [yyjson](https://github.com/ibireme/yyjson) by YaoYuan, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above): table-driven decoding of `\u` escapes and fixed-offset unrolled checks.
|
||||||
|
|
||||||
|
The view's parser (`<nlohmann/json_view.hpp>`) validates non-ASCII strings with the vector UTF-8 check of [simdjson](https://github.com/simdjson/simdjson) by Daniel Lemire, Geoff Langdale, John Keiser, and contributors (its "lookup4" algorithm and tables, after J. Keiser and D. Lemire, "Validating UTF-8 In Less Than One Instruction Per Byte", 2021), which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here) and the Apache 2.0 License. Copyright © 2018-2025 The simdjson authors
|
||||||
@@ -132,12 +132,6 @@ Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/
|
|||||||
|
|
||||||
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"
|
||||||
|
|
||||||
|
|||||||
Loaded 100 of 175 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user