mirror of
https://github.com/nlohmann/json.git
synced 2026-10-25 07:18:55 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37cd434784 | ||
|
|
3250b5ce46 | ||
|
|
52724f5ae5 | ||
|
|
d01e6382fe | ||
|
|
589c29d69b | ||
|
|
80fd9c0fb4 | ||
|
|
169f1fcb2d | ||
|
|
020a834128 | ||
|
|
7dcff6b8cd | ||
|
|
769c5cde57 | ||
|
|
993e37e7ec |
No files matched your search
+10
-3
@@ -108,9 +108,16 @@ The tests are located in [`tests/src/unit-*.cpp`](https://github.com/nlohmann/js
|
||||
are structured along the features of the library or the nature of the tests. Usually, it should be clear from the
|
||||
context which existing file needs to be extended, and only very few cases require creating new test files.
|
||||
|
||||
When fixing a bug, edit `unit-regression3.cpp` and add a section referencing the fixed issue.
|
||||
`unit-regression2.cpp` holds the older tests; the two files exist because a single one grew large enough for the
|
||||
MinGW linker to fail relocating it, so please keep adding to the smaller file rather than growing the larger one.
|
||||
When fixing a bug, edit `unit-regression3.cpp` and add a section referencing the fixed issue. Tests that need C++17 or
|
||||
C++20 go into `unit-regression3-cpp17.cpp` or `unit-regression3-cpp20.cpp` instead, so the large file is not rebuilt
|
||||
for every C++ standard. `unit-regression2.cpp` holds the older tests; the two files exist because a single one grew
|
||||
large enough for the MinGW linker to fail relocating it, so please keep adding to the smaller file rather than growing
|
||||
the larger one.
|
||||
|
||||
To keep compile times down, several test files are compiled together as one translation unit. This sets a few rules
|
||||
for test files, such as giving file-scope helpers file-specific names. See the README in the
|
||||
[`tests`](https://github.com/nlohmann/json/tree/develop/tests) folder for how the tests are built and what to keep in
|
||||
mind when adding them.
|
||||
|
||||
#### Exceptions
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ environment:
|
||||
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. The Visual Studio 2019
|
||||
# job builds the tests for all standards and is split for the same reason.
|
||||
# stay below AppVeyor's 60-minute limit per job.
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
configuration: Debug
|
||||
platform: x86
|
||||
@@ -51,13 +50,7 @@ environment:
|
||||
configuration: Release
|
||||
platform: x86
|
||||
CXX_FLAGS: "/W4 /WX"
|
||||
CMAKE_OPTIONS: "-DJSON_ImplicitConversions=OFF -DJSON_TestShard=0/2"
|
||||
GENERATOR: Visual Studio 16 2019
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
configuration: Release
|
||||
platform: x86
|
||||
CXX_FLAGS: "/W4 /WX"
|
||||
CMAKE_OPTIONS: "-DJSON_ImplicitConversions=OFF -DJSON_TestShard=1/2"
|
||||
CMAKE_OPTIONS: "-DJSON_ImplicitConversions=OFF"
|
||||
GENERATOR: Visual Studio 16 2019
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
|
||||
@@ -64,7 +64,6 @@ labels:
|
||||
- "tests/src/unit-json_view.*"
|
||||
- "tests/src/json_view_test_helpers\\.hpp"
|
||||
- "tests/src/fuzzer-(parse_json_view|json_view_image)\\.cpp"
|
||||
- "tests/benchmarks/json_view/.*"
|
||||
- "tools/amalgamate/config_json_view\\.json"
|
||||
- "docs/mkdocs/docs/features/json_view\\.md"
|
||||
- "docs/mkdocs/docs/api/basic_json_(document|view)/.*"
|
||||
|
||||
@@ -154,28 +154,6 @@ jobs:
|
||||
# PR content in a job without credentials.
|
||||
python3 tools/generate_natvis/generate_natvis.py $MAIN_DIR
|
||||
|
||||
- name: Check the nlohmann_json.natvis generator options
|
||||
run: |
|
||||
cd $MAIN_DIR
|
||||
# The options for configurations outside the checked-in file write
|
||||
# to a temporary file, so they do not affect the diff below.
|
||||
GENERATOR=tools/generate_natvis/generate_natvis.py
|
||||
python3 $GENERATOR --list-tags
|
||||
TAG_COUNT=$(python3 $GENERATOR --list-tags | wc -l)
|
||||
|
||||
python3 $GENERATOR --abi-tags diag,_dp,_vns --abi-tags _diag --output $RUNNER_TEMP/abi_tags.natvis
|
||||
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_vns -->' $RUNNER_TEMP/abi_tags.natvis
|
||||
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_vns_v[0-9_]* -->' $RUNNER_TEMP/abi_tags.natvis
|
||||
test $(grep -c '<!-- Namespace ' $RUNNER_TEMP/abi_tags.natvis) -eq $(( $(grep -c '<!-- Namespace ' nlohmann_json.natvis) + 2 ))
|
||||
|
||||
python3 $GENERATOR --all --output $RUNNER_TEMP/all.natvis
|
||||
test $(grep -c '<!-- Namespace ' $RUNNER_TEMP/all.natvis) -eq $(( (1 << TAG_COUNT) * 2 + 1 ))
|
||||
|
||||
if python3 $GENERATOR --abi-tags _unknown --output $RUNNER_TEMP/unknown.natvis; then
|
||||
echo "generate_natvis.py accepted an unknown ABI tag"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build patch and check for differences
|
||||
id: diff
|
||||
run: |
|
||||
|
||||
@@ -38,14 +38,14 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
|
||||
with:
|
||||
languages: c-cpp
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/autobuild@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
|
||||
@@ -37,14 +37,6 @@ jobs:
|
||||
var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "pr"
|
||||
})[0];
|
||||
// a run that failed before its jobs started (e.g. a stale queued
|
||||
// run cancelled long after its push) has no artifact to report on
|
||||
if (!matchArtifact) {
|
||||
core.notice('Run ${{ github.event.workflow_run.id }} has no "pr" artifact; nothing to comment on.');
|
||||
core.setOutput('found', 'false');
|
||||
return;
|
||||
}
|
||||
core.setOutput('found', 'true');
|
||||
var download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
@@ -59,11 +51,9 @@ jobs:
|
||||
# Extract the untrusted PR artifact into a dedicated empty directory and
|
||||
# read only the two expected files by fixed path afterwards. This avoids a
|
||||
# malicious archive overwriting workspace files or escaping via ../ paths.
|
||||
- if: steps.download.outputs.found == 'true'
|
||||
run: unzip -o pr.zip -d ./pr_artifact
|
||||
- run: unzip -o pr.zip -d ./pr_artifact
|
||||
|
||||
- name: 'Comment on PR'
|
||||
if: steps.download.outputs.found == 'true'
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -47,6 +47,6 @@ jobs:
|
||||
output: 'flawfinder_results.sarif'
|
||||
|
||||
- name: Upload analysis results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
|
||||
with:
|
||||
sarif_file: ${{github.workspace}}/flawfinder_results.sarif
|
||||
@@ -1,84 +0,0 @@
|
||||
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
|
||||
|
||||
concurrency:
|
||||
# (the label is part of the group: adding an unrelated label must not cancel a running benchmark)
|
||||
group: json-view-benchmarks-${{ github.workflow }}-${{ github.ref }}-${{ github.event.label.name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
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 }}
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.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@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: json_view-benchmarks-${{ matrix.runner }}-${{ inputs.compiler || 'g++' }}
|
||||
path: tests/benchmarks/json_view/results/
|
||||
@@ -80,6 +80,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
|
||||
# Upload SARIF file generated in previous step
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
||||
uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
|
||||
with:
|
||||
sarif_file: semgrep.sarif
|
||||
if: always()
|
||||
@@ -37,7 +37,6 @@ cc_library(
|
||||
"include/nlohmann/detail/input/parser.hpp",
|
||||
"include/nlohmann/detail/input/position_t.hpp",
|
||||
"include/nlohmann/detail/input/pow5_table.hpp",
|
||||
"include/nlohmann/detail/input/simd_scan.hpp",
|
||||
"include/nlohmann/detail/input/string_scan.hpp",
|
||||
"include/nlohmann/detail/iterators/internal_iterator.hpp",
|
||||
"include/nlohmann/detail/iterators/iter_impl.hpp",
|
||||
|
||||
@@ -6,7 +6,6 @@ This file describes the source for supporting files; that is, files that are not
|
||||
- [GitHub](#github)
|
||||
- [REUSE](#reuse)
|
||||
- [Package Managers](#package-managers)
|
||||
- [Debugging](#debugging)
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
@@ -290,29 +289,3 @@ The module definition for [Bazel](https://bazel.build)'s [Bzlmod](https://bazel.
|
||||
Further documentation:
|
||||
|
||||
- [Bazel modules](https://bazel.build/external/module)
|
||||
|
||||
## Debugging
|
||||
|
||||
### `nlohmann_json.natvis`
|
||||
|
||||
The [Natvis](https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects) file that
|
||||
gives `json` values a friendly view in the Visual Studio debugger. The file is generated by
|
||||
`tools/generate_natvis/generate_natvis.py` from the template `tools/generate_natvis/nlohmann_json.natvis.j2` and the ABI
|
||||
tags and version in `include/nlohmann/detail/abi_macros.hpp`; change the script or the template rather than editing
|
||||
the file by hand. The file can be updated by calling
|
||||
|
||||
```shell
|
||||
make natvis
|
||||
```
|
||||
|
||||
The "Check amalgamation" workflow fails if the file is out of date.
|
||||
|
||||
The file covers the namespace variants with up to two ABI tags. A Natvis file for other configurations can be
|
||||
generated with the `--abi-tags` or `--all` options, for example
|
||||
`make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_vns --output my_nlohmann_json.natvis"`; see
|
||||
[`tools/generate_natvis`](tools/generate_natvis/README.md). With MSVC, CMake adds the file to the `nlohmann_json`
|
||||
target and installs it.
|
||||
|
||||
Further documentation:
|
||||
|
||||
- [Create custom views of C++ objects in the debugger using the Natvis framework](https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects)
|
||||
@@ -46,7 +46,7 @@ all:
|
||||
@echo "clean - remove built files"
|
||||
@echo "(fuzzers) - see tests/fuzzing.md, or run 'make -C tests fuzzers' to build the AFL fuzzers"
|
||||
@echo "macro_builder_check - check that macro_scope.hpp matches tools/macro_builder's output"
|
||||
@echo "natvis - regenerate nlohmann_json.natvis from the current ABI tags and version (pass generator options via NATVIS_ARGS, see tools/generate_natvis/README.md)"
|
||||
@echo "natvis - regenerate nlohmann_json.natvis from the current ABI tags and version"
|
||||
@echo "pretty - beautify code with Artistic Style"
|
||||
@echo "pvs_studio - run the PVS-Studio static analyzer and open the report"
|
||||
@echo "release - create the release files (include.zip, json.tar.xz, single headers, signatures, hashes)"
|
||||
@@ -120,15 +120,13 @@ $(AMALGAMATED_VIEW_FILE): $(SRCS)
|
||||
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_view.json -s . --verbose=yes
|
||||
|
||||
NATVIS_VENV=tools/generate_natvis/venv
|
||||
# extra options for generate_natvis.py, e.g. NATVIS_ARGS="--abi-tags _diag,_dp,_vns --output my.natvis"
|
||||
NATVIS_ARGS=
|
||||
|
||||
# regenerate nlohmann_json.natvis from the ABI tags and version in include/nlohmann/detail/abi_macros.hpp
|
||||
# (the dependencies are installed into a virtual environment first)
|
||||
natvis:
|
||||
@test -d $(NATVIS_VENV) || python3 -mvenv $(NATVIS_VENV)
|
||||
@$(NATVIS_VENV)/bin/python3 -c 'import jinja2' 2>/dev/null || $(NATVIS_VENV)/bin/pip3 install --quiet -r tools/generate_natvis/requirements.txt
|
||||
$(NATVIS_VENV)/bin/python3 tools/generate_natvis/generate_natvis.py $(NATVIS_ARGS) .
|
||||
$(NATVIS_VENV)/bin/python3 tools/generate_natvis/generate_natvis.py .
|
||||
|
||||
# regenerate the two tools/macro_builder blocks of $(MACRO_SCOPE_HPP) (see its README.md) and diff against the
|
||||
# checked-in header; phony, because it never writes $(MACRO_SCOPE_HPP) itself
|
||||
|
||||
+3
-3
@@ -890,11 +890,11 @@ add_custom_target(ci_icpx
|
||||
# The following tests are excluded as they trigger known nvc++ 25.5 defects (not
|
||||
# library bugs); see https://github.com/nlohmann/json for tracking. Only the
|
||||
# affected language-standard variants are excluded so coverage is otherwise kept:
|
||||
# - test-comparison_cpp20, test-comparison_legacy_cpp20
|
||||
# - test-comparison-cpp20_cpp20, test-comparison_legacy-cpp20_cpp20
|
||||
# miscompiles cross-type/<=> comparison (e.g. `-17 <= null`)
|
||||
# - test-constructor1_cpp11
|
||||
# std::initializer_list lifetime bug -> SIGSEGV
|
||||
# - test-deserialization_cpp20
|
||||
# - test-deserialization-cpp20_cpp20
|
||||
# mangles the UTF-8 u8"" string literal in the char8_t (C++20) section
|
||||
add_custom_target(ci_nvhpc
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
@@ -906,7 +906,7 @@ add_custom_target(ci_nvhpc
|
||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_nvhpc
|
||||
# the pipes are escaped so the surrounding shell passes them to ctest verbatim
|
||||
# instead of treating them as shell pipe operators
|
||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_nvhpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-comparison_cpp20\\|test-comparison_legacy_cpp20\\|test-constructor1_cpp11\\|test-deserialization_cpp20" --output-on-failure
|
||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_nvhpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-comparison-cpp20_cpp20\\|test-comparison_legacy-cpp20_cpp20\\|test-constructor1_cpp11\\|test-deserialization-cpp20_cpp20" --output-on-failure
|
||||
COMMENT "Compile and test with NVIDIA HPC SDK (nvc++)"
|
||||
)
|
||||
|
||||
|
||||
+366
-39
@@ -109,6 +109,55 @@ function(_json_test_apply_test_properties test_target properties_target)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# for internal use by _json_test_add_test() and _json_test_add_unity_batch():
|
||||
# registers the CTest test <test_name>_cpp<cxx_standard> (plus its Valgrind
|
||||
# variant), which runs the executable target <test_target> with the arguments
|
||||
# in ARGN, and applies the test properties of the test- and standard-specific
|
||||
# interface targets
|
||||
function(_json_test_register_test test_name test_target cxx_standard)
|
||||
set(ctest_name ${test_name}_cpp${cxx_standard})
|
||||
|
||||
if (JSON_FastTests)
|
||||
add_test(NAME ${ctest_name}
|
||||
COMMAND ${test_target} ${DOCTEST_TEST_FILTER} ${ARGN}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
else()
|
||||
add_test(NAME ${ctest_name}
|
||||
COMMAND ${test_target} ${DOCTEST_TEST_FILTER} ${ARGN} --no-skip
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
endif()
|
||||
set_tests_properties(${ctest_name} PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
|
||||
|
||||
# apply standard-specific test properties
|
||||
if(TARGET _json_test_interface__cpp_${cxx_standard})
|
||||
_json_test_apply_test_properties(${ctest_name} _json_test_interface__cpp_${cxx_standard})
|
||||
endif()
|
||||
|
||||
# apply test-specific test properties
|
||||
if(TARGET _json_test_interface_${test_name})
|
||||
_json_test_apply_test_properties(${ctest_name} _json_test_interface_${test_name})
|
||||
endif()
|
||||
|
||||
# apply test- and standard-specific test properties
|
||||
if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard})
|
||||
_json_test_apply_test_properties(${ctest_name}
|
||||
_json_test_interface_${test_name}_cpp_${cxx_standard}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(JSON_Valgrind)
|
||||
add_test(NAME ${ctest_name}_valgrind
|
||||
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER} ${ARGN}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
set_tests_properties(${ctest_name}_valgrind PROPERTIES
|
||||
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# for internal use by json_test_add_test_for()
|
||||
function(_json_test_add_test test_name file main cxx_standard)
|
||||
set(test_target ${test_name}_cpp${cxx_standard})
|
||||
@@ -143,45 +192,7 @@ function(_json_test_add_test test_name file main cxx_standard)
|
||||
)
|
||||
endif()
|
||||
|
||||
if (JSON_FastTests)
|
||||
add_test(NAME ${test_target}
|
||||
COMMAND ${test_target} ${DOCTEST_TEST_FILTER}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
else()
|
||||
add_test(NAME ${test_target}
|
||||
COMMAND ${test_target} ${DOCTEST_TEST_FILTER} --no-skip
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
endif()
|
||||
set_tests_properties(${test_target} PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
|
||||
|
||||
# apply standard-specific test properties
|
||||
if(TARGET _json_test_interface__cpp_${cxx_standard})
|
||||
_json_test_apply_test_properties(${test_target} _json_test_interface__cpp_${cxx_standard})
|
||||
endif()
|
||||
|
||||
# apply test-specific test properties
|
||||
if(TARGET _json_test_interface_${test_name})
|
||||
_json_test_apply_test_properties(${test_target} _json_test_interface_${test_name})
|
||||
endif()
|
||||
|
||||
# apply test- and standard-specific test properties
|
||||
if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard})
|
||||
_json_test_apply_test_properties(${test_target}
|
||||
_json_test_interface_${test_name}_cpp_${cxx_standard}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(JSON_Valgrind)
|
||||
add_test(NAME ${test_target}_valgrind
|
||||
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
set_tests_properties(${test_target}_valgrind PROPERTIES
|
||||
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA
|
||||
)
|
||||
endif()
|
||||
_json_test_register_test(${test_name} ${test_target} ${cxx_standard})
|
||||
endfunction()
|
||||
|
||||
#############################################################################
|
||||
@@ -200,6 +211,14 @@ endfunction()
|
||||
# Use NAME <name> to override the filename-derived test name.
|
||||
# Use FORCE to create the test regardless of the file containing
|
||||
# JSON_HAS_CPP_<version_number>.
|
||||
#
|
||||
# Tests that depend on the C++ standard (e.g., because they use the macros
|
||||
# JSON_HAS_FILESYSTEM, JSON_HAS_RANGES, or JSON_HAS_THREE_WAY_COMPARISON)
|
||||
# should not make the whole of a large unit-foo.cpp be rebuilt for every
|
||||
# standard. Put them into a separate file unit-foo-cpp<NN>.cpp (see, e.g.,
|
||||
# unit-items-cpp17.cpp) which wraps its content in #ifdef JSON_HAS_CPP_<NN>.
|
||||
# Then, unit-foo.cpp itself contains no JSON_HAS_CPP_<NN> and is only built for
|
||||
# C++11.
|
||||
# Test targets are linked against <main>.
|
||||
# CXX_STANDARDS defaults to "11".
|
||||
#############################################################################
|
||||
@@ -243,6 +262,314 @@ function(json_test_add_test_for file)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# for internal use by json_test_add_unity_tests(): sets <result> to whether the
|
||||
# (absolute) <file> is built for <cxx_standard>; same rule as in
|
||||
# json_test_add_test_for(): C++11 always, others only if the file contains
|
||||
# JSON_HAS_CPP_<cxx_standard> or <force> is set
|
||||
function(_json_test_unity_applies file cxx_standard force result)
|
||||
set(${result} TRUE PARENT_SCOPE)
|
||||
if(NOT ("${cxx_standard}" STREQUAL 11 OR force))
|
||||
file(READ ${file} file_content)
|
||||
string(FIND "${file_content}" JSON_HAS_CPP_${cxx_standard} has_cpp_found)
|
||||
if(${has_cpp_found} EQUAL -1)
|
||||
set(${result} FALSE PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# for internal use by json_test_add_unity_tests(): creates the executable
|
||||
# test-unity-<batch_name>_cpp<cxx_standard> from the (absolute) source files
|
||||
# in ARGN, which are #include-d by a generated source file, and registers one
|
||||
# CTest test per source file that runs only the test cases of that file; if
|
||||
# <private> is true, the generated file defines JSON_TESTS_PRIVATE first
|
||||
function(_json_test_add_unity_batch batch_name cxx_standard main private)
|
||||
set(batch_target test-unity-${batch_name}_cpp${cxx_standard})
|
||||
set(batch_source ${PROJECT_BINARY_DIR}/tests/unity/${batch_target}.cpp)
|
||||
|
||||
set(batch_content "// generated by cmake/test.cmake; do not edit\n")
|
||||
if(private)
|
||||
string(APPEND batch_content "// at least one file of this batch needs access to private members of the library\n")
|
||||
string(APPEND batch_content "#define JSON_TESTS_PRIVATE\n")
|
||||
# the files define the macro again; mark this definition as used, as
|
||||
# -Wunused-macros reports an unused definition when it is redefined
|
||||
string(APPEND batch_content "#ifdef JSON_TESTS_PRIVATE\n#endif\n")
|
||||
endif()
|
||||
foreach(file ${ARGN})
|
||||
string(APPEND batch_content "#include \"${file}\" // NOLINT(bugprone-suspicious-include)\n")
|
||||
endforeach()
|
||||
|
||||
# only touch the generated file if it changed to keep incremental builds incremental
|
||||
set(old_content "")
|
||||
if(EXISTS ${batch_source})
|
||||
file(READ ${batch_source} old_content)
|
||||
endif()
|
||||
if(NOT "${old_content}" STREQUAL "${batch_content}")
|
||||
file(WRITE ${batch_source} "${batch_content}")
|
||||
endif()
|
||||
|
||||
add_executable(${batch_target} ${batch_source})
|
||||
target_link_libraries(${batch_target} PRIVATE ${main})
|
||||
set_target_properties(${batch_target} PROPERTIES
|
||||
CXX_STANDARD ${cxx_standard}
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
if(TARGET _json_test_interface__cpp_${cxx_standard})
|
||||
target_link_libraries(${batch_target} PRIVATE _json_test_interface__cpp_${cxx_standard})
|
||||
endif()
|
||||
|
||||
# rebuild the batch when one of its files changes, and show the files in IDEs;
|
||||
# files that are also built standalone (VARIANT_FILES) are left out, as
|
||||
# HEADER_FILE_ONLY is a per-file property and would also affect those targets
|
||||
set_source_files_properties(${batch_source} PROPERTIES OBJECT_DEPENDS "${ARGN}")
|
||||
foreach(file ${ARGN})
|
||||
if(NOT file IN_LIST _json_test_unity_variant_files)
|
||||
set_source_files_properties(${file} PROPERTIES HEADER_FILE_ONLY ON)
|
||||
target_sources(${batch_target} PRIVATE ${file})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(file ${ARGN})
|
||||
get_filename_component(file_basename ${file} NAME_WE)
|
||||
string(REGEX REPLACE "unit-(.+)" "test-\\1" test_name ${file_basename})
|
||||
|
||||
# run only the test cases defined in this file (and in the shared
|
||||
# make_test_data_available.hpp if the file uses it)
|
||||
file(READ ${file} file_content)
|
||||
set(source_filter "--source-file=*${file_basename}.cpp")
|
||||
string(FIND "${file_content}" make_test_data_available.hpp uses_test_data)
|
||||
if(NOT ${uses_test_data} EQUAL -1)
|
||||
string(APPEND source_filter ",*make_test_data_available.hpp")
|
||||
endif()
|
||||
|
||||
_json_test_register_test(${test_name} ${batch_target} ${cxx_standard} "${source_filter}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
#############################################################################
|
||||
# json_test_add_unity_tests(
|
||||
# FILES <files>...
|
||||
# MAIN <main>
|
||||
# [CXX_STANDARDS <version_number>...] [FORCE]
|
||||
# [BATCH_SIZE <size>]
|
||||
# [GROUPS <group>...]
|
||||
# [VARIANT_FILES <files>...])
|
||||
#
|
||||
# Like calling json_test_add_test_for(<file> MAIN <main> ...) for each of the
|
||||
# <files>, but compiles several files together to speed up the build: for each
|
||||
# C++ standard, the files are split into batches of <size> files (default: 8)
|
||||
# and each batch is built as a single executable
|
||||
#
|
||||
# test-unity-<pool><index>_cpp<version_number>
|
||||
#
|
||||
# whose generated source file #include-s the files of the batch (so they share
|
||||
# the template instantiations of the library). The tests are still named
|
||||
# test-foo_cpp<version_number>, one per file, but run the batch executable with
|
||||
# a doctest filter that selects the test cases of that file only.
|
||||
#
|
||||
# Files are only batched with files that agree on the macros defined before
|
||||
# the library is included: files that define at most JSON_TESTS_PRIVATE (or
|
||||
# macros derived from global compile definitions) form the pools "plain" and
|
||||
# "private". All other files are added with json_test_add_test_for() as usual,
|
||||
# as are files with test-specific build settings (see
|
||||
# json_test_set_test_options()) and the files listed in the explicit
|
||||
# exclusion list below.
|
||||
# Each <group> names a list variable json_test_unity_group_<group> of test file
|
||||
# stems (file names without "unit-" and ".cpp"). The batchable files of a group
|
||||
# are compiled together (regardless of BATCH_SIZE) as one executable
|
||||
#
|
||||
# test-unity-<group>_cpp<version_number>
|
||||
#
|
||||
# so that related tests, which instantiate the same templates, share one
|
||||
# translation unit. A group may mix the pools "plain" and "private"; if any of
|
||||
# its files needs JSON_TESTS_PRIVATE, the whole group is built with it. Files
|
||||
# that cannot be batched stay standalone even if they are listed in a group.
|
||||
# Files in no group are batched by BATCH_SIZE as described above.
|
||||
# <files> in VARIANT_FILES are also built standalone with other settings, so
|
||||
# they are not marked as header-only sources of the batch.
|
||||
#############################################################################
|
||||
|
||||
function(json_test_add_unity_tests)
|
||||
cmake_parse_arguments(args "FORCE" "MAIN;BATCH_SIZE" "FILES;CXX_STANDARDS;VARIANT_FILES;GROUPS" ${ARGN})
|
||||
|
||||
if("${args_MAIN}" STREQUAL "")
|
||||
message(FATAL_ERROR "Required argument MAIN <main> missing.")
|
||||
endif()
|
||||
|
||||
if("${args_BATCH_SIZE}" STREQUAL "")
|
||||
set(args_BATCH_SIZE 8)
|
||||
endif()
|
||||
|
||||
if("${args_CXX_STANDARDS}" STREQUAL "")
|
||||
set(args_CXX_STANDARDS 11)
|
||||
endif()
|
||||
|
||||
if(args_FORCE)
|
||||
set(force FORCE)
|
||||
else()
|
||||
set(force "")
|
||||
endif()
|
||||
|
||||
set(_json_test_unity_variant_files "")
|
||||
foreach(file ${args_VARIANT_FILES})
|
||||
get_filename_component(file ${file} ABSOLUTE)
|
||||
list(APPEND _json_test_unity_variant_files ${file})
|
||||
endforeach()
|
||||
|
||||
# files that must not be merged into a batch: unit-32bit.cpp is only built
|
||||
# for 32bit targets, and unit-no-macro-leak.cpp checks that including the
|
||||
# library defines no unprefixed macro, which any other file would disturb
|
||||
set(standalone_files unit-32bit.cpp unit-no-macro-leak.cpp)
|
||||
|
||||
set(harmless_macros "^(DOCTEST_.*|SKIP_TESTS_FOR_.*|JSON_TEST_DEPRECATED_FUNCTIONS_DELETED|JSON_TEST_STRICT_NUL_HANDLING_ENABLED|JSON_TEST_STRINGIZE)$")
|
||||
|
||||
# classify the files
|
||||
set(plain_files "")
|
||||
set(private_files "")
|
||||
set(standalone_abs_files "")
|
||||
foreach(file ${args_FILES})
|
||||
get_filename_component(file_name ${file} NAME)
|
||||
get_filename_component(file_basename ${file} NAME_WE)
|
||||
string(REGEX REPLACE "unit-(.+)" "test-\\1" test_name ${file_basename})
|
||||
|
||||
set(batchable TRUE)
|
||||
if(file_name IN_LIST standalone_files)
|
||||
set(batchable FALSE)
|
||||
endif()
|
||||
if(TARGET _json_test_interface_${test_name})
|
||||
set(batchable FALSE)
|
||||
endif()
|
||||
foreach(cxx_standard ${args_CXX_STANDARDS})
|
||||
if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard})
|
||||
set(batchable FALSE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# files that suppress GCC's -Wnoexcept around their include of the
|
||||
# library: the suppression has no effect once another file of the
|
||||
# batch included the library first
|
||||
if(batchable)
|
||||
file(READ ${file} file_content)
|
||||
string(FIND "${file_content}" "SUPPRESS_WARNING(\"-Wnoexcept\")" suppresses_noexcept)
|
||||
if(NOT ${suppresses_noexcept} EQUAL -1)
|
||||
set(batchable FALSE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(pool plain)
|
||||
if(batchable)
|
||||
# collect the macros (un)defined before the library is included
|
||||
file(READ ${file} file_content)
|
||||
string(FIND "${file_content}" "#include <nlohmann/" include_position)
|
||||
if(NOT ${include_position} EQUAL -1)
|
||||
string(SUBSTRING "${file_content}" 0 ${include_position} file_content)
|
||||
endif()
|
||||
string(REGEX MATCHALL "(^|\n)[ \t]*#[ \t]*(define|undef)[ \t]+[A-Za-z_0-9]+" directives "${file_content}")
|
||||
foreach(directive ${directives})
|
||||
string(REGEX REPLACE "^.*[ \t]([A-Za-z_0-9]+)$" "\\1" macro "${directive}")
|
||||
if(macro MATCHES "${harmless_macros}")
|
||||
continue()
|
||||
elseif("${macro}" STREQUAL JSON_TESTS_PRIVATE)
|
||||
set(pool private)
|
||||
else()
|
||||
set(batchable FALSE)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
get_filename_component(file_abs ${file} ABSOLUTE)
|
||||
if(NOT batchable)
|
||||
list(APPEND standalone_abs_files ${file_abs})
|
||||
json_test_add_test_for(${file} MAIN ${args_MAIN} CXX_STANDARDS ${args_CXX_STANDARDS} ${force})
|
||||
continue()
|
||||
endif()
|
||||
get_filename_component(file ${file} ABSOLUTE)
|
||||
list(APPEND ${pool}_files ${file})
|
||||
endforeach()
|
||||
|
||||
# resolve the explicit groups: group_<name>_files are the (absolute) files
|
||||
# of the group, group_<name>_private tells whether one of them is private
|
||||
set(grouped_files "")
|
||||
foreach(group ${args_GROUPS})
|
||||
if(NOT DEFINED json_test_unity_group_${group})
|
||||
message(FATAL_ERROR "Unity test group '${group}' is not defined (json_test_unity_group_${group}).")
|
||||
endif()
|
||||
set(group_${group}_files "")
|
||||
set(group_${group}_private FALSE)
|
||||
foreach(stem ${json_test_unity_group_${group}})
|
||||
# check against the source directory, because FILES may be filtered (JSON_TestShard)
|
||||
get_filename_component(file ${CMAKE_CURRENT_SOURCE_DIR}/src/unit-${stem}.cpp ABSOLUTE)
|
||||
if(NOT EXISTS ${file})
|
||||
message(FATAL_ERROR "Unity test group '${group}' lists '${stem}', but ${file} does not exist.")
|
||||
endif()
|
||||
if(file IN_LIST grouped_files)
|
||||
message(FATAL_ERROR "Unity test file unit-${stem}.cpp is listed in more than one group (second: '${group}').")
|
||||
endif()
|
||||
list(APPEND grouped_files ${file})
|
||||
|
||||
if(file IN_LIST standalone_abs_files)
|
||||
message(STATUS "Unity test group '${group}': unit-${stem}.cpp cannot be batched and stays standalone")
|
||||
elseif(file IN_LIST plain_files)
|
||||
list(APPEND group_${group}_files ${file})
|
||||
list(REMOVE_ITEM plain_files ${file})
|
||||
elseif(file IN_LIST private_files)
|
||||
list(APPEND group_${group}_files ${file})
|
||||
list(REMOVE_ITEM private_files ${file})
|
||||
set(group_${group}_private TRUE)
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
foreach(cxx_standard ${args_CXX_STANDARDS})
|
||||
if(NOT compiler_supports_cpp_${cxx_standard})
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# explicit groups: one batch per group
|
||||
foreach(group ${args_GROUPS})
|
||||
set(batch_files "")
|
||||
foreach(file ${group_${group}_files})
|
||||
_json_test_unity_applies(${file} ${cxx_standard} "${force}" applies)
|
||||
if(applies)
|
||||
list(APPEND batch_files ${file})
|
||||
endif()
|
||||
endforeach()
|
||||
if(batch_files)
|
||||
_json_test_add_unity_batch(${group} ${cxx_standard} ${args_MAIN} ${group_${group}_private} ${batch_files})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# remaining files: batches of BATCH_SIZE files per pool
|
||||
foreach(pool plain private)
|
||||
set(is_private FALSE)
|
||||
if(pool STREQUAL private)
|
||||
set(is_private TRUE)
|
||||
endif()
|
||||
|
||||
set(batch_files "")
|
||||
set(batch_count 0)
|
||||
set(batch_index 0)
|
||||
foreach(file ${${pool}_files})
|
||||
_json_test_unity_applies(${file} ${cxx_standard} "${force}" applies)
|
||||
if(NOT applies)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
list(APPEND batch_files ${file})
|
||||
math(EXPR batch_count "${batch_count} + 1")
|
||||
if(batch_count EQUAL args_BATCH_SIZE)
|
||||
_json_test_add_unity_batch(${pool}${batch_index} ${cxx_standard} ${args_MAIN} ${is_private} ${batch_files})
|
||||
set(batch_files "")
|
||||
set(batch_count 0)
|
||||
math(EXPR batch_index "${batch_index} + 1")
|
||||
endif()
|
||||
endforeach()
|
||||
if(batch_files)
|
||||
_json_test_add_unity_batch(${pool}${batch_index} ${cxx_standard} ${args_MAIN} ${is_private} ${batch_files})
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
#############################################################################
|
||||
# json_test_should_build_32bit_test(
|
||||
# <build_32bit_var> <build_32bit_only_var> <input>)
|
||||
|
||||
@@ -341,14 +341,13 @@ def download(url, docs) -> str:
|
||||
raise ValueError(f'not an http(s) URL: {url}')
|
||||
req = urllib.request.Request(u.geturl(), headers={'User-Agent': USER_AGENT})
|
||||
# (the scheme is checked above)
|
||||
# nosemgrep: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected
|
||||
with urllib.request.urlopen(req, timeout=20) as r: # nosec B310
|
||||
data = r.read()
|
||||
ctype = r.headers.get_content_type()
|
||||
path = urllib.parse.unquote(u.path).lstrip('/')
|
||||
ext = os.path.splitext(path)[1]
|
||||
if u.query or not ext or path.endswith('/'):
|
||||
digest = hashlib.sha256(url.encode()).hexdigest()[:12]
|
||||
digest = hashlib.sha1(url.encode(), usedforsecurity=False).hexdigest()[:12]
|
||||
path = os.path.join(os.path.dirname(path), digest + CONTENT_TYPE_EXT.get(ctype, ext or '.bin'))
|
||||
rel = os.path.normpath(os.path.join('assets', 'external', u.hostname, path))
|
||||
out = os.path.join(docs, rel)
|
||||
|
||||
@@ -30,14 +30,6 @@ struct adl_serializer {
|
||||
- [**from_json**](from_json.md) - convert a JSON value to any value type
|
||||
- [**to_json**](to_json.md) - convert any value type to a JSON value
|
||||
|
||||
## See also
|
||||
|
||||
- [Arbitrary type conversions](../../features/arbitrary_types.md) - how to make your types convertible
|
||||
- [**get**](../basic_json/get.md) / [**get_to**](../basic_json/get_to.md) - convert a JSON value to a C++ type
|
||||
- [**basic_json**](../basic_json/basic_json.md) - construct a JSON value from a C++ value
|
||||
- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE**](../macros/nlohmann_define_type_intrusive.md) - generate the conversion functions for a type
|
||||
- [Specializing enum conversion](../../features/enum_conversion.md)
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 2.1.0.
|
||||
@@ -23,9 +23,6 @@ Checks whether the input is valid JSON.
|
||||
respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to
|
||||
the iterator type with `operator!=`.
|
||||
|
||||
Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its
|
||||
low surrogate, and a code point above `U+10FFFF` all make this function return `false`.
|
||||
|
||||
Unlike the [`parse()`](parse.md) function, this function neither throws an exception in case of invalid JSON input
|
||||
(i.e., a parse error) nor creates diagnostic information.
|
||||
|
||||
@@ -38,12 +35,9 @@ Unlike the [`parse()`](parse.md) function, this function neither throws an excep
|
||||
- a `#!c FILE` pointer (throws if null)
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters (throws if null)
|
||||
- a `std::string` or a `std::string_view` (C++17)
|
||||
- a `std::string`
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
- wide characters (`wchar_t`, `char16_t`, `char32_t`), which are converted to UTF-8: a wide string object
|
||||
(`std::wstring`, `std::u16string`, `std::u32string`) or an array (e.g. a wide string literal); a pointer to a
|
||||
null-terminated wide string (e.g. `std::u16string::c_str()`) is not supported
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type, for instance.
|
||||
@@ -131,21 +125,6 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
|
||||
--8<-- "examples/accept__iterator_pair.output"
|
||||
```
|
||||
|
||||
??? example "Example: (3) reading from UTF-16 strings"
|
||||
|
||||
The encoding is deduced from the character type of the input. String literals like `u"..."`, `U"..."`, and
|
||||
`L"..."` work as well.
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/accept__wide_string.cpp"
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
--8<-- "examples/accept__wide_string.output"
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse](parse.md) - deserialize from a compatible input
|
||||
@@ -172,9 +151,6 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
|
||||
([`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md)).
|
||||
- Parsing from a `FILE*` locks the file once instead of once per character in version 3.13.0
|
||||
([`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md)).
|
||||
- Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or
|
||||
a code point above `U+10FFFF`) is rejected in version 3.13.0; before that, some such sequences were accepted or
|
||||
ended the input silently.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -239,8 +239,9 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
||||
|
||||
1. Added in version 1.0.0.
|
||||
2. Added in version 1.0.0.
|
||||
3. Added in version 3.11.0. Support for keys convertible to `std::string_view` added in version 3.13.0, consistently
|
||||
across the lookup functions.
|
||||
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
|
||||
already supported by [`operator[]`](operator[].md), [`value`](value.md), [`find`](find.md), and other lookup
|
||||
functions.
|
||||
4. Added in version 2.0.0. Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of
|
||||
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is not
|
||||
a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones.
|
||||
@@ -63,4 +63,4 @@ Constant.
|
||||
## Version history
|
||||
|
||||
- Added in version 1.0.0.
|
||||
- Binary values are supported since version 3.8.0.
|
||||
- Adjusted code to return reference to binary values in version 3.8.0.
|
||||
@@ -482,15 +482,15 @@ basic_json(basic_json&& other) noexcept;
|
||||
|
||||
## Version history
|
||||
|
||||
1. Added in version 1.0.0.
|
||||
2. Added in version 1.0.0.
|
||||
3. Added in version 2.1.0.
|
||||
4. Added in version 3.1.2. Explicit for different string types if `JSON_USE_IMPLICIT_CONVERSIONS` is `0` since
|
||||
1. Since version 1.0.0.
|
||||
2. Since version 1.0.0.
|
||||
3. Since version 2.1.0.
|
||||
4. Since version 3.2.0. Explicit for different string types if `JSON_USE_IMPLICIT_CONVERSIONS` is `0` since
|
||||
version 3.13.0.
|
||||
5. Added in version 1.0.0.
|
||||
6. Added in version 1.0.0.
|
||||
7. Added in version 1.0.0. Fixed in version 3.13.0 to also check the iterator range for binary values; before, a range
|
||||
5. Since version 1.0.0.
|
||||
6. Since version 1.0.0.
|
||||
7. Since version 1.0.0. Fixed in version 3.13.0 to also check the iterator range for binary values; before, a range
|
||||
that did not cover the whole value (such as `(end(), end())`) was accepted and the whole binary value was copied,
|
||||
unlike the other primitive types.
|
||||
8. Added in version 1.0.0.
|
||||
9. Added in version 1.0.0.
|
||||
8. Since version 1.0.0.
|
||||
9. Since version 1.0.0.
|
||||
@@ -141,8 +141,9 @@ Logarithmic in the size of the JSON object.
|
||||
## Version history
|
||||
|
||||
1. Added in version 3.11.0.
|
||||
2. Added in version 3.6.0. Extended template `KeyType` to support comparable types in version 3.11.0. Support for keys
|
||||
convertible to `std::string_view` added in version 3.13.0, consistently across the lookup functions.
|
||||
2. Added in version 3.6.0. Extended template `KeyType` to support comparable types in version 3.11.0. Fixed in
|
||||
version 3.13.0 to consistently accept `std::string_view`-convertible keys, as already supported by
|
||||
[`operator[]`](operator[].md), [`at`](at.md), [`value`](value.md), and other lookup functions.
|
||||
3. Added in version 3.7.0.
|
||||
4. Deleted overloads for integral key types added in version 3.13.0 to reject such calls at compile time instead of
|
||||
causing undefined behavior at runtime.
|
||||
@@ -92,7 +92,8 @@ Logarithmic in the size of the JSON object.
|
||||
## Version history
|
||||
|
||||
1. Added in version 3.11.0.
|
||||
2. Added in version 1.0.0. Changed to support comparable key types in version 3.11.0. Support for keys convertible to
|
||||
`std::string_view` added in version 3.13.0, consistently across the lookup functions.
|
||||
2. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0. Fixed in version 3.13.0 to
|
||||
consistently accept `std::string_view`-convertible keys, as already supported by [`operator[]`](operator[].md),
|
||||
[`at`](at.md), [`value`](value.md), and other lookup functions.
|
||||
3. Deleted overload for integral key types added in version 3.13.0 to reject such calls at compile time instead of
|
||||
causing undefined behavior at runtime.
|
||||
@@ -69,6 +69,6 @@ Logarithmic in the size of the container, O(log(`size()`)).
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 2.0.8.
|
||||
- Since version 2.0.8.
|
||||
- Fixed in version 3.13.0: for [`ordered_json`](../ordered_json.md), the value could previously only be passed as an
|
||||
rvalue; it can now also be passed as an lvalue or a `#!cpp const` lvalue, matching the behavior of `json`.
|
||||
@@ -67,5 +67,5 @@ Amortized constant.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 2.0.8.
|
||||
- Since version 2.0.8.
|
||||
- Returns reference since 3.7.0.
|
||||
@@ -213,6 +213,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
||||
1. Added in version 1.0.0. Added support for binary types in version 3.8.0.
|
||||
2. Added in version 1.0.0. Added support for binary types in version 3.8.0.
|
||||
3. Added in version 1.0.0.
|
||||
4. Added in version 3.11.0. Support for keys convertible to `std::string_view` added in version 3.13.0, consistently
|
||||
across the lookup functions.
|
||||
4. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
|
||||
already supported by [`operator[]`](operator[].md), [`at`](at.md), [`value`](value.md), and other lookup
|
||||
functions.
|
||||
5. Added in version 1.0.0.
|
||||
@@ -84,4 +84,4 @@ constructor.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.0.0.
|
||||
- Since version 3.0.0.
|
||||
@@ -99,7 +99,8 @@ Logarithmic in the size of the JSON object.
|
||||
## Version history
|
||||
|
||||
1. Added in version 3.11.0.
|
||||
2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0. Support for keys convertible to
|
||||
`std::string_view` added in version 3.13.0, consistently across the lookup functions.
|
||||
2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0. Fixed in version 3.13.0 to
|
||||
consistently accept `std::string_view`-convertible keys, as already supported by [`operator[]`](operator[].md),
|
||||
[`at`](at.md), [`value`](value.md), and other lookup functions.
|
||||
3. Deleted overloads for integral key types added in version 3.13.0 to reject such calls at compile time instead of
|
||||
causing undefined behavior at runtime.
|
||||
@@ -57,4 +57,4 @@ Constant.
|
||||
## Version history
|
||||
|
||||
- Added in version 1.0.0.
|
||||
- Binary values are supported since version 3.8.0.
|
||||
- Adjusted code to return reference to binary values in version 3.8.0.
|
||||
@@ -188,6 +188,6 @@ overload (3).
|
||||
|
||||
## Version history
|
||||
|
||||
1. Added in version 2.1.0.
|
||||
2. Added in version 2.1.0. Extended to work with other specializations of `basic_json` in version 3.1.2.
|
||||
3. Added in version 1.0.0.
|
||||
1. Since version 2.1.0.
|
||||
2. Since version 2.1.0. Extended to work with other specializations of `basic_json` in version 3.2.0.
|
||||
3. Since version 1.0.0.
|
||||
@@ -76,5 +76,5 @@ Depends on the `json_serializer<ValueType>::from_json()` implementation.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.3.0.
|
||||
- Since version 3.3.0.
|
||||
- Added a `static_assert` with a clear message for `const` arguments in version 3.13.0.
|
||||
@@ -44,22 +44,6 @@ are collected in [Template Parameter Requirements](../../features/types/template
|
||||
- [**json**](../json.md) - default specialization
|
||||
- [**ordered_json**](../ordered_json.md) - a specialization that maintains the insertion order of object keys
|
||||
|
||||
## Documents and views
|
||||
|
||||
Besides `basic_json`, the library offers a second way to hold a parsed JSON text: a
|
||||
[`basic_json_document`](../basic_json_document/index.md), which owns or borrows the text and holds a flat index of the
|
||||
values in it, and a [`basic_json_view`](../basic_json_view/index.md), a read-only handle to one value of such a document.
|
||||
Both are defined in the header `<nlohmann/json_view.hpp>`; see
|
||||
[Zero-copy JSON views](../../features/json_view.md) for the concept and the trade-offs.
|
||||
|
||||
- [**json_document**](../json_document.md) / [**ordered_json_document**](../ordered_json_document.md) - read-only
|
||||
documents of the `basic_json` specialization they belong to
|
||||
- [**json_editable_document**](../json_editable_document.md) /
|
||||
[**ordered_json_editable_document**](../ordered_json_editable_document.md) - documents that can be modified in place
|
||||
- [**json_view**](../json_view.md) / [**ordered_json_view**](../ordered_json_view.md) - views of a document
|
||||
- [**json_editable_view**](../json_editable_view.md) /
|
||||
[**ordered_json_editable_view**](../ordered_json_editable_view.md) - views of an editable document
|
||||
|
||||
## Iterator invalidation
|
||||
|
||||
All operations that add values to an **array** ([`push_back`](push_back.md) , [`operator+=`](operator+=.md),
|
||||
@@ -359,9 +343,6 @@ Access to the JSON value
|
||||
## See also
|
||||
|
||||
- [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc8259)
|
||||
- [basic_json_document](../basic_json_document/index.md) / [basic_json_view](../basic_json_view/index.md) - parse a JSON
|
||||
text into a flat index and read it through a view
|
||||
- [Zero-copy JSON views](../../features/json_view.md) - when to use a document and a view instead of a `basic_json`
|
||||
|
||||
## Version history
|
||||
|
||||
|
||||
@@ -75,4 +75,4 @@ classDiagram
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.0.0.
|
||||
- Since version 3.0.0.
|
||||
@@ -104,8 +104,8 @@ When iterating over an array, `key()` will return the index of the element as st
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.1.0 as the replacement of the static function `iterator_wrapper`, which was available since
|
||||
version 1.0.0 and is deprecated since version 3.1.0.
|
||||
- Added `iterator_wrapper` in version 3.0.0.
|
||||
- Added `items` and deprecated `iterator_wrapper` in version 3.1.0.
|
||||
- Added structured binding support in version 3.5.0.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
@@ -51,4 +51,4 @@ deserializes. See [Template Parameter Requirements](../../features/types/templat
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 2.1.0.
|
||||
- Since version 2.0.0.
|
||||
@@ -71,6 +71,6 @@ returned by `#!cpp (*this)[key]`); it is read as it was when `merge_patch()` was
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.1.0.
|
||||
- Added in version 3.0.0.
|
||||
- Fixed use of freed or relocated memory when `apply_patch` is `#!cpp *this` or refers to a value contained in
|
||||
`#!cpp *this`, in version 3.13.0.
|
||||
@@ -128,6 +128,6 @@ interpreted as `object_t::value_type` or `std::initializer_list<basic_json>`, se
|
||||
|
||||
## Version history
|
||||
|
||||
1. Added in version 1.0.0.
|
||||
2. Added in version 1.0.0.
|
||||
3. Added in version 2.0.0.
|
||||
1. Since version 1.0.0.
|
||||
2. Since version 1.0.0.
|
||||
3. Since version 2.0.0.
|
||||
@@ -284,10 +284,10 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
||||
1. Added in version 1.0.0. Fixed in version 3.13.0 to throw `#!cpp std::length_error` instead of emptying the array and
|
||||
accessing it out of bounds when `idx` equals the maximum value of `size_type`. A missing index in the const version
|
||||
is guarded by a runtime assertion since version 3.13.0.
|
||||
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. The `T* key` overloads forward to
|
||||
overload 3 since version 3.11.0.
|
||||
3. Added in version 3.11.0. Support for keys convertible to `std::string_view` added in version 3.13.0, consistently
|
||||
across the lookup functions.
|
||||
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3)
|
||||
in version 3.11.0.
|
||||
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
|
||||
already supported by [`at`](at.md), [`value`](value.md), [`find`](find.md), and other lookup functions.
|
||||
4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since
|
||||
version 3.13.0. Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of
|
||||
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is not
|
||||
|
||||
@@ -89,6 +89,6 @@ Linear in the size of the JSON value.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 1.0.0.
|
||||
- Since version 1.0.0.
|
||||
- Macros `JSON_EXPLICIT`/[`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) added
|
||||
in version 3.9.0.
|
||||
@@ -75,4 +75,4 @@ classDiagram
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.0.0.
|
||||
- Since version 3.0.0.
|
||||
@@ -76,4 +76,4 @@ classDiagram
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.0.0.
|
||||
- Since version 3.0.0.
|
||||
@@ -25,10 +25,6 @@ static basic_json parse(IteratorType first, SentinelType last,
|
||||
respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to
|
||||
the iterator type with `operator!=`.
|
||||
|
||||
Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its
|
||||
low surrogate, and a code point above `U+10FFFF` all yield a
|
||||
[`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`InputType`
|
||||
@@ -38,12 +34,9 @@ static basic_json parse(IteratorType first, SentinelType last,
|
||||
- a `FILE` pointer (throws if null)
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters (throws if null)
|
||||
- a `std::string` or a `std::string_view` (C++17)
|
||||
- a `std::string`
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
- wide characters (`wchar_t`, `char16_t`, `char32_t`), which are converted to UTF-8: a wide string object
|
||||
(`std::wstring`, `std::u16string`, `std::u32string`) or an array (e.g. a wide string literal); a pointer to a
|
||||
null-terminated wide string (e.g. `std::u16string::c_str()`) is not supported
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type, for instance.
|
||||
@@ -119,13 +112,6 @@ By default, a `'\0'` (NUL) byte anywhere in the input is treated as end of input
|
||||
outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-bytes-in-the-input) for details and the
|
||||
[`JSON_STRICT_NUL_HANDLING`](../macros/json_strict_nul_handling.md) macro to opt into rejecting it instead.
|
||||
|
||||
!!! tip "Parsing into a document instead of a value"
|
||||
|
||||
[`basic_json_document::parse`](../basic_json_document/parse.md) accepts the same inputs and the same options, but
|
||||
keeps the result as a flat index of the parsed values instead of a tree of `basic_json` values. It is faster and uses
|
||||
less memory when only parts of the document are read, and it also accepts a pointer to a null-terminated wide string,
|
||||
which `parse()` does not. See [Zero-copy JSON views](../../features/json_view.md).
|
||||
|
||||
!!! tip "Performance"
|
||||
|
||||
Contiguous inputs (strings, string views, vectors, arrays, pointer ranges) are the fastest to parse. A
|
||||
@@ -264,22 +250,6 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
|
||||
--8<-- "examples/trailing_commas.output"
|
||||
```
|
||||
|
||||
??? example "Example: parse from UTF-16, UTF-32, and wide strings"
|
||||
|
||||
The encoding is deduced from the character type of the input; `std::u16string` and `std::u32string` are interpreted
|
||||
as UTF-16 and UTF-32, and `std::wstring` uses the platform's `wchar_t` width. String literals like `u"..."`,
|
||||
`U"..."`, and `L"..."` work as well, as do iterators over wide characters.
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/parse__wide_string.cpp"
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
--8<-- "examples/parse__wide_string.output"
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [accept](accept.md) - check if the input is valid JSON
|
||||
@@ -310,9 +280,6 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
|
||||
time).
|
||||
- Parsing from a `FILE*` locks the file once instead of once per character in version 3.13.0
|
||||
([`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md) restores `std::fgetc`).
|
||||
- Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or
|
||||
a code point above `U+10FFFF`) is rejected with `parse_error.101` in version 3.13.0; before that, some such
|
||||
sequences were accepted or ended the input silently.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -84,4 +84,4 @@ or the end of file. This also holds true when reading a byte vector for binary f
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.0.0.
|
||||
- Since version 3.0.0.
|
||||
@@ -125,6 +125,6 @@ throws.
|
||||
|
||||
## Version history
|
||||
|
||||
1. Added in version 1.0.0.
|
||||
2. Added in version 1.0.0.
|
||||
3. Added in version 2.0.0.
|
||||
1. Since version 1.0.0.
|
||||
2. Since version 1.0.0.
|
||||
3. Since version 2.0.0.
|
||||
@@ -31,10 +31,6 @@ Read from input and generate SAX events
|
||||
respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to
|
||||
the iterator type with `operator!=`.
|
||||
|
||||
Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its
|
||||
low surrogate, and a code point above `U+10FFFF` all yield a
|
||||
[`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101).
|
||||
|
||||
The SAX event lister must follow the interface of [`json_sax`](../json_sax/index.md).
|
||||
|
||||
## Template parameters
|
||||
@@ -46,12 +42,8 @@ The SAX event lister must follow the interface of [`json_sax`](../json_sax/index
|
||||
- a `FILE` pointer
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters
|
||||
- a `std::string` or a `std::string_view` (C++17)
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
- wide characters (`wchar_t`, `char16_t`, `char32_t`), which are converted to UTF-8: a wide string object
|
||||
(`std::wstring`, `std::u16string`, `std::u32string`) or an array (e.g. a wide string literal); a pointer to a
|
||||
null-terminated wide string (e.g. `std::u16string::c_str()`) is not supported
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type for overload (2); a pair of character iterators whose `value_type` is an integral type
|
||||
@@ -168,9 +160,6 @@ use the same file with stdio functions, but it must not wait for another thread
|
||||
([`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md)).
|
||||
- Parsing from a `FILE*` locks the file once instead of once per character in version 3.13.0
|
||||
([`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md)).
|
||||
- Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or
|
||||
a code point above `U+10FFFF`) is rejected with `parse_error.101` in version 3.13.0; before that, some such
|
||||
sequences were accepted or ended the input silently.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -182,10 +182,10 @@ Constant.
|
||||
|
||||
## Version history
|
||||
|
||||
1. Added in version 1.0.0. Exchanges the `json_base_class_t` subobject along with the value since version 3.13.0.
|
||||
2. Added in version 1.0.0. Exchanges the `json_base_class_t` subobject along with the value since version 3.13.0.
|
||||
3. Added in version 1.0.0.
|
||||
4. Added in version 1.0.0.
|
||||
5. Added in version 1.0.0.
|
||||
6. Added in version 3.8.0.
|
||||
7. Added in version 3.8.0.
|
||||
1. Since version 1.0.0. Exchanges the `json_base_class_t` subobject along with the value since version 3.13.0.
|
||||
2. Since version 1.0.0. Exchanges the `json_base_class_t` subobject along with the value since version 3.13.0.
|
||||
3. Since version 1.0.0.
|
||||
4. Since version 1.0.0.
|
||||
5. Since version 1.0.0.
|
||||
6. Since version 3.8.0.
|
||||
7. Since version 3.8.0.
|
||||
@@ -124,3 +124,5 @@ Linear in the size of the JSON value `j`.
|
||||
[`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.
|
||||
- Writes unsigned integers wider than 64 bits as high-precision numbers since version 3.13.0; previously, they were
|
||||
silently truncated to 64 bits.
|
||||
@@ -76,4 +76,4 @@ classDiagram
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.0.0.
|
||||
- Since version 3.0.0.
|
||||
@@ -231,8 +231,11 @@ changes to any JSON value.
|
||||
1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version
|
||||
3.11.0. Deleted overload for integral key types added in version 3.13.0 to reject such calls at compile time
|
||||
instead of causing undefined behavior at runtime.
|
||||
2. Added in version 3.11.0. Made `ValueType` the first template parameter in version 3.11.2. Support for keys
|
||||
convertible to `std::string_view` added in version 3.13.0, consistently across the lookup functions.
|
||||
3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0. Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109)
|
||||
2. Added in version 3.11.0. Made `ValueType` the first template parameter in version 3.11.2. Fixed in version 3.13.0
|
||||
to consistently accept `std::string_view`-convertible keys, as already supported by
|
||||
[`operator[]`](operator[].md), [`at`](at.md), [`find`](find.md), and other lookup functions.
|
||||
3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0, including fixing an issue where resolving
|
||||
`ptr` through an array unexpectedly threw `out_of_range` instead of returning the resolved element (or
|
||||
`default_value`, as documented). Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109)
|
||||
instead of returning `default_value` for a one-character array index that is not a digit (e.g., `/x`) in version
|
||||
3.13.0, as it already did for longer ones.
|
||||
@@ -9,8 +9,8 @@ class basic_json_document;
|
||||
|
||||
A parsed JSON text, held as a flat index of its values
|
||||
([16 bytes per value](../../home/architecture.md#node-index-of-json-views)) instead of a tree of `BasicJsonType` values.
|
||||
Strings and floating-point numbers stay in the source text; integers are converted while parsing, and strings that
|
||||
contain escapes are decoded into one buffer owned by the document. [`basic_json_view`](../basic_json_view/index.md) is a read-only handle to one value of a
|
||||
Strings and numbers stay in the source text; only strings that contain escapes are decoded, into one buffer owned by
|
||||
the document. [`basic_json_view`](../basic_json_view/index.md) is a read-only handle to one value of a
|
||||
`basic_json_document`; [`materialize()`](../basic_json_view/materialize.md) turns a subtree into the
|
||||
`BasicJsonType` value that [`BasicJsonType::parse()`](../basic_json/parse.md) would have produced for it.
|
||||
|
||||
@@ -115,13 +115,6 @@ points apply to every edit:
|
||||
[`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.
|
||||
|
||||
## See also
|
||||
|
||||
- [Zero-copy JSON views](../../features/json_view.md) - guide to documents and views
|
||||
- [**basic_json_view**](../basic_json_view/index.md) - the non-owning handle to a value in a document
|
||||
- [**json_document**](../json_document.md) and [**json_editable_document**](../json_editable_document.md) - the default specializations
|
||||
- [**materialize**](../basic_json_view/materialize.md) - build a `basic_json` value from a view
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
@@ -21,19 +21,17 @@ static basic_json_document parse(IteratorType first, IteratorType last,
|
||||
|
||||
Both overloads accept the same JSON text as [`BasicJsonType::parse()`](../basic_json/parse.md), with the same
|
||||
`ignore_comments`/`ignore_trailing_commas` options, but build a [`basic_json_document`](index.md) (a flat index into
|
||||
the input) instead of a tree of `BasicJsonType` values. They accept every input `BasicJsonType::parse()` takes, and in
|
||||
addition a pointer to a null-terminated wide string (which `BasicJsonType::parse()` rejects). Contiguous inputs of
|
||||
single-byte characters that stay alive can be borrowed; all others (streams, `#!cpp FILE*`, wide characters, which
|
||||
must be converted to UTF-8, and non-contiguous iterators) are read into a copy that the document owns -- see the
|
||||
Notes. Use [`parse_copy()`](parse_copy.md) to get an owned copy of a borrowable input
|
||||
as well.
|
||||
the input) instead of a tree of `BasicJsonType` values. They take the same inputs as `BasicJsonType::parse()`. Byte
|
||||
inputs that stay alive can be borrowed; all others (streams, `#!cpp FILE*`, wide characters, non-contiguous
|
||||
iterators) are read into a copy that the document owns -- see the Notes. Use [`parse_copy()`](parse_copy.md) to get an
|
||||
owned copy of a borrowable input as well.
|
||||
|
||||
## Template parameters
|
||||
|
||||
`InputType`
|
||||
: A compatible input, for instance:
|
||||
|
||||
- a `#!cpp std::string`, a `#!cpp std::string_view` (C++17), or a C-style array of single-byte characters
|
||||
- a `#!cpp std::string`, `#!cpp std::string_view`, or a C-style array of single-byte characters
|
||||
- a pointer to a null-terminated string of single-byte characters (`#!cpp char`, `#!cpp signed char`,
|
||||
`#!cpp unsigned char`, `#!cpp std::uint8_t`)
|
||||
- a container for which `#!cpp obj.data()` and `#!cpp obj.size()` give contiguous single-byte access, e.g.
|
||||
@@ -49,10 +47,6 @@ as well.
|
||||
`#!cpp std::string::iterator`; the iterators of single-byte characters are borrowed or read like the byte inputs
|
||||
above, those of wide characters are converted to UTF-8
|
||||
|
||||
Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low
|
||||
surrogate, and a code point above `U+10FFFF` all yield a
|
||||
[`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101).
|
||||
|
||||
## Parameters
|
||||
|
||||
`input` (in)
|
||||
@@ -161,5 +155,3 @@ buffer of a given length, pass a pair of pointers: `#!cpp parse(ptr, ptr + len)`
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
- Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or
|
||||
a code point above `U+10FFFF`) is rejected with `parse_error.101`.
|
||||
@@ -80,8 +80,7 @@ None of these exceptions carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics
|
||||
Objects with 128 or more members get a hash index of their keys 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
|
||||
index (unlike `BasicJsonType`'s array, which is random-access). Constant if no element of the array is an array
|
||||
or object, since the elements are then adjacent in the index.
|
||||
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
|
||||
that level (as 1.) or the index into the array (as 2.).
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@ This exception does not carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.
|
||||
|
||||
Linear in the size of the array or object: unlike [`front()`](front.md), which only ever looks at the first
|
||||
element, `back()` has to walk every element to find where they end, since elements are not a fixed size in the
|
||||
index. Constant if no element of the array is an array or object, since the elements are then adjacent
|
||||
in the index.
|
||||
index.
|
||||
|
||||
## Notes
|
||||
|
||||
|
||||
@@ -143,13 +143,6 @@ still refers to it -- including ones taken before the change -- reads the new va
|
||||
|
||||
- [**source_offset**](source_offset.md) - byte offset of this value in the document's source text
|
||||
|
||||
## See also
|
||||
|
||||
- [Zero-copy JSON views](../../features/json_view.md) - guide to documents and views
|
||||
- [**basic_json_document**](../basic_json_document/index.md) - the document that owns the parsed data
|
||||
- [**json_view**](../json_view.md) and [**json_editable_view**](../json_editable_view.md) - the default specializations
|
||||
- [**materialize**](materialize.md) - build a `basic_json` value from a view
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
@@ -86,8 +86,7 @@ None of these exceptions carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics
|
||||
Objects with 128 or more members get a hash index of their keys 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
|
||||
index (unlike `BasicJsonType`'s array, which is random-access). Constant if no element of the array is an array
|
||||
or object, since the elements are then adjacent in the index.
|
||||
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
|
||||
that level (as 1.) or the index into the array (as 2.).
|
||||
|
||||
|
||||
@@ -51,4 +51,4 @@ byte_container_with_subtype(container_type&& container, subtype_type subtype);
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.8.0.
|
||||
Since version 3.8.0.
|
||||
@@ -39,4 +39,4 @@ Constant.
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.8.0.
|
||||
Since version 3.8.0.
|
||||
@@ -42,4 +42,4 @@ Constant.
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.8.0.
|
||||
Since version 3.8.0.
|
||||
@@ -29,14 +29,6 @@ specific naming scheme in order to override the binary type.
|
||||
- [**has_subtype**](has_subtype.md) - return whether the value has a subtype
|
||||
- [**clear_subtype**](clear_subtype.md) - clears the binary subtype
|
||||
|
||||
## See also
|
||||
|
||||
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
|
||||
- [**binary**](../basic_json/binary.md) - create a binary array value
|
||||
- [**get_binary**](../basic_json/get_binary.md) - get a reference to the stored binary value
|
||||
- [**binary_t**](../basic_json/binary_t.md) - type for binary arrays
|
||||
- [Binary formats](../../features/binary_formats/index.md) - formats that can store binary values
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.8.0.
|
||||
|
||||
@@ -44,4 +44,4 @@ Constant.
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.8.0.
|
||||
Since version 3.8.0.
|
||||
@@ -30,4 +30,4 @@ types.
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 1.0.0.
|
||||
Since version 1.0.0.
|
||||
@@ -32,4 +32,4 @@ specialization.
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.13.0.
|
||||
Since version 3.13.0.
|
||||
@@ -40,4 +40,4 @@ parsing, without ever rewriting the source text -- see [Edits](basic_json_docume
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.13.0.
|
||||
Since version 3.13.0.
|
||||
@@ -38,4 +38,4 @@ still referring to it seeing the change, see [Edits](basic_json_document/index.m
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.13.0.
|
||||
Since version 3.13.0.
|
||||
@@ -51,5 +51,5 @@ operator string_t() const
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 2.0.0.
|
||||
- Since version 2.0.0.
|
||||
- Changed type to `string_t` and deprecated in version 3.11.0.
|
||||
@@ -49,5 +49,5 @@ ptr == json_pointer(ptr.to_string());
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 2.0.0.
|
||||
- Since version 2.0.0.
|
||||
- Changed return type to `string_t` in version 3.11.0.
|
||||
@@ -59,13 +59,6 @@ leading `-` sign.
|
||||
- [**start_object**](start_object.md) (_virtual_) - the beginning of an object was read
|
||||
- [**string**](string.md) (_virtual_) - a string value was read
|
||||
|
||||
## See also
|
||||
|
||||
- [SAX interface](../../features/parsing/sax_interface.md) - guide to event-based parsing
|
||||
- [**sax_parse**](../basic_json/sax_parse.md) - generate SAX events from an input
|
||||
- [**parse**](../basic_json/parse.md) - DOM parsing, with optional [parser callbacks](../../features/parsing/parser_callbacks.md)
|
||||
- [Parse exceptions](../../features/parsing/parse_exceptions.md)
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.2.0.
|
||||
|
||||
@@ -31,4 +31,4 @@ This type is a [`basic_json_view`](basic_json_view/index.md) of a value of a [`j
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.13.0.
|
||||
Since version 3.13.0.
|
||||
@@ -38,7 +38,6 @@ header. See also the [macro overview page](../../features/macros.md).
|
||||
- [**JSON_HAS_THREE_WAY_COMPARISON**](json_has_three_way_comparison.md) - control 3-way comparison support
|
||||
- [**JSON_NO_AUTOMATIC_UDLS**](json_no_automatic_udls.md) - do not include the user-defined string literals (UDLs) automatically
|
||||
- [**JSON_NO_IO**](json_no_io.md) - switch off functions relying on certain C++ I/O headers
|
||||
- [**JSON_NO_SIMD**](json_no_simd.md) - use only portable code instead of vector instructions (SSE2, SSSE3, NEON)
|
||||
- [**JSON_NO_THREAD_LOCAL**](json_no_thread_local.md) - switch off the use of `thread_local` storage
|
||||
- [**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
|
||||
@@ -137,13 +136,4 @@ header. See also the [macro overview page](../../features/macros.md).
|
||||
- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize
|
||||
a derived class; uses default values; uses custom names
|
||||
- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize a derived
|
||||
class; uses custom names
|
||||
|
||||
## See also
|
||||
|
||||
- [Macros](../../features/macros.md) - guide to the supported macros
|
||||
- [Runtime assertions](../../features/assertions.md)
|
||||
- [Arbitrary type conversions](../../features/arbitrary_types.md) - using the `NLOHMANN_DEFINE_TYPE_*` macros
|
||||
- [Enum conversion](../../features/enum_conversion.md) - using `NLOHMANN_JSON_SERIALIZE_ENUM`
|
||||
- [The `nlohmann` namespace](../../features/namespace.md)
|
||||
- [CMake integration](../../integration/cmake.md) - setting macros from the build system
|
||||
class; uses custom names
|
||||
@@ -1,83 +0,0 @@
|
||||
# JSON_NO_SIMD
|
||||
|
||||
```cpp
|
||||
#define JSON_NO_SIMD
|
||||
```
|
||||
|
||||
When defined, the library uses only portable C++ code where it would otherwise use vector instructions: when scanning
|
||||
strings during parsing, and when writing floating-point numbers during serialization.
|
||||
|
||||
The macro is an escape hatch, for example for toolchains that cannot compile the vector code, for sanitizers or
|
||||
analyzers that do not understand it, or to compare the speed of both variants. It does not change any result: values,
|
||||
exceptions, and error positions are the same either way. Only the speed differs.
|
||||
|
||||
## Default definition
|
||||
|
||||
By default, `#!cpp JSON_NO_SIMD` is not defined, and vector instructions are used where the target has them.
|
||||
|
||||
```cpp
|
||||
#undef JSON_NO_SIMD
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
!!! note "Which instructions are used"
|
||||
|
||||
- **x86-64:** SSE2, which every x86-64 CPU has, finds the end of runs of plain string characters 16 bytes at a time
|
||||
and writes the digits of floating-point numbers. The UTF-8 check of non-ASCII text needs SSSE3, which is not part
|
||||
of x86-64: it is compiled for SSSE3 with a function attribute and used when the CPU has SSSE3 (every x86-64 CPU
|
||||
since about 2011), else the portable check. Code compiled for SSSE3 anyway (e.g., with `-mssse3` or `-march=native`)
|
||||
skips this check of the CPU. 32-bit x86 uses SSE2 for strings when the compiler targets it.
|
||||
- **AArch64:** NEON, which every 64-bit Arm CPU has, checks UTF-8 text and long runs of plain string characters 16
|
||||
bytes at a time, and writes the digits of floating-point numbers. With MSVC, only the floating-point digits use
|
||||
NEON.
|
||||
- **Other targets:** portable code only.
|
||||
|
||||
Strings are only scanned this way for contiguous input and for the characters a `#!cpp std::istream` holds in its
|
||||
stream buffer (see [`JSON_DISABLE_STREAM_BULK_SCAN`](json_disable_stream_bulk_scan.md)); other inputs are read one
|
||||
character at a time.
|
||||
|
||||
!!! note "Interaction with `JSON_USE_SIMDUTF`"
|
||||
|
||||
With [`JSON_USE_SIMDUTF`](json_use_simdutf.md), runs of string characters are first validated by simdutf; the code
|
||||
described here is used for what simdutf does not accept, so that errors are reported at the same position.
|
||||
`JSON_NO_SIMD` does not affect simdutf.
|
||||
|
||||
!!! note "ABI compatibility"
|
||||
|
||||
The macro selects between two definitions of the library's internal scanning and formatting functions. Whether it
|
||||
is defined is encoded in the [namespace](../../features/namespace.md) (tag `_ns`), 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: switching off vector instructions"
|
||||
|
||||
The program parses and serializes the same values with and without the macro:
|
||||
|
||||
```cpp
|
||||
#define JSON_NO_SIMD
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
const json j = json::parse(R"({"name": "日本語 text", "pi": 3.141592653589793})");
|
||||
std::cout << j.dump() << '\n'; // {"name":"日本語 text","pi":3.141592653589793}
|
||||
}
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [**parse**](../basic_json/parse.md) - deserialize from a compatible input
|
||||
- [**dump**](../basic_json/dump.md) - serialization
|
||||
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
|
||||
- [**JSON_DISABLE_STREAM_BULK_SCAN**](json_disable_stream_bulk_scan.md) - read a `std::istream` one character at a time
|
||||
- [Parsing: input sources and performance](../../features/parsing/index.md#input-sources-and-performance)
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
@@ -6,9 +6,8 @@
|
||||
|
||||
When defined, the parser validates the UTF-8 content of JSON strings that come from a **contiguous byte input**
|
||||
(`std::string`, `std::vector<char>`/`<std::uint8_t>`, string literals, `const char*` ranges, …) using the
|
||||
[simdutf](https://github.com/simdutf/simdutf) library instead of the built-in validator (which uses SSSE3 or NEON where
|
||||
available, see [`JSON_NO_SIMD`](json_no_simd.md)). On text with many non-ASCII characters (e.g. CJK or emoji) this can
|
||||
validate faster, depending on the CPU.
|
||||
[simdutf](https://github.com/simdutf/simdutf) library instead of the built-in scalar validator. On text with many
|
||||
non-ASCII characters (e.g. CJK or emoji) this can validate several times faster.
|
||||
|
||||
This is an **opt-in external dependency**. The library itself remains header-only and its behavior is unchanged: the
|
||||
same input is accepted or rejected either way, and every parse error is reported at the same position with the same
|
||||
|
||||
@@ -39,6 +39,6 @@ the library.
|
||||
## Version history
|
||||
|
||||
- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. Added the ABI tag `_dp` in
|
||||
version 3.12.0, and the ABI tags `_bics`, `_psp`, `_snul`, `_sbu8`, `_ekmo`, `_dsbs`, `_dufio`, `_ns`, `_vns`,
|
||||
and `_vssse3` in version 3.13.0; see
|
||||
version 3.12.0, and the ABI tags `_bics`, `_psp`, `_snul`, `_sbu8`, `_ekmo`, `_dsbs`, `_dufio`, `_vns`, and
|
||||
`_vssse3` in version 3.13.0; see
|
||||
[`nlohmann` Namespace](../../features/namespace.md#structure).
|
||||
@@ -42,4 +42,4 @@ parsing an object of `n` keys costs O(n²) rather than O(n log n). See
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.9.0.
|
||||
Since version 3.9.0.
|
||||
@@ -35,4 +35,4 @@ of object keys, instead of sorting them like [`json_document`](json_document.md)
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.13.0.
|
||||
Since version 3.13.0.
|
||||
@@ -44,4 +44,4 @@ members [`set`](basic_json_document/set.md) added -- instead of sorting them lik
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.13.0.
|
||||
Since version 3.13.0.
|
||||
@@ -37,4 +37,4 @@ This type is a [`basic_json_view`](basic_json_view/index.md) of a value of an
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.13.0.
|
||||
Since version 3.13.0.
|
||||
@@ -32,4 +32,4 @@ This type is a [`basic_json_view`](basic_json_view/index.md) of a value of an
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.13.0.
|
||||
Since version 3.13.0.
|
||||
@@ -58,7 +58,7 @@ particular, a 3.x release does not:
|
||||
- remove or rename a documented macro, CMake option, CMake target, or header, or change what a documented macro does.
|
||||
|
||||
Exceptions to these rules, for instance when fixing a bug requires changing the exception a function throws, are
|
||||
documented in the [release notes](../home/releases/index.md).
|
||||
documented in the [release notes](../home/releases.md).
|
||||
|
||||
The following are **not** part of the public API and may change in any release, including patch releases:
|
||||
|
||||
|
||||
@@ -18,32 +18,3 @@
|
||||
white-space: nowrap;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
/* byte layout tables of the binary formats */
|
||||
.md-typeset .byte-layout td code {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.md-typeset .bl {
|
||||
display: inline-block;
|
||||
padding: 0 .25em;
|
||||
border-radius: .2em;
|
||||
font-family: var(--md-code-font-family);
|
||||
font-size: .85em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.md-typeset .bl-t {
|
||||
background-color: rgba(66, 133, 244, .25);
|
||||
box-shadow: inset 0 -.12em 0 rgba(66, 133, 244, .8);
|
||||
}
|
||||
|
||||
.md-typeset .bl-l {
|
||||
background-color: rgba(251, 140, 0, .25);
|
||||
box-shadow: inset 0 -.12em 0 rgba(251, 140, 0, .8);
|
||||
}
|
||||
|
||||
.md-typeset .bl-d {
|
||||
background-color: rgba(67, 160, 71, .25);
|
||||
box-shadow: inset 0 -.12em 0 rgba(67, 160, 71, .8);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// a valid JSON text, given as UTF-16
|
||||
const std::u16string valid_text = u"{\"name\":\"\u00e9\"}";
|
||||
|
||||
// an invalid JSON text, given as UTF-16
|
||||
const std::u16string invalid_text = u"{\"name\":\"\u00e9\",}";
|
||||
|
||||
std::cout << std::boolalpha
|
||||
<< json::accept(valid_text) << ' '
|
||||
<< json::accept(invalid_text) << '\n';
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
true false
|
||||
@@ -1,27 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// the same JSON text, given in different encodings
|
||||
const std::string utf8 = "{\"name\":\"\u00e9\"}";
|
||||
const std::u16string utf16 = u"{\"name\":\"\u00e9\"}";
|
||||
const std::u32string utf32 = U"{\"name\":\"\u00e9\"}";
|
||||
const std::wstring wide = L"{\"name\":\"\u00e9\"}";
|
||||
|
||||
// the encoding is deduced from the character type of the input, and all
|
||||
// of them yield the same value
|
||||
std::cout << json::parse(utf8) << '\n'
|
||||
<< json::parse(utf16) << '\n'
|
||||
<< json::parse(utf32) << '\n'
|
||||
<< json::parse(wide) << '\n';
|
||||
|
||||
// a wide string literal works as well: u"..." is UTF-16, U"..." is UTF-32
|
||||
std::cout << json::parse(u"[1, 2, 3]") << '\n';
|
||||
|
||||
// iterators over wide characters work as well
|
||||
std::cout << json::parse(utf16.begin(), utf16.end()) << '\n';
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{"name":"é"}
|
||||
{"name":"é"}
|
||||
{"name":"é"}
|
||||
{"name":"é"}
|
||||
[1,2,3]
|
||||
{"name":"é"}
|
||||
@@ -190,41 +190,6 @@ The library uses the following mapping from JSON values types to BJData types ac
|
||||
--8<-- "examples/to_bjdata.output"
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Byte layout
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 300,
|
||||
"name": "json",
|
||||
"pi": 3.14,
|
||||
"tags": [
|
||||
"a",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`to_bjdata` encodes it to 51 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: <span class="bl bl-t">type/marker</span> <span class="bl bl-l">length/count/size</span> <span class="bl bl-d">data</span>.
|
||||
|
||||
<div class="byte-layout" markdown="0"><table>
|
||||
<thead><tr><th>JSON</th><th>Bytes</th><th>Meaning</th></tr></thead><tbody>
|
||||
<tr><td><code>{</code></td><td><span class="bl bl-t">7B</span></td><td>object start (<code>{</code>)</td></tr>
|
||||
<tr><td><code>"id": 300,</code></td><td><span class="bl bl-l">69 02</span> <span class="bl bl-d">69 64</span> <span class="bl bl-t">49</span> <span class="bl bl-d">2C 01</span></td><td>key: length 2 as int8 (<code>i</code>), then UTF-8 bytes; value: int16 (<code>I</code>), little-endian</td></tr>
|
||||
<tr><td><code>"name": "json",</code></td><td><span class="bl bl-l">69 04</span> <span class="bl bl-d">6E 61 6D 65</span> <span class="bl bl-t">53</span> <span class="bl bl-l">69 04</span> <span class="bl bl-d">6A 73 6F 6E</span></td><td>key: length 4; value: string (<code>S</code>), length 4 as int8, UTF-8 bytes</td></tr>
|
||||
<tr><td><code>"pi": 3.14,</code></td><td><span class="bl bl-l">69 02</span> <span class="bl bl-d">70 69</span> <span class="bl bl-t">44</span> <span class="bl bl-d">1F 85 EB 51 B8 1E 09 40</span></td><td>key: length 2; value: float64 (<code>D</code>), little-endian</td></tr>
|
||||
<tr><td><code>"tags": [</code></td><td><span class="bl bl-l">69 04</span> <span class="bl bl-d">74 61 67 73</span> <span class="bl bl-t">5B</span></td><td>key: length 4; value: array start (<code>[</code>)</td></tr>
|
||||
<tr><td><code>"a",</code></td><td><span class="bl bl-t">53</span> <span class="bl bl-l">69 01</span> <span class="bl bl-d">61</span></td><td>string, length 1</td></tr>
|
||||
<tr><td><code>"b"</code></td><td><span class="bl bl-t">53</span> <span class="bl bl-l">69 01</span> <span class="bl bl-d">62</span></td><td>string, length 1</td></tr>
|
||||
<tr><td><code>]</code></td><td><span class="bl bl-t">5D</span></td><td>array end (<code>]</code>)</td></tr>
|
||||
<tr><td><code>}</code></td><td><span class="bl bl-t">7D</span></td><td>object end (<code>}</code>)</td></tr>
|
||||
</tbody></table></div>
|
||||
|
||||
## Deserialization
|
||||
|
||||
The library maps BJData types to JSON value types as follows:
|
||||
|
||||
@@ -105,41 +105,6 @@ serialized as 0x81 0x65 0xFF, but `[1,2,3,4,"e"]` as 0x85 0x91 0x92 0x93 0x94 0x
|
||||
--8<-- "examples/to_bon8.output"
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Byte layout
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 300,
|
||||
"name": "json",
|
||||
"pi": 3.14,
|
||||
"tags": [
|
||||
"a",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`to_bon8` encodes it to 35 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: <span class="bl bl-t">type/marker</span> <span class="bl bl-l">length/count/size</span> <span class="bl bl-d">data</span>.
|
||||
|
||||
<div class="byte-layout" markdown="0"><table>
|
||||
<thead><tr><th>JSON</th><th>Bytes</th><th>Meaning</th></tr></thead><tbody>
|
||||
<tr><td><code>{</code></td><td><span class="bl bl-t">8A</span></td><td>object with 4 members</td></tr>
|
||||
<tr><td><code>"id": 300,</code></td><td><span class="bl bl-d">69 64</span> <span class="bl bl-t">C4</span> <span class="bl bl-d">04</span></td><td>key: UTF-8 bytes; the string ends at the next byte, which cannot continue a UTF-8 character; value: 2-byte positive integer (lead byte, then a byte below 0x80)</td></tr>
|
||||
<tr><td><code>"name": "json",</code></td><td><span class="bl bl-d">6E 61 6D 65</span> <span class="bl bl-l">FF</span> <span class="bl bl-d">6A 73 6F 6E</span> <span class="bl bl-l">FF</span></td><td>key: UTF-8 bytes; 0xFF terminates the string as another string follows; value: UTF-8 bytes; terminated as a string key follows</td></tr>
|
||||
<tr><td><code>"pi": 3.14,</code></td><td><span class="bl bl-d">70 69</span> <span class="bl bl-t">8F</span> <span class="bl bl-d">40 09 1E B8 51 EB 85 1F</span></td><td>key: UTF-8 bytes; value: binary64 (IEEE 754, big-endian); its marker also ends <code>"pi"</code></td></tr>
|
||||
<tr><td><code>"tags": [</code></td><td><span class="bl bl-d">74 61 67 73</span> <span class="bl bl-t">82</span></td><td>key: UTF-8 bytes; value: array with 2 elements; its marker also ends <code>"tags"</code></td></tr>
|
||||
<tr><td><code>"a",</code></td><td><span class="bl bl-d">61</span> <span class="bl bl-l">FF</span></td><td>UTF-8 bytes; terminated as a string follows</td></tr>
|
||||
<tr><td><code>"b"</code></td><td><span class="bl bl-d">62</span> <span class="bl bl-l">FF</span></td><td>UTF-8 bytes; terminated as nothing follows</td></tr>
|
||||
<tr><td><code>]</code></td><td></td><td>no end marker: the element count was given up front</td></tr>
|
||||
<tr><td><code>}</code></td><td></td><td>no end marker: the member count was given up front</td></tr>
|
||||
</tbody></table></div>
|
||||
|
||||
## Deserialization
|
||||
|
||||
The library maps BON8 types to JSON value types as follows:
|
||||
|
||||
@@ -61,41 +61,6 @@ The library uses the following mapping from JSON values types to BSON types:
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Byte layout
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 300,
|
||||
"name": "json",
|
||||
"pi": 3.14,
|
||||
"tags": [
|
||||
"a",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`to_bson` encodes it to 69 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: <span class="bl bl-t">type/marker</span> <span class="bl bl-l">length/count/size</span> <span class="bl bl-d">data</span>.
|
||||
|
||||
<div class="byte-layout" markdown="0"><table>
|
||||
<thead><tr><th>JSON</th><th>Bytes</th><th>Meaning</th></tr></thead><tbody>
|
||||
<tr><td><code>{</code></td><td><span class="bl bl-l">45 00 00 00</span></td><td>document size: 69 bytes (int32, little-endian)</td></tr>
|
||||
<tr><td><code>"id": 300,</code></td><td><span class="bl bl-t">10</span> <span class="bl bl-d">69 64 00</span> <span class="bl bl-d">2C 01 00 00</span></td><td>int32 element; key as NUL-terminated string; value (little-endian)</td></tr>
|
||||
<tr><td><code>"name": "json",</code></td><td><span class="bl bl-t">02</span> <span class="bl bl-d">6E 61 6D 65 00</span> <span class="bl bl-l">05 00 00 00</span> <span class="bl bl-d">6A 73 6F 6E 00</span></td><td>string element; key; length incl. NUL (int32); NUL-terminated UTF-8 bytes</td></tr>
|
||||
<tr><td><code>"pi": 3.14,</code></td><td><span class="bl bl-t">01</span> <span class="bl bl-d">70 69 00</span> <span class="bl bl-d">1F 85 EB 51 B8 1E 09 40</span></td><td>double element; key; value (little-endian)</td></tr>
|
||||
<tr><td><code>"tags": [</code></td><td><span class="bl bl-t">04</span> <span class="bl bl-d">74 61 67 73 00</span> <span class="bl bl-l">17 00 00 00</span></td><td>array element; key; embedded document of 23 bytes (keys are the indices)</td></tr>
|
||||
<tr><td><code>"a",</code></td><td><span class="bl bl-t">02</span> <span class="bl bl-d">30 00</span> <span class="bl bl-l">02 00 00 00</span> <span class="bl bl-d">61 00</span></td><td>string element; key <code>"0"</code>; length 2; <code>a</code> + NUL</td></tr>
|
||||
<tr><td><code>"b"</code></td><td><span class="bl bl-t">02</span> <span class="bl bl-d">31 00</span> <span class="bl bl-l">02 00 00 00</span> <span class="bl bl-d">62 00</span></td><td>string element; key <code>"1"</code>; length 2; <code>b</code> + NUL</td></tr>
|
||||
<tr><td><code>]</code></td><td><span class="bl bl-t">00</span></td><td>end of the array document</td></tr>
|
||||
<tr><td><code>}</code></td><td><span class="bl bl-t">00</span></td><td>end of the document</td></tr>
|
||||
</tbody></table></div>
|
||||
|
||||
## Deserialization
|
||||
|
||||
The library maps BSON record types to JSON value types as follows:
|
||||
|
||||
@@ -110,41 +110,6 @@ see "binary" cells in the table above.
|
||||
--8<-- "examples/to_cbor.output"
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Byte layout
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 300,
|
||||
"name": "json",
|
||||
"pi": 3.14,
|
||||
"tags": [
|
||||
"a",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`to_cbor` encodes it to 39 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: <span class="bl bl-t">type/marker</span> <span class="bl bl-l">length/count/size</span> <span class="bl bl-d">data</span>.
|
||||
|
||||
<div class="byte-layout" markdown="0"><table>
|
||||
<thead><tr><th>JSON</th><th>Bytes</th><th>Meaning</th></tr></thead><tbody>
|
||||
<tr><td><code>{</code></td><td><span class="bl bl-t">A4</span></td><td>map with 4 key/value pairs</td></tr>
|
||||
<tr><td><code>"id": 300,</code></td><td><span class="bl bl-t">62</span> <span class="bl bl-d">69 64</span> <span class="bl bl-t">19</span> <span class="bl bl-d">01 2C</span></td><td>key: text string of length 2, then its UTF-8 bytes; value: unsigned integer, 2 bytes follow (big-endian)</td></tr>
|
||||
<tr><td><code>"name": "json",</code></td><td><span class="bl bl-t">64</span> <span class="bl bl-d">6E 61 6D 65</span> <span class="bl bl-t">64</span> <span class="bl bl-d">6A 73 6F 6E</span></td><td>key: text string of length 4; value: text string of length 4</td></tr>
|
||||
<tr><td><code>"pi": 3.14,</code></td><td><span class="bl bl-t">62</span> <span class="bl bl-d">70 69</span> <span class="bl bl-t">FB</span> <span class="bl bl-d">40 09 1E B8 51 EB 85 1F</span></td><td>key: text string of length 2; value: double-precision float (IEEE 754, big-endian)</td></tr>
|
||||
<tr><td><code>"tags": [</code></td><td><span class="bl bl-t">64</span> <span class="bl bl-d">74 61 67 73</span> <span class="bl bl-t">82</span></td><td>key: text string of length 4; value: array with 2 elements</td></tr>
|
||||
<tr><td><code>"a",</code></td><td><span class="bl bl-t">61</span> <span class="bl bl-d">61</span></td><td>text string of length 1</td></tr>
|
||||
<tr><td><code>"b"</code></td><td><span class="bl bl-t">61</span> <span class="bl bl-d">62</span></td><td>text string of length 1</td></tr>
|
||||
<tr><td><code>]</code></td><td></td><td>no end marker: the element count was given up front</td></tr>
|
||||
<tr><td><code>}</code></td><td></td><td>no end marker: the member count was given up front</td></tr>
|
||||
</tbody></table></div>
|
||||
|
||||
## Deserialization
|
||||
|
||||
The library maps CBOR types to JSON value types as follows:
|
||||
|
||||
@@ -45,19 +45,12 @@ See [binary values](../binary_values.md) for more information.
|
||||
| BJData | 53.2 % | 91.1 % | 78.1 % | 96.6 % |
|
||||
| BJData (size) | 58.6 % | 92.1 % | 86.7 % | 97.4 % |
|
||||
| BJData (size+type) | 58.6 % | 92.1 % | 86.5 % | 97.4 % |
|
||||
| BON8 | **50.5 %** | **83.8 %** | **63.5 %** | **87.5 %** |
|
||||
| BON8 | 50.5 % | 83.8 % | 63.5 % | 87.5 % |
|
||||
| BSON | 85.8 % | 95.2 % | 95.8 % | 106.7 % |
|
||||
| CBOR | **50.5 %** | 86.3 % | 68.4 % | 88.0 % |
|
||||
| MessagePack | **50.5 %** | 86.0 % | 68.5 % | 87.9 % |
|
||||
| CBOR | 50.5 % | 86.3 % | 68.4 % | 88.0 % |
|
||||
| MessagePack | 50.5 % | 86.0 % | 68.5 % | 87.9 % |
|
||||
| UBJSON | 53.2 % | 91.3 % | 78.2 % | 96.6 % |
|
||||
| UBJSON (size) | 58.6 % | 92.3 % | 86.8 % | 97.4 % |
|
||||
| UBJSON (size+type) | 55.9 % | 92.3 % | 85.0 % | 95.0 % |
|
||||
|
||||
Sizes compared to minified JSON value; the smallest size per file is printed in bold.
|
||||
|
||||
## See also
|
||||
|
||||
- [Binary values](../binary_values.md) - binary values and subtypes
|
||||
- [**to_cbor**](../../api/basic_json/to_cbor.md) / [**from_cbor**](../../api/basic_json/from_cbor.md), [**to_msgpack**](../../api/basic_json/to_msgpack.md) / [**from_msgpack**](../../api/basic_json/from_msgpack.md), [**to_bson**](../../api/basic_json/to_bson.md) / [**from_bson**](../../api/basic_json/from_bson.md), [**to_ubjson**](../../api/basic_json/to_ubjson.md) / [**from_ubjson**](../../api/basic_json/from_ubjson.md), [**to_bjdata**](../../api/basic_json/to_bjdata.md) / [**from_bjdata**](../../api/basic_json/from_bjdata.md), [**to_bon8**](../../api/basic_json/to_bon8.md) / [**from_bon8**](../../api/basic_json/from_bon8.md) - the conversion functions
|
||||
- [Parsing untrusted input](../parsing/untrusted_input.md)
|
||||
- [SAX interface](../parsing/sax_interface.md) - decode binary formats without building a value
|
||||
Sizes compared to minified JSON value.
|
||||
@@ -91,41 +91,6 @@ specification:
|
||||
--8<-- "examples/to_msgpack.output"
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Byte layout
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 300,
|
||||
"name": "json",
|
||||
"pi": 3.14,
|
||||
"tags": [
|
||||
"a",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`to_msgpack` encodes it to 39 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: <span class="bl bl-t">type/marker</span> <span class="bl bl-l">length/count/size</span> <span class="bl bl-d">data</span>.
|
||||
|
||||
<div class="byte-layout" markdown="0"><table>
|
||||
<thead><tr><th>JSON</th><th>Bytes</th><th>Meaning</th></tr></thead><tbody>
|
||||
<tr><td><code>{</code></td><td><span class="bl bl-t">84</span></td><td>map with 4 key/value pairs</td></tr>
|
||||
<tr><td><code>"id": 300,</code></td><td><span class="bl bl-t">A2</span> <span class="bl bl-d">69 64</span> <span class="bl bl-t">CD</span> <span class="bl bl-d">01 2C</span></td><td>key: fixstr of length 2, then its UTF-8 bytes; value: uint 16 (big-endian)</td></tr>
|
||||
<tr><td><code>"name": "json",</code></td><td><span class="bl bl-t">A4</span> <span class="bl bl-d">6E 61 6D 65</span> <span class="bl bl-t">A4</span> <span class="bl bl-d">6A 73 6F 6E</span></td><td>key: fixstr of length 4; value: fixstr of length 4</td></tr>
|
||||
<tr><td><code>"pi": 3.14,</code></td><td><span class="bl bl-t">A2</span> <span class="bl bl-d">70 69</span> <span class="bl bl-t">CB</span> <span class="bl bl-d">40 09 1E B8 51 EB 85 1F</span></td><td>key: fixstr of length 2; value: float 64 (IEEE 754, big-endian)</td></tr>
|
||||
<tr><td><code>"tags": [</code></td><td><span class="bl bl-t">A4</span> <span class="bl bl-d">74 61 67 73</span> <span class="bl bl-t">92</span></td><td>key: fixstr of length 4; value: fixarray with 2 elements</td></tr>
|
||||
<tr><td><code>"a",</code></td><td><span class="bl bl-t">A1</span> <span class="bl bl-d">61</span></td><td>fixstr of length 1</td></tr>
|
||||
<tr><td><code>"b"</code></td><td><span class="bl bl-t">A1</span> <span class="bl bl-d">62</span></td><td>fixstr of length 1</td></tr>
|
||||
<tr><td><code>]</code></td><td></td><td>no end marker: the element count was given up front</td></tr>
|
||||
<tr><td><code>}</code></td><td></td><td>no end marker: the member count was given up front</td></tr>
|
||||
</tbody></table></div>
|
||||
|
||||
## Deserialization
|
||||
|
||||
The library maps MessagePack types to JSON value types as follows:
|
||||
|
||||
@@ -103,41 +103,6 @@ The library uses the following mapping from JSON values types to UBJSON types ac
|
||||
--8<-- "examples/to_ubjson.output"
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Byte layout
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 300,
|
||||
"name": "json",
|
||||
"pi": 3.14,
|
||||
"tags": [
|
||||
"a",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`to_ubjson` encodes it to 51 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: <span class="bl bl-t">type/marker</span> <span class="bl bl-l">length/count/size</span> <span class="bl bl-d">data</span>.
|
||||
|
||||
<div class="byte-layout" markdown="0"><table>
|
||||
<thead><tr><th>JSON</th><th>Bytes</th><th>Meaning</th></tr></thead><tbody>
|
||||
<tr><td><code>{</code></td><td><span class="bl bl-t">7B</span></td><td>object start (<code>{</code>)</td></tr>
|
||||
<tr><td><code>"id": 300,</code></td><td><span class="bl bl-l">69 02</span> <span class="bl bl-d">69 64</span> <span class="bl bl-t">49</span> <span class="bl bl-d">01 2C</span></td><td>key: length 2 as int8 (<code>i</code>), then UTF-8 bytes; value: int16 (<code>I</code>), big-endian</td></tr>
|
||||
<tr><td><code>"name": "json",</code></td><td><span class="bl bl-l">69 04</span> <span class="bl bl-d">6E 61 6D 65</span> <span class="bl bl-t">53</span> <span class="bl bl-l">69 04</span> <span class="bl bl-d">6A 73 6F 6E</span></td><td>key: length 4; value: string (<code>S</code>), length 4 as int8, UTF-8 bytes</td></tr>
|
||||
<tr><td><code>"pi": 3.14,</code></td><td><span class="bl bl-l">69 02</span> <span class="bl bl-d">70 69</span> <span class="bl bl-t">44</span> <span class="bl bl-d">40 09 1E B8 51 EB 85 1F</span></td><td>key: length 2; value: float64 (<code>D</code>), big-endian</td></tr>
|
||||
<tr><td><code>"tags": [</code></td><td><span class="bl bl-l">69 04</span> <span class="bl bl-d">74 61 67 73</span> <span class="bl bl-t">5B</span></td><td>key: length 4; value: array start (<code>[</code>)</td></tr>
|
||||
<tr><td><code>"a",</code></td><td><span class="bl bl-t">53</span> <span class="bl bl-l">69 01</span> <span class="bl bl-d">61</span></td><td>string, length 1</td></tr>
|
||||
<tr><td><code>"b"</code></td><td><span class="bl bl-t">53</span> <span class="bl bl-l">69 01</span> <span class="bl bl-d">62</span></td><td>string, length 1</td></tr>
|
||||
<tr><td><code>]</code></td><td><span class="bl bl-t">5D</span></td><td>array end (<code>]</code>)</td></tr>
|
||||
<tr><td><code>}</code></td><td><span class="bl bl-t">7D</span></td><td>object end (<code>}</code>)</td></tr>
|
||||
</tbody></table></div>
|
||||
|
||||
## Deserialization
|
||||
|
||||
The library maps UBJSON types to JSON value types as follows:
|
||||
|
||||
@@ -38,18 +38,6 @@ which avoids repeating it:
|
||||
--8<-- "examples/get_to.output"
|
||||
```
|
||||
|
||||
!!! info "Getting values out of a document or a view"
|
||||
|
||||
A [view](../api/basic_json_view/index.md) offers the same `get<T>()` conversion. For the built-in types (booleans,
|
||||
numbers, strings, `#!cpp std::vector`, `#!cpp std::map`, ...) it reads the value straight from the document's
|
||||
index, without building a `basic_json` value first; user-defined types with a `from_json()` are converted from a
|
||||
`basic_json` value, see the [list](../api/basic_json_view/get.md). Two conversions never copy at all:
|
||||
[`get_string()`](../api/basic_json_view/get_string.md) returns a string as a view into the source text, and
|
||||
[`number_token()`](../api/basic_json_view/number_token.md) returns a number exactly as it was written. Every other
|
||||
type is obtained from a subtree that is built on demand with
|
||||
[`materialize()`](../api/basic_json_view/materialize.md). See
|
||||
[Zero-copy JSON views](json_view.md#getting-values-out-without-copying).
|
||||
|
||||
The library already knows how to convert to and from the scalar types and the STL containers (such as
|
||||
`#!cpp std::vector`, `#!cpp std::map`, `#!cpp std::array`, `#!cpp std::optional`, and many more). Converting a JSON
|
||||
object back to a `#!cpp std::map` or a JSON array back to a `#!cpp std::vector` therefore works without any extra code:
|
||||
@@ -246,4 +234,3 @@ The conversions above are built in for standard types. To make the same syntax w
|
||||
- [`get_ref`](../api/basic_json/get_ref.md) / [`get_ptr`](../api/basic_json/get_ptr.md) - access the stored value without copying
|
||||
- [Arbitrary types conversions](arbitrary_types.md) - support your own types
|
||||
- [`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md) - toggle implicit conversions
|
||||
- [Zero-copy JSON views](json_view.md) - get values out of a document or a view
|
||||
@@ -1,9 +1,7 @@
|
||||
# Creating JSON values
|
||||
|
||||
There are several ways to create a JSON value in memory. This page gives an overview; to read a value from JSON text
|
||||
instead, see [parsing](parsing/index.md). A JSON text can also be parsed into a
|
||||
[document](../api/basic_json_document/index.md) and read through a [view](../api/basic_json_view/index.md) instead of
|
||||
into a value; see [Zero-copy JSON views](json_view.md).
|
||||
instead, see [parsing](parsing/index.md).
|
||||
|
||||
## From C++ values
|
||||
|
||||
@@ -103,4 +101,3 @@ string `#!json "42"`.
|
||||
- [`operator""_json`](../api/operator_literal_json.md) - the `_json` literal
|
||||
- [Converting values](conversions.md) - which C++ types can be used
|
||||
- [Parsing](parsing/index.md) - create a value from JSON text
|
||||
- [Zero-copy JSON views](json_view.md) - create a document and a view from JSON text instead of a value
|
||||
@@ -21,12 +21,3 @@ flowchart TD
|
||||
A --> F{"just testing first?"}
|
||||
F -->|"yes"| G["contains() / find()"]
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [**operator[]**](../../api/basic_json/operator%5B%5D.md) - unchecked access
|
||||
- [**at**](../../api/basic_json/at.md) - checked access
|
||||
- [**value**](../../api/basic_json/value.md) - access with default value
|
||||
- [**contains**](../../api/basic_json/contains.md) and [**find**](../../api/basic_json/find.md) - test for existence
|
||||
- [**front**](../../api/basic_json/front.md) and [**back**](../../api/basic_json/back.md) - first and last element
|
||||
- [**items**](../../api/basic_json/items.md) - iterate over keys and values
|
||||
@@ -59,11 +59,3 @@ C++ types, and finally serialize it again.
|
||||
|
||||
This section gives conceptual overviews. For the precise signature, parameters, and return value of a function, see
|
||||
the [API Documentation](../api/basic_json/index.md).
|
||||
|
||||
## See also
|
||||
|
||||
- [API documentation](../api/basic_json/index.md) - reference of all classes and functions
|
||||
- [FAQ](../home/faq.md) - answers to common questions
|
||||
- [Exceptions](../home/exceptions.md) - all exceptions and their error codes
|
||||
- [Design goals](../home/design_goals.md)
|
||||
- [Integration](../integration/index.md) - how to add the library to a project
|
||||
@@ -174,13 +174,6 @@ security reasons (e.g., Intel Software Guard Extensions (SGX)).
|
||||
|
||||
See [full documentation of `JSON_NO_IO`](../api/macros/json_no_io.md).
|
||||
|
||||
## `JSON_NO_SIMD`
|
||||
|
||||
When defined, the library uses only portable code instead of vector instructions (SSE2, SSSE3, NEON) for scanning
|
||||
strings and writing floating-point numbers. Results are the same either way. It is not defined by default.
|
||||
|
||||
See [full documentation of `JSON_NO_SIMD`](../api/macros/json_no_simd.md).
|
||||
|
||||
## `JSON_NO_THREAD_LOCAL`
|
||||
|
||||
When defined, the library does not use `#!cpp thread_local` storage. Copying a value and comparing two values then
|
||||
@@ -287,23 +280,6 @@ external dependency and is not defined by default.
|
||||
|
||||
See [full documentation of `JSON_USE_SIMDUTF`](../api/macros/json_use_simdutf.md).
|
||||
|
||||
## `JSON_VIEW_NO_SIMD`
|
||||
|
||||
When defined, the parser of [`basic_json_document`](../api/basic_json_document/index.md)
|
||||
(`<nlohmann/json_view.hpp>`) uses only portable C++ to scan strings, instead of vector instructions (SSE2 on x86-64,
|
||||
NEON on AArch64). The same input is accepted or rejected either way; only the speed differs. It is not defined by
|
||||
default.
|
||||
|
||||
See [full documentation of `JSON_VIEW_NO_SIMD`](../api/macros/json_view_no_simd.md).
|
||||
|
||||
## `JSON_VIEW_USE_SSSE3`
|
||||
|
||||
When defined on x86-64, the parser of [`basic_json_document`](../api/basic_json_document/index.md)
|
||||
(`<nlohmann/json_view.hpp>`) validates non-ASCII text in strings with SSSE3 without asking the CPU first. It is not
|
||||
defined by default.
|
||||
|
||||
See [full documentation of `JSON_VIEW_USE_SSSE3`](../api/macros/json_view_use_ssse3.md).
|
||||
|
||||
## `NLOHMANN_DEFINE_TYPE_*(...)`, `NLOHMANN_DEFINE_DERIVED_TYPE_*(...)`
|
||||
|
||||
The library defines 12 macros to simplify the serialization/deserialization of types. See the page on
|
||||
|
||||
@@ -85,18 +85,6 @@ json a = {1, 2, 3, 4};
|
||||
a.erase(1); // [1,3,4] (erase by index)
|
||||
```
|
||||
|
||||
## Editing a document
|
||||
|
||||
The operations above work on a `basic_json` value. A JSON text that was parsed into a
|
||||
[document](json_view.md#editing-a-document) can also be changed in place, without building a `basic_json` tree for the
|
||||
parts that are not touched: [`set`](../api/basic_json_document/set.md) replaces a value, adds or replaces an object
|
||||
member, or replaces an array element (also through a JSON pointer),
|
||||
[`push_back`](../api/basic_json_document/push_back.md) appends to an array,
|
||||
[`insert`](../api/basic_json_document/insert.md) inserts into an array (unlike `basic_json::insert`, it has no object
|
||||
overload; members are added with `set`), and [`erase`](../api/basic_json_document/erase.md) removes a member or an
|
||||
element. These functions are available on the
|
||||
editable document types, such as [`json_editable_document`](../api/json_editable_document.md).
|
||||
|
||||
## See also
|
||||
|
||||
- [`push_back`](../api/basic_json/push_back.md) / [`emplace_back`](../api/basic_json/emplace_back.md) - append to an array
|
||||
@@ -105,4 +93,3 @@ editable document types, such as [`json_editable_document`](../api/json_editable
|
||||
- [`merge_patch`](../api/basic_json/merge_patch.md) - apply an RFC 7396 merge patch
|
||||
- [`erase`](../api/basic_json/erase.md) / [`clear`](../api/basic_json/clear.md) - remove elements
|
||||
- [JSON Patch and Diff](json_patch.md) and [JSON Merge Patch](merge_patch.md) - structured modifications
|
||||
- [Editing a document](json_view.md#editing-a-document) - change a parsed document in place
|
||||
@@ -27,7 +27,6 @@ The complete default namespace name is derived as follows:
|
||||
`_dsbs`.
|
||||
- [`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md) defined non-zero appends
|
||||
`_dufio`.
|
||||
- [`JSON_NO_SIMD`](../api/macros/json_no_simd.md) defined appends `_ns`.
|
||||
- [`JSON_VIEW_NO_SIMD`](../api/macros/json_view_no_simd.md) defined appends `_vns`.
|
||||
- [`JSON_VIEW_USE_SSSE3`](../api/macros/json_view_use_ssse3.md) defined appends `_vssse3`.
|
||||
- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by
|
||||
@@ -115,7 +114,6 @@ follows:
|
||||
([`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md)), `_ekmo`
|
||||
([`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md)), `_dsbs`
|
||||
([`JSON_DISABLE_STREAM_BULK_SCAN`](../api/macros/json_disable_stream_bulk_scan.md)), `_dufio`
|
||||
([`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md)), `_ns`
|
||||
([`JSON_NO_SIMD`](../api/macros/json_no_simd.md)), `_vns`
|
||||
([`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md)), `_vns`
|
||||
([`JSON_VIEW_NO_SIMD`](../api/macros/json_view_no_simd.md)), and `_vssse3`
|
||||
([`JSON_VIEW_USE_SSSE3`](../api/macros/json_view_use_ssse3.md)) in version 3.13.0.
|
||||
@@ -18,7 +18,6 @@ flowchart LR
|
||||
The [`parse`](../../api/basic_json/parse.md) function reads a JSON value from an input. The input can be
|
||||
|
||||
- a string (`#!cpp std::string`, C string, or string literal),
|
||||
- a wide string (`#!cpp std::u16string`, `#!cpp std::u32string`, or `#!cpp std::wstring`, or a wide string literal),
|
||||
- a `#!cpp std::istream` (e.g., an `#!cpp std::ifstream` reading from a file),
|
||||
- a `#!cpp FILE*` pointer,
|
||||
- a pair of iterators over a contiguous range (e.g., a `#!cpp std::vector<std::uint8_t>`), or
|
||||
@@ -33,18 +32,12 @@ std::ifstream f("example.json");
|
||||
json data = json::parse(f);
|
||||
```
|
||||
|
||||
The input must be encoded in UTF-8; other encodings are not supported. The exception is wide-character input, which
|
||||
is read as UTF-16 or UTF-32 -- depending on the character type -- and converted to UTF-8; see the
|
||||
[`parse`](../../api/basic_json/parse.md) page for an example. A single input may contain only one JSON value.
|
||||
The input must be encoded in UTF-8; other encodings are not supported. A single input may contain only one JSON value.
|
||||
Inputs consisting of multiple values separated by newlines are handled by the [JSON Lines](json_lines.md) format.
|
||||
|
||||
By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the `parse`
|
||||
function — see [comments](../comments.md) and [trailing commas](../trailing_commas.md).
|
||||
|
||||
[`basic_json_document::parse`](../../api/basic_json_document/parse.md) accepts the same inputs with the same options,
|
||||
but keeps the result in a document rather than in a `basic_json` value; see
|
||||
[Documents and views](#documents-and-views) below.
|
||||
|
||||
## Strictness and trailing data
|
||||
|
||||
[`parse`](../../api/basic_json/parse.md) reads a single JSON value and requires the whole input to be consumed: any
|
||||
@@ -86,10 +79,6 @@ follow the usual `std::streambuf` contract, and
|
||||
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../../api/macros/json_disable_unlocked_file_io.md) for programs in which another
|
||||
thread must use the same `#!cpp FILE` object while it is parsed.
|
||||
|
||||
Where the target has them, strings are scanned with vector instructions: SSE2 on x86-64 (and SSSE3 for UTF-8 text, when
|
||||
the CPU has it) and NEON on AArch64. [`JSON_NO_SIMD`](../../api/macros/json_no_simd.md) selects portable code instead,
|
||||
again without changing any result.
|
||||
|
||||
## SAX vs. DOM parsing
|
||||
|
||||
The library offers two parsing models:
|
||||
@@ -105,26 +94,6 @@ The library offers two parsing models:
|
||||
You can influence a DOM parse without switching to the SAX interface by passing a
|
||||
[parser callback](parser_callbacks.md), which is called during parsing and can, for example, discard parts of the input.
|
||||
|
||||
## Documents and views
|
||||
|
||||
A third model sits between DOM and SAX: [`basic_json_document::parse`](../../api/basic_json_document/parse.md) parses
|
||||
the input into a document that keeps the text and a flat index of the values in it, and
|
||||
[`basic_json_view`](../../api/basic_json_view/index.md) gives read-only access to the values through that index.
|
||||
The whole input is validated during parsing, but only integers and strings that contain escape sequences are converted
|
||||
right away (the strings into a buffer owned by the document). Floating-point numbers and all other strings stay in the
|
||||
source text and are only converted when they are read, which is faster and uses less memory than building a tree of `basic_json` values when only parts
|
||||
of the document are needed. A document can also be
|
||||
modified in place, and it can be saved and loaded again without parsing it.
|
||||
|
||||
```cpp
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
json_document doc = json_document::parse(R"({"happy": true, "pi": 3.141})");
|
||||
std::cout << doc.root()["happy"].get<bool>() << '\n';
|
||||
```
|
||||
|
||||
See [Zero-copy JSON views](../json_view.md) for the concept and the trade-offs.
|
||||
|
||||
## Exceptions
|
||||
|
||||
When the input is not valid JSON, the `parse` function throws an exception by default. If exceptions are undesired or
|
||||
@@ -135,7 +104,6 @@ options.
|
||||
## See also
|
||||
|
||||
- [`parse`](../../api/basic_json/parse.md) - deserialize from a compatible input
|
||||
- [`basic_json_document::parse`](../../api/basic_json_document/parse.md) - deserialize into a document instead of a value
|
||||
- [`accept`](../../api/basic_json/accept.md) - check if the input is valid JSON
|
||||
- [`sax_parse`](../../api/basic_json/sax_parse.md) - generate SAX events
|
||||
- [JSON Lines](json_lines.md) - parse newline-delimited JSON
|
||||
@@ -143,4 +111,3 @@ options.
|
||||
- [SAX interface](sax_interface.md) - implement a custom SAX handler
|
||||
- [parsing and exceptions](parse_exceptions.md) - control error handling
|
||||
- [parsing untrusted input](untrusted_input.md) - what to consider when parsing input from untrusted sources
|
||||
- [Zero-copy JSON views](../json_view.md) - parse into a document and read it through a view
|
||||
@@ -81,9 +81,6 @@ Invalid UTF-8 is rejected while parsing, not just while serializing:
|
||||
|
||||
- In JSON text, an ill-formed UTF-8 byte in a string is a
|
||||
[`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) ("invalid string: ill-formed UTF-8 byte").
|
||||
- In UTF-16 or UTF-32 input, an ill-formed sequence is a
|
||||
[`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) as well: a lone surrogate, a high surrogate
|
||||
that is not followed by its low surrogate, and a code point above `U+10FFFF` are all rejected.
|
||||
- In a binary format, a string that is not valid UTF-8 is a
|
||||
[`parse_error.113`](../../home/exceptions.md#jsonexceptionparse_error113).
|
||||
|
||||
|
||||
@@ -20,38 +20,31 @@ below apply on every supported standard. This adapter exposes two optimizations
|
||||
|
||||
- it can reconstruct already-consumed input on demand for error messages, instead of copying every character as it is
|
||||
read, and
|
||||
- the lexer can scan ordinary string characters, numbers, and indentation directly out of the buffer, several bytes at
|
||||
a time, rather than one character (and one function call) at a time.
|
||||
- the lexer can scan ordinary string characters directly out of the buffer, several bytes at a time, rather than one
|
||||
character (and one function call) at a time.
|
||||
|
||||
A `#!cpp std::istream` (including `#!cpp std::ifstream`) gets the same bulk scanning: `input_stream_adapter` scans the
|
||||
characters its stream buffer already holds (the *get area*) and asks the stream buffer for more only when they are used
|
||||
up. Nothing is read ahead, so the stream is left exactly where it would be after reading one character at a time, and
|
||||
[`operator>>`](../api/operator_gtgt.md) can still read several values from one stream. A stream buffer without a get
|
||||
area is read one character at a time. A `#!cpp FILE*` is still read one character at a time, but `file_input_adapter`
|
||||
locks the file once per parse instead of once per character. See
|
||||
[input sources and performance](parsing/index.md#input-sources-and-performance) for the full table. According to the
|
||||
description of [#5828](https://github.com/nlohmann/json/pull/5828), parsing from a stream is within about 10 to 20 % of
|
||||
parsing an equivalent `#!cpp std::string`.
|
||||
A `#!cpp std::istream` (including `#!cpp std::ifstream`) or `#!cpp FILE*`, by contrast, is read through
|
||||
`input_stream_adapter` or `file_input_adapter`, which read one character (or one block, for binary formats) at a time
|
||||
and expose neither optimization -- the lexer falls back to the same byte-at-a-time path it uses for any
|
||||
non-contiguous, general-purpose iterator range. An iterator pair over non-contiguous but random-access storage (e.g.
|
||||
`#!cpp std::deque<char>::iterator`) gets the first optimization but not the second, since the byte-scanning fast path
|
||||
additionally requires contiguous storage.
|
||||
|
||||
Inputs that are still read one character at a time: iterator ranges that are not contiguous (e.g.
|
||||
`#!cpp std::list<char>` or `#!cpp std::istreambuf_iterator<char>`), wide strings, and user-defined adapters. An
|
||||
iterator pair over non-contiguous but random-access storage (e.g. `#!cpp std::deque<char>::iterator`) gets the first
|
||||
optimization but not the second, since the byte-scanning fast path requires contiguous storage.
|
||||
|
||||
Practically: a file can be passed directly to `parse`, which also avoids the memory for a copy of the file. Reading it
|
||||
into a string first is no longer necessary for speed:
|
||||
Practically: if the JSON text is already in memory, or small enough to read into memory, prefer passing a
|
||||
`#!cpp std::string`, a `#!cpp std::vector<char>`, or a pointer range to `parse` over a `#!cpp std::istream`. For a
|
||||
file, that means reading it into a string first and then parsing the string, rather than passing a
|
||||
`#!cpp std::ifstream` directly to `parse` -- the latter never benefits from either optimization:
|
||||
|
||||
```cpp
|
||||
// fast: the stream buffer's get area is scanned in bulk
|
||||
// gets the contiguous fast paths
|
||||
std::ifstream f("example.json");
|
||||
json j = json::parse(f);
|
||||
```
|
||||
std::string contents((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
||||
json j = json::parse(contents);
|
||||
|
||||
Two macros switch the stream optimizations off without changing any result:
|
||||
[`JSON_DISABLE_STREAM_BULK_SCAN`](../api/macros/json_disable_stream_bulk_scan.md) for stream buffers that do not follow
|
||||
the usual `#!cpp std::streambuf` contract, and
|
||||
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md) for programs in which another thread
|
||||
must use the same `#!cpp FILE` object while it is parsed.
|
||||
// does not: input_stream_adapter has no fast path
|
||||
std::ifstream f2("example.json");
|
||||
json j2 = json::parse(f2);
|
||||
```
|
||||
|
||||
For contiguous input with many non-ASCII characters, [`JSON_USE_SIMDUTF`](../api/macros/json_use_simdutf.md) can
|
||||
additionally speed up UTF-8 validation by using the [simdutf](https://github.com/simdutf/simdutf) library instead of
|
||||
|
||||
Loaded 100 of 278 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user