mirror of
https://github.com/nlohmann/json.git
synced 2026-10-01 04:00:31 +00:00
Compare commits
33
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d23803fd32 | ||
|
|
f1014c938a | ||
|
|
e91fdad877 | ||
|
|
9c71689715 | ||
|
|
44ec53c77b | ||
|
|
6a073dbae4 | ||
|
|
fdcc569eee | ||
|
|
6fc0d501f3 | ||
|
|
67435c9c7e | ||
|
|
2ea6d8c127 | ||
|
|
66877675b1 | ||
|
|
7fd6895788 | ||
|
|
6ae17630a4 | ||
|
|
5bd766aa50 | ||
|
|
4bb1b14b06 | ||
|
|
bfe0f32d71 | ||
|
|
44a88d85be | ||
|
|
5b11a0282c | ||
|
|
bfea6f36d3 | ||
|
|
e444a66276 | ||
|
|
1151826508 | ||
|
|
6218aa212b | ||
|
|
42f89e3130 | ||
|
|
6d7845d207 | ||
|
|
678fd3017b | ||
|
|
fc4c9c3446 | ||
|
|
68beba727c | ||
|
|
0050d0f7a4 | ||
|
|
6a8a7735ed | ||
|
|
65af260117 | ||
|
|
d268eaa693 | ||
|
|
5b9ffae8bb | ||
|
|
04f6ddd227 |
@@ -67,6 +67,7 @@ jobs:
|
|||||||
|
|
||||||
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json.json -s .
|
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json.json -s .
|
||||||
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json_fwd.json -s .
|
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json_fwd.json -s .
|
||||||
|
cp include/nlohmann/json_literals.hpp $INCLUDE_DIR/json_literals.hpp
|
||||||
|
|
||||||
# the header list of the Bazel "json" target must match the files in include/
|
# the header list of the Bazel "json" target must match the files in include/
|
||||||
cmake -P cmake/scripts/gen_bazel_build_file.cmake
|
cmake -P cmake/scripts/gen_bazel_build_file.cmake
|
||||||
|
|||||||
@@ -71,38 +71,3 @@ jobs:
|
|||||||
run: cmake --build build --parallel 10
|
run: cmake --build build --parallel 10
|
||||||
- name: Test
|
- name: Test
|
||||||
run: cd build ; ctest -j 10 --output-on-failure
|
run: cd build ; ctest -j 10 --output-on-failure
|
||||||
|
|
||||||
swiftpm:
|
|
||||||
runs-on: macos-15
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
- name: Check that Package.swift resolves without a deprecation warning
|
|
||||||
run: swift package dump-package
|
|
||||||
- name: Build the SwiftPM documentation example against this checkout
|
|
||||||
run: |
|
|
||||||
mkdir -p /tmp/json-swiftpm-consumer/Sources/MyLibrary
|
|
||||||
cp docs/mkdocs/docs/integration/swift/example.cpp /tmp/json-swiftpm-consumer/Sources/MyLibrary/example.cpp
|
|
||||||
cat > /tmp/json-swiftpm-consumer/Package.swift << EOF
|
|
||||||
// swift-tools-version: 5.9
|
|
||||||
import PackageDescription
|
|
||||||
|
|
||||||
let package = Package(
|
|
||||||
name: "MyPackage",
|
|
||||||
dependencies: [
|
|
||||||
.package(path: "${{ github.workspace }}")
|
|
||||||
],
|
|
||||||
targets: [
|
|
||||||
.target(
|
|
||||||
name: "MyLibrary",
|
|
||||||
dependencies: [
|
|
||||||
.product(name: "json", package: "json")
|
|
||||||
],
|
|
||||||
publicHeadersPath: "."
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
EOF
|
|
||||||
cd /tmp/json-swiftpm-consumer
|
|
||||||
swift build
|
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: json
|
||||||
|
Upstream-Contact: Niels Lohmann <mail@nlohmann.me>
|
||||||
|
Source: https://github.com/nlohmann/json
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
Files: include/nlohmann/thirdparty/hedley.hpp
|
||||||
|
Copyright: 2016-2021 Evan Nemerson <evan@nemerson.com>
|
||||||
|
License: CC0
|
||||||
|
|
||||||
|
Files: include/nlohmann/detail/meta/cpp_future.hpp
|
||||||
|
Copyright: 2013-2026 Niels Lohmann <https://nlohmann.me> and 2018 The Abseil Authors
|
||||||
|
License: MIT AND Apache-2.0
|
||||||
|
|
||||||
|
Files: tests/thirdparty/doctest/*
|
||||||
|
Copyright: 2016-2023 Viktor Kirilov
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
Files: tests/thirdparty/fifo_map/*
|
||||||
|
Copyright: 2015-2017 Niels Lohmann
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
Files: tests/thirdparty/Fuzzer/*
|
||||||
|
Copyright: 2003-2022 LLVM Project.
|
||||||
|
License: Apache-2.0
|
||||||
|
|
||||||
|
Files: tests/thirdparty/imapdl/*
|
||||||
|
Copyright: 2017 Georg Sauthoff <mail@gms.tf>
|
||||||
|
License: GPL-3.0-only
|
||||||
|
|
||||||
|
Files: tools/amalgamate/*
|
||||||
|
Copyright: 2012 Erik Edlund <erik.edlund@32767.se>
|
||||||
|
License: BSD-3-Clause
|
||||||
|
|
||||||
|
Files: tools/gdb_pretty_printer/*
|
||||||
|
Copyright: 2020 Hannes Domani <https://github.com/ssbssa>
|
||||||
|
License: MIT
|
||||||
+3
-1
@@ -21,6 +21,7 @@ cc_library(
|
|||||||
"include/nlohmann/adl_serializer.hpp",
|
"include/nlohmann/adl_serializer.hpp",
|
||||||
"include/nlohmann/byte_container_with_subtype.hpp",
|
"include/nlohmann/byte_container_with_subtype.hpp",
|
||||||
"include/nlohmann/detail/abi_macros.hpp",
|
"include/nlohmann/detail/abi_macros.hpp",
|
||||||
|
"include/nlohmann/detail/bit_ops.hpp",
|
||||||
"include/nlohmann/detail/conversions/from_json.hpp",
|
"include/nlohmann/detail/conversions/from_json.hpp",
|
||||||
"include/nlohmann/detail/conversions/to_chars.hpp",
|
"include/nlohmann/detail/conversions/to_chars.hpp",
|
||||||
"include/nlohmann/detail/conversions/to_json.hpp",
|
"include/nlohmann/detail/conversions/to_json.hpp",
|
||||||
@@ -33,6 +34,7 @@ cc_library(
|
|||||||
"include/nlohmann/detail/input/number_parse.hpp",
|
"include/nlohmann/detail/input/number_parse.hpp",
|
||||||
"include/nlohmann/detail/input/parser.hpp",
|
"include/nlohmann/detail/input/parser.hpp",
|
||||||
"include/nlohmann/detail/input/position_t.hpp",
|
"include/nlohmann/detail/input/position_t.hpp",
|
||||||
|
"include/nlohmann/detail/input/pow5_table.hpp",
|
||||||
"include/nlohmann/detail/input/string_scan.hpp",
|
"include/nlohmann/detail/input/string_scan.hpp",
|
||||||
"include/nlohmann/detail/iterators/internal_iterator.hpp",
|
"include/nlohmann/detail/iterators/internal_iterator.hpp",
|
||||||
"include/nlohmann/detail/iterators/iter_impl.hpp",
|
"include/nlohmann/detail/iterators/iter_impl.hpp",
|
||||||
@@ -65,6 +67,7 @@ cc_library(
|
|||||||
"include/nlohmann/detail/value_t.hpp",
|
"include/nlohmann/detail/value_t.hpp",
|
||||||
"include/nlohmann/json.hpp",
|
"include/nlohmann/json.hpp",
|
||||||
"include/nlohmann/json_fwd.hpp",
|
"include/nlohmann/json_fwd.hpp",
|
||||||
|
"include/nlohmann/json_literals.hpp",
|
||||||
"include/nlohmann/ordered_map.hpp",
|
"include/nlohmann/ordered_map.hpp",
|
||||||
"include/nlohmann/thirdparty/hedley/hedley.hpp",
|
"include/nlohmann/thirdparty/hedley/hedley.hpp",
|
||||||
"include/nlohmann/thirdparty/hedley/hedley_undef.hpp",
|
"include/nlohmann/thirdparty/hedley/hedley_undef.hpp",
|
||||||
@@ -77,7 +80,6 @@ cc_library(
|
|||||||
name = "singleheader-json",
|
name = "singleheader-json",
|
||||||
hdrs = [
|
hdrs = [
|
||||||
"single_include/nlohmann/json.hpp",
|
"single_include/nlohmann/json.hpp",
|
||||||
"single_include/nlohmann/json_fwd.hpp",
|
|
||||||
],
|
],
|
||||||
includes = ["single_include"],
|
includes = ["single_include"],
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
|
|||||||
+1
-1
@@ -10,5 +10,5 @@ title: "JSON for Modern C++"
|
|||||||
version: 3.12.0
|
version: 3.12.0
|
||||||
date-released: 2025-04-07
|
date-released: 2025-04-07
|
||||||
license: MIT
|
license: MIT
|
||||||
repository-code: "https://github.com/nlohmann/json"
|
repository-code: "https://github.com/nlohmann"
|
||||||
url: https://json.nlohmann.me
|
url: https://json.nlohmann.me
|
||||||
|
|||||||
+1
-4
@@ -42,11 +42,8 @@ endif()
|
|||||||
## OPTIONS
|
## OPTIONS
|
||||||
##
|
##
|
||||||
|
|
||||||
# Build the tests by default only for the main project and only if the tests
|
|
||||||
# directory exists (the release archive json.tar.xz does not contain it).
|
|
||||||
# VERSION_GREATER_EQUAL is not available in older CMake (< 3.7)
|
# VERSION_GREATER_EQUAL is not available in older CMake (< 3.7)
|
||||||
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13)
|
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13))
|
||||||
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
|
|
||||||
set(JSON_BuildTests_INIT ON)
|
set(JSON_BuildTests_INIT ON)
|
||||||
else()
|
else()
|
||||||
set(JSON_BuildTests_INIT OFF)
|
set(JSON_BuildTests_INIT OFF)
|
||||||
|
|||||||
@@ -207,19 +207,19 @@ Further documentation:
|
|||||||
|
|
||||||
## REUSE
|
## REUSE
|
||||||
|
|
||||||
### `REUSE.toml`
|
### `.reuse/dep5`
|
||||||
|
|
||||||
The file defines the licenses of certain third-party components in the repository. The root `Makefile` contains a target `reuse` that checks for compliance.
|
The file defines the licenses of certain third-party components in the repository. The root `Makefile` contains a target `reuse` that checks for compliance.
|
||||||
|
|
||||||
Further documentation:
|
Further documentation:
|
||||||
|
|
||||||
- [REUSE.toml](https://reuse.software/spec-3.3/#reusetoml)
|
- [DEP5](https://reuse.software/spec-3.2/#dep5-deprecated)
|
||||||
- [reuse command-line tool](https://pypi.org/project/reuse/)
|
- [reuse command-line tool](https://pypi.org/project/reuse/)
|
||||||
- [documentation of linting](https://reuse.readthedocs.io/en/stable/man/reuse-lint.html)
|
- [documentation of linting](https://reuse.readthedocs.io/en/stable/man/reuse-lint.html)
|
||||||
- [REUSE](http://reuse.software)
|
- [REUSE](http://reuse.software)
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> The filename `REUSE.toml` is predetermined by REUSE. Alternatively, a `.reuse/dep5` file (deprecated) can be used.
|
> The filename `.reuse/dep5` is predetermined by REUSE. Alternatively, a `REUSE.toml` file can be used.
|
||||||
|
|
||||||
### `.reuse/templates`
|
### `.reuse/templates`
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,6 @@
|
|||||||
# find GNU sed to use `-i` parameter
|
# find GNU sed to use `-i` parameter
|
||||||
SED:=$(shell command -v gsed || which sed)
|
SED:=$(shell command -v gsed || which sed)
|
||||||
|
|
||||||
# find GNU tar to use `--sort` and `--pax-option` parameters
|
|
||||||
TAR:=$(shell command -v gtar || which tar)
|
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# source files
|
# source files
|
||||||
@@ -24,6 +21,8 @@ TESTS_SRCS=$(shell find tests -type f \( -name '*.hpp' -o -name '*.cpp' -o -name
|
|||||||
# the single headers (amalgamated from the source files)
|
# the single headers (amalgamated from the source files)
|
||||||
AMALGAMATED_FILE=single_include/nlohmann/json.hpp
|
AMALGAMATED_FILE=single_include/nlohmann/json.hpp
|
||||||
AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp
|
AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp
|
||||||
|
# json_literals.hpp only includes <nlohmann/json.hpp>, so it is copied verbatim
|
||||||
|
AMALGAMATED_LITERALS_FILE=single_include/nlohmann/json_literals.hpp
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@@ -32,7 +31,7 @@ AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp
|
|||||||
|
|
||||||
# main target
|
# main target
|
||||||
all:
|
all:
|
||||||
@echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd}.hpp from the include/nlohmann sources"
|
@echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd,_literals}.hpp from the include/nlohmann sources"
|
||||||
@echo "BUILD.bazel - regenerate the Bazel BUILD file from the include/nlohmann sources"
|
@echo "BUILD.bazel - regenerate the Bazel BUILD file from the include/nlohmann sources"
|
||||||
@echo "ChangeLog.md - generate ChangeLog file"
|
@echo "ChangeLog.md - generate ChangeLog file"
|
||||||
@echo "check-amalgamation - check whether sources have been amalgamated and BUILD.bazel is up to date"
|
@echo "check-amalgamation - check whether sources have been amalgamated and BUILD.bazel is up to date"
|
||||||
@@ -157,14 +156,14 @@ install_astyle:
|
|||||||
|
|
||||||
# call the Artistic Style pretty printer on all source files
|
# call the Artistic Style pretty printer on all source files
|
||||||
pretty: install_astyle
|
pretty: install_astyle
|
||||||
$(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) docs/mkdocs/docs/examples/*.cpp
|
$(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) docs/mkdocs/docs/examples/*.cpp
|
||||||
|
|
||||||
# call the Clang-Format on all source files
|
# call the Clang-Format on all source files
|
||||||
pretty_format:
|
pretty_format:
|
||||||
for FILE in $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/mkdocs/docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done
|
for FILE in $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/mkdocs/docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done
|
||||||
|
|
||||||
# create single header files and pretty print
|
# create single header files and pretty print
|
||||||
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE)
|
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE)
|
||||||
$(MAKE) pretty
|
$(MAKE) pretty
|
||||||
|
|
||||||
# call the amalgamation tool for json.hpp
|
# call the amalgamation tool for json.hpp
|
||||||
@@ -175,16 +174,23 @@ $(AMALGAMATED_FILE): $(SRCS)
|
|||||||
$(AMALGAMATED_FWD_FILE): $(SRCS)
|
$(AMALGAMATED_FWD_FILE): $(SRCS)
|
||||||
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_fwd.json -s . --verbose=yes
|
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_fwd.json -s . --verbose=yes
|
||||||
|
|
||||||
|
# copy json_literals.hpp
|
||||||
|
$(AMALGAMATED_LITERALS_FILE): include/nlohmann/json_literals.hpp
|
||||||
|
cp include/nlohmann/json_literals.hpp $(AMALGAMATED_LITERALS_FILE)
|
||||||
|
|
||||||
# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources
|
# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources
|
||||||
# Note: this target is called by Travis
|
# Note: this target is called by Travis
|
||||||
check-amalgamation:
|
check-amalgamation:
|
||||||
@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~
|
@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~
|
||||||
@mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~
|
@mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~
|
||||||
|
@mv $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~
|
||||||
@$(MAKE) amalgamate
|
@$(MAKE) amalgamate
|
||||||
@diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false)
|
@diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false)
|
||||||
@diff $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) ; false)
|
@diff $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) ; false)
|
||||||
|
@diff $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE) ; false)
|
||||||
@mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE)
|
@mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE)
|
||||||
@mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE)
|
@mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE)
|
||||||
|
@mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE)
|
||||||
@mv BUILD.bazel BUILD.bazel~
|
@mv BUILD.bazel BUILD.bazel~
|
||||||
@$(MAKE) BUILD.bazel
|
@$(MAKE) BUILD.bazel
|
||||||
@diff BUILD.bazel BUILD.bazel~ || (echo "===================================================================\n BUILD.bazel is out of date! Please run 'make BUILD.bazel'.\n===================================================================" ; mv BUILD.bazel~ BUILD.bazel ; false)
|
@diff BUILD.bazel BUILD.bazel~ || (echo "===================================================================\n BUILD.bazel is out of date! Please run 'make BUILD.bazel'.\n===================================================================" ; mv BUILD.bazel~ BUILD.bazel ; false)
|
||||||
@@ -218,14 +224,14 @@ ChangeLog.md:
|
|||||||
# archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>.
|
# archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>.
|
||||||
json.tar.xz:
|
json.tar.xz:
|
||||||
mkdir json
|
mkdir json
|
||||||
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include src/modules -type f) json
|
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include -type f) json
|
||||||
$(TAR) --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz
|
gtar --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz
|
||||||
rm -fr json
|
rm -fr json
|
||||||
|
|
||||||
# We use `-X` to make the resulting ZIP file reproducible, see
|
# We use `-X` to make the resulting ZIP file reproducible, see
|
||||||
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
|
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
|
||||||
include.zip: BUILD.bazel
|
include.zip: BUILD.bazel
|
||||||
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT
|
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT
|
||||||
|
|
||||||
# Create the files for a release and add signatures and hashes.
|
# Create the files for a release and add signatures and hashes.
|
||||||
release: include.zip json.tar.xz
|
release: include.zip json.tar.xz
|
||||||
@@ -234,10 +240,12 @@ release: include.zip json.tar.xz
|
|||||||
gpg --armor --detach-sig include.zip
|
gpg --armor --detach-sig include.zip
|
||||||
gpg --armor --detach-sig $(AMALGAMATED_FILE)
|
gpg --armor --detach-sig $(AMALGAMATED_FILE)
|
||||||
gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE)
|
gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE)
|
||||||
|
gpg --armor --detach-sig $(AMALGAMATED_LITERALS_FILE)
|
||||||
gpg --armor --detach-sig json.tar.xz
|
gpg --armor --detach-sig json.tar.xz
|
||||||
cp $(AMALGAMATED_FILE) release_files
|
cp $(AMALGAMATED_FILE) release_files
|
||||||
cp $(AMALGAMATED_FWD_FILE) release_files
|
cp $(AMALGAMATED_FWD_FILE) release_files
|
||||||
mv $(AMALGAMATED_FILE).asc $(AMALGAMATED_FWD_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc release_files
|
cp $(AMALGAMATED_LITERALS_FILE) release_files
|
||||||
|
mv $(AMALGAMATED_FILE).asc $(AMALGAMATED_FWD_FILE).asc $(AMALGAMATED_LITERALS_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc release_files
|
||||||
cd release_files ; shasum -a 256 json.hpp include.zip json.tar.xz > hashes.txt
|
cd release_files ; shasum -a 256 json.hpp include.zip json.tar.xz > hashes.txt
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import PackageDescription
|
|||||||
let package = Package(
|
let package = Package(
|
||||||
name: "nlohmann-json",
|
name: "nlohmann-json",
|
||||||
platforms: [
|
platforms: [
|
||||||
.iOS(.v12), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v9), .visionOS(.v1)
|
.iOS(.v12), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v4), .visionOS(.v1)
|
||||||
],
|
],
|
||||||
products: [
|
products: [
|
||||||
.library(name: "json", targets: ["json"])
|
.library(name: "json", targets: ["json"])
|
||||||
|
|||||||
@@ -1204,18 +1204,15 @@ language bindings, format converters, and the like. See the curated [Ecosystem](
|
|||||||
|
|
||||||
Though it's 2026 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
|
Though it's 2026 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
|
||||||
|
|
||||||
- GCC 4.8 - 16.2 (and possibly later)
|
- GCC 4.8 - 14.2 (and possibly later)
|
||||||
- Clang 3.4 - 22.1 (and possibly later)
|
- Clang 3.4 - 21.0 (and possibly later)
|
||||||
- Apple Clang 15.0 - 21.0 (and possibly later)
|
- Apple Clang 9.1 - 16.0 (and possibly later)
|
||||||
- Intel C++ Compiler Classic (icpc) 2021.10
|
- Intel C++ Compiler 17.0.2 (and possibly later)
|
||||||
- Intel oneAPI DPC++/C++ Compiler (icpx) 2025.3 (and possibly later)
|
- Nvidia CUDA Compiler 11.0.221 (and possibly later)
|
||||||
- NVIDIA CUDA Compiler (nvcc) 11.8 - 12.6 (and possibly later)
|
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
|
||||||
- NVIDIA HPC SDK C++ Compiler (nvc++) 25.5 (and possibly later)
|
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
|
||||||
- Microsoft Visual C++ 2015 / MSVC 19.0 (and possibly later)
|
- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)
|
||||||
- Microsoft Visual C++ 2017 / MSVC 19.16 (and possibly later)
|
- Microsoft Visual C++ 2022 / Build Tools 19.30.30709.0 (and possibly later)
|
||||||
- Microsoft Visual C++ 2019 / MSVC 19.29 (and possibly later)
|
|
||||||
- Microsoft Visual C++ 2022 / MSVC 19.44 (and possibly later)
|
|
||||||
- Microsoft Visual C++ 2026 / MSVC 19.51 (and possibly later)
|
|
||||||
|
|
||||||
I would be happy to learn about other compilers/versions.
|
I would be happy to learn about other compilers/versions.
|
||||||
|
|
||||||
@@ -1398,6 +1395,7 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I
|
|||||||
- The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](https://florian.loitsch.com/)
|
- The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](https://florian.loitsch.com/)
|
||||||
- The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
|
- The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||||
- The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
|
- The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
|
||||||
|
- The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright © 2021 The fast_float authors
|
||||||
|
|
||||||
<img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
|
<img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
|
||||||
|
|
||||||
@@ -1405,7 +1403,7 @@ The library is compliant to version 3.3 of the [**REUSE specification**](https:/
|
|||||||
|
|
||||||
- Every source file contains an SPDX copyright header.
|
- Every source file contains an SPDX copyright header.
|
||||||
- The full text of all licenses used in the repository can be found in the `LICENSES` folder.
|
- The full text of all licenses used in the repository can be found in the `LICENSES` folder.
|
||||||
- File `REUSE.toml` contains an overview of all files' copyrights and licenses.
|
- File `.reuse/dep5` contains an overview of all files' copyrights and licenses.
|
||||||
- Run `pipx run reuse lint` to verify the project's REUSE compliance and `pipx run reuse spdx` to generate a SPDX SBOM.
|
- Run `pipx run reuse lint` to verify the project's REUSE compliance and `pipx run reuse spdx` to generate a SPDX SBOM.
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
version = 1
|
|
||||||
SPDX-PackageName = "json"
|
|
||||||
SPDX-PackageSupplier = "Niels Lohmann <mail@nlohmann.me>"
|
|
||||||
SPDX-PackageDownloadLocation = "https://github.com/nlohmann/json"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me>"
|
|
||||||
SPDX-License-Identifier = "MIT"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "include/nlohmann/thirdparty/hedley.hpp"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2016-2021 Evan Nemerson <evan@nemerson.com>"
|
|
||||||
SPDX-License-Identifier = "CC0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "include/nlohmann/detail/meta/cpp_future.hpp"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me> and 2018 The Abseil Authors"
|
|
||||||
SPDX-License-Identifier = "MIT AND Apache-2.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tests/thirdparty/doctest/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2016-2023 Viktor Kirilov"
|
|
||||||
SPDX-License-Identifier = "MIT"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tests/thirdparty/fifo_map/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2015-2017 Niels Lohmann"
|
|
||||||
SPDX-License-Identifier = "MIT"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tests/thirdparty/Fuzzer/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2003-2022 LLVM Project."
|
|
||||||
SPDX-License-Identifier = "Apache-2.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tests/thirdparty/imapdl/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2017 Georg Sauthoff <mail@gms.tf>"
|
|
||||||
SPDX-License-Identifier = "GPL-3.0-only"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tools/amalgamate/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2012 Erik Edlund <erik.edlund@32767.se>"
|
|
||||||
SPDX-License-Identifier = "BSD-3-Clause"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "tools/gdb_pretty_printer/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2020 Hannes Domani <https://github.com/ssbssa>"
|
|
||||||
SPDX-License-Identifier = "MIT"
|
|
||||||
+4
-1
@@ -373,9 +373,10 @@ file(GLOB_RECURSE INDENT_FILES
|
|||||||
set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann)
|
set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann)
|
||||||
set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate)
|
set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate)
|
||||||
add_custom_target(ci_test_amalgamation
|
add_custom_target(ci_test_amalgamation
|
||||||
COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~
|
COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~
|
||||||
COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~
|
COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~
|
||||||
COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~
|
COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~
|
||||||
|
COMMAND cp ${include_dir}/json_literals.hpp ${include_dir}/json_literals.hpp~
|
||||||
|
|
||||||
COMMAND ${Python3_EXECUTABLE} -mvenv venv_astyle
|
COMMAND ${Python3_EXECUTABLE} -mvenv venv_astyle
|
||||||
COMMAND venv_astyle/bin/pip3 --quiet install -r ${CMAKE_SOURCE_DIR}/tools/astyle/requirements.txt
|
COMMAND venv_astyle/bin/pip3 --quiet install -r ${CMAKE_SOURCE_DIR}/tools/astyle/requirements.txt
|
||||||
@@ -383,10 +384,12 @@ add_custom_target(ci_test_amalgamation
|
|||||||
|
|
||||||
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json.json -s .
|
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json.json -s .
|
||||||
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s .
|
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s .
|
||||||
|
COMMAND cp ${PROJECT_SOURCE_DIR}/include/nlohmann/json_literals.hpp ${include_dir}/json_literals.hpp
|
||||||
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=none ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp
|
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=none ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp
|
||||||
|
|
||||||
COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp
|
COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp
|
||||||
COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp
|
COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp
|
||||||
|
COMMAND diff ${include_dir}/json_literals.hpp~ ${include_dir}/json_literals.hpp
|
||||||
|
|
||||||
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES}
|
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES}
|
||||||
COMMAND for FILE in `find . -name '*.orig'`\; do false \; done
|
COMMAND for FILE in `find . -name '*.orig'`\; do false \; done
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ cc_library(
|
|||||||
name = "singleheader-json",
|
name = "singleheader-json",
|
||||||
hdrs = [
|
hdrs = [
|
||||||
"single_include/nlohmann/json.hpp",
|
"single_include/nlohmann/json.hpp",
|
||||||
"single_include/nlohmann/json_fwd.hpp",
|
|
||||||
],
|
],
|
||||||
includes = ["single_include"],
|
includes = ["single_include"],
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ if(MODE STREQUAL "undef")
|
|||||||
# recipe is self-contained and its output is byte-stable across reruns.
|
# recipe is self-contained and its output is byte-stable across reruns.
|
||||||
# The embedded SPDX tags below are part of the *generated* file's
|
# The embedded SPDX tags below are part of the *generated* file's
|
||||||
# content, not a REUSE header for this .cmake script itself (which is
|
# content, not a REUSE header for this .cmake script itself (which is
|
||||||
# already covered by the blanket path = "**" rule in REUSE.toml) -- keep
|
# already covered by the blanket "Files: *" rule in .reuse/dep5) -- keep
|
||||||
# them wrapped in REUSE-IgnoreStart/End so `reuse lint` does not try to
|
# them wrapped in REUSE-IgnoreStart/End so `reuse lint` does not try to
|
||||||
# parse "MIT\n")" as this file's own SPDX-License-Identifier value.
|
# parse "MIT\n")" as this file's own SPDX-License-Identifier value.
|
||||||
# REUSE-IgnoreStart
|
# REUSE-IgnoreStart
|
||||||
|
|||||||
@@ -139,8 +139,8 @@ basic_json(basic_json&& other) noexcept;
|
|||||||
|
|
||||||
- In case of a `#!json null` type, [invalid_iterator.206](../../home/exceptions.md#jsonexceptioninvalid_iterator206)
|
- In case of a `#!json null` type, [invalid_iterator.206](../../home/exceptions.md#jsonexceptioninvalid_iterator206)
|
||||||
is thrown.
|
is thrown.
|
||||||
- In case of other primitive types (number, boolean, or string), `first` must be `begin()` and `last` must be
|
- In case of other primitive types (number, boolean, string, or binary), `first` must be `begin()` and `last`
|
||||||
`end()`. In this case, the value is copied. Otherwise,
|
must be `end()`. In this case, the value is copied. Otherwise,
|
||||||
[`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) is thrown.
|
[`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) is thrown.
|
||||||
- In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or
|
- In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or
|
||||||
`std::map`; that is, a JSON array or object is constructed from the values in the range.
|
`std::map`; that is, a JSON array or object is constructed from the values in the range.
|
||||||
@@ -242,8 +242,8 @@ basic_json(basic_json&& other) noexcept;
|
|||||||
and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range
|
and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range
|
||||||
`[first, last)` is undefined.
|
`[first, last)` is undefined.
|
||||||
- Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if iterators `first`
|
- Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if iterators `first`
|
||||||
and `last` belong to a primitive type (number, boolean, or string), but `first` does not point to the first
|
and `last` belong to a primitive type (number, boolean, string, or binary), but `first` does not point to the
|
||||||
element anymore. In this case, the range `[first, last)` is undefined. See the example code below.
|
first element anymore. In this case, the range `[first, last)` is undefined. See the example code below.
|
||||||
- Throws [`invalid_iterator.206`](../../home/exceptions.md#jsonexceptioninvalid_iterator206) if iterators `first`
|
- Throws [`invalid_iterator.206`](../../home/exceptions.md#jsonexceptioninvalid_iterator206) if iterators `first`
|
||||||
and `last` belong to a `#!json null` value. In this case, the range `[first, last)` is undefined.
|
and `last` belong to a `#!json null` value. In this case, the range `[first, last)` is undefined.
|
||||||
8. (none)
|
8. (none)
|
||||||
@@ -423,6 +423,8 @@ basic_json(basic_json&& other) noexcept;
|
|||||||
4. Since version 3.2.0.
|
4. Since version 3.2.0.
|
||||||
5. Since version 1.0.0.
|
5. Since version 1.0.0.
|
||||||
6. Since version 1.0.0.
|
6. Since version 1.0.0.
|
||||||
7. 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. Since version 1.0.0.
|
8. Since version 1.0.0.
|
||||||
9. Since version 1.0.0.
|
9. Since version 1.0.0.
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ void clear() noexcept;
|
|||||||
Clears the content of a JSON value and resets it to the default value as if [`basic_json(value_t)`](basic_json.md) would
|
Clears the content of a JSON value and resets it to the default value as if [`basic_json(value_t)`](basic_json.md) would
|
||||||
have been called with the current value type from [`type()`](type.md):
|
have been called with the current value type from [`type()`](type.md):
|
||||||
|
|
||||||
| Value type | initial value |
|
| Value type | initial value |
|
||||||
|------------|----------------------|
|
|------------|-----------------------------------------|
|
||||||
| null | `null` |
|
| null | `null` |
|
||||||
| boolean | `false` |
|
| boolean | `false` |
|
||||||
| string | `""` |
|
| string | `""` |
|
||||||
| number | `0` |
|
| number | `0` |
|
||||||
| binary | An empty byte vector |
|
| binary | An empty byte vector with no subtype |
|
||||||
| object | `{}` |
|
| object | `{}` |
|
||||||
| array | `[]` |
|
| array | `[]` |
|
||||||
|
|
||||||
Has the same effect as calling
|
Has the same effect as calling
|
||||||
|
|
||||||
@@ -56,3 +56,4 @@ All iterators, pointers, and references related to this container are invalidate
|
|||||||
|
|
||||||
- Added in version 1.0.0.
|
- Added in version 1.0.0.
|
||||||
- Added support for binary types in version 3.8.0.
|
- Added support for binary types in version 3.8.0.
|
||||||
|
- Fixed in version 3.13.0 to also clear the subtype of a binary value; before, the subtype was left unchanged.
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ Logarithmic in the size of the JSON object.
|
|||||||
|
|
||||||
- This method always returns `#!cpp false` when executed on a JSON type that is not an object.
|
- This method always returns `#!cpp false` when executed on a JSON type that is not an object.
|
||||||
- This method can be executed on any JSON value type.
|
- This method can be executed on any JSON value type.
|
||||||
|
- Calling this function with an integer argument (for example, `#!cpp contains(0)`) does not compile: such an argument
|
||||||
|
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
|
||||||
|
constructing a `#!cpp std::string` for the object key. To check for an array element instead, use [`at`](at.md),
|
||||||
|
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
|
||||||
|
|
||||||
!!! info "Postconditions"
|
!!! info "Postconditions"
|
||||||
|
|
||||||
@@ -117,3 +121,5 @@ Logarithmic in the size of the JSON object.
|
|||||||
1. Added in version 3.11.0.
|
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.
|
2. Added in version 3.6.0. Extended template `KeyType` to support comparable types in version 3.11.0.
|
||||||
3. Added in version 3.7.0.
|
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.
|
||||||
|
|||||||
@@ -40,7 +40,11 @@ Logarithmic in the size of the JSON object.
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
This method always returns `0` when executed on a JSON type that is not an object.
|
- This method always returns `0` when executed on a JSON type that is not an object.
|
||||||
|
- Calling this function with an integer argument (for example, `#!cpp count(0)`) does not compile: such an argument
|
||||||
|
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
|
||||||
|
constructing a `#!cpp std::string` for the object key. To check for an array element instead, use [`at`](at.md),
|
||||||
|
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -81,3 +85,5 @@ This method always returns `0` when executed on a JSON type that is not an objec
|
|||||||
|
|
||||||
1. Added in version 3.11.0.
|
1. Added in version 3.11.0.
|
||||||
2. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0.
|
2. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0.
|
||||||
|
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.
|
||||||
|
|||||||
@@ -44,7 +44,11 @@ Logarithmic in the size of the JSON object.
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
This method always returns `end()` when executed on a JSON type that is not an object.
|
- This method always returns `end()` when executed on a JSON type that is not an object.
|
||||||
|
- Calling this function with an integer argument (for example, `#!cpp find(0)`) does not compile: such an argument
|
||||||
|
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
|
||||||
|
constructing a `#!cpp std::string` for the object key. To access an array element instead, use [`at`](at.md),
|
||||||
|
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -85,3 +89,5 @@ This method always returns `end()` when executed on a JSON type that is not an o
|
|||||||
|
|
||||||
1. Added in version 3.11.0.
|
1. Added in version 3.11.0.
|
||||||
2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0.
|
2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0.
|
||||||
|
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.
|
||||||
|
|||||||
@@ -195,5 +195,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
|||||||
1. Added in version 1.0.0.
|
1. Added in version 1.0.0.
|
||||||
2. Added in version 1.0.0.
|
2. Added in version 1.0.0.
|
||||||
3. Added in version 1.0.0.
|
3. Added in version 1.0.0.
|
||||||
4. Added in version 1.0.0.
|
4. Added in version 1.0.0. Fixed in version 3.13.0 to copy the values before inserting; before, an `ilist` that
|
||||||
|
referred to elements of the array being inserted into could insert wrong values, because the range insert could
|
||||||
|
move from or shift an element before it was copied.
|
||||||
5. Added in version 3.0.0.
|
5. Added in version 3.0.0.
|
||||||
|
|||||||
@@ -23,9 +23,10 @@ type to use.
|
|||||||
## Template parameters
|
## Template parameters
|
||||||
|
|
||||||
`NumberFloatType`
|
`NumberFloatType`
|
||||||
: the type to store floating-point numbers. Parsing and serialization are implemented in terms of
|
: the type to store floating-point numbers. The parser converts `#!cpp float`, `#!cpp double`, and a
|
||||||
`#!cpp std::strtof`/`#!cpp std::strtod`/`#!cpp std::strtold` and `#!cpp std::snprintf`, so the type must be
|
`#!cpp long double` that is IEEE 754 binary64 itself and other `#!cpp long double` formats with
|
||||||
`#!cpp float`, `#!cpp double`, or `#!cpp long double`. The
|
`#!cpp std::from_chars` or `#!cpp std::strtold`, and serialization falls back to `#!cpp std::snprintf`, so the
|
||||||
|
type must be `#!cpp float`, `#!cpp double`, or `#!cpp long double`. The
|
||||||
[binary formats](../../features/binary_formats/index.md) additionally require `#!cpp float` or `#!cpp double`,
|
[binary formats](../../features/binary_formats/index.md) additionally require `#!cpp float` or `#!cpp double`,
|
||||||
because they have no encoding for `#!cpp long double`. See
|
because they have no encoding for `#!cpp long double`. See
|
||||||
[Template Parameter Requirements](../../features/types/template_parameters.md#numberfloattype).
|
[Template Parameter Requirements](../../features/types/template_parameters.md#numberfloattype).
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
|||||||
1. The function can throw the following exceptions:
|
1. The function can throw the following exceptions:
|
||||||
- Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an array
|
- Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an array
|
||||||
or null; in that case, using the `[]` operator with an index makes no sense.
|
or null; in that case, using the `[]` operator with an index makes no sense.
|
||||||
|
- Throws `#!cpp std::length_error` if `idx` equals the maximum value of `size_type`; the array is left unchanged.
|
||||||
|
(This is the one index for which growing the array to hold it cannot be expressed as a `size_type` size, the same
|
||||||
|
way an oversized [`resize`](https://en.cppreference.com/w/cpp/container/vector/resize) throws.)
|
||||||
2. The function can throw the following exceptions:
|
2. The function can throw the following exceptions:
|
||||||
- Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an object
|
- Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an object
|
||||||
or null; in that case, using the `[]` operator with a key makes no sense.
|
or null; in that case, using the `[]` operator with a key makes no sense.
|
||||||
@@ -257,7 +260,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
|||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
1. Added in version 1.0.0.
|
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`.
|
||||||
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)
|
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.
|
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
|
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
|
||||||
|
|||||||
@@ -88,7 +88,12 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
|||||||
## Exceptions
|
## Exceptions
|
||||||
|
|
||||||
- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token, or
|
- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token, or
|
||||||
empty input like a null `FILE*` or `char*` pointer.
|
empty input like a null `FILE*` or `char*` pointer, or an `std::istream` without a stream buffer
|
||||||
|
(`#!cpp i.rdbuf() == nullptr`, for instance `#!cpp std::istream(nullptr)`).
|
||||||
|
- If reading from an `std::istream` reaches the end of the input and `eofbit` is part of the stream's
|
||||||
|
[`exceptions()`](https://en.cppreference.com/w/cpp/io/basic_ios/exceptions) mask, the `std::ios_base::failure`
|
||||||
|
thrown by the stream itself propagates instead of a `parse_error`, the same as it would for the standard library's
|
||||||
|
own extraction operators.
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
@@ -254,6 +259,8 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
|
|||||||
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
|
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
|
||||||
- `JSON_STRICT_NUL_HANDLING` added in version 3.13.0 to optionally reject a NUL byte in the input instead of treating
|
- `JSON_STRICT_NUL_HANDLING` added in version 3.13.0 to optionally reject a NUL byte in the input instead of treating
|
||||||
it as end of input; planned to become the default in version 4.0.0.
|
it as end of input; planned to become the default in version 4.0.0.
|
||||||
|
- Extended empty-input detection to also cover an `std::istream` without a stream buffer, and fixed a crash
|
||||||
|
(`std::terminate`) when parsing from an `std::istream` with `eofbit` in its exception mask, in version 3.13.0.
|
||||||
|
|
||||||
!!! warning "Deprecation"
|
!!! warning "Deprecation"
|
||||||
|
|
||||||
|
|||||||
@@ -100,3 +100,6 @@ the latter case, it is skipped completely, or replaced by `null` if it is the to
|
|||||||
- Added in version 1.0.0.
|
- Added in version 1.0.0.
|
||||||
- Fixed in version 3.13.0 to also remove discarded values from a parent object; before, discarding an array or a value
|
- Fixed in version 3.13.0 to also remove discarded values from a parent object; before, discarding an array or a value
|
||||||
stored under an object key left a discarded member behind, which made the parse result serialize to invalid JSON.
|
stored under an object key left a discarded member behind, which made the parse result serialize to invalid JSON.
|
||||||
|
- Fixed in version 3.13.0 so that discarding an array or object at its start event also hides its content from the
|
||||||
|
callback, as documented above; before, the callback was still called for the content, and the key of every member of
|
||||||
|
a discarded object was kept in memory until the parse ended.
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ void swap(reference other) noexcept (
|
|||||||
std::is_nothrow_move_constructible<value_t>::value &&
|
std::is_nothrow_move_constructible<value_t>::value &&
|
||||||
std::is_nothrow_move_assignable<value_t>::value &&
|
std::is_nothrow_move_assignable<value_t>::value &&
|
||||||
std::is_nothrow_move_constructible<json_value>::value &&
|
std::is_nothrow_move_constructible<json_value>::value &&
|
||||||
std::is_nothrow_move_assignable<json_value>::value
|
std::is_nothrow_move_assignable<json_value>::value &&
|
||||||
|
std::is_nothrow_move_constructible<json_base_class_t>::value &&
|
||||||
|
std::is_nothrow_move_assignable<json_base_class_t>::value
|
||||||
);
|
);
|
||||||
|
|
||||||
// (2)
|
// (2)
|
||||||
@@ -14,7 +16,9 @@ friend void swap(reference left, reference right) noexcept (
|
|||||||
std::is_nothrow_move_constructible<value_t>::value &&
|
std::is_nothrow_move_constructible<value_t>::value &&
|
||||||
std::is_nothrow_move_assignable<value_t>::value &&
|
std::is_nothrow_move_assignable<value_t>::value &&
|
||||||
std::is_nothrow_move_constructible<json_value>::value &&
|
std::is_nothrow_move_constructible<json_value>::value &&
|
||||||
std::is_nothrow_move_assignable<json_value>::value
|
std::is_nothrow_move_assignable<json_value>::value &&
|
||||||
|
std::is_nothrow_move_constructible<json_base_class_t>::value &&
|
||||||
|
std::is_nothrow_move_assignable<json_base_class_t>::value
|
||||||
);
|
);
|
||||||
|
|
||||||
// (3)
|
// (3)
|
||||||
@@ -37,11 +41,15 @@ void swap(typename binary_t::container_type& other);
|
|||||||
individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. If macro
|
individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. If macro
|
||||||
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) is defined to `#!cpp 1`, the
|
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) is defined to `#!cpp 1`, the
|
||||||
[`start_pos()`](start_pos.md)/[`end_pos()`](end_pos.md) diagnostic positions are exchanged along with the value.
|
[`start_pos()`](start_pos.md)/[`end_pos()`](end_pos.md) diagnostic positions are exchanged along with the value.
|
||||||
|
The [`json_base_class_t`](json_base_class_t.md) subobject is exchanged along with the value as well, the same way it
|
||||||
|
is copied or moved by the copy/move constructors and assignment operators.
|
||||||
2. Exchanges the contents of the JSON value from `left` with those of `right`. Does not invoke any move, copy, or swap
|
2. Exchanges the contents of the JSON value from `left` with those of `right`. Does not invoke any move, copy, or swap
|
||||||
operations on individual elements. All iterators and references remain valid. The past-the-end iterator is
|
operations on individual elements. All iterators and references remain valid. The past-the-end iterator is
|
||||||
invalidated. Implemented as a friend function callable via ADL. If macro
|
invalidated. Implemented as a friend function callable via ADL. If macro
|
||||||
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) is defined to `#!cpp 1`, the
|
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) is defined to `#!cpp 1`, the
|
||||||
[`start_pos()`](start_pos.md)/[`end_pos()`](end_pos.md) diagnostic positions are exchanged along with the value.
|
[`start_pos()`](start_pos.md)/[`end_pos()`](end_pos.md) diagnostic positions are exchanged along with the value.
|
||||||
|
The [`json_base_class_t`](json_base_class_t.md) subobject is exchanged along with the value as well, the same way it
|
||||||
|
is copied or moved by the copy/move constructors and assignment operators.
|
||||||
3. Exchanges the contents of a JSON array with those of `other`. Does not invoke any move, copy, or swap operations on
|
3. Exchanges the contents of a JSON array with those of `other`. Does not invoke any move, copy, or swap operations on
|
||||||
individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated.
|
individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated.
|
||||||
4. Exchanges the contents of a JSON object with those of `other`. Does not invoke any move, copy, or swap operations on
|
4. Exchanges the contents of a JSON object with those of `other`. Does not invoke any move, copy, or swap operations on
|
||||||
@@ -164,8 +172,8 @@ Constant.
|
|||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
1. Since version 1.0.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.
|
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.
|
3. Since version 1.0.0.
|
||||||
4. Since version 1.0.0.
|
4. Since version 1.0.0.
|
||||||
5. Since version 1.0.0.
|
5. Since version 1.0.0.
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
|||||||
- Throws [`out_of_range.412`](../../home/exceptions.md#jsonexceptionout_of_range412) if the length of a document, array,
|
- Throws [`out_of_range.412`](../../home/exceptions.md#jsonexceptionout_of_range412) if the length of a document, array,
|
||||||
string, or binary value exceeds the range of the 32-bit BSON length field; example:
|
string, or binary value exceeds the range of the 32-bit BSON length field; example:
|
||||||
`"BSON length 2147483661 exceeds maximum of 2147483647"`
|
`"BSON length 2147483661 exceeds maximum of 2147483647"`
|
||||||
|
- Throws [`out_of_range.415`](../../home/exceptions.md#jsonexceptionout_of_range415) if the subtype of a binary value
|
||||||
|
exceeds 255, the maximum of the BSON binary subtype; example:
|
||||||
|
`"subtype 70000 is too large for the BSON binary subtype (max 255)"`
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
@@ -78,3 +81,4 @@ pass before anything is written.
|
|||||||
|
|
||||||
- Added in version 3.4.0.
|
- Added in version 3.4.0.
|
||||||
- Linear in the size of `j`, and no longer limited by the call stack for deeply nested values, since version 3.13.0.
|
- Linear in the size of `j`, and no longer limited by the call stack for deeply nested values, since version 3.13.0.
|
||||||
|
- `out_of_range.415` is now detected before anything is written, like the other exceptions above, since version 3.13.0.
|
||||||
|
|||||||
@@ -76,3 +76,6 @@ Linear in the size of the JSON value `j`.
|
|||||||
|
|
||||||
- Added in version 2.0.9.
|
- Added in version 2.0.9.
|
||||||
- Throws `out_of_range.412` and `out_of_range.415` since version 3.13.0.
|
- Throws `out_of_range.412` and `out_of_range.415` since version 3.13.0.
|
||||||
|
- Fixed in version 3.13.0 to serialize `number_integer_t`/`number_unsigned_t` pairs of different width correctly;
|
||||||
|
before, integers could be serialized with the wrong value if `number_integer_t` was narrower than
|
||||||
|
`number_unsigned_t`.
|
||||||
|
|||||||
@@ -52,6 +52,14 @@ This is equivalent to Python's `dict.get(key, default)`.
|
|||||||
- Unlike [`operator[]`](operator[].md), this function does not implicitly add an element to the position defined by
|
- Unlike [`operator[]`](operator[].md), this function does not implicitly add an element to the position defined by
|
||||||
`key`/`ptr` key. This function is furthermore also applicable to const objects.
|
`key`/`ptr` key. This function is furthermore also applicable to const objects.
|
||||||
|
|
||||||
|
!!! note "Integer keys"
|
||||||
|
|
||||||
|
Calling this function with an integer `key` argument (for example, `#!cpp value(0, 1)`) does not compile in
|
||||||
|
C++11, where `object_comparator_t` is not transparent: such an argument would otherwise implicitly convert to a
|
||||||
|
null `#!cpp const char*` and, from there, cause undefined behavior when constructing a `#!cpp std::string` for the
|
||||||
|
object key. To access an array element with a default value, use [`at`](at.md) together with a `#!cpp try`/`#!cpp
|
||||||
|
catch` block, or compare against [`size`](size.md) instead.
|
||||||
|
|
||||||
## Template parameters
|
## Template parameters
|
||||||
|
|
||||||
`KeyType`
|
`KeyType`
|
||||||
@@ -184,7 +192,9 @@ changes to any JSON value.
|
|||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version 3.11.0.
|
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.
|
2. Added in version 3.11.0. Made `ValueType` the first template parameter in version 3.11.2.
|
||||||
3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0, including fixing an issue where resolving
|
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
|
`ptr` through an array unexpectedly threw `out_of_range` instead of returning the resolved element (or
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ header. See also the [macro overview page](../../features/macros.md).
|
|||||||
- [**JSON_HAS_RANGES**](json_has_ranges.md) - control `std::ranges` support
|
- [**JSON_HAS_RANGES**](json_has_ranges.md) - control `std::ranges` support
|
||||||
- [**JSON_HAS_STD_FORMAT**](json_has_std_format.md) - control `std::format`/`std::formatter` support
|
- [**JSON_HAS_STD_FORMAT**](json_has_std_format.md) - control `std::format`/`std::formatter` support
|
||||||
- [**JSON_HAS_THREE_WAY_COMPARISON**](json_has_three_way_comparison.md) - control 3-way comparison support
|
- [**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_IO**](json_no_io.md) - switch off functions relying on certain C++ I/O headers
|
||||||
- [**JSON_NO_THREAD_LOCAL**](json_no_thread_local.md) - switch off the use of `thread_local` storage
|
- [**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_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# JSON_NO_AUTOMATIC_UDLS
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_NO_AUTOMATIC_UDLS
|
||||||
|
```
|
||||||
|
|
||||||
|
When defined, `<nlohmann/json.hpp>` does not include `<nlohmann/json_literals.hpp>`, so the user-defined string
|
||||||
|
literals [`operator""_json`](../operator_literal_json.md) and
|
||||||
|
[`operator""_json_pointer`](../operator_literal_json_pointer.md) are not declared. Include
|
||||||
|
`<nlohmann/json_literals.hpp>` in the files that use them.
|
||||||
|
|
||||||
|
The literals are ordinary inline functions whose bodies call the parser, so every translation unit that includes them
|
||||||
|
instantiates the parser — even if it never parses anything itself. Defining `JSON_NO_AUTOMATIC_UDLS` for a whole project
|
||||||
|
avoids this cost in translation units that do not parse (e.g., ones that only define types and conversions or pass
|
||||||
|
`json` values around) and reduces their compile time.
|
||||||
|
|
||||||
|
## Default definition
|
||||||
|
|
||||||
|
By default, `#!cpp JSON_NO_AUTOMATIC_UDLS` is not defined, and `<nlohmann/json.hpp>` includes
|
||||||
|
`<nlohmann/json_literals.hpp>`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#undef JSON_NO_AUTOMATIC_UDLS
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
!!! info "Header `<nlohmann/json_literals.hpp>`"
|
||||||
|
|
||||||
|
The header includes `<nlohmann/json.hpp>` itself and places the literals according to
|
||||||
|
[`JSON_USE_GLOBAL_UDLS`](json_use_global_udls.md). It is part of the multi-header sources (`include/nlohmann`)
|
||||||
|
and of the single-header sources (`single_include/nlohmann`), next to `json.hpp`.
|
||||||
|
|
||||||
|
!!! info "C++ modules"
|
||||||
|
|
||||||
|
The `nlohmann.json` [module](../../features/modules.md) always exports the literals, regardless of this macro.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The code below includes the library without the literals and adds them in a single translation unit.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// compiled with -DJSON_NO_AUTOMATIC_UDLS for the whole project
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
// this file uses the literals, so it includes them explicitly
|
||||||
|
#include <nlohmann/json_literals.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
auto j = R"({"foo": 42})"_json;
|
||||||
|
return j.at("/foo"_json_pointer) == 42 ? 0 : 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Without the include of `<nlohmann/json_literals.hpp>`, the code would fail to compile.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [`operator""_json`](../operator_literal_json.md)
|
||||||
|
- [`operator""_json_pointer`](../operator_literal_json_pointer.md)
|
||||||
|
- [`JSON_USE_GLOBAL_UDLS`](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -16,7 +16,8 @@ byte is still not rejected:
|
|||||||
[`from_msgpack`](../basic_json/from_msgpack.md), [`from_ubjson`](../basic_json/from_ubjson.md)) are never affected: there, `0x00` is ordinary data.
|
[`from_msgpack`](../basic_json/from_msgpack.md), [`from_ubjson`](../basic_json/from_ubjson.md)) are never affected: there, `0x00` is ordinary data.
|
||||||
- A bare `const char*` pointer has no length of its own, so its length is still determined with `strlen()`. The first
|
- A bare `const char*` pointer has no length of its own, so its length is still determined with `strlen()`. The first
|
||||||
NUL byte therefore still marks the end of the input, and nothing after it is read.
|
NUL byte therefore still marks the end of the input, and nothing after it is read.
|
||||||
- One trailing `'\0'` at the end of a `char` array (e.g., a string literal) is trimmed; see the warning below.
|
- One trailing `'\0'` at the end of a `char`, `wchar_t`, `char16_t`, `char32_t`, or (C++20) `char8_t` array (e.g., a
|
||||||
|
string literal) is trimmed; see the warning below.
|
||||||
|
|
||||||
## Default definition
|
## Default definition
|
||||||
|
|
||||||
@@ -57,13 +58,15 @@ The default value is `0` (disabled — existing behavior is preserved).
|
|||||||
This macro must be defined **before** including `<nlohmann/json.hpp>`. Defining it after the include has no
|
This macro must be defined **before** including `<nlohmann/json.hpp>`. Defining it after the include has no
|
||||||
effect.
|
effect.
|
||||||
|
|
||||||
Enabling it also changes how a `char` array (including a string literal, e.g. `json::parse("123")`) is read: such
|
Enabling it also changes how an array of a text-literal element type (`char`, `wchar_t`, `char16_t`, `char32_t`,
|
||||||
an array normally carries a trailing `'\0'` contributed by the compiler, not by the source text. With this macro
|
or, since C++20, `char8_t` - including a string literal, e.g. `json::parse("123")` or `json::parse(L"123")`) is
|
||||||
enabled, that one trailing byte is trimmed if present so that parsing a string literal keeps working; every other
|
read: such an array normally carries a trailing `'\0'` contributed by the compiler, not by the source text. With
|
||||||
byte in the array - including any `'\0'` that is not the very last element - is read as real data and rejected
|
this macro enabled, that one trailing element is trimmed if present so that parsing a string literal keeps
|
||||||
like any other unexpected byte. Arrays of any other element type (`unsigned char`, `std::uint8_t`, ...), as used
|
working, for any of these character types; every other element in the array - including any `'\0'` that is not
|
||||||
for CBOR or MessagePack, are never affected by this trimming; their full extent - including a genuine trailing
|
the very last element - is read as real data and rejected like any other unexpected byte. Arrays of any other
|
||||||
`0x00` - is always preserved, in both states of this macro.
|
element type (`unsigned char`, `std::uint8_t`, ...), as used for CBOR or MessagePack, are never affected by this
|
||||||
|
trimming; their full extent - including a genuine trailing `0x00` - is always preserved, in both states of this
|
||||||
|
macro.
|
||||||
|
|
||||||
!!! note "ABI compatibility"
|
!!! note "ABI compatibility"
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ The default value is `1`.
|
|||||||
#define JSON_USE_GLOBAL_UDLS 1
|
#define JSON_USE_GLOBAL_UDLS 1
|
||||||
```
|
```
|
||||||
|
|
||||||
When the macro is not defined, the library will define it to its default value.
|
When the macro is not defined, the library behaves as if it were defined to its default value.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
@@ -32,6 +32,11 @@ When the macro is not defined, the library will define it to its default value.
|
|||||||
[`JSON_GlobalUDLs`](../../integration/cmake.md#json_globaludls) (`ON` by default) which defines
|
[`JSON_GlobalUDLs`](../../integration/cmake.md#json_globaludls) (`ON` by default) which defines
|
||||||
`JSON_USE_GLOBAL_UDLS` accordingly.
|
`JSON_USE_GLOBAL_UDLS` accordingly.
|
||||||
|
|
||||||
|
!!! info "Leaving out the literals"
|
||||||
|
|
||||||
|
If [`JSON_NO_AUTOMATIC_UDLS`](json_no_automatic_udls.md) is defined, the literals are only declared where
|
||||||
|
`<nlohmann/json_literals.hpp>` is included; this macro then applies to that header.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example 1: Default behavior"
|
??? example "Example 1: Default behavior"
|
||||||
@@ -92,6 +97,7 @@ When the macro is not defined, the library will define it to its default value.
|
|||||||
|
|
||||||
- [`operator""_json`](../operator_literal_json.md)
|
- [`operator""_json`](../operator_literal_json.md)
|
||||||
- [`operator""_json_pointer`](../operator_literal_json_pointer.md)
|
- [`operator""_json_pointer`](../operator_literal_json_pointer.md)
|
||||||
|
- [`JSON_NO_AUTOMATIC_UDLS`](json_no_automatic_udls.md) - do not include the user-defined string literals automatically
|
||||||
- [:simple-cmake: JSON_GlobalUDLs](../../integration/cmake.md#json_globaludls) - CMake option to control the macro
|
- [:simple-cmake: JSON_GlobalUDLs](../../integration/cmake.md#json_globaludls) - CMake option to control the macro
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|||||||
@@ -18,9 +18,18 @@ Deserializes an input stream to a JSON value.
|
|||||||
|
|
||||||
the stream `i`
|
the stream `i`
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong guarantee: if an exception is thrown, there are no changes in `j`.
|
||||||
|
|
||||||
## Exceptions
|
## Exceptions
|
||||||
|
|
||||||
- Throws [`parse_error.101`](../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token.
|
- Throws [`parse_error.101`](../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token, or if
|
||||||
|
`i` has no stream buffer (`#!cpp i.rdbuf() == nullptr`, for instance `#!cpp std::istream(nullptr)`).
|
||||||
|
- If reading from `i` reaches the end of the input and `eofbit` is part of `i`'s
|
||||||
|
[`exceptions()`](https://en.cppreference.com/w/cpp/io/basic_ios/exceptions) mask, the `std::ios_base::failure`
|
||||||
|
thrown by `i` itself propagates instead of a `parse_error`, the same as it would for the standard library's own
|
||||||
|
extraction operators.
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
@@ -118,3 +127,7 @@ being read.
|
|||||||
it as end of input; planned to become the default in version 4.0.0.
|
it as end of input; planned to become the default in version 4.0.0.
|
||||||
- `JSON_PRECISE_STREAM_POSITION` added in version 3.13.0 to optionally leave the character that terminates a number in
|
- `JSON_PRECISE_STREAM_POSITION` added in version 3.13.0 to optionally leave the character that terminates a number in
|
||||||
the stream; planned to become the default in version 4.0.0.
|
the stream; planned to become the default in version 4.0.0.
|
||||||
|
- Fixed a null pointer dereference for an `std::istream` without a stream buffer (now throws `parse_error.101`), and a
|
||||||
|
crash (`std::terminate`) when `i` has `eofbit` in its exception mask, in version 3.13.0.
|
||||||
|
- Changed to the strong exception safety guarantee in version 3.13.0: `j` is no longer left with a partially parsed
|
||||||
|
value if parsing throws.
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ using namespace nlohmann;
|
|||||||
```
|
```
|
||||||
|
|
||||||
This is suggested to ease migration to the next major version release of the library. See
|
This is suggested to ease migration to the next major version release of the library. See
|
||||||
[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details.
|
[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. The operator is declared in header
|
||||||
|
`<nlohmann/json_literals.hpp>`, which `<nlohmann/json.hpp>` includes unless
|
||||||
|
[`JSON_NO_AUTOMATIC_UDLS`](macros/json_no_automatic_udls.md) is defined.
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
@@ -59,6 +61,8 @@ Linear.
|
|||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [Creating JSON values](../features/creating_values.md) - the article on creating JSON values
|
- [Creating JSON values](../features/creating_values.md) - the article on creating JSON values
|
||||||
|
- [JSON_NO_AUTOMATIC_UDLS](macros/json_no_automatic_udls.md) - do not include the user-defined string literals
|
||||||
|
automatically
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ using namespace nlohmann::literals::json_literals;
|
|||||||
using namespace nlohmann;
|
using namespace nlohmann;
|
||||||
```
|
```
|
||||||
This is suggested to ease migration to the next major version release of the library. See
|
This is suggested to ease migration to the next major version release of the library. See
|
||||||
[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details.
|
[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. The operator is declared in header
|
||||||
|
`<nlohmann/json_literals.hpp>`, which `<nlohmann/json.hpp>` includes unless
|
||||||
|
[`JSON_NO_AUTOMATIC_UDLS`](macros/json_no_automatic_udls.md) is defined.
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
@@ -58,6 +60,8 @@ Linear.
|
|||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [json_pointer](json_pointer/index.md) - type to represent JSON Pointers
|
- [json_pointer](json_pointer/index.md) - type to represent JSON Pointers
|
||||||
|
- [JSON_NO_AUTOMATIC_UDLS](macros/json_no_automatic_udls.md) - do not include the user-defined string literals
|
||||||
|
automatically
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ A minimal map-like container that preserves insertion order for use within [`nlo
|
|||||||
The type uses a `std::vector` to store object elements. Therefore, adding elements can yield a reallocation in which
|
The type uses a `std::vector` to store object elements. Therefore, adding elements can yield a reallocation in which
|
||||||
case all iterators (including the `end()` iterator) and all references to the elements are invalidated.
|
case all iterators (including the `end()` iterator) and all references to the elements are invalidated.
|
||||||
|
|
||||||
|
When the storage grows, the keys are copied and the mapped values are moved to the new storage. A plain `std::vector`
|
||||||
|
would copy the whole elements instead, because their `#!cpp const` keys make them not nothrow move constructible; for
|
||||||
|
[`ordered_json`](ordered_json.md), this would be a deep copy of every nested value. The values are only copied if
|
||||||
|
`T` is not default constructible or not nothrow move assignable.
|
||||||
|
|
||||||
## Member types
|
## Member types
|
||||||
|
|
||||||
- **key_type** - key type (`Key`)
|
- **key_type** - key type (`Key`)
|
||||||
@@ -56,6 +61,11 @@ std::equal_to<> // since C++14
|
|||||||
- **find**
|
- **find**
|
||||||
- **insert**
|
- **insert**
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
**emplace**, **operator\[\]**, and **insert(value)** have the strong exception guarantee: if an exception is thrown (for
|
||||||
|
instance, because copying a key or allocating memory fails), the contents of the container are unchanged.
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
Because the elements are stored in a `std::vector` in insertion order, there is no index to look a key up by. Every
|
Because the elements are stored in a `std::vector` in insertion order, there is no index to look a key up by. Every
|
||||||
@@ -122,3 +132,4 @@ This differs from `#!cpp std::map`, where the same operations are O(log n).
|
|||||||
|
|
||||||
- Added in version 3.9.0 to implement [`nlohmann::ordered_json`](ordered_json.md).
|
- Added in version 3.9.0 to implement [`nlohmann::ordered_json`](ordered_json.md).
|
||||||
- Added **key_compare** member in version 3.11.0.
|
- Added **key_compare** member in version 3.11.0.
|
||||||
|
- Changed in version 3.13.0: growing the storage moves the mapped values instead of copying them.
|
||||||
|
|||||||
@@ -83,6 +83,15 @@ When defined, default parse and serialize functions for enums are excluded and h
|
|||||||
|
|
||||||
See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md).
|
See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md).
|
||||||
|
|
||||||
|
## `JSON_NO_AUTOMATIC_UDLS`
|
||||||
|
|
||||||
|
When defined, `<nlohmann/json.hpp>` does not include `<nlohmann/json_literals.hpp>` with the user-defined string literals
|
||||||
|
`operator""_json` and `operator""_json_pointer`. This reduces the compile time of translation units that do not use
|
||||||
|
them, because the literals instantiate the parser in every translation unit that includes them. Include
|
||||||
|
`<nlohmann/json_literals.hpp>` where the literals are needed.
|
||||||
|
|
||||||
|
See [full documentation of `JSON_NO_AUTOMATIC_UDLS`](../api/macros/json_no_automatic_udls.md).
|
||||||
|
|
||||||
## `JSON_NO_IO`
|
## `JSON_NO_IO`
|
||||||
|
|
||||||
When defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostream>` are not included and parse functions
|
When defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostream>` are not included and parse functions
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ Only the following symbols are exported from `nlohmann.json`:
|
|||||||
- `nlohmann::literals::json_literals::operator""_json`
|
- `nlohmann::literals::json_literals::operator""_json`
|
||||||
- `nlohmann::literals::json_literals::operator""_json_pointer`
|
- `nlohmann::literals::json_literals::operator""_json_pointer`
|
||||||
|
|
||||||
|
The module always exports the two user-defined string literals, even if
|
||||||
|
[`JSON_NO_AUTOMATIC_UDLS`](../api/macros/json_no_automatic_udls.md) is defined when building it.
|
||||||
|
|
||||||
Additionally, the following `nlohmann::detail` symbols are exported, solely to work around an MSVC compilation issue
|
Additionally, the following `nlohmann::detail` symbols are exported, solely to work around an MSVC compilation issue
|
||||||
([#3970](https://github.com/nlohmann/json/issues/3970)). They are implementation details, not part of the public API,
|
([#3970](https://github.com/nlohmann/json/issues/3970)). They are implementation details, not part of the public API,
|
||||||
and should not be used directly:
|
and should not be used directly:
|
||||||
|
|||||||
@@ -71,10 +71,11 @@ otherwise, it uses unsigned integer storage.
|
|||||||
|
|
||||||
- Numbers with a decimal digit or scientific notation are always stored as `#!c double`.
|
- Numbers with a decimal digit or scientific notation are always stored as `#!c double`.
|
||||||
- The number types can be changed, see [Template number types](#template-number-types).
|
- The number types can be changed, see [Template number types](#template-number-types).
|
||||||
- As of version 3.9.1, the conversion is realized by
|
- The library converts integers and floating-point numbers itself, independent of the locale. Floating-point
|
||||||
[`std::strtoull`](https://en.cppreference.com/w/cpp/string/byte/strtoul),
|
numbers are correctly rounded (to nearest, ties to even). Only a `#!c long double` that is not IEEE 754 binary64
|
||||||
[`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and
|
(e.g., the 80-bit x87 format) is converted with `#!cpp std::from_chars` where available, or with
|
||||||
[`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof), respectively.
|
[`std::strtold`](https://en.cppreference.com/w/cpp/string/byte/strtof), which gets the decimal point of the
|
||||||
|
current locale, also one longer than one byte (e.g., in `fa_IR.UTF-8`).
|
||||||
|
|
||||||
!!! example "Examples"
|
!!! example "Examples"
|
||||||
|
|
||||||
@@ -85,10 +86,10 @@ otherwise, it uses unsigned integer storage.
|
|||||||
### Number limits
|
### Number limits
|
||||||
|
|
||||||
- Any 64-bit signed or unsigned integer can be stored without loss of precision.
|
- Any 64-bit signed or unsigned integer can be stored without loss of precision.
|
||||||
- Numbers exceeding the limits of `#!c double` (i.e., numbers that after conversion via
|
- Numbers exceeding the limits of `#!c double` (i.e., numbers whose rounded value is not satisfying
|
||||||
[`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof) are not satisfying
|
|
||||||
[`std::isfinite`](https://en.cppreference.com/w/cpp/numeric/math/isfinite) such as `#!c 1E400`) will throw exception
|
[`std::isfinite`](https://en.cppreference.com/w/cpp/numeric/math/isfinite) such as `#!c 1E400`) will throw exception
|
||||||
[`json.exception.out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406) during parsing.
|
[`json.exception.out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406) during parsing. Numbers too
|
||||||
|
small for `#!c double` (such as `#!c 1E-400`) become zero, with the sign of the number.
|
||||||
- Floating-point numbers are rounded to the next number representable as `double`. For instance
|
- Floating-point numbers are rounded to the next number representable as `double`. For instance
|
||||||
`#!c 3.141592653589793238462643383279` is stored as [`0x400921fb54442d18`](https://float.exposed/0x400921fb54442d18).
|
`#!c 3.141592653589793238462643383279` is stored as [`0x400921fb54442d18`](https://float.exposed/0x400921fb54442d18).
|
||||||
This is the same behavior as the code `#!c double x = 3.141592653589793238462643383279;`.
|
This is the same behavior as the code `#!c double x = 3.141592653589793238462643383279;`.
|
||||||
|
|||||||
@@ -26,8 +26,9 @@ Requirements are split into two groups:
|
|||||||
diagnosed with dedicated error messages, and violating most of them results in a compiler error somewhere inside
|
diagnosed with dedicated error messages, and violating most of them results in a compiler error somewhere inside
|
||||||
the library. Four violations are not caught at compile time at all:
|
the library. Four violations are not caught at compile time at all:
|
||||||
|
|
||||||
- A [`StringType`](#stringtype) whose `data()` is not null-terminated compiles and silently misparses numbers,
|
- A [`StringType`](#stringtype) whose `data()` is not null-terminated compiles and silently misparses numbers
|
||||||
because the lexer hands the buffer to `#!cpp std::strtoull`/`#!cpp std::strtoll`/`#!cpp std::strtod`.
|
stored as a `#!cpp long double` that is not IEEE 754 binary64 (e.g., the 80-bit x87 format), because the lexer
|
||||||
|
hands the buffer to `#!cpp std::strtold`.
|
||||||
- A stateful [`AllocatorType`](#allocatortype) compiles and silently ignores its state: allocation, deallocation,
|
- A stateful [`AllocatorType`](#allocatortype) compiles and silently ignores its state: allocation, deallocation,
|
||||||
and [`get_allocator()`](../../api/basic_json/get_allocator.md) each use a different default-constructed instance.
|
and [`get_allocator()`](../../api/basic_json/get_allocator.md) each use a different default-constructed instance.
|
||||||
- The two [cross-specialization conversions](#cross-specialization-conversions) below. These abort on an assertion
|
- The two [cross-specialization conversions](#cross-specialization-conversions) below. These abort on an assertion
|
||||||
@@ -389,6 +390,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
|||||||
| Functionality | Additional requirement |
|
| Functionality | Additional requirement |
|
||||||
|-----------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [`diff`](../../api/basic_json/diff.md), [`items`](../../api/basic_json/items.md), [`std::hash`](../../api/basic_json/std_hash.md) | conversion of a `#!cpp std::size_t` to `StringType`: either assignability from the result of `#!cpp std::to_string`, or an ADL overload `#!cpp void int_to_string(StringType&, std::size_t)` |
|
| [`diff`](../../api/basic_json/diff.md), [`items`](../../api/basic_json/items.md), [`std::hash`](../../api/basic_json/std_hash.md) | conversion of a `#!cpp std::size_t` to `StringType`: either assignability from the result of `#!cpp std::to_string`, or an ADL overload `#!cpp void int_to_string(StringType&, std::size_t)` |
|
||||||
|
| [`operator/(std::size_t)`](../../api/json_pointer/operator_slash.md) | the same conversion of a `#!cpp std::size_t` to `StringType` as `diff`, `items`, and `std::hash` above |
|
||||||
| [`std::hash<basic_json>`](../../api/basic_json/std_hash.md) | additionally a specialization of `#!cpp std::hash<StringType>` |
|
| [`std::hash<basic_json>`](../../api/basic_json/std_hash.md) | additionally a specialization of `#!cpp std::hash<StringType>` |
|
||||||
| [`to_bson`](../../api/basic_json/to_bson.md) | `find(value_type)` and `npos` |
|
| [`to_bson`](../../api/basic_json/to_bson.md) | `find(value_type)` and `npos` |
|
||||||
| [`parse`](../../api/basic_json/parse.md) from a `string_t` | the input adapters must accept it; otherwise pass a character range |
|
| [`parse`](../../api/basic_json/parse.md) from a `string_t` | the input adapters must accept it; otherwise pass a character range |
|
||||||
@@ -534,8 +536,10 @@ therefore silently changes parse results rather than raising an error. See
|
|||||||
|
|
||||||
`NumberFloatType` must be one of `#!cpp float`, `#!cpp double`, or `#!cpp long double`:
|
`NumberFloatType` must be one of `#!cpp float`, `#!cpp double`, or `#!cpp long double`:
|
||||||
|
|
||||||
- The [parser](../parsing/index.md) converts number literals with `#!cpp std::strtof`, `#!cpp std::strtod`, or
|
- The [parser](../parsing/index.md) converts number literals to `#!cpp float`, `#!cpp double`, and a
|
||||||
`#!cpp std::strtold`; the library provides overloads for exactly these three types.
|
`#!cpp long double` that is IEEE 754 binary64 itself; other `#!cpp long double` formats are converted with
|
||||||
|
`#!cpp std::from_chars` where available, or with `#!cpp std::strtold`. The library provides overloads for exactly
|
||||||
|
these three types.
|
||||||
- [`dump`](../../api/basic_json/dump.md) falls back to `#!cpp std::snprintf` with the `%g` and `%Lg` conversion
|
- [`dump`](../../api/basic_json/dump.md) falls back to `#!cpp std::snprintf` with the `%g` and `%Lg` conversion
|
||||||
specifiers, for which the library likewise provides only `#!cpp double` and `#!cpp long double` overloads
|
specifiers, for which the library likewise provides only `#!cpp double` and `#!cpp long double` overloads
|
||||||
(`#!cpp float` is promoted to `#!cpp double`).
|
(`#!cpp float` is promoted to `#!cpp double`).
|
||||||
|
|||||||
@@ -19,3 +19,5 @@ The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed und
|
|||||||
The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](https://florian.loitsch.com/)
|
The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](https://florian.loitsch.com/)
|
||||||
|
|
||||||
The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
|
The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||||
|
|
||||||
|
The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright © 2021 The fast_float authors
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ automatically download a release as a dependency at configure time.
|
|||||||
|
|
||||||
### `JSON_BuildTests`
|
### `JSON_BuildTests`
|
||||||
|
|
||||||
Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project and the `tests` directory exists (the release archive `json.tar.xz` does not contain it). That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.
|
Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.
|
||||||
|
|
||||||
### `JSON_CI`
|
### `JSON_CI`
|
||||||
|
|
||||||
|
|||||||
@@ -15,4 +15,7 @@ Clang).
|
|||||||
|
|
||||||
You can further use file
|
You can further use file
|
||||||
[`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp)
|
[`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp)
|
||||||
for forward declarations.
|
for forward declarations, and file
|
||||||
|
[`single_include/nlohmann/json_literals.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_literals.hpp)
|
||||||
|
for the user-defined string literals if you define
|
||||||
|
[`JSON_NO_AUTOMATIC_UDLS`](../api/macros/json_no_automatic_udls.md).
|
||||||
|
|||||||
@@ -443,30 +443,6 @@ installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nl
|
|||||||
- :octicons-file-24: File issues at the [library issue tracker](https://github.com/nlohmann/json/issues)
|
- :octicons-file-24: File issues at the [library issue tracker](https://github.com/nlohmann/json/issues)
|
||||||
- :octicons-question-24: [Xcode documentation](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app)
|
- :octicons-question-24: [Xcode documentation](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app)
|
||||||
|
|
||||||
The `json` target's public headers live at `single_include/nlohmann`, so a consumer must write `#include <json.hpp>` rather than the
|
|
||||||
`#include <nlohmann/json.hpp>` form used elsewhere in this documentation. The `json` target also ships only headers, and SwiftPM/Xcode
|
|
||||||
expect every library target to produce an object file to link against; without one, linking a consumer fails with a missing `json.o`
|
|
||||||
([#4650](https://github.com/nlohmann/json/issues/4650)). The workaround is to add at least one `.cpp` file of your own to the target
|
|
||||||
that depends on `json`.
|
|
||||||
|
|
||||||
??? example
|
|
||||||
|
|
||||||
1. Create the following files:
|
|
||||||
|
|
||||||
```swift title="Package.swift"
|
|
||||||
--8<-- "integration/swift/Package.swift"
|
|
||||||
```
|
|
||||||
|
|
||||||
```cpp title="Sources/MyLibrary/example.cpp"
|
|
||||||
--8<-- "integration/swift/example.cpp"
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Build
|
|
||||||
|
|
||||||
```shell
|
|
||||||
swift build
|
|
||||||
```
|
|
||||||
|
|
||||||
## NuGet
|
## NuGet
|
||||||
|
|
||||||
!!! abstract "Summary"
|
!!! abstract "Summary"
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
// swift-tools-version: 5.9
|
|
||||||
import PackageDescription
|
|
||||||
|
|
||||||
let package = Package(
|
|
||||||
name: "MyPackage",
|
|
||||||
dependencies: [
|
|
||||||
.package(url: "https://github.com/nlohmann/json.git", from: "3.12.0")
|
|
||||||
],
|
|
||||||
targets: [
|
|
||||||
// the C++ target that uses nlohmann/json
|
|
||||||
.target(
|
|
||||||
name: "MyLibrary",
|
|
||||||
dependencies: [
|
|
||||||
.product(name: "json", package: "json")
|
|
||||||
],
|
|
||||||
// works around missing public headers in MyLibrary; not related to nlohmann/json
|
|
||||||
publicHeadersPath: "."
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// MyLibrary must contain at least one .cpp file, or SwiftPM/Xcode will
|
|
||||||
// not build a usable "json" library to link against (see nlohmann/json#4650)
|
|
||||||
#include <json.hpp>
|
|
||||||
|
|
||||||
nlohmann::json example()
|
|
||||||
{
|
|
||||||
return nlohmann::json::meta();
|
|
||||||
}
|
|
||||||
@@ -293,6 +293,7 @@ nav:
|
|||||||
- 'JSON_HAS_STATIC_RTTI': api/macros/json_has_static_rtti.md
|
- 'JSON_HAS_STATIC_RTTI': api/macros/json_has_static_rtti.md
|
||||||
- 'JSON_HAS_STD_FORMAT': api/macros/json_has_std_format.md
|
- 'JSON_HAS_STD_FORMAT': api/macros/json_has_std_format.md
|
||||||
- 'JSON_HAS_THREE_WAY_COMPARISON': api/macros/json_has_three_way_comparison.md
|
- 'JSON_HAS_THREE_WAY_COMPARISON': api/macros/json_has_three_way_comparison.md
|
||||||
|
- 'JSON_NO_AUTOMATIC_UDLS': api/macros/json_no_automatic_udls.md
|
||||||
- 'JSON_NOEXCEPTION': api/macros/json_noexception.md
|
- 'JSON_NOEXCEPTION': api/macros/json_noexception.md
|
||||||
- 'JSON_NO_IO': api/macros/json_no_io.md
|
- 'JSON_NO_IO': api/macros/json_no_io.md
|
||||||
- 'JSON_NO_THREAD_LOCAL': api/macros/json_no_thread_local.md
|
- 'JSON_NO_THREAD_LOCAL': api/macros/json_no_thread_local.md
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // uint64_t
|
||||||
|
|
||||||
|
#include <nlohmann/detail/abi_macros.hpp>
|
||||||
|
|
||||||
|
// Portable bit-level helpers for the number and string scanners. They use
|
||||||
|
// compiler builtins where available and plain C++ otherwise, so they need no
|
||||||
|
// platform headers and work regardless of byte order.
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
/// number of leading zero bits of x (x != 0)
|
||||||
|
inline int count_leading_zeros(std::uint64_t x) noexcept
|
||||||
|
{
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
return __builtin_clzll(x);
|
||||||
|
#else
|
||||||
|
int n = 0;
|
||||||
|
for (int shift = 32; shift != 0; shift >>= 1)
|
||||||
|
{
|
||||||
|
if ((x >> (64 - shift)) == 0)
|
||||||
|
{
|
||||||
|
n += shift;
|
||||||
|
x <<= shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// number of trailing zero bits of x (x != 0)
|
||||||
|
inline int count_trailing_zeros(std::uint64_t x) noexcept
|
||||||
|
{
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
return __builtin_ctzll(x);
|
||||||
|
#else
|
||||||
|
int n = 0;
|
||||||
|
for (int shift = 32; shift != 0; shift >>= 1)
|
||||||
|
{
|
||||||
|
if ((x << (64 - shift)) == 0)
|
||||||
|
{
|
||||||
|
n += shift;
|
||||||
|
x >>= shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// the 128-bit product of two 64-bit numbers
|
||||||
|
struct uint128_parts
|
||||||
|
{
|
||||||
|
std::uint64_t low;
|
||||||
|
std::uint64_t high;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline uint128_parts full_multiplication(std::uint64_t a, std::uint64_t b) noexcept
|
||||||
|
{
|
||||||
|
#if defined(__SIZEOF_INT128__)
|
||||||
|
__extension__ using uint128 = unsigned __int128;
|
||||||
|
const uint128 r = static_cast<uint128>(a) * b;
|
||||||
|
return {static_cast<std::uint64_t>(r), static_cast<std::uint64_t>(r >> 64u)};
|
||||||
|
#else
|
||||||
|
const std::uint64_t a_lo = a & 0xFFFFFFFFu;
|
||||||
|
const std::uint64_t a_hi = a >> 32u;
|
||||||
|
const std::uint64_t b_lo = b & 0xFFFFFFFFu;
|
||||||
|
const std::uint64_t b_hi = b >> 32u;
|
||||||
|
const std::uint64_t lo_lo = a_lo * b_lo;
|
||||||
|
const std::uint64_t hi_lo = a_hi * b_lo;
|
||||||
|
const std::uint64_t lo_hi = a_lo * b_hi;
|
||||||
|
const std::uint64_t hi_hi = a_hi * b_hi;
|
||||||
|
const std::uint64_t cross = (lo_lo >> 32u) + (hi_lo & 0xFFFFFFFFu) + lo_hi;
|
||||||
|
return {(cross << 32u) | (lo_lo & 0xFFFFFFFFu), (hi_lo >> 32u) + (cross >> 32u) + hi_hi};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// eight bytes as a little-endian word (compilers fold this into one load on
|
||||||
|
/// little-endian targets)
|
||||||
|
inline std::uint64_t read_eight_bytes(const unsigned char* b) noexcept
|
||||||
|
{
|
||||||
|
return static_cast<std::uint64_t>(b[0]) | (static_cast<std::uint64_t>(b[1]) << 8u)
|
||||||
|
| (static_cast<std::uint64_t>(b[2]) << 16u) | (static_cast<std::uint64_t>(b[3]) << 24u)
|
||||||
|
| (static_cast<std::uint64_t>(b[4]) << 32u) | (static_cast<std::uint64_t>(b[5]) << 40u)
|
||||||
|
| (static_cast<std::uint64_t>(b[6]) << 48u) | (static_cast<std::uint64_t>(b[7]) << 56u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// eight bytes as a little-endian word
|
||||||
|
inline std::uint64_t read_eight_bytes(const char* p) noexcept
|
||||||
|
{
|
||||||
|
return read_eight_bytes(reinterpret_cast<const unsigned char*>(p)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
@@ -167,9 +167,13 @@ template<typename BasicJsonType, typename EnumType,
|
|||||||
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
||||||
inline void from_json(const BasicJsonType& j, EnumType& e)
|
inline void from_json(const BasicJsonType& j, EnumType& e)
|
||||||
{
|
{
|
||||||
typename std::underlying_type<EnumType>::type val;
|
using underlying_type = typename std::underlying_type<EnumType>::type;
|
||||||
|
// get_arithmetic_value() does not accept boolean_t; read the number that to_json() wrote instead
|
||||||
|
using value_type = typename std::conditional<std::is_same<underlying_type, typename BasicJsonType::boolean_t>::value,
|
||||||
|
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
||||||
|
value_type val;
|
||||||
get_arithmetic_value(j, val);
|
get_arithmetic_value(j, val);
|
||||||
e = static_cast<EnumType>(val);
|
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
@@ -564,7 +568,7 @@ inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allo
|
|||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
|
JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &p));
|
||||||
}
|
}
|
||||||
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
|
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
|
||||||
}
|
}
|
||||||
@@ -584,7 +588,7 @@ inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Has
|
|||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
|
JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &p));
|
||||||
}
|
}
|
||||||
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
|
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ struct external_constructor<value_t::object>
|
|||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T,
|
||||||
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
||||||
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept
|
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(std::is_nothrow_assignable<BasicJsonType&, const T&>::value)
|
||||||
{
|
{
|
||||||
if (opt.has_value())
|
if (opt.has_value())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,7 +106,13 @@ class input_stream_adapter
|
|||||||
// was given back with release_lookahead()
|
// was given back with release_lookahead()
|
||||||
commit_lookahead();
|
commit_lookahead();
|
||||||
#endif
|
#endif
|
||||||
is->clear(is->rdstate() & std::ios::eofbit);
|
// only call clear() if there is something to clear: it throws
|
||||||
|
// std::ios_base::failure if the stream has exceptions() enabled
|
||||||
|
// for a state bit that remains set, and a destructor must not throw
|
||||||
|
if ((is->rdstate() & ~std::ios::eofbit) != 0)
|
||||||
|
{
|
||||||
|
is->clear(is->rdstate() & std::ios::eofbit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,12 +817,16 @@ inline file_input_adapter input_adapter(std::FILE* file)
|
|||||||
|
|
||||||
inline input_stream_adapter input_adapter(std::istream& stream)
|
inline input_stream_adapter input_adapter(std::istream& stream)
|
||||||
{
|
{
|
||||||
|
if (stream.rdbuf() == nullptr)
|
||||||
|
{
|
||||||
|
JSON_THROW(parse_error::create(101, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
|
||||||
|
}
|
||||||
return input_stream_adapter(stream);
|
return input_stream_adapter(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline input_stream_adapter input_adapter(std::istream&& stream)
|
inline input_stream_adapter input_adapter(std::istream&& stream)
|
||||||
{
|
{
|
||||||
return input_stream_adapter(stream);
|
return input_adapter(stream);
|
||||||
}
|
}
|
||||||
#endif // JSON_NO_IO
|
#endif // JSON_NO_IO
|
||||||
|
|
||||||
@@ -845,16 +855,28 @@ template<typename T, std::size_t N>
|
|||||||
auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||||
{
|
{
|
||||||
#if JSON_STRICT_NUL_HANDLING
|
#if JSON_STRICT_NUL_HANDLING
|
||||||
// A `char` array from string-literal initialization (e.g. json::parse("123"))
|
// A text-literal array from string-literal initialization (e.g.
|
||||||
// carries a trailing '\0' contributed by the compiler, not by the source
|
// json::parse("123") or json::parse(L"123")) carries a trailing '\0'
|
||||||
// text; drop exactly that one byte so it is not mistaken for real trailing
|
// contributed by the compiler, not by the source text; drop exactly that
|
||||||
// data. Every other element type (unsigned char, std::uint8_t, ...) keeps
|
// one byte so it is not mistaken for real trailing data. This covers all
|
||||||
// the full extent unconditionally, since a trailing zero byte there is
|
// character types that string literals can use: char, wchar_t, char16_t,
|
||||||
// genuine data (e.g. CBOR/MessagePack). This intentionally does not
|
// char32_t, and (C++20) char8_t. Every other element type (unsigned char,
|
||||||
// strlen()-scan the array (as the pointer overload above does for a
|
// std::uint8_t, ...) keeps the full extent unconditionally, since a
|
||||||
// null-delimited string): for a `char` array that is not NUL-terminated
|
// trailing zero byte there is genuine data (e.g. CBOR/MessagePack). This
|
||||||
// within its bounds, that would read past the end of the array.
|
// intentionally does not strlen()-scan the array (as the pointer overload
|
||||||
if (std::is_same<typename std::remove_cv<T>::type, char>::value && N > 0 && array[N - 1] == 0)
|
// above does for a null-delimited string): for an array that is not
|
||||||
|
// NUL-terminated within its bounds, that would read past the end of the
|
||||||
|
// array.
|
||||||
|
using char_t = typename std::remove_cv<T>::type;
|
||||||
|
constexpr bool is_text_literal_type = std::is_same<char_t, char>::value
|
||||||
|
|| std::is_same<char_t, wchar_t>::value
|
||||||
|
|| std::is_same<char_t, char16_t>::value
|
||||||
|
|| std::is_same<char_t, char32_t>::value
|
||||||
|
#if defined(__cpp_char8_t)
|
||||||
|
|| std::is_same<char_t, char8_t>::value
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
if (is_text_literal_type && N > 0 && array[N - 1] == 0)
|
||||||
{
|
{
|
||||||
return input_adapter(array, array + N - 1);
|
return input_adapter(array, array + N - 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -582,8 +582,8 @@ class json_sax_dom_callback_parser
|
|||||||
|
|
||||||
bool start_object(std::size_t len)
|
bool start_object(std::size_t len)
|
||||||
{
|
{
|
||||||
// check callback for object start
|
// check callback for object start; not called inside a discarded container
|
||||||
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
|
const bool keep = keep_stack.back() && callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
|
||||||
keep_stack.push_back(keep);
|
keep_stack.push_back(keep);
|
||||||
|
|
||||||
// the key this object will be stored under, read before handle_value()
|
// the key this object will be stored under, read before handle_value()
|
||||||
@@ -619,6 +619,18 @@ class json_sax_dom_callback_parser
|
|||||||
|
|
||||||
bool key(string_t& val)
|
bool key(string_t& val)
|
||||||
{
|
{
|
||||||
|
if (!keep_stack.back() || !ref_stack.back())
|
||||||
|
{
|
||||||
|
// the object is not stored: the value of this key is dropped in
|
||||||
|
// handle_value() without touching the key stacks
|
||||||
|
if (keep_stack.back())
|
||||||
|
{
|
||||||
|
BasicJsonType k = BasicJsonType(val);
|
||||||
|
static_cast<void>(callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
BasicJsonType k = BasicJsonType(val);
|
BasicJsonType k = BasicJsonType(val);
|
||||||
|
|
||||||
// check callback for the key
|
// check callback for the key
|
||||||
@@ -704,7 +716,7 @@ class json_sax_dom_callback_parser
|
|||||||
|
|
||||||
bool start_array(std::size_t len)
|
bool start_array(std::size_t len)
|
||||||
{
|
{
|
||||||
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
|
const bool keep = keep_stack.back() && callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
|
||||||
keep_stack.push_back(keep);
|
keep_stack.push_back(keep);
|
||||||
|
|
||||||
// see start_object()
|
// see start_object()
|
||||||
|
|||||||
@@ -9,10 +9,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <clocale> // localeconv
|
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <cstdio> // snprintf
|
#include <cstdio> // snprintf
|
||||||
#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
|
|
||||||
#include <initializer_list> // initializer_list
|
#include <initializer_list> // initializer_list
|
||||||
#include <string> // char_traits, string
|
#include <string> // char_traits, string
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
@@ -217,22 +215,48 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
~lexer() = default;
|
~lexer() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/////////////////////
|
|
||||||
// locales
|
|
||||||
/////////////////////
|
|
||||||
|
|
||||||
/// return the decimal point of the current locale
|
|
||||||
static char get_decimal_point() noexcept
|
|
||||||
{
|
|
||||||
const auto* loc = localeconv();
|
|
||||||
JSON_ASSERT(loc != nullptr);
|
|
||||||
return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// scan functions
|
// scan functions
|
||||||
/////////////////////
|
/////////////////////
|
||||||
|
|
||||||
|
/// contiguous input: try to decode the 4 hex digits following `\u`
|
||||||
|
/// directly from the input buffer via hex_codepoint(), instead of 4 calls
|
||||||
|
/// to get(). On success, advances the adapter and the position counters
|
||||||
|
/// exactly as those 4 get() calls would (a hex digit is never '\n', so
|
||||||
|
/// only the flat counters move) and leaves @a current holding the last of
|
||||||
|
/// the 4 digits, just as the last such get() would; the codepoint is
|
||||||
|
/// written to @a out. Makes no state change and returns false - for a
|
||||||
|
/// pending unget, fewer than 4 remaining bytes, or any of the 4 bytes not
|
||||||
|
/// being a hex digit - so the caller falls back unchanged to the
|
||||||
|
/// per-character loop, which then reports the same diagnostic (stopping
|
||||||
|
/// at the first invalid digit) as before this optimization.
|
||||||
|
bool get_codepoint_bulk(std::true_type /*bulk*/, int& out)
|
||||||
|
{
|
||||||
|
if (next_unget || ia.bulk_remaining() < 4)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const char_type* const raw = ia.bulk_data();
|
||||||
|
const int codepoint = hex_codepoint(reinterpret_cast<const unsigned char*>(raw));
|
||||||
|
if (codepoint < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ia.bulk_skip(4);
|
||||||
|
// a hex digit is never a newline, so only the flat counters advance
|
||||||
|
position.chars_read_total += 4;
|
||||||
|
position.chars_read_current_line += 4;
|
||||||
|
current = char_traits<char_type>::to_int_type(raw[3]);
|
||||||
|
out = codepoint;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// streaming input: no bulk fast path
|
||||||
|
bool get_codepoint_bulk(std::false_type /*bulk*/, int& /*out*/) const noexcept
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief get codepoint from 4 hex characters following `\u`
|
@brief get codepoint from 4 hex characters following `\u`
|
||||||
|
|
||||||
@@ -252,6 +276,14 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
{
|
{
|
||||||
// this function only makes sense after reading `\u`
|
// this function only makes sense after reading `\u`
|
||||||
JSON_ASSERT(current == 'u');
|
JSON_ASSERT(current == 'u');
|
||||||
|
|
||||||
|
// contiguous input: decode all 4 hex digits directly from the buffer
|
||||||
|
int fast_codepoint = 0;
|
||||||
|
if (get_codepoint_bulk(std::integral_constant<bool, bulk_scan> {}, fast_codepoint))
|
||||||
|
{
|
||||||
|
return fast_codepoint;
|
||||||
|
}
|
||||||
|
|
||||||
int codepoint = 0;
|
int codepoint = 0;
|
||||||
|
|
||||||
const auto factors = { 12u, 8u, 4u, 0u };
|
const auto factors = { 12u, 8u, 4u, 0u };
|
||||||
@@ -1036,24 +1068,6 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
|
||||||
static void strtof(float& f, const char* str, char** endptr) noexcept
|
|
||||||
{
|
|
||||||
f = std::strtof(str, endptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
|
||||||
static void strtof(double& f, const char* str, char** endptr) noexcept
|
|
||||||
{
|
|
||||||
f = std::strtod(str, endptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
|
||||||
static void strtof(long double& f, const char* str, char** endptr) noexcept
|
|
||||||
{
|
|
||||||
f = std::strtold(str, endptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief scan a number literal
|
@brief scan a number literal
|
||||||
|
|
||||||
@@ -1091,9 +1105,11 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
token_type::parse_error otherwise
|
token_type::parse_error otherwise
|
||||||
|
|
||||||
@note The scanner is independent of the current locale: token_buffer
|
@note The scanner is independent of the current locale: token_buffer
|
||||||
always holds `.`. Only the std::strtod fallback of convert_number()
|
always holds `.`. The conversion of float and double does not use
|
||||||
depends on the locale, and it looks up the decimal point right
|
the locale either. Only the std::strtold fallback of
|
||||||
before converting (see convert_float_locale_aware()).
|
convert_number() for long double formats other than binary64
|
||||||
|
depends on it, and it looks up the decimal point right before
|
||||||
|
converting (see detail::convert_float_locale_aware()).
|
||||||
*/
|
*/
|
||||||
token_type scan_number() // lgtm [cpp/use-of-goto] `goto` is used in this function to implement the number-parsing state machine described above. By design, any finite input will eventually reach the "done" state or return token_type::parse_error. In each intermediate state, 1 byte of the input is appended to the token_buffer vector, and only the already initialized variables token_buffer, number_type, and error_message are manipulated.
|
token_type scan_number() // lgtm [cpp/use-of-goto] `goto` is used in this function to implement the number-parsing state machine described above. By design, any finite input will eventually reach the "done" state or return token_type::parse_error. In each intermediate state, 1 byte of the input is appended to the token_buffer vector, and only the already initialized variables token_buffer, number_type, and error_message are manipulated.
|
||||||
{
|
{
|
||||||
@@ -1106,7 +1122,7 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
|
|
||||||
// offset just past the last mantissa byte in token_buffer (i.e. the
|
// offset just past the last mantissa byte in token_buffer (i.e. the
|
||||||
// index of 'e'/'E', or the whole token when there is no exponent).
|
// index of 'e'/'E', or the whole token when there is no exponent).
|
||||||
// convert_number() uses it to count significant digits; npos means
|
// convert_number() uses it to split the token; npos means
|
||||||
// "not seen an exponent yet" and is resolved at scan_number_done
|
// "not seen an exponent yet" and is resolved at scan_number_done
|
||||||
std::size_t mantissa_end = std::string::npos;
|
std::size_t mantissa_end = std::string::npos;
|
||||||
|
|
||||||
@@ -1424,59 +1440,6 @@ scan_number_done:
|
|||||||
return token_type::uninitialized;
|
return token_type::uninitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief check whether Clinger's fast path can still succeed for this token
|
|
||||||
|
|
||||||
parse_float_fast() needs a significand below 2^53. A mantissa with 17 or
|
|
||||||
more significant digits is at least 10^16 and therefore always exceeds it,
|
|
||||||
so calling the fast path would walk the token one extra time only to
|
|
||||||
decline before strtod has to run anyway.
|
|
||||||
|
|
||||||
Significant digits are the mantissa's digits from the first nonzero one on;
|
|
||||||
the sign, the decimal point, leading zeros, and the exponent do not count.
|
|
||||||
The answer is derived from indices - the digits are not scanned again - so
|
|
||||||
this stays off the hot path of the number scanners.
|
|
||||||
|
|
||||||
@param[in] mantissa_end offset just past the last mantissa byte in
|
|
||||||
token_buffer
|
|
||||||
@return false if parse_float_fast() is guaranteed to decline
|
|
||||||
*/
|
|
||||||
bool mantissa_fits_clinger(std::size_t mantissa_end) const
|
|
||||||
{
|
|
||||||
// 10^16 already exceeds 2^53, so 17 digits can never fit
|
|
||||||
constexpr std::size_t limit = 17;
|
|
||||||
|
|
||||||
const std::size_t neg = (!token_buffer.empty() && token_buffer[0] == '-') ? 1u : 0u;
|
|
||||||
const std::size_t has_dot = (decimal_point_position != std::string::npos) ? 1u : 0u;
|
|
||||||
// the JSON grammar restricts the integer part to "0" or [1-9][0-9]*, so
|
|
||||||
// a leading zero can only be a lone "0", which is not significant
|
|
||||||
const std::size_t lead_zero = (token_buffer[neg] == '0') ? 1u : 0u;
|
|
||||||
JSON_ASSERT(mantissa_end >= neg + has_dot + lead_zero);
|
|
||||||
std::size_t digits = mantissa_end - neg - has_dot - lead_zero;
|
|
||||||
|
|
||||||
if (JSON_HEDLEY_LIKELY(digits < limit))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only a number below 1 can carry further insignificant zeros, and only
|
|
||||||
// while the count stays at the limit does removing them change the
|
|
||||||
// answer - so this loop is skipped for all but a few tokens. The
|
|
||||||
// fraction is located through decimal_point_position rather than by
|
|
||||||
// searching '.'.
|
|
||||||
if (lead_zero != 0)
|
|
||||||
{
|
|
||||||
JSON_ASSERT(has_dot != 0); // an integer "0" cannot reach the limit
|
|
||||||
for (std::size_t i = decimal_point_position + 1;
|
|
||||||
digits >= limit && i < mantissa_end && token_buffer[i] == '0'; ++i)
|
|
||||||
{
|
|
||||||
--digits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return digits < limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief convert the number text in token_buffer to its value and token type
|
@brief convert the number text in token_buffer to its value and token type
|
||||||
|
|
||||||
@@ -1489,8 +1452,8 @@ scan_number_done:
|
|||||||
@param[in] mantissa_end offset just past the last mantissa byte in
|
@param[in] mantissa_end offset just past the last mantissa byte in
|
||||||
token_buffer (the index of 'e'/'E', or
|
token_buffer (the index of 'e'/'E', or
|
||||||
token_buffer.size() when there is no exponent);
|
token_buffer.size() when there is no exponent);
|
||||||
used to skip Clinger's fast path when it cannot
|
with decimal_point_position, it locates the parts
|
||||||
possibly succeed - see mantissa_fits_clinger()
|
of a float token without scanning it again
|
||||||
*/
|
*/
|
||||||
token_type convert_number(token_type number_type, std::size_t mantissa_end)
|
token_type convert_number(token_type number_type, std::size_t mantissa_end)
|
||||||
{
|
{
|
||||||
@@ -1559,81 +1522,20 @@ scan_number_done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this code is reached if we parse a floating-point number or if an
|
// this code is reached if we parse a floating-point number or if an
|
||||||
// integer conversion above overflowed. Prefer std::from_chars
|
// integer conversion above overflowed. float and double (and long
|
||||||
// (Eisel-Lemire, locale-independent, correctly rounded) when available;
|
// double where it is binary64) are converted by the library itself,
|
||||||
// otherwise the exact Clinger fast path (double only); otherwise the
|
// correctly rounded and independent of the locale; other long double
|
||||||
// locale-aware strtof/strtod/strtold.
|
// formats use std::from_chars when available, otherwise the
|
||||||
if (parse_float_from_chars(num_begin, num_end, value_float))
|
// locale-aware strtold.
|
||||||
{
|
if (convert_float_fast(num_begin, num_end, decimal_point_position, mantissa_end, value_float))
|
||||||
return token_type::value_float;
|
|
||||||
}
|
|
||||||
// Skipping a fast path that cannot succeed is lossless and saves a full
|
|
||||||
// extra pass over the token's bytes, which otherwise shows up on
|
|
||||||
// high-precision inputs such as canada.json
|
|
||||||
if (mantissa_fits_clinger(mantissa_end)
|
|
||||||
&& parse_float_fast(num_begin, num_end, value_float))
|
|
||||||
{
|
{
|
||||||
return token_type::value_float;
|
return token_type::value_float;
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_float_locale_aware();
|
convert_float_locale_aware(token_buffer, decimal_point_position, value_float);
|
||||||
return token_type::value_float;
|
return token_type::value_float;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief convert the float in token_buffer with strtof/strtod/strtold
|
|
||||||
|
|
||||||
These functions expect the decimal point of the *current* locale, so it is
|
|
||||||
looked up right before the conversion instead of once when the lexer is
|
|
||||||
constructed: a locale change in between (by a parser callback, a SAX
|
|
||||||
handler, or another thread) must not truncate the value (#5198). The
|
|
||||||
token has been validated before, so if the conversion stops early and the
|
|
||||||
decimal point changed in the meantime, the locale changed between the
|
|
||||||
lookup and the call, and the conversion is repeated with the new decimal
|
|
||||||
point. If the decimal point did not change, a retry cannot succeed: the
|
|
||||||
locale's decimal point is not a single character (e.g., the two-byte
|
|
||||||
U+066B of ar_EG.UTF-8 or fa_IR.UTF-8) and cannot be substituted in place.
|
|
||||||
The value strtod parsed up to that point is kept, as before this change.
|
|
||||||
|
|
||||||
Note that changing the locale in another thread *while* strtod runs is
|
|
||||||
undefined behavior of the C library, which this function cannot prevent.
|
|
||||||
*/
|
|
||||||
void convert_float_locale_aware()
|
|
||||||
{
|
|
||||||
const bool has_dot = decimal_point_position != std::string::npos;
|
|
||||||
char decimal_point = get_decimal_point();
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
const bool substitute = has_dot && decimal_point != '.';
|
|
||||||
if (substitute)
|
|
||||||
{
|
|
||||||
token_buffer[decimal_point_position] = static_cast<typename string_t::value_type>(decimal_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* endptr = nullptr; // NOLINT(misc-const-correctness,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
|
||||||
strtof(value_float, token_buffer.data(), &endptr);
|
|
||||||
|
|
||||||
if (substitute)
|
|
||||||
{
|
|
||||||
// get_string() hands the token to the SAX interface with '.'
|
|
||||||
token_buffer[decimal_point_position] = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON_HEDLEY_LIKELY(endptr == token_buffer.data() + token_buffer.size()))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// retry only if the locale changed; otherwise, this would loop forever
|
|
||||||
const char current_decimal_point = get_decimal_point();
|
|
||||||
if (current_decimal_point == decimal_point)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
decimal_point = current_decimal_point;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief contiguous fast path for scanning a number
|
@brief contiguous fast path for scanning a number
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,371 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2021 The fast_float authors <https://github.com/fastfloat/fast_float>
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array> // array
|
||||||
|
#include <cstdint> // int64_t, uint64_t
|
||||||
|
|
||||||
|
#include <nlohmann/detail/abi_macros.hpp>
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
/// the range of decimal exponents covered by pow5_128()
|
||||||
|
constexpr std::int64_t pow5_128_smallest_power = -342;
|
||||||
|
constexpr std::int64_t pow5_128_largest_power = 308;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief 128-bit approximations of 5^q for q in [-342, 308]
|
||||||
|
|
||||||
|
Entry q (at index 2 * (q + 342)) holds the most significant 128 bits of 5^q,
|
||||||
|
normalized so that the highest bit is set: for q >= 0 the truncated value, for
|
||||||
|
q < 0 the value rounded up. This is the table of fast_float (Daniel Lemire and
|
||||||
|
contributors, used under the MIT license), generated like its
|
||||||
|
script/table_generation.py; unit-class_lexer.cpp recomputes every entry.
|
||||||
|
*/
|
||||||
|
inline const std::array<std::uint64_t, 1302>& pow5_128() noexcept
|
||||||
|
{
|
||||||
|
static const std::array<std::uint64_t, 1302> table =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0xeef453d6923bd65au, 0x113faa2906a13b3fu, 0x9558b4661b6565f8u, 0x4ac7ca59a424c507u,
|
||||||
|
0xbaaee17fa23ebf76u, 0x5d79bcf00d2df649u, 0xe95a99df8ace6f53u, 0xf4d82c2c107973dcu,
|
||||||
|
0x91d8a02bb6c10594u, 0x79071b9b8a4be869u, 0xb64ec836a47146f9u, 0x9748e2826cdee284u,
|
||||||
|
0xe3e27a444d8d98b7u, 0xfd1b1b2308169b25u, 0x8e6d8c6ab0787f72u, 0xfe30f0f5e50e20f7u,
|
||||||
|
0xb208ef855c969f4fu, 0xbdbd2d335e51a935u, 0xde8b2b66b3bc4723u, 0xad2c788035e61382u,
|
||||||
|
0x8b16fb203055ac76u, 0x4c3bcb5021afcc31u, 0xaddcb9e83c6b1793u, 0xdf4abe242a1bbf3du,
|
||||||
|
0xd953e8624b85dd78u, 0xd71d6dad34a2af0du, 0x87d4713d6f33aa6bu, 0x8672648c40e5ad68u,
|
||||||
|
0xa9c98d8ccb009506u, 0x680efdaf511f18c2u, 0xd43bf0effdc0ba48u, 0x0212bd1b2566def2u,
|
||||||
|
0x84a57695fe98746du, 0x014bb630f7604b57u, 0xa5ced43b7e3e9188u, 0x419ea3bd35385e2du,
|
||||||
|
0xcf42894a5dce35eau, 0x52064cac828675b9u, 0x818995ce7aa0e1b2u, 0x7343efebd1940993u,
|
||||||
|
0xa1ebfb4219491a1fu, 0x1014ebe6c5f90bf8u, 0xca66fa129f9b60a6u, 0xd41a26e077774ef6u,
|
||||||
|
0xfd00b897478238d0u, 0x8920b098955522b4u, 0x9e20735e8cb16382u, 0x55b46e5f5d5535b0u,
|
||||||
|
0xc5a890362fddbc62u, 0xeb2189f734aa831du, 0xf712b443bbd52b7bu, 0xa5e9ec7501d523e4u,
|
||||||
|
0x9a6bb0aa55653b2du, 0x47b233c92125366eu, 0xc1069cd4eabe89f8u, 0x999ec0bb696e840au,
|
||||||
|
0xf148440a256e2c76u, 0xc00670ea43ca250du, 0x96cd2a865764dbcau, 0x380406926a5e5728u,
|
||||||
|
0xbc807527ed3e12bcu, 0xc605083704f5ecf2u, 0xeba09271e88d976bu, 0xf7864a44c633682eu,
|
||||||
|
0x93445b8731587ea3u, 0x7ab3ee6afbe0211du, 0xb8157268fdae9e4cu, 0x5960ea05bad82964u,
|
||||||
|
0xe61acf033d1a45dfu, 0x6fb92487298e33bdu, 0x8fd0c16206306babu, 0xa5d3b6d479f8e056u,
|
||||||
|
0xb3c4f1ba87bc8696u, 0x8f48a4899877186cu, 0xe0b62e2929aba83cu, 0x331acdabfe94de87u,
|
||||||
|
0x8c71dcd9ba0b4925u, 0x9ff0c08b7f1d0b14u, 0xaf8e5410288e1b6fu, 0x07ecf0ae5ee44dd9u,
|
||||||
|
0xdb71e91432b1a24au, 0xc9e82cd9f69d6150u, 0x892731ac9faf056eu, 0xbe311c083a225cd2u,
|
||||||
|
0xab70fe17c79ac6cau, 0x6dbd630a48aaf406u, 0xd64d3d9db981787du, 0x092cbbccdad5b108u,
|
||||||
|
0x85f0468293f0eb4eu, 0x25bbf56008c58ea5u, 0xa76c582338ed2621u, 0xaf2af2b80af6f24eu,
|
||||||
|
0xd1476e2c07286faau, 0x1af5af660db4aee1u, 0x82cca4db847945cau, 0x50d98d9fc890ed4du,
|
||||||
|
0xa37fce126597973cu, 0xe50ff107bab528a0u, 0xcc5fc196fefd7d0cu, 0x1e53ed49a96272c8u,
|
||||||
|
0xff77b1fcbebcdc4fu, 0x25e8e89c13bb0f7au, 0x9faacf3df73609b1u, 0x77b191618c54e9acu,
|
||||||
|
0xc795830d75038c1du, 0xd59df5b9ef6a2417u, 0xf97ae3d0d2446f25u, 0x4b0573286b44ad1du,
|
||||||
|
0x9becce62836ac577u, 0x4ee367f9430aec32u, 0xc2e801fb244576d5u, 0x229c41f793cda73fu,
|
||||||
|
0xf3a20279ed56d48au, 0x6b43527578c1110fu, 0x9845418c345644d6u, 0x830a13896b78aaa9u,
|
||||||
|
0xbe5691ef416bd60cu, 0x23cc986bc656d553u, 0xedec366b11c6cb8fu, 0x2cbfbe86b7ec8aa8u,
|
||||||
|
0x94b3a202eb1c3f39u, 0x7bf7d71432f3d6a9u, 0xb9e08a83a5e34f07u, 0xdaf5ccd93fb0cc53u,
|
||||||
|
0xe858ad248f5c22c9u, 0xd1b3400f8f9cff68u, 0x91376c36d99995beu, 0x23100809b9c21fa1u,
|
||||||
|
0xb58547448ffffb2du, 0xabd40a0c2832a78au, 0xe2e69915b3fff9f9u, 0x16c90c8f323f516cu,
|
||||||
|
0x8dd01fad907ffc3bu, 0xae3da7d97f6792e3u, 0xb1442798f49ffb4au, 0x99cd11cfdf41779cu,
|
||||||
|
0xdd95317f31c7fa1du, 0x40405643d711d583u, 0x8a7d3eef7f1cfc52u, 0x482835ea666b2572u,
|
||||||
|
0xad1c8eab5ee43b66u, 0xda3243650005eecfu, 0xd863b256369d4a40u, 0x90bed43e40076a82u,
|
||||||
|
0x873e4f75e2224e68u, 0x5a7744a6e804a291u, 0xa90de3535aaae202u, 0x711515d0a205cb36u,
|
||||||
|
0xd3515c2831559a83u, 0x0d5a5b44ca873e03u, 0x8412d9991ed58091u, 0xe858790afe9486c2u,
|
||||||
|
0xa5178fff668ae0b6u, 0x626e974dbe39a872u, 0xce5d73ff402d98e3u, 0xfb0a3d212dc8128fu,
|
||||||
|
0x80fa687f881c7f8eu, 0x7ce66634bc9d0b99u, 0xa139029f6a239f72u, 0x1c1fffc1ebc44e80u,
|
||||||
|
0xc987434744ac874eu, 0xa327ffb266b56220u, 0xfbe9141915d7a922u, 0x4bf1ff9f0062baa8u,
|
||||||
|
0x9d71ac8fada6c9b5u, 0x6f773fc3603db4a9u, 0xc4ce17b399107c22u, 0xcb550fb4384d21d3u,
|
||||||
|
0xf6019da07f549b2bu, 0x7e2a53a146606a48u, 0x99c102844f94e0fbu, 0x2eda7444cbfc426du,
|
||||||
|
0xc0314325637a1939u, 0xfa911155fefb5308u, 0xf03d93eebc589f88u, 0x793555ab7eba27cau,
|
||||||
|
0x96267c7535b763b5u, 0x4bc1558b2f3458deu, 0xbbb01b9283253ca2u, 0x9eb1aaedfb016f16u,
|
||||||
|
0xea9c227723ee8bcbu, 0x465e15a979c1cadcu, 0x92a1958a7675175fu, 0x0bfacd89ec191ec9u,
|
||||||
|
0xb749faed14125d36u, 0xcef980ec671f667bu, 0xe51c79a85916f484u, 0x82b7e12780e7401au,
|
||||||
|
0x8f31cc0937ae58d2u, 0xd1b2ecb8b0908810u, 0xb2fe3f0b8599ef07u, 0x861fa7e6dcb4aa15u,
|
||||||
|
0xdfbdcece67006ac9u, 0x67a791e093e1d49au, 0x8bd6a141006042bdu, 0xe0c8bb2c5c6d24e0u,
|
||||||
|
0xaecc49914078536du, 0x58fae9f773886e18u, 0xda7f5bf590966848u, 0xaf39a475506a899eu,
|
||||||
|
0x888f99797a5e012du, 0x6d8406c952429603u, 0xaab37fd7d8f58178u, 0xc8e5087ba6d33b83u,
|
||||||
|
0xd5605fcdcf32e1d6u, 0xfb1e4a9a90880a64u, 0x855c3be0a17fcd26u, 0x5cf2eea09a55067fu,
|
||||||
|
0xa6b34ad8c9dfc06fu, 0xf42faa48c0ea481eu, 0xd0601d8efc57b08bu, 0xf13b94daf124da26u,
|
||||||
|
0x823c12795db6ce57u, 0x76c53d08d6b70858u, 0xa2cb1717b52481edu, 0x54768c4b0c64ca6eu,
|
||||||
|
0xcb7ddcdda26da268u, 0xa9942f5dcf7dfd09u, 0xfe5d54150b090b02u, 0xd3f93b35435d7c4cu,
|
||||||
|
0x9efa548d26e5a6e1u, 0xc47bc5014a1a6dafu, 0xc6b8e9b0709f109au, 0x359ab6419ca1091bu,
|
||||||
|
0xf867241c8cc6d4c0u, 0xc30163d203c94b62u, 0x9b407691d7fc44f8u, 0x79e0de63425dcf1du,
|
||||||
|
0xc21094364dfb5636u, 0x985915fc12f542e4u, 0xf294b943e17a2bc4u, 0x3e6f5b7b17b2939du,
|
||||||
|
0x979cf3ca6cec5b5au, 0xa705992ceecf9c42u, 0xbd8430bd08277231u, 0x50c6ff782a838353u,
|
||||||
|
0xece53cec4a314ebdu, 0xa4f8bf5635246428u, 0x940f4613ae5ed136u, 0x871b7795e136be99u,
|
||||||
|
0xb913179899f68584u, 0x28e2557b59846e3fu, 0xe757dd7ec07426e5u, 0x331aeada2fe589cfu,
|
||||||
|
0x9096ea6f3848984fu, 0x3ff0d2c85def7621u, 0xb4bca50b065abe63u, 0x0fed077a756b53a9u,
|
||||||
|
0xe1ebce4dc7f16dfbu, 0xd3e8495912c62894u, 0x8d3360f09cf6e4bdu, 0x64712dd7abbbd95cu,
|
||||||
|
0xb080392cc4349decu, 0xbd8d794d96aacfb3u, 0xdca04777f541c567u, 0xecf0d7a0fc5583a0u,
|
||||||
|
0x89e42caaf9491b60u, 0xf41686c49db57244u, 0xac5d37d5b79b6239u, 0x311c2875c522ced5u,
|
||||||
|
0xd77485cb25823ac7u, 0x7d633293366b828bu, 0x86a8d39ef77164bcu, 0xae5dff9c02033197u,
|
||||||
|
0xa8530886b54dbdebu, 0xd9f57f830283fdfcu, 0xd267caa862a12d66u, 0xd072df63c324fd7bu,
|
||||||
|
0x8380dea93da4bc60u, 0x4247cb9e59f71e6du, 0xa46116538d0deb78u, 0x52d9be85f074e608u,
|
||||||
|
0xcd795be870516656u, 0x67902e276c921f8bu, 0x806bd9714632dff6u, 0x00ba1cd8a3db53b6u,
|
||||||
|
0xa086cfcd97bf97f3u, 0x80e8a40eccd228a4u, 0xc8a883c0fdaf7df0u, 0x6122cd128006b2cdu,
|
||||||
|
0xfad2a4b13d1b5d6cu, 0x796b805720085f81u, 0x9cc3a6eec6311a63u, 0xcbe3303674053bb0u,
|
||||||
|
0xc3f490aa77bd60fcu, 0xbedbfc4411068a9cu, 0xf4f1b4d515acb93bu, 0xee92fb5515482d44u,
|
||||||
|
0x991711052d8bf3c5u, 0x751bdd152d4d1c4au, 0xbf5cd54678eef0b6u, 0xd262d45a78a0635du,
|
||||||
|
0xef340a98172aace4u, 0x86fb897116c87c34u, 0x9580869f0e7aac0eu, 0xd45d35e6ae3d4da0u,
|
||||||
|
0xbae0a846d2195712u, 0x8974836059cca109u, 0xe998d258869facd7u, 0x2bd1a438703fc94bu,
|
||||||
|
0x91ff83775423cc06u, 0x7b6306a34627ddcfu, 0xb67f6455292cbf08u, 0x1a3bc84c17b1d542u,
|
||||||
|
0xe41f3d6a7377eecau, 0x20caba5f1d9e4a93u, 0x8e938662882af53eu, 0x547eb47b7282ee9cu,
|
||||||
|
0xb23867fb2a35b28du, 0xe99e619a4f23aa43u, 0xdec681f9f4c31f31u, 0x6405fa00e2ec94d4u,
|
||||||
|
0x8b3c113c38f9f37eu, 0xde83bc408dd3dd04u, 0xae0b158b4738705eu, 0x9624ab50b148d445u,
|
||||||
|
0xd98ddaee19068c76u, 0x3badd624dd9b0957u, 0x87f8a8d4cfa417c9u, 0xe54ca5d70a80e5d6u,
|
||||||
|
0xa9f6d30a038d1dbcu, 0x5e9fcf4ccd211f4cu, 0xd47487cc8470652bu, 0x7647c3200069671fu,
|
||||||
|
0x84c8d4dfd2c63f3bu, 0x29ecd9f40041e073u, 0xa5fb0a17c777cf09u, 0xf468107100525890u,
|
||||||
|
0xcf79cc9db955c2ccu, 0x7182148d4066eeb4u, 0x81ac1fe293d599bfu, 0xc6f14cd848405530u,
|
||||||
|
0xa21727db38cb002fu, 0xb8ada00e5a506a7cu, 0xca9cf1d206fdc03bu, 0xa6d90811f0e4851cu,
|
||||||
|
0xfd442e4688bd304au, 0x908f4a166d1da663u, 0x9e4a9cec15763e2eu, 0x9a598e4e043287feu,
|
||||||
|
0xc5dd44271ad3cdbau, 0x40eff1e1853f29fdu, 0xf7549530e188c128u, 0xd12bee59e68ef47cu,
|
||||||
|
0x9a94dd3e8cf578b9u, 0x82bb74f8301958ceu, 0xc13a148e3032d6e7u, 0xe36a52363c1faf01u,
|
||||||
|
0xf18899b1bc3f8ca1u, 0xdc44e6c3cb279ac1u, 0x96f5600f15a7b7e5u, 0x29ab103a5ef8c0b9u,
|
||||||
|
0xbcb2b812db11a5deu, 0x7415d448f6b6f0e7u, 0xebdf661791d60f56u, 0x111b495b3464ad21u,
|
||||||
|
0x936b9fcebb25c995u, 0xcab10dd900beec34u, 0xb84687c269ef3bfbu, 0x3d5d514f40eea742u,
|
||||||
|
0xe65829b3046b0afau, 0x0cb4a5a3112a5112u, 0x8ff71a0fe2c2e6dcu, 0x47f0e785eaba72abu,
|
||||||
|
0xb3f4e093db73a093u, 0x59ed216765690f56u, 0xe0f218b8d25088b8u, 0x306869c13ec3532cu,
|
||||||
|
0x8c974f7383725573u, 0x1e414218c73a13fbu, 0xafbd2350644eeacfu, 0xe5d1929ef90898fau,
|
||||||
|
0xdbac6c247d62a583u, 0xdf45f746b74abf39u, 0x894bc396ce5da772u, 0x6b8bba8c328eb783u,
|
||||||
|
0xab9eb47c81f5114fu, 0x066ea92f3f326564u, 0xd686619ba27255a2u, 0xc80a537b0efefebdu,
|
||||||
|
0x8613fd0145877585u, 0xbd06742ce95f5f36u, 0xa798fc4196e952e7u, 0x2c48113823b73704u,
|
||||||
|
0xd17f3b51fca3a7a0u, 0xf75a15862ca504c5u, 0x82ef85133de648c4u, 0x9a984d73dbe722fbu,
|
||||||
|
0xa3ab66580d5fdaf5u, 0xc13e60d0d2e0ebbau, 0xcc963fee10b7d1b3u, 0x318df905079926a8u,
|
||||||
|
0xffbbcfe994e5c61fu, 0xfdf17746497f7052u, 0x9fd561f1fd0f9bd3u, 0xfeb6ea8bedefa633u,
|
||||||
|
0xc7caba6e7c5382c8u, 0xfe64a52ee96b8fc0u, 0xf9bd690a1b68637bu, 0x3dfdce7aa3c673b0u,
|
||||||
|
0x9c1661a651213e2du, 0x06bea10ca65c084eu, 0xc31bfa0fe5698db8u, 0x486e494fcff30a62u,
|
||||||
|
0xf3e2f893dec3f126u, 0x5a89dba3c3efccfau, 0x986ddb5c6b3a76b7u, 0xf89629465a75e01cu,
|
||||||
|
0xbe89523386091465u, 0xf6bbb397f1135823u, 0xee2ba6c0678b597fu, 0x746aa07ded582e2cu,
|
||||||
|
0x94db483840b717efu, 0xa8c2a44eb4571cdcu, 0xba121a4650e4ddebu, 0x92f34d62616ce413u,
|
||||||
|
0xe896a0d7e51e1566u, 0x77b020baf9c81d17u, 0x915e2486ef32cd60u, 0x0ace1474dc1d122eu,
|
||||||
|
0xb5b5ada8aaff80b8u, 0x0d819992132456bau, 0xe3231912d5bf60e6u, 0x10e1fff697ed6c69u,
|
||||||
|
0x8df5efabc5979c8fu, 0xca8d3ffa1ef463c1u, 0xb1736b96b6fd83b3u, 0xbd308ff8a6b17cb2u,
|
||||||
|
0xddd0467c64bce4a0u, 0xac7cb3f6d05ddbdeu, 0x8aa22c0dbef60ee4u, 0x6bcdf07a423aa96bu,
|
||||||
|
0xad4ab7112eb3929du, 0x86c16c98d2c953c6u, 0xd89d64d57a607744u, 0xe871c7bf077ba8b7u,
|
||||||
|
0x87625f056c7c4a8bu, 0x11471cd764ad4972u, 0xa93af6c6c79b5d2du, 0xd598e40d3dd89bcfu,
|
||||||
|
0xd389b47879823479u, 0x4aff1d108d4ec2c3u, 0x843610cb4bf160cbu, 0xcedf722a585139bau,
|
||||||
|
0xa54394fe1eedb8feu, 0xc2974eb4ee658828u, 0xce947a3da6a9273eu, 0x733d226229feea32u,
|
||||||
|
0x811ccc668829b887u, 0x0806357d5a3f525fu, 0xa163ff802a3426a8u, 0xca07c2dcb0cf26f7u,
|
||||||
|
0xc9bcff6034c13052u, 0xfc89b393dd02f0b5u, 0xfc2c3f3841f17c67u, 0xbbac2078d443ace2u,
|
||||||
|
0x9d9ba7832936edc0u, 0xd54b944b84aa4c0du, 0xc5029163f384a931u, 0x0a9e795e65d4df11u,
|
||||||
|
0xf64335bcf065d37du, 0x4d4617b5ff4a16d5u, 0x99ea0196163fa42eu, 0x504bced1bf8e4e45u,
|
||||||
|
0xc06481fb9bcf8d39u, 0xe45ec2862f71e1d6u, 0xf07da27a82c37088u, 0x5d767327bb4e5a4cu,
|
||||||
|
0x964e858c91ba2655u, 0x3a6a07f8d510f86fu, 0xbbe226efb628afeau, 0x890489f70a55368bu,
|
||||||
|
0xeadab0aba3b2dbe5u, 0x2b45ac74ccea842eu, 0x92c8ae6b464fc96fu, 0x3b0b8bc90012929du,
|
||||||
|
0xb77ada0617e3bbcbu, 0x09ce6ebb40173744u, 0xe55990879ddcaabdu, 0xcc420a6a101d0515u,
|
||||||
|
0x8f57fa54c2a9eab6u, 0x9fa946824a12232du, 0xb32df8e9f3546564u, 0x47939822dc96abf9u,
|
||||||
|
0xdff9772470297ebdu, 0x59787e2b93bc56f7u, 0x8bfbea76c619ef36u, 0x57eb4edb3c55b65au,
|
||||||
|
0xaefae51477a06b03u, 0xede622920b6b23f1u, 0xdab99e59958885c4u, 0xe95fab368e45ecedu,
|
||||||
|
0x88b402f7fd75539bu, 0x11dbcb0218ebb414u, 0xaae103b5fcd2a881u, 0xd652bdc29f26a119u,
|
||||||
|
0xd59944a37c0752a2u, 0x4be76d3346f0495fu, 0x857fcae62d8493a5u, 0x6f70a4400c562ddbu,
|
||||||
|
0xa6dfbd9fb8e5b88eu, 0xcb4ccd500f6bb952u, 0xd097ad07a71f26b2u, 0x7e2000a41346a7a7u,
|
||||||
|
0x825ecc24c873782fu, 0x8ed400668c0c28c8u, 0xa2f67f2dfa90563bu, 0x728900802f0f32fau,
|
||||||
|
0xcbb41ef979346bcau, 0x4f2b40a03ad2ffb9u, 0xfea126b7d78186bcu, 0xe2f610c84987bfa8u,
|
||||||
|
0x9f24b832e6b0f436u, 0x0dd9ca7d2df4d7c9u, 0xc6ede63fa05d3143u, 0x91503d1c79720dbbu,
|
||||||
|
0xf8a95fcf88747d94u, 0x75a44c6397ce912au, 0x9b69dbe1b548ce7cu, 0xc986afbe3ee11abau,
|
||||||
|
0xc24452da229b021bu, 0xfbe85badce996168u, 0xf2d56790ab41c2a2u, 0xfae27299423fb9c3u,
|
||||||
|
0x97c560ba6b0919a5u, 0xdccd879fc967d41au, 0xbdb6b8e905cb600fu, 0x5400e987bbc1c920u,
|
||||||
|
0xed246723473e3813u, 0x290123e9aab23b68u, 0x9436c0760c86e30bu, 0xf9a0b6720aaf6521u,
|
||||||
|
0xb94470938fa89bceu, 0xf808e40e8d5b3e69u, 0xe7958cb87392c2c2u, 0xb60b1d1230b20e04u,
|
||||||
|
0x90bd77f3483bb9b9u, 0xb1c6f22b5e6f48c2u, 0xb4ecd5f01a4aa828u, 0x1e38aeb6360b1af3u,
|
||||||
|
0xe2280b6c20dd5232u, 0x25c6da63c38de1b0u, 0x8d590723948a535fu, 0x579c487e5a38ad0eu,
|
||||||
|
0xb0af48ec79ace837u, 0x2d835a9df0c6d851u, 0xdcdb1b2798182244u, 0xf8e431456cf88e65u,
|
||||||
|
0x8a08f0f8bf0f156bu, 0x1b8e9ecb641b58ffu, 0xac8b2d36eed2dac5u, 0xe272467e3d222f3fu,
|
||||||
|
0xd7adf884aa879177u, 0x5b0ed81dcc6abb0fu, 0x86ccbb52ea94baeau, 0x98e947129fc2b4e9u,
|
||||||
|
0xa87fea27a539e9a5u, 0x3f2398d747b36224u, 0xd29fe4b18e88640eu, 0x8eec7f0d19a03aadu,
|
||||||
|
0x83a3eeeef9153e89u, 0x1953cf68300424acu, 0xa48ceaaab75a8e2bu, 0x5fa8c3423c052dd7u,
|
||||||
|
0xcdb02555653131b6u, 0x3792f412cb06794du, 0x808e17555f3ebf11u, 0xe2bbd88bbee40bd0u,
|
||||||
|
0xa0b19d2ab70e6ed6u, 0x5b6aceaeae9d0ec4u, 0xc8de047564d20a8bu, 0xf245825a5a445275u,
|
||||||
|
0xfb158592be068d2eu, 0xeed6e2f0f0d56712u, 0x9ced737bb6c4183du, 0x55464dd69685606bu,
|
||||||
|
0xc428d05aa4751e4cu, 0xaa97e14c3c26b886u, 0xf53304714d9265dfu, 0xd53dd99f4b3066a8u,
|
||||||
|
0x993fe2c6d07b7fabu, 0xe546a8038efe4029u, 0xbf8fdb78849a5f96u, 0xde98520472bdd033u,
|
||||||
|
0xef73d256a5c0f77cu, 0x963e66858f6d4440u, 0x95a8637627989aadu, 0xdde7001379a44aa8u,
|
||||||
|
0xbb127c53b17ec159u, 0x5560c018580d5d52u, 0xe9d71b689dde71afu, 0xaab8f01e6e10b4a6u,
|
||||||
|
0x9226712162ab070du, 0xcab3961304ca70e8u, 0xb6b00d69bb55c8d1u, 0x3d607b97c5fd0d22u,
|
||||||
|
0xe45c10c42a2b3b05u, 0x8cb89a7db77c506au, 0x8eb98a7a9a5b04e3u, 0x77f3608e92adb242u,
|
||||||
|
0xb267ed1940f1c61cu, 0x55f038b237591ed3u, 0xdf01e85f912e37a3u, 0x6b6c46dec52f6688u,
|
||||||
|
0x8b61313bbabce2c6u, 0x2323ac4b3b3da015u, 0xae397d8aa96c1b77u, 0xabec975e0a0d081au,
|
||||||
|
0xd9c7dced53c72255u, 0x96e7bd358c904a21u, 0x881cea14545c7575u, 0x7e50d64177da2e54u,
|
||||||
|
0xaa242499697392d2u, 0xdde50bd1d5d0b9e9u, 0xd4ad2dbfc3d07787u, 0x955e4ec64b44e864u,
|
||||||
|
0x84ec3c97da624ab4u, 0xbd5af13bef0b113eu, 0xa6274bbdd0fadd61u, 0xecb1ad8aeacdd58eu,
|
||||||
|
0xcfb11ead453994bau, 0x67de18eda5814af2u, 0x81ceb32c4b43fcf4u, 0x80eacf948770ced7u,
|
||||||
|
0xa2425ff75e14fc31u, 0xa1258379a94d028du, 0xcad2f7f5359a3b3eu, 0x096ee45813a04330u,
|
||||||
|
0xfd87b5f28300ca0du, 0x8bca9d6e188853fcu, 0x9e74d1b791e07e48u, 0x775ea264cf55347eu,
|
||||||
|
0xc612062576589ddau, 0x95364afe032a819eu, 0xf79687aed3eec551u, 0x3a83ddbd83f52205u,
|
||||||
|
0x9abe14cd44753b52u, 0xc4926a9672793543u, 0xc16d9a0095928a27u, 0x75b7053c0f178294u,
|
||||||
|
0xf1c90080baf72cb1u, 0x5324c68b12dd6339u, 0x971da05074da7beeu, 0xd3f6fc16ebca5e04u,
|
||||||
|
0xbce5086492111aeau, 0x88f4bb1ca6bcf585u, 0xec1e4a7db69561a5u, 0x2b31e9e3d06c32e6u,
|
||||||
|
0x9392ee8e921d5d07u, 0x3aff322e62439fd0u, 0xb877aa3236a4b449u, 0x09befeb9fad487c3u,
|
||||||
|
0xe69594bec44de15bu, 0x4c2ebe687989a9b4u, 0x901d7cf73ab0acd9u, 0x0f9d37014bf60a11u,
|
||||||
|
0xb424dc35095cd80fu, 0x538484c19ef38c95u, 0xe12e13424bb40e13u, 0x2865a5f206b06fbau,
|
||||||
|
0x8cbccc096f5088cbu, 0xf93f87b7442e45d4u, 0xafebff0bcb24aafeu, 0xf78f69a51539d749u,
|
||||||
|
0xdbe6fecebdedd5beu, 0xb573440e5a884d1cu, 0x89705f4136b4a597u, 0x31680a88f8953031u,
|
||||||
|
0xabcc77118461cefcu, 0xfdc20d2b36ba7c3eu, 0xd6bf94d5e57a42bcu, 0x3d32907604691b4du,
|
||||||
|
0x8637bd05af6c69b5u, 0xa63f9a49c2c1b110u, 0xa7c5ac471b478423u, 0x0fcf80dc33721d54u,
|
||||||
|
0xd1b71758e219652bu, 0xd3c36113404ea4a9u, 0x83126e978d4fdf3bu, 0x645a1cac083126eau,
|
||||||
|
0xa3d70a3d70a3d70au, 0x3d70a3d70a3d70a4u, 0xccccccccccccccccu, 0xcccccccccccccccdu,
|
||||||
|
0x8000000000000000u, 0x0000000000000000u, 0xa000000000000000u, 0x0000000000000000u,
|
||||||
|
0xc800000000000000u, 0x0000000000000000u, 0xfa00000000000000u, 0x0000000000000000u,
|
||||||
|
0x9c40000000000000u, 0x0000000000000000u, 0xc350000000000000u, 0x0000000000000000u,
|
||||||
|
0xf424000000000000u, 0x0000000000000000u, 0x9896800000000000u, 0x0000000000000000u,
|
||||||
|
0xbebc200000000000u, 0x0000000000000000u, 0xee6b280000000000u, 0x0000000000000000u,
|
||||||
|
0x9502f90000000000u, 0x0000000000000000u, 0xba43b74000000000u, 0x0000000000000000u,
|
||||||
|
0xe8d4a51000000000u, 0x0000000000000000u, 0x9184e72a00000000u, 0x0000000000000000u,
|
||||||
|
0xb5e620f480000000u, 0x0000000000000000u, 0xe35fa931a0000000u, 0x0000000000000000u,
|
||||||
|
0x8e1bc9bf04000000u, 0x0000000000000000u, 0xb1a2bc2ec5000000u, 0x0000000000000000u,
|
||||||
|
0xde0b6b3a76400000u, 0x0000000000000000u, 0x8ac7230489e80000u, 0x0000000000000000u,
|
||||||
|
0xad78ebc5ac620000u, 0x0000000000000000u, 0xd8d726b7177a8000u, 0x0000000000000000u,
|
||||||
|
0x878678326eac9000u, 0x0000000000000000u, 0xa968163f0a57b400u, 0x0000000000000000u,
|
||||||
|
0xd3c21bcecceda100u, 0x0000000000000000u, 0x84595161401484a0u, 0x0000000000000000u,
|
||||||
|
0xa56fa5b99019a5c8u, 0x0000000000000000u, 0xcecb8f27f4200f3au, 0x0000000000000000u,
|
||||||
|
0x813f3978f8940984u, 0x4000000000000000u, 0xa18f07d736b90be5u, 0x5000000000000000u,
|
||||||
|
0xc9f2c9cd04674edeu, 0xa400000000000000u, 0xfc6f7c4045812296u, 0x4d00000000000000u,
|
||||||
|
0x9dc5ada82b70b59du, 0xf020000000000000u, 0xc5371912364ce305u, 0x6c28000000000000u,
|
||||||
|
0xf684df56c3e01bc6u, 0xc732000000000000u, 0x9a130b963a6c115cu, 0x3c7f400000000000u,
|
||||||
|
0xc097ce7bc90715b3u, 0x4b9f100000000000u, 0xf0bdc21abb48db20u, 0x1e86d40000000000u,
|
||||||
|
0x96769950b50d88f4u, 0x1314448000000000u, 0xbc143fa4e250eb31u, 0x17d955a000000000u,
|
||||||
|
0xeb194f8e1ae525fdu, 0x5dcfab0800000000u, 0x92efd1b8d0cf37beu, 0x5aa1cae500000000u,
|
||||||
|
0xb7abc627050305adu, 0xf14a3d9e40000000u, 0xe596b7b0c643c719u, 0x6d9ccd05d0000000u,
|
||||||
|
0x8f7e32ce7bea5c6fu, 0xe4820023a2000000u, 0xb35dbf821ae4f38bu, 0xdda2802c8a800000u,
|
||||||
|
0xe0352f62a19e306eu, 0xd50b2037ad200000u, 0x8c213d9da502de45u, 0x4526f422cc340000u,
|
||||||
|
0xaf298d050e4395d6u, 0x9670b12b7f410000u, 0xdaf3f04651d47b4cu, 0x3c0cdd765f114000u,
|
||||||
|
0x88d8762bf324cd0fu, 0xa5880a69fb6ac800u, 0xab0e93b6efee0053u, 0x8eea0d047a457a00u,
|
||||||
|
0xd5d238a4abe98068u, 0x72a4904598d6d880u, 0x85a36366eb71f041u, 0x47a6da2b7f864750u,
|
||||||
|
0xa70c3c40a64e6c51u, 0x999090b65f67d924u, 0xd0cf4b50cfe20765u, 0xfff4b4e3f741cf6du,
|
||||||
|
0x82818f1281ed449fu, 0xbff8f10e7a8921a4u, 0xa321f2d7226895c7u, 0xaff72d52192b6a0du,
|
||||||
|
0xcbea6f8ceb02bb39u, 0x9bf4f8a69f764490u, 0xfee50b7025c36a08u, 0x02f236d04753d5b4u,
|
||||||
|
0x9f4f2726179a2245u, 0x01d762422c946590u, 0xc722f0ef9d80aad6u, 0x424d3ad2b7b97ef5u,
|
||||||
|
0xf8ebad2b84e0d58bu, 0xd2e0898765a7deb2u, 0x9b934c3b330c8577u, 0x63cc55f49f88eb2fu,
|
||||||
|
0xc2781f49ffcfa6d5u, 0x3cbf6b71c76b25fbu, 0xf316271c7fc3908au, 0x8bef464e3945ef7au,
|
||||||
|
0x97edd871cfda3a56u, 0x97758bf0e3cbb5acu, 0xbde94e8e43d0c8ecu, 0x3d52eeed1cbea317u,
|
||||||
|
0xed63a231d4c4fb27u, 0x4ca7aaa863ee4bddu, 0x945e455f24fb1cf8u, 0x8fe8caa93e74ef6au,
|
||||||
|
0xb975d6b6ee39e436u, 0xb3e2fd538e122b44u, 0xe7d34c64a9c85d44u, 0x60dbbca87196b616u,
|
||||||
|
0x90e40fbeea1d3a4au, 0xbc8955e946fe31cdu, 0xb51d13aea4a488ddu, 0x6babab6398bdbe41u,
|
||||||
|
0xe264589a4dcdab14u, 0xc696963c7eed2dd1u, 0x8d7eb76070a08aecu, 0xfc1e1de5cf543ca2u,
|
||||||
|
0xb0de65388cc8ada8u, 0x3b25a55f43294bcbu, 0xdd15fe86affad912u, 0x49ef0eb713f39ebeu,
|
||||||
|
0x8a2dbf142dfcc7abu, 0x6e3569326c784337u, 0xacb92ed9397bf996u, 0x49c2c37f07965404u,
|
||||||
|
0xd7e77a8f87daf7fbu, 0xdc33745ec97be906u, 0x86f0ac99b4e8dafdu, 0x69a028bb3ded71a3u,
|
||||||
|
0xa8acd7c0222311bcu, 0xc40832ea0d68ce0cu, 0xd2d80db02aabd62bu, 0xf50a3fa490c30190u,
|
||||||
|
0x83c7088e1aab65dbu, 0x792667c6da79e0fau, 0xa4b8cab1a1563f52u, 0x577001b891185938u,
|
||||||
|
0xcde6fd5e09abcf26u, 0xed4c0226b55e6f86u, 0x80b05e5ac60b6178u, 0x544f8158315b05b4u,
|
||||||
|
0xa0dc75f1778e39d6u, 0x696361ae3db1c721u, 0xc913936dd571c84cu, 0x03bc3a19cd1e38e9u,
|
||||||
|
0xfb5878494ace3a5fu, 0x04ab48a04065c723u, 0x9d174b2dcec0e47bu, 0x62eb0d64283f9c76u,
|
||||||
|
0xc45d1df942711d9au, 0x3ba5d0bd324f8394u, 0xf5746577930d6500u, 0xca8f44ec7ee36479u,
|
||||||
|
0x9968bf6abbe85f20u, 0x7e998b13cf4e1ecbu, 0xbfc2ef456ae276e8u, 0x9e3fedd8c321a67eu,
|
||||||
|
0xefb3ab16c59b14a2u, 0xc5cfe94ef3ea101eu, 0x95d04aee3b80ece5u, 0xbba1f1d158724a12u,
|
||||||
|
0xbb445da9ca61281fu, 0x2a8a6e45ae8edc97u, 0xea1575143cf97226u, 0xf52d09d71a3293bdu,
|
||||||
|
0x924d692ca61be758u, 0x593c2626705f9c56u, 0xb6e0c377cfa2e12eu, 0x6f8b2fb00c77836cu,
|
||||||
|
0xe498f455c38b997au, 0x0b6dfb9c0f956447u, 0x8edf98b59a373fecu, 0x4724bd4189bd5eacu,
|
||||||
|
0xb2977ee300c50fe7u, 0x58edec91ec2cb657u, 0xdf3d5e9bc0f653e1u, 0x2f2967b66737e3edu,
|
||||||
|
0x8b865b215899f46cu, 0xbd79e0d20082ee74u, 0xae67f1e9aec07187u, 0xecd8590680a3aa11u,
|
||||||
|
0xda01ee641a708de9u, 0xe80e6f4820cc9495u, 0x884134fe908658b2u, 0x3109058d147fdcddu,
|
||||||
|
0xaa51823e34a7eedeu, 0xbd4b46f0599fd415u, 0xd4e5e2cdc1d1ea96u, 0x6c9e18ac7007c91au,
|
||||||
|
0x850fadc09923329eu, 0x03e2cf6bc604ddb0u, 0xa6539930bf6bff45u, 0x84db8346b786151cu,
|
||||||
|
0xcfe87f7cef46ff16u, 0xe612641865679a63u, 0x81f14fae158c5f6eu, 0x4fcb7e8f3f60c07eu,
|
||||||
|
0xa26da3999aef7749u, 0xe3be5e330f38f09du, 0xcb090c8001ab551cu, 0x5cadf5bfd3072cc5u,
|
||||||
|
0xfdcb4fa002162a63u, 0x73d9732fc7c8f7f6u, 0x9e9f11c4014dda7eu, 0x2867e7fddcdd9afau,
|
||||||
|
0xc646d63501a1511du, 0xb281e1fd541501b8u, 0xf7d88bc24209a565u, 0x1f225a7ca91a4226u,
|
||||||
|
0x9ae757596946075fu, 0x3375788de9b06958u, 0xc1a12d2fc3978937u, 0x0052d6b1641c83aeu,
|
||||||
|
0xf209787bb47d6b84u, 0xc0678c5dbd23a49au, 0x9745eb4d50ce6332u, 0xf840b7ba963646e0u,
|
||||||
|
0xbd176620a501fbffu, 0xb650e5a93bc3d898u, 0xec5d3fa8ce427affu, 0xa3e51f138ab4cebeu,
|
||||||
|
0x93ba47c980e98cdfu, 0xc66f336c36b10137u, 0xb8a8d9bbe123f017u, 0xb80b0047445d4184u,
|
||||||
|
0xe6d3102ad96cec1du, 0xa60dc059157491e5u, 0x9043ea1ac7e41392u, 0x87c89837ad68db2fu,
|
||||||
|
0xb454e4a179dd1877u, 0x29babe4598c311fbu, 0xe16a1dc9d8545e94u, 0xf4296dd6fef3d67au,
|
||||||
|
0x8ce2529e2734bb1du, 0x1899e4a65f58660cu, 0xb01ae745b101e9e4u, 0x5ec05dcff72e7f8fu,
|
||||||
|
0xdc21a1171d42645du, 0x76707543f4fa1f73u, 0x899504ae72497ebau, 0x6a06494a791c53a8u,
|
||||||
|
0xabfa45da0edbde69u, 0x0487db9d17636892u, 0xd6f8d7509292d603u, 0x45a9d2845d3c42b6u,
|
||||||
|
0x865b86925b9bc5c2u, 0x0b8a2392ba45a9b2u, 0xa7f26836f282b732u, 0x8e6cac7768d7141eu,
|
||||||
|
0xd1ef0244af2364ffu, 0x3207d795430cd926u, 0x8335616aed761f1fu, 0x7f44e6bd49e807b8u,
|
||||||
|
0xa402b9c5a8d3a6e7u, 0x5f16206c9c6209a6u, 0xcd036837130890a1u, 0x36dba887c37a8c0fu,
|
||||||
|
0x802221226be55a64u, 0xc2494954da2c9789u, 0xa02aa96b06deb0fdu, 0xf2db9baa10b7bd6cu,
|
||||||
|
0xc83553c5c8965d3du, 0x6f92829494e5acc7u, 0xfa42a8b73abbf48cu, 0xcb772339ba1f17f9u,
|
||||||
|
0x9c69a97284b578d7u, 0xff2a760414536efbu, 0xc38413cf25e2d70du, 0xfef5138519684abau,
|
||||||
|
0xf46518c2ef5b8cd1u, 0x7eb258665fc25d69u, 0x98bf2f79d5993802u, 0xef2f773ffbd97a61u,
|
||||||
|
0xbeeefb584aff8603u, 0xaafb550ffacfd8fau, 0xeeaaba2e5dbf6784u, 0x95ba2a53f983cf38u,
|
||||||
|
0x952ab45cfa97a0b2u, 0xdd945a747bf26183u, 0xba756174393d88dfu, 0x94f971119aeef9e4u,
|
||||||
|
0xe912b9d1478ceb17u, 0x7a37cd5601aab85du, 0x91abb422ccb812eeu, 0xac62e055c10ab33au,
|
||||||
|
0xb616a12b7fe617aau, 0x577b986b314d6009u, 0xe39c49765fdf9d94u, 0xed5a7e85fda0b80bu,
|
||||||
|
0x8e41ade9fbebc27du, 0x14588f13be847307u, 0xb1d219647ae6b31cu, 0x596eb2d8ae258fc8u,
|
||||||
|
0xde469fbd99a05fe3u, 0x6fca5f8ed9aef3bbu, 0x8aec23d680043beeu, 0x25de7bb9480d5854u,
|
||||||
|
0xada72ccc20054ae9u, 0xaf561aa79a10ae6au, 0xd910f7ff28069da4u, 0x1b2ba1518094da04u,
|
||||||
|
0x87aa9aff79042286u, 0x90fb44d2f05d0842u, 0xa99541bf57452b28u, 0x353a1607ac744a53u,
|
||||||
|
0xd3fa922f2d1675f2u, 0x42889b8997915ce8u, 0x847c9b5d7c2e09b7u, 0x69956135febada11u,
|
||||||
|
0xa59bc234db398c25u, 0x43fab9837e699095u, 0xcf02b2c21207ef2eu, 0x94f967e45e03f4bbu,
|
||||||
|
0x8161afb94b44f57du, 0x1d1be0eebac278f5u, 0xa1ba1ba79e1632dcu, 0x6462d92a69731732u,
|
||||||
|
0xca28a291859bbf93u, 0x7d7b8f7503cfdcfeu, 0xfcb2cb35e702af78u, 0x5cda735244c3d43eu,
|
||||||
|
0x9defbf01b061adabu, 0x3a0888136afa64a7u, 0xc56baec21c7a1916u, 0x088aaa1845b8fdd0u,
|
||||||
|
0xf6c69a72a3989f5bu, 0x8aad549e57273d45u, 0x9a3c2087a63f6399u, 0x36ac54e2f678864bu,
|
||||||
|
0xc0cb28a98fcf3c7fu, 0x84576a1bb416a7ddu, 0xf0fdf2d3f3c30b9fu, 0x656d44a2a11c51d5u,
|
||||||
|
0x969eb7c47859e743u, 0x9f644ae5a4b1b325u, 0xbc4665b596706114u, 0x873d5d9f0dde1feeu,
|
||||||
|
0xeb57ff22fc0c7959u, 0xa90cb506d155a7eau, 0x9316ff75dd87cbd8u, 0x09a7f12442d588f2u,
|
||||||
|
0xb7dcbf5354e9beceu, 0x0c11ed6d538aeb2fu, 0xe5d3ef282a242e81u, 0x8f1668c8a86da5fau,
|
||||||
|
0x8fa475791a569d10u, 0xf96e017d694487bcu, 0xb38d92d760ec4455u, 0x37c981dcc395a9acu,
|
||||||
|
0xe070f78d3927556au, 0x85bbe253f47b1417u, 0x8c469ab843b89562u, 0x93956d7478ccec8eu,
|
||||||
|
0xaf58416654a6babbu, 0x387ac8d1970027b2u, 0xdb2e51bfe9d0696au, 0x06997b05fcc0319eu,
|
||||||
|
0x88fcf317f22241e2u, 0x441fece3bdf81f03u, 0xab3c2fddeeaad25au, 0xd527e81cad7626c3u,
|
||||||
|
0xd60b3bd56a5586f1u, 0x8a71e223d8d3b074u, 0x85c7056562757456u, 0xf6872d5667844e49u,
|
||||||
|
0xa738c6bebb12d16cu, 0xb428f8ac016561dbu, 0xd106f86e69d785c7u, 0xe13336d701beba52u,
|
||||||
|
0x82a45b450226b39cu, 0xecc0024661173473u, 0xa34d721642b06084u, 0x27f002d7f95d0190u,
|
||||||
|
0xcc20ce9bd35c78a5u, 0x31ec038df7b441f4u, 0xff290242c83396ceu, 0x7e67047175a15271u,
|
||||||
|
0x9f79a169bd203e41u, 0x0f0062c6e984d386u, 0xc75809c42c684dd1u, 0x52c07b78a3e60868u,
|
||||||
|
0xf92e0c3537826145u, 0xa7709a56ccdf8a82u, 0x9bbcc7a142b17ccbu, 0x88a66076400bb691u,
|
||||||
|
0xc2abf989935ddbfeu, 0x6acff893d00ea435u, 0xf356f7ebf83552feu, 0x0583f6b8c4124d43u,
|
||||||
|
0x98165af37b2153deu, 0xc3727a337a8b704au, 0xbe1bf1b059e9a8d6u, 0x744f18c0592e4c5cu,
|
||||||
|
0xeda2ee1c7064130cu, 0x1162def06f79df73u, 0x9485d4d1c63e8be7u, 0x8addcb5645ac2ba8u,
|
||||||
|
0xb9a74a0637ce2ee1u, 0x6d953e2bd7173692u, 0xe8111c87c5c1ba99u, 0xc8fa8db6ccdd0437u,
|
||||||
|
0x910ab1d4db9914a0u, 0x1d9c9892400a22a2u, 0xb54d5e4a127f59c8u, 0x2503beb6d00cab4bu,
|
||||||
|
0xe2a0b5dc971f303au, 0x2e44ae64840fd61du, 0x8da471a9de737e24u, 0x5ceaecfed289e5d2u,
|
||||||
|
0xb10d8e1456105dadu, 0x7425a83e872c5f47u, 0xdd50f1996b947518u, 0xd12f124e28f77719u,
|
||||||
|
0x8a5296ffe33cc92fu, 0x82bd6b70d99aaa6fu, 0xace73cbfdc0bfb7bu, 0x636cc64d1001550bu,
|
||||||
|
0xd8210befd30efa5au, 0x3c47f7e05401aa4eu, 0x8714a775e3e95c78u, 0x65acfaec34810a71u,
|
||||||
|
0xa8d9d1535ce3b396u, 0x7f1839a741a14d0du, 0xd31045a8341ca07cu, 0x1ede48111209a050u,
|
||||||
|
0x83ea2b892091e44du, 0x934aed0aab460432u, 0xa4e4b66b68b65d60u, 0xf81da84d5617853fu,
|
||||||
|
0xce1de40642e3f4b9u, 0x36251260ab9d668eu, 0x80d2ae83e9ce78f3u, 0xc1d72b7c6b426019u,
|
||||||
|
0xa1075a24e4421730u, 0xb24cf65b8612f81fu, 0xc94930ae1d529cfcu, 0xdee033f26797b627u,
|
||||||
|
0xfb9b7cd9a4a7443cu, 0x169840ef017da3b1u, 0x9d412e0806e88aa5u, 0x8e1f289560ee864eu,
|
||||||
|
0xc491798a08a2ad4eu, 0xf1a6f2bab92a27e2u, 0xf5b5d7ec8acb58a2u, 0xae10af696774b1dbu,
|
||||||
|
0x9991a6f3d6bf1765u, 0xacca6da1e0a8ef29u, 0xbff610b0cc6edd3fu, 0x17fd090a58d32af3u,
|
||||||
|
0xeff394dcff8a948eu, 0xddfc4b4cef07f5b0u, 0x95f83d0a1fb69cd9u, 0x4abdaf101564f98eu,
|
||||||
|
0xbb764c4ca7a4440fu, 0x9d6d1ad41abe37f1u, 0xea53df5fd18d5513u, 0x84c86189216dc5edu,
|
||||||
|
0x92746b9be2f8552cu, 0x32fd3cf5b4e49bb4u, 0xb7118682dbb66a77u, 0x3fbc8c33221dc2a1u,
|
||||||
|
0xe4d5e82392a40515u, 0x0fabaf3feaa5334au, 0x8f05b1163ba6832du, 0x29cb4d87f2a7400eu,
|
||||||
|
0xb2c71d5bca9023f8u, 0x743e20e9ef511012u, 0xdf78e4b2bd342cf6u, 0x914da9246b255416u,
|
||||||
|
0x8bab8eefb6409c1au, 0x1ad089b6c2f7548eu, 0xae9672aba3d0c320u, 0xa184ac2473b529b1u,
|
||||||
|
0xda3c0f568cc4f3e8u, 0xc9e5d72d90a2741eu, 0x8865899617fb1871u, 0x7e2fa67c7a658892u,
|
||||||
|
0xaa7eebfb9df9de8du, 0xddbb901b98feeab7u, 0xd51ea6fa85785631u, 0x552a74227f3ea565u,
|
||||||
|
0x8533285c936b35deu, 0xd53a88958f87275fu, 0xa67ff273b8460356u, 0x8a892abaf368f137u,
|
||||||
|
0xd01fef10a657842cu, 0x2d2b7569b0432d85u, 0x8213f56a67f6b29bu, 0x9c3b29620e29fc73u,
|
||||||
|
0xa298f2c501f45f42u, 0x8349f3ba91b47b8fu, 0xcb3f2f7642717713u, 0x241c70a936219a73u,
|
||||||
|
0xfe0efb53d30dd4d7u, 0xed238cd383aa0110u, 0x9ec95d1463e8a506u, 0xf4363804324a40aau,
|
||||||
|
0xc67bb4597ce2ce48u, 0xb143c6053edcd0d5u, 0xf81aa16fdc1b81dau, 0xdd94b7868e94050au,
|
||||||
|
0x9b10a4e5e9913128u, 0xca7cf2b4191c8326u, 0xc1d4ce1f63f57d72u, 0xfd1c2f611f63a3f0u,
|
||||||
|
0xf24a01a73cf2dccfu, 0xbc633b39673c8cecu, 0x976e41088617ca01u, 0xd5be0503e085d813u,
|
||||||
|
0xbd49d14aa79dbc82u, 0x4b2d8644d8a74e18u, 0xec9c459d51852ba2u, 0xddf8e7d60ed1219eu,
|
||||||
|
0x93e1ab8252f33b45u, 0xcabb90e5c942b503u, 0xb8da1662e7b00a17u, 0x3d6a751f3b936243u,
|
||||||
|
0xe7109bfba19c0c9du, 0x0cc512670a783ad4u, 0x906a617d450187e2u, 0x27fb2b80668b24c5u,
|
||||||
|
0xb484f9dc9641e9dau, 0xb1f9f660802dedf6u, 0xe1a63853bbd26451u, 0x5e7873f8a0396973u,
|
||||||
|
0x8d07e33455637eb2u, 0xdb0b487b6423e1e8u, 0xb049dc016abc5e5fu, 0x91ce1a9a3d2cda62u,
|
||||||
|
0xdc5c5301c56b75f7u, 0x7641a140cc7810fbu, 0x89b9b3e11b6329bau, 0xa9e904c87fcb0a9du,
|
||||||
|
0xac2820d9623bf429u, 0x546345fa9fbdcd44u, 0xd732290fbacaf133u, 0xa97c177947ad4095u,
|
||||||
|
0x867f59a9d4bed6c0u, 0x49ed8eabcccc485du, 0xa81f301449ee8c70u, 0x5c68f256bfff5a74u,
|
||||||
|
0xd226fc195c6a2f8cu, 0x73832eec6fff3111u, 0x83585d8fd9c25db7u, 0xc831fd53c5ff7eabu,
|
||||||
|
0xa42e74f3d032f525u, 0xba3e7ca8b77f5e55u, 0xcd3a1230c43fb26fu, 0x28ce1bd2e55f35ebu,
|
||||||
|
0x80444b5e7aa7cf85u, 0x7980d163cf5b81b3u, 0xa0555e361951c366u, 0xd7e105bcc332621fu,
|
||||||
|
0xc86ab5c39fa63440u, 0x8dd9472bf3fefaa7u, 0xfa856334878fc150u, 0xb14f98f6f0feb951u,
|
||||||
|
0x9c935e00d4b9d8d2u, 0x6ed1bf9a569f33d3u, 0xc3b8358109e84f07u, 0x0a862f80ec4700c8u,
|
||||||
|
0xf4a642e14c6262c8u, 0xcd27bb612758c0fau, 0x98e7e9cccfbd7dbdu, 0x8038d51cb897789cu,
|
||||||
|
0xbf21e44003acdd2cu, 0xe0470a63e6bd56c3u, 0xeeea5d5004981478u, 0x1858ccfce06cac74u,
|
||||||
|
0x95527a5202df0ccbu, 0x0f37801e0c43ebc8u, 0xbaa718e68396cffdu, 0xd30560258f54e6bau,
|
||||||
|
0xe950df20247c83fdu, 0x47c6b82ef32a2069u, 0x91d28b7416cdd27eu, 0x4cdc331d57fa5441u,
|
||||||
|
0xb6472e511c81471du, 0xe0133fe4adf8e952u, 0xe3d8f9e563a198e5u, 0x58180fddd97723a6u,
|
||||||
|
0x8e679c2f5e44ff8fu, 0x570f09eaa7ea7648u,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
@@ -8,10 +8,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array> // array
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <cstdint> // uint64_t
|
#include <cstdint> // uint64_t, uint8_t
|
||||||
#include <cstring> // memcpy
|
#include <cstring> // memcpy
|
||||||
|
|
||||||
|
#include <nlohmann/detail/bit_ops.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
// Optional SIMD backend for bulk UTF-8 validation. This is an opt-in external
|
// Optional SIMD backend for bulk UTF-8 validation. This is an opt-in external
|
||||||
@@ -69,18 +71,12 @@ inline std::size_t find_string_special(const unsigned char* data, std::size_t n)
|
|||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (; i + 8 <= n; i += 8)
|
for (; i + 8 <= n; i += 8)
|
||||||
{
|
{
|
||||||
std::uint64_t word = 0;
|
const std::uint64_t special = swar_string_special(read_eight_bytes(data + i));
|
||||||
std::memcpy(&word, data + i, sizeof(word));
|
if (special != 0)
|
||||||
if (swar_string_special(word) != 0)
|
|
||||||
{
|
{
|
||||||
// a special byte is in this word; locate it (endian-agnostic)
|
// the lowest flagged byte is the first special one: the borrows of
|
||||||
for (std::size_t j = 0; j < 8; ++j)
|
// the subtractions can only flag bytes above a true hit
|
||||||
{
|
return i + (static_cast<std::size_t>(count_trailing_zeros(special)) / 8);
|
||||||
if (is_string_special(data[i + j]))
|
|
||||||
{
|
|
||||||
return i + j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (; i < n; ++i)
|
for (; i < n; ++i)
|
||||||
@@ -114,8 +110,7 @@ inline std::size_t find_ascii_copyable_run(const unsigned char* data, std::size_
|
|||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (; i + 8 <= n; i += 8)
|
for (; i + 8 <= n; i += 8)
|
||||||
{
|
{
|
||||||
std::uint64_t v = 0;
|
const std::uint64_t v = read_eight_bytes(data + i);
|
||||||
std::memcpy(&v, data + i, sizeof(v));
|
|
||||||
const std::uint64_t q = v ^ 0x2222222222222222ull; // '"' (0x22)
|
const std::uint64_t q = v ^ 0x2222222222222222ull; // '"' (0x22)
|
||||||
const std::uint64_t b = v ^ 0x5C5C5C5C5C5C5C5Cull; // '\\' (0x5C)
|
const std::uint64_t b = v ^ 0x5C5C5C5C5C5C5C5Cull; // '\\' (0x5C)
|
||||||
const std::uint64_t d = v ^ 0x7F7F7F7F7F7F7F7Full; // DEL (0x7F)
|
const std::uint64_t d = v ^ 0x7F7F7F7F7F7F7F7Full; // DEL (0x7F)
|
||||||
@@ -126,7 +121,9 @@ inline std::size_t find_ascii_copyable_run(const unsigned char* data, std::size_
|
|||||||
| (v & high); // >= 0x80
|
| (v & high); // >= 0x80
|
||||||
if (stop != 0)
|
if (stop != 0)
|
||||||
{
|
{
|
||||||
break;
|
// the lowest flagged byte is the first one to stop at (see
|
||||||
|
// find_string_special())
|
||||||
|
return i + (static_cast<std::size_t>(count_trailing_zeros(stop)) / 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (; i < n; ++i)
|
for (; i < n; ++i)
|
||||||
@@ -253,12 +250,18 @@ inline std::size_t scalar_string_bulk_run(const unsigned char* data, std::size_t
|
|||||||
{
|
{
|
||||||
break; // end of buffer, or a quote/escape/control byte
|
break; // end of buffer, or a quote/escape/control byte
|
||||||
}
|
}
|
||||||
const std::size_t seq = validate_one_utf8(data + pos, n - pos);
|
// a run of multi-byte sequences (e.g. CJK text) is validated sequence
|
||||||
if (seq == 0)
|
// by sequence without searching for the next special byte in between
|
||||||
|
do
|
||||||
{
|
{
|
||||||
break; // ill-formed or truncated: let the byte path diagnose it
|
const std::size_t seq = validate_one_utf8(data + pos, n - pos);
|
||||||
|
if (seq == 0)
|
||||||
|
{
|
||||||
|
return pos; // ill-formed or truncated: let the byte path diagnose it
|
||||||
|
}
|
||||||
|
pos += seq;
|
||||||
}
|
}
|
||||||
pos += seq;
|
while (pos < n && data[pos] >= 0x80u);
|
||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
@@ -273,8 +276,7 @@ inline std::size_t find_string_delimiter(const unsigned char* data, std::size_t
|
|||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (; i + 8 <= n; i += 8)
|
for (; i + 8 <= n; i += 8)
|
||||||
{
|
{
|
||||||
std::uint64_t v = 0;
|
const std::uint64_t v = read_eight_bytes(data + i);
|
||||||
std::memcpy(&v, data + i, sizeof(v));
|
|
||||||
const std::uint64_t q = v ^ 0x2222222222222222ull;
|
const std::uint64_t q = v ^ 0x2222222222222222ull;
|
||||||
const std::uint64_t b = v ^ 0x5C5C5C5C5C5C5C5Cull;
|
const std::uint64_t b = v ^ 0x5C5C5C5C5C5C5C5Cull;
|
||||||
const std::uint64_t hit = ((q - ones) & ~q & high)
|
const std::uint64_t hit = ((q - ones) & ~q & high)
|
||||||
@@ -282,14 +284,8 @@ inline std::size_t find_string_delimiter(const unsigned char* data, std::size_t
|
|||||||
| ((v - 0x2020202020202020ull) & ~v & high);
|
| ((v - 0x2020202020202020ull) & ~v & high);
|
||||||
if (hit != 0)
|
if (hit != 0)
|
||||||
{
|
{
|
||||||
for (std::size_t j = 0; j < 8; ++j)
|
// the lowest flagged byte is the first delimiter (see find_string_special())
|
||||||
{
|
return i + (static_cast<std::size_t>(count_trailing_zeros(hit)) / 8);
|
||||||
const unsigned char c = data[i + j];
|
|
||||||
if (c == '\"' || c == '\\' || c < 0x20u)
|
|
||||||
{
|
|
||||||
return i + j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (; i < n; ++i)
|
for (; i < n; ++i)
|
||||||
@@ -320,5 +316,50 @@ inline std::size_t string_bulk_run(const unsigned char* data, std::size_t n) noe
|
|||||||
return scalar_string_bulk_run(data, n);
|
return scalar_string_bulk_run(data, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode the 4 hex digits at [data, data+4) - the digits following a `\u`
|
||||||
|
// escape - into a codepoint 0x0000..0xFFFF via one table lookup per byte
|
||||||
|
// (after yyjson's read_hex_u16), or return -1 if any of the 4 bytes is not a
|
||||||
|
// hex digit ('0'..'9', 'A'..'F', 'a'..'f'). The caller must already have
|
||||||
|
// checked that 4 bytes are available; used by lexer::get_codepoint()'s
|
||||||
|
// contiguous fast path. On -1 it falls back to the byte-at-a-time loop, which
|
||||||
|
// stops at the first invalid digit, so the reported error and position are
|
||||||
|
// unaffected by this fast path.
|
||||||
|
inline int hex_codepoint(const unsigned char* data) noexcept
|
||||||
|
{
|
||||||
|
static const std::array<std::uint8_t, 256> hex_digit_table = // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 00..0F
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 10..1F
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 20..2F
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 30..3F ('0'..'9')
|
||||||
|
0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 40..4F ('A'..'F')
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 50..5F
|
||||||
|
0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 60..6F ('a'..'f')
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 70..7F
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 80..8F
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 90..9F
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // A0..AF
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // B0..BF
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C0..CF
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // D0..DF
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // E0..EF
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // F0..FF
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::uint8_t d0 = hex_digit_table[data[0]];
|
||||||
|
const std::uint8_t d1 = hex_digit_table[data[1]];
|
||||||
|
const std::uint8_t d2 = hex_digit_table[data[2]];
|
||||||
|
const std::uint8_t d3 = hex_digit_table[data[3]];
|
||||||
|
// every valid digit is <= 0xF; the combined OR only exceeds it if at
|
||||||
|
// least one of the four bytes was not a hex digit (looked up as 0xFF)
|
||||||
|
if ((d0 | d1 | d2 | d3) > 0x0F)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (d0 << 12) | (d1 << 8) | (d2 << 4) | d3;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
#include <nlohmann/detail/string_concat.hpp>
|
#include <nlohmann/detail/string_concat.hpp>
|
||||||
#include <nlohmann/detail/string_escape.hpp>
|
#include <nlohmann/detail/string_escape.hpp>
|
||||||
|
#include <nlohmann/detail/string_utils.hpp>
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
@@ -116,7 +117,7 @@ class json_pointer
|
|||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
|
||||||
json_pointer& operator/=(std::size_t array_idx)
|
json_pointer& operator/=(std::size_t array_idx)
|
||||||
{
|
{
|
||||||
return *this /= std::to_string(array_idx);
|
return *this /= detail::to_string<string_t>(array_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
|
/// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
|
||||||
@@ -746,7 +747,13 @@ class json_pointer
|
|||||||
// "-" always fails the range check
|
// "-" always fails the range check
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
|
if (JSON_HEDLEY_UNLIKELY(reference_token.empty()))
|
||||||
|
{
|
||||||
|
// an empty reference token is not an array index; array_index()
|
||||||
|
// would throw out_of_range.404 -- contains() must not throw (see #5395)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !('0' <= reference_token[0] && reference_token[0] <= '9')))
|
||||||
{
|
{
|
||||||
// invalid char
|
// invalid char
|
||||||
return false;
|
return false;
|
||||||
@@ -774,7 +781,7 @@ class json_pointer
|
|||||||
// not throw (see #5395), so such a reference token is treated as "not found"
|
// not throw (see #5395), so such a reference token is treated as "not found"
|
||||||
errno = 0; // strtoull() does not reset errno on success
|
errno = 0; // strtoull() does not reset errno on success
|
||||||
char* p_end = nullptr; // NOLINT(misc-const-correctness)
|
char* p_end = nullptr; // NOLINT(misc-const-correctness)
|
||||||
const unsigned long long magnitude = std::strtoull(reference_token.c_str(), &p_end, 10); // NOLINT(runtime/int)
|
const unsigned long long magnitude = std::strtoull(reference_token.data(), &p_end, 10); // NOLINT(runtime/int)
|
||||||
if (JSON_HEDLEY_UNLIKELY(errno == ERANGE // the value exceeds ULLONG_MAX
|
if (JSON_HEDLEY_UNLIKELY(errno == ERANGE // the value exceeds ULLONG_MAX
|
||||||
|| magnitude >= static_cast<unsigned long long>((std::numeric_limits<typename BasicJsonType::size_type>::max)()))) // NOLINT(runtime/int)
|
|| magnitude >= static_cast<unsigned long long>((std::numeric_limits<typename BasicJsonType::size_type>::max)()))) // NOLINT(runtime/int)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ void templated_json_throw(ExceptionType exception)
|
|||||||
return ej_pair.second == j; \
|
return ej_pair.second == j; \
|
||||||
}); \
|
}); \
|
||||||
if (it != std::end(m)) e = it->first; \
|
if (it != std::end(m)) e = it->first; \
|
||||||
else templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(410,"enum value out of range for " #ENUM_TYPE ": " + j.dump(), &j)); \
|
else templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(410, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", j.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace)), &j)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
|
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
|
||||||
@@ -915,7 +915,3 @@ void templated_json_throw(ExceptionType exception)
|
|||||||
#ifndef JSON_DISABLE_ENUM_SERIALIZATION
|
#ifndef JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
#define JSON_DISABLE_ENUM_SERIALIZATION 0
|
#define JSON_DISABLE_ENUM_SERIALIZATION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef JSON_USE_GLOBAL_UDLS
|
|
||||||
#define JSON_USE_GLOBAL_UDLS 1
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#undef JSON_INLINE_VARIABLE
|
#undef JSON_INLINE_VARIABLE
|
||||||
#undef JSON_NO_UNIQUE_ADDRESS
|
#undef JSON_NO_UNIQUE_ADDRESS
|
||||||
#undef JSON_DISABLE_ENUM_SERIALIZATION
|
#undef JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
#undef JSON_USE_GLOBAL_UDLS
|
|
||||||
|
|
||||||
#ifndef JSON_TEST_KEEP_MACROS
|
#ifndef JSON_TEST_KEEP_MACROS
|
||||||
#undef JSON_CATCH
|
#undef JSON_CATCH
|
||||||
|
|||||||
@@ -725,7 +725,7 @@ std::is_constructible <decltype(std::declval<Compare>()(std::declval<A>(), std::
|
|||||||
// avoid their instantiation on all compilers, even when the first operand
|
// avoid their instantiation on all compilers, even when the first operand
|
||||||
// is false. The dispatch on is_json_pointer_of can be removed once the
|
// is false. The dispatch on is_json_pointer_of can be removed once the
|
||||||
// deprecated json_pointer comparison operators have been removed.
|
// deprecated json_pointer comparison operators have been removed.
|
||||||
template<typename Compare, typename A, typename B, bool = is_json_pointer_of<A, B>::value>
|
template<typename Compare, typename A, typename B, bool = is_json_pointer_of<uncvref_t<A>, uncvref_t<B>>::value>
|
||||||
struct is_comparable : std::false_type {};
|
struct is_comparable : std::false_type {};
|
||||||
|
|
||||||
template<typename Compare, typename A, typename B>
|
template<typename Compare, typename A, typename B>
|
||||||
|
|||||||
@@ -337,24 +337,25 @@ class binary_writer
|
|||||||
// MessagePack does not differentiate between positive
|
// MessagePack does not differentiate between positive
|
||||||
// signed integers and unsigned integers. Therefore, we used
|
// signed integers and unsigned integers. Therefore, we used
|
||||||
// the code from the value_t::number_unsigned case here.
|
// the code from the value_t::number_unsigned case here.
|
||||||
if (j.m_data.m_value.number_unsigned < 128)
|
const auto value_as_unsigned = static_cast<typename BasicJsonType::number_unsigned_t>(j.m_data.m_value.number_integer);
|
||||||
|
if (value_as_unsigned < 128)
|
||||||
{
|
{
|
||||||
// positive fixnum
|
// positive fixnum
|
||||||
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
else if (value_as_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 8
|
// uint 8
|
||||||
oa.write_character(to_char_type(0xCC));
|
oa.write_character(to_char_type(0xCC));
|
||||||
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (value_as_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 16
|
// uint 16
|
||||||
oa.write_character(to_char_type(0xCD));
|
oa.write_character(to_char_type(0xCD));
|
||||||
write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
|
write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (value_as_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 32
|
// uint 32
|
||||||
oa.write_character(to_char_type(0xCE));
|
oa.write_character(to_char_type(0xCE));
|
||||||
@@ -410,31 +411,31 @@ class binary_writer
|
|||||||
if (j.m_data.m_value.number_unsigned < 128)
|
if (j.m_data.m_value.number_unsigned < 128)
|
||||||
{
|
{
|
||||||
// positive fixnum
|
// positive fixnum
|
||||||
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 8
|
// uint 8
|
||||||
oa.write_character(to_char_type(0xCC));
|
oa.write_character(to_char_type(0xCC));
|
||||||
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 16
|
// uint 16
|
||||||
oa.write_character(to_char_type(0xCD));
|
oa.write_character(to_char_type(0xCD));
|
||||||
write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
|
write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 32
|
// uint 32
|
||||||
oa.write_character(to_char_type(0xCE));
|
oa.write_character(to_char_type(0xCE));
|
||||||
write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
|
write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// uint 64
|
// uint 64
|
||||||
oa.write_character(to_char_type(0xCF));
|
oa.write_character(to_char_type(0xCF));
|
||||||
write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
|
write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1055,15 +1056,26 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@return The size of the BSON-encoded binary array @a value
|
@return The size of the BSON-encoded binary array in @a j
|
||||||
|
@throw out_of_range.415 if the subtype of @a j does not fit into a byte,
|
||||||
|
before anything is written
|
||||||
*/
|
*/
|
||||||
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
|
static std::size_t calc_bson_binary_size(const BasicJsonType& j)
|
||||||
{
|
{
|
||||||
|
const auto& value = *j.m_data.m_value.binary;
|
||||||
|
|
||||||
|
if (value.has_subtype() && JSON_HEDLEY_UNLIKELY(value.subtype() > (std::numeric_limits<std::uint8_t>::max)()))
|
||||||
|
{
|
||||||
|
JSON_THROW(out_of_range::create(415, concat("subtype ", std::to_string(value.subtype()), " is too large for the BSON binary subtype (max 255)"), &j));
|
||||||
|
}
|
||||||
|
|
||||||
return sizeof(std::int32_t) + value.size() + 1ul;
|
return sizeof(std::int32_t) + value.size() + 1ul;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and binary value @a value
|
@brief Writes a BSON element with key @a name and binary value @a value
|
||||||
|
@pre @a value's subtype, if any, fits into a byte; @ref calc_bson_sizes
|
||||||
|
checks this for every binary value in the document beforehand.
|
||||||
*/
|
*/
|
||||||
void write_bson_binary(const string_t& name,
|
void write_bson_binary(const string_t& name,
|
||||||
const binary_t& value)
|
const binary_t& value)
|
||||||
@@ -1072,11 +1084,6 @@ class binary_writer
|
|||||||
|
|
||||||
write_number<std::int32_t>(to_bson_length(value.size()), true);
|
write_number<std::int32_t>(to_bson_length(value.size()), true);
|
||||||
|
|
||||||
if (value.has_subtype() && JSON_HEDLEY_UNLIKELY(value.subtype() > (std::numeric_limits<std::uint8_t>::max)()))
|
|
||||||
{
|
|
||||||
JSON_THROW(out_of_range::create(415, concat("subtype ", std::to_string(value.subtype()), " is too large for the BSON binary subtype (max 255)"), nullptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
|
write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
|
||||||
|
|
||||||
oa.write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
|
oa.write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
|
||||||
@@ -1085,13 +1092,15 @@ class binary_writer
|
|||||||
/*!
|
/*!
|
||||||
@return The size of the value of the BSON document entry for @a j, which
|
@return The size of the value of the BSON document entry for @a j, which
|
||||||
is neither an object nor an array
|
is neither an object nor an array
|
||||||
|
@throw out_of_range.415 if @a j is binary with a subtype that does not fit
|
||||||
|
into a byte, before anything is written
|
||||||
*/
|
*/
|
||||||
static std::size_t calc_bson_value_size(const BasicJsonType& j)
|
static std::size_t calc_bson_value_size(const BasicJsonType& j)
|
||||||
{
|
{
|
||||||
switch (j.type())
|
switch (j.type())
|
||||||
{
|
{
|
||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
return calc_bson_binary_size(*j.m_data.m_value.binary);
|
return calc_bson_binary_size(j);
|
||||||
|
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
return 1ul;
|
return 1ul;
|
||||||
@@ -1217,6 +1226,8 @@ class binary_writer
|
|||||||
@return the size of @a document
|
@return the size of @a document
|
||||||
@throw out_of_range.409 if a key contains U+0000, before anything is
|
@throw out_of_range.409 if a key contains U+0000, before anything is
|
||||||
written
|
written
|
||||||
|
@throw out_of_range.415 if a binary value's subtype does not fit into a
|
||||||
|
byte, before anything is written
|
||||||
*/
|
*/
|
||||||
static std::size_t calc_bson_sizes(const BasicJsonType& document, std::vector<std::size_t>& nested_sizes)
|
static std::size_t calc_bson_sizes(const BasicJsonType& document, std::vector<std::size_t>& nested_sizes)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,11 +19,17 @@ namespace detail
|
|||||||
/*!
|
/*!
|
||||||
@brief the number of nesting levels an operation recurses into
|
@brief the number of nesting levels an operation recurses into
|
||||||
|
|
||||||
Operations that walk a value (serializing, hashing, merging, ...) recurse once
|
Operations that walk a value (copying, comparing, serializing, hashing, merging,
|
||||||
|
...) recurse once
|
||||||
per nesting level, which is fastest, but a value nested deeply enough would
|
per nesting level, which is fastest, but a value nested deeply enough would
|
||||||
exhaust the call stack. So they recurse only this many levels deep and finish
|
exhaust the call stack. So they recurse only this many levels deep and finish
|
||||||
whatever lies below with an explicit stack. All of them share this limit.
|
whatever lies below with an explicit stack. All of them share this limit.
|
||||||
|
|
||||||
|
Most of them pass the depth down as an argument. The copy constructor and the
|
||||||
|
comparison operators cannot, as their signatures are fixed, so they count it
|
||||||
|
in basic_json::nesting_depth() instead, a byte per thread; the limit must
|
||||||
|
therefore stay below 255.
|
||||||
|
|
||||||
@sa https://github.com/nlohmann/json/issues/5387
|
@sa https://github.com/nlohmann/json/issues/5387
|
||||||
*/
|
*/
|
||||||
constexpr std::size_t recursion_depth_limit() noexcept
|
constexpr std::size_t recursion_depth_limit() noexcept
|
||||||
|
|||||||
+99
-90
@@ -36,7 +36,9 @@
|
|||||||
#include <iosfwd> // istream, ostream
|
#include <iosfwd> // istream, ostream
|
||||||
#endif // JSON_NO_IO
|
#endif // JSON_NO_IO
|
||||||
#include <iterator> // make_move_iterator, random_access_iterator_tag
|
#include <iterator> // make_move_iterator, random_access_iterator_tag
|
||||||
|
#include <limits> // numeric_limits
|
||||||
#include <memory> // unique_ptr
|
#include <memory> // unique_ptr
|
||||||
|
#include <stdexcept> // length_error
|
||||||
#include <string> // string, stoi, to_string
|
#include <string> // string, stoi, to_string
|
||||||
#include <utility> // declval, forward, move, pair, swap
|
#include <utility> // declval, forward, move, pair, swap
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
@@ -898,12 +900,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef JSON_NO_THREAD_LOCAL
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
/// the number of levels an operation descends into before it finishes the
|
// nesting_depth() is a byte and may exceed the limit by one level
|
||||||
/// value below it without the call stack
|
static_assert(detail::recursion_depth_limit() < 255, "the nesting depth count must fit in a byte");
|
||||||
static constexpr std::uint8_t nesting_depth_limit()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief how many levels the operation going on in this thread has descended into
|
@brief how many levels the operation going on in this thread has descended into
|
||||||
@@ -945,7 +943,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
static_cast<void>(may_descend);
|
static_cast<void>(may_descend);
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
return !may_descend || nesting_depth() >= nesting_depth_limit();
|
return !may_descend || nesting_depth() >= detail::recursion_depth_limit();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -969,7 +967,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
#ifdef JSON_NO_THREAD_LOCAL
|
#ifdef JSON_NO_THREAD_LOCAL
|
||||||
: m_okay(false)
|
: m_okay(false)
|
||||||
#else
|
#else
|
||||||
: m_okay(nesting_depth() < nesting_depth_limit())
|
: m_okay(nesting_depth() < detail::recursion_depth_limit())
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef JSON_NO_THREAD_LOCAL
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
@@ -1118,6 +1116,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
// provides the latter (e.g., ones without a matching allocator-aware
|
// provides the latter (e.g., ones without a matching allocator-aware
|
||||||
// fill constructor)
|
// fill constructor)
|
||||||
dst.m_data.m_value.array = create<array_t>();
|
dst.m_data.m_value.array = create<array_t>();
|
||||||
|
// only now that the array exists may dst stop being a null value
|
||||||
|
dst.m_data.m_type = value_t::array;
|
||||||
dst.m_data.m_value.array->resize(src_array.size());
|
dst.m_data.m_value.array->resize(src_array.size());
|
||||||
|
|
||||||
auto dst_it = dst.m_data.m_value.array->begin();
|
auto dst_it = dst.m_data.m_value.array->begin();
|
||||||
@@ -1146,6 +1146,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
dst.m_data.m_value.object = create<object_t>(std::make_move_iterator(scratch.begin()),
|
dst.m_data.m_value.object = create<object_t>(std::make_move_iterator(scratch.begin()),
|
||||||
std::make_move_iterator(scratch.end()));
|
std::make_move_iterator(scratch.end()));
|
||||||
|
// only now that the object exists may dst stop being a null value
|
||||||
|
dst.m_data.m_type = value_t::object;
|
||||||
scratch.clear();
|
scratch.clear();
|
||||||
|
|
||||||
// pair every value of the copy with its counterpart in the original;
|
// pair every value of the copy with its counterpart in the original;
|
||||||
@@ -1173,7 +1175,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
The values whose copy has not been created yet are kept on an explicit
|
The values whose copy has not been created yet are kept on an explicit
|
||||||
worklist rather than on the call stack. This is only reached for values
|
worklist rather than on the call stack. This is only reached for values
|
||||||
nested deeper than @ref nesting_depth_limit levels, which is why it copies
|
nested deeper than @ref detail::recursion_depth_limit levels, which is why it copies
|
||||||
every container by hand instead of letting the container do it: the fast
|
every container by hand instead of letting the container do it: the fast
|
||||||
ways of doing so would descend into the elements and defeat the purpose.
|
ways of doing so would descend into the elements and defeat the purpose.
|
||||||
*/
|
*/
|
||||||
@@ -1208,9 +1210,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
src_value = next.first;
|
src_value = next.first;
|
||||||
dst_value = next.second;
|
dst_value = next.second;
|
||||||
worklist.pop_back();
|
worklist.pop_back();
|
||||||
|
|
||||||
// the value stops being a null value exactly here
|
|
||||||
dst_value->m_data.m_type = src_value->m_data.m_type;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1239,7 +1238,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
Copying a container copies its elements, so a value nested deeply enough
|
Copying a container copies its elements, so a value nested deeply enough
|
||||||
used to exhaust the call stack. The descent is bounded here: the first
|
used to exhaust the call stack. The descent is bounded here: the first
|
||||||
@ref nesting_depth_limit levels are copied by the containers themselves, just
|
@ref detail::recursion_depth_limit levels are copied by the containers themselves, just
|
||||||
as they always were, and anything below that is copied without the call
|
as they always were, and anything below that is copied without the call
|
||||||
stack by @ref copy_iteratively. Copying a value can therefore no longer
|
stack by @ref copy_iteratively. Copying a value can therefore no longer
|
||||||
exhaust the stack, however deeply it is nested, just like destroying one
|
exhaust the stack, however deeply it is nested, just like destroying one
|
||||||
@@ -1377,7 +1376,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/*!
|
/*!
|
||||||
@brief compare @a lhs and @a rhs without descending into them
|
@brief compare @a lhs and @a rhs without descending into them
|
||||||
|
|
||||||
Reached once a comparison has descended @ref nesting_depth_limit levels, so
|
Reached once a comparison has descended @ref detail::recursion_depth_limit levels, so
|
||||||
that comparing values cannot exhaust the call stack however deeply they are
|
that comparing values cannot exhaust the call stack however deeply they are
|
||||||
nested. The two values are walked in lockstep on an explicit stack and
|
nested. The two values are walked in lockstep on an explicit stack and
|
||||||
compared lexicographically, element by element in the order the containers
|
compared lexicographically, element by element in the order the containers
|
||||||
@@ -1507,7 +1506,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
const auto found = (!Ordered && !detail::is_ordered_map<object_t>::value)
|
const auto found = (!Ordered && !detail::is_ordered_map<object_t>::value)
|
||||||
? rhs_object->find(current.lhs_object_it->first)
|
? rhs_object->find(current.lhs_object_it->first)
|
||||||
: rhs_object->cend();
|
: rhs_object->cend();
|
||||||
if (found == rhs_object->cend())
|
// the object's comparator may find an entry whose
|
||||||
|
// key is only equivalent, not equal, to this one
|
||||||
|
if (found == rhs_object->cend() || !(found->first == current.lhs_object_it->first))
|
||||||
{
|
{
|
||||||
return key_result;
|
return key_result;
|
||||||
}
|
}
|
||||||
@@ -1829,6 +1830,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
case value_t::number_integer:
|
case value_t::number_integer:
|
||||||
case value_t::number_unsigned:
|
case value_t::number_unsigned:
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
|
case value_t::binary:
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
|
if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
|
||||||
|| !last.m_it.primitive_iterator.is_end()))
|
|| !last.m_it.primitive_iterator.is_end()))
|
||||||
@@ -1841,7 +1843,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
case value_t::null:
|
case value_t::null:
|
||||||
case value_t::object:
|
case value_t::object:
|
||||||
case value_t::array:
|
case value_t::array:
|
||||||
case value_t::binary:
|
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -2830,6 +2831,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
// fill up the array with null values if given idx is outside the range
|
// fill up the array with null values if given idx is outside the range
|
||||||
if (idx >= m_data.m_value.array->size())
|
if (idx >= m_data.m_value.array->size())
|
||||||
{
|
{
|
||||||
|
// idx + 1 would overflow size_type and wrap to 0, which would empty
|
||||||
|
// the array instead of growing it; reject such an idx the same way
|
||||||
|
// resize() rejects other indices that are too large to represent
|
||||||
|
if (JSON_HEDLEY_UNLIKELY(idx == (std::numeric_limits<size_type>::max)()))
|
||||||
|
{
|
||||||
|
JSON_THROW(std::length_error(detail::concat("array index ", std::to_string(idx), " exceeds size_type")));
|
||||||
|
}
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
// remember array size & capacity before resizing
|
// remember array size & capacity before resizing
|
||||||
const auto old_size = m_data.m_value.array->size();
|
const auto old_size = m_data.m_value.array->size();
|
||||||
@@ -2975,6 +2983,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
string_t, typename std::decay<ValueType>::type >;
|
string_t, typename std::decay<ValueType>::type >;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// an integer literal 0 would otherwise convert to a null const char* and from there to key_type
|
||||||
|
template<typename T, typename ValueType, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
|
||||||
|
ValueType value(T, ValueType&&) const = delete;
|
||||||
|
|
||||||
/// @brief access specified object element with default value
|
/// @brief access specified object element with default value
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/value/
|
/// @sa https://json.nlohmann.me/api/basic_json/value/
|
||||||
template < class ValueType, detail::enable_if_t <
|
template < class ValueType, detail::enable_if_t <
|
||||||
@@ -3409,6 +3421,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @name lookup
|
/// @name lookup
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
// an integer literal 0 would otherwise convert to a null const char* and from there to key_type
|
||||||
|
template<typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
|
||||||
|
iterator find(T) = delete;
|
||||||
|
template<typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
|
||||||
|
const_iterator find(T) const = delete;
|
||||||
|
template<typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
|
||||||
|
size_type count(T) const = delete;
|
||||||
|
template<typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
|
||||||
|
bool contains(T) const = delete;
|
||||||
|
|
||||||
/// @brief find an element in a JSON object
|
/// @brief find an element in a JSON object
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/find/
|
/// @sa https://json.nlohmann.me/api/basic_json/find/
|
||||||
iterator find(const typename object_t::key_type& key)
|
iterator find(const typename object_t::key_type& key)
|
||||||
@@ -3833,6 +3855,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
{
|
{
|
||||||
m_data.m_value.binary->clear();
|
m_data.m_value.binary->clear();
|
||||||
|
m_data.m_value.binary->clear_subtype();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4152,8 +4175,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
|
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy the values first: ilist may refer to elements of this array
|
||||||
|
array_t values;
|
||||||
|
detail::reserve_array(values, ilist.size(), detail::priority_tag<1> {});
|
||||||
|
for (const auto& element : ilist)
|
||||||
|
{
|
||||||
|
values.push_back(element.moved_or_copied());
|
||||||
|
}
|
||||||
|
|
||||||
// insert to array and return iterator
|
// insert to array and return iterator
|
||||||
return insert_iterator(pos, ilist.begin(), ilist.end());
|
return insert_iterator(pos, std::make_move_iterator(values.begin()), std::make_move_iterator(values.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief inserts range of elements into object
|
/// @brief inserts range of elements into object
|
||||||
@@ -4335,12 +4366,21 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
std::is_nothrow_move_constructible<value_t>::value&&
|
std::is_nothrow_move_constructible<value_t>::value&&
|
||||||
std::is_nothrow_move_assignable<value_t>::value&&
|
std::is_nothrow_move_assignable<value_t>::value&&
|
||||||
std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
||||||
std::is_nothrow_move_assignable<json_value>::value
|
std::is_nothrow_move_assignable<json_value>::value&&
|
||||||
|
std::is_nothrow_move_constructible<json_base_class_t>::value&&
|
||||||
|
std::is_nothrow_move_assignable<json_base_class_t>::value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::swap(m_data.m_type, other.m_data.m_type);
|
std::swap(m_data.m_type, other.m_data.m_type);
|
||||||
std::swap(m_data.m_value, other.m_data.m_value);
|
std::swap(m_data.m_value, other.m_data.m_value);
|
||||||
|
|
||||||
|
// the custom base class travels with the value when it is copied or
|
||||||
|
// moved, so it is exchanged along with it
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(static_cast<json_base_class_t&>(*this), static_cast<json_base_class_t&>(other));
|
||||||
|
}
|
||||||
|
|
||||||
#if JSON_DIAGNOSTIC_POSITIONS
|
#if JSON_DIAGNOSTIC_POSITIONS
|
||||||
std::swap(start_position, other.start_position);
|
std::swap(start_position, other.start_position);
|
||||||
std::swap(end_position, other.end_position);
|
std::swap(end_position, other.end_position);
|
||||||
@@ -4357,7 +4397,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
std::is_nothrow_move_constructible<value_t>::value&&
|
std::is_nothrow_move_constructible<value_t>::value&&
|
||||||
std::is_nothrow_move_assignable<value_t>::value&&
|
std::is_nothrow_move_assignable<value_t>::value&&
|
||||||
std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
||||||
std::is_nothrow_move_assignable<json_value>::value
|
std::is_nothrow_move_assignable<json_value>::value&&
|
||||||
|
std::is_nothrow_move_constructible<json_base_class_t>::value&&
|
||||||
|
std::is_nothrow_move_assignable<json_base_class_t>::value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
left.swap(right);
|
left.swap(right);
|
||||||
@@ -5050,7 +5092,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
|
||||||
friend std::istream& operator>>(std::istream& i, basic_json& j)
|
friend std::istream& operator>>(std::istream& i, basic_json& j)
|
||||||
{
|
{
|
||||||
parser(detail::input_adapter(i)).parse(false, j);
|
// parse into a temporary so that j is left unchanged if parsing fails
|
||||||
|
basic_json result;
|
||||||
|
parser(detail::input_adapter(i)).parse(false, result);
|
||||||
|
j = std::move(result);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
#endif // JSON_NO_IO
|
#endif // JSON_NO_IO
|
||||||
@@ -6150,12 +6195,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
// the same time, determine whether every added key comes
|
// the same time, determine whether every added key comes
|
||||||
// after every common key in target's order (a precondition
|
// after every common key in target's order (a precondition
|
||||||
// for the fast path below, which only ever appends new keys
|
// for the fast path below, which only ever appends new keys
|
||||||
// at the very end): for an object_t whose iteration order is
|
// at the very end). Both are only needed for an object_t that
|
||||||
// a pure function of the key set (e.g. the default std::map,
|
// keeps its members in insertion order, such as the one
|
||||||
// which always iterates in sorted key order), the order
|
// backing `ordered_json`; for any other object_t, the fast
|
||||||
// check further below is always true and this whole
|
// path is always taken and they are not computed.
|
||||||
// mechanism is effectively a no-op; it only matters for a
|
|
||||||
// reorderable object_t such as the one backing `ordered_json`.
|
|
||||||
// patch ops for keys that were added (i.e., in target but not
|
// patch ops for keys that were added (i.e., in target but not
|
||||||
// in source); built here so the fast path below can reuse
|
// in source); built here so the fast path below can reuse
|
||||||
// them without a second source.find() per target key. Only
|
// them without a second source.find() per target key. Only
|
||||||
@@ -6179,15 +6222,32 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
common_keys_target_order.push_back(it.key());
|
#ifdef JSON_HEDLEY_MSVC_VERSION
|
||||||
if (seen_new_key)
|
#pragma warning(push )
|
||||||
|
#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
|
||||||
|
#endif
|
||||||
|
if (detail::is_ordered_map<object_t>::value)
|
||||||
{
|
{
|
||||||
new_keys_form_suffix = false;
|
common_keys_target_order.push_back(it.key());
|
||||||
|
if (seen_new_key)
|
||||||
|
{
|
||||||
|
new_keys_form_suffix = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef JSON_HEDLEY_MSVC_VERSION
|
||||||
|
#pragma warning( pop )
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (common_keys_source_order == common_keys_target_order && new_keys_form_suffix)
|
// Only an object type that keeps its members in insertion
|
||||||
|
// order, such as nlohmann::ordered_map, can need reordering:
|
||||||
|
// patch() appends a new member at the end of such an object.
|
||||||
|
// Any other object type places its members itself - std::map
|
||||||
|
// in key order, a hash map in an order its operator== ignores -
|
||||||
|
// so a member-by-member diff always reproduces target there.
|
||||||
|
if (!detail::is_ordered_map<object_t>::value
|
||||||
|
|| (common_keys_source_order == common_keys_target_order && new_keys_form_suffix))
|
||||||
{
|
{
|
||||||
// fast path: order of common keys already matches (or the
|
// fast path: order of common keys already matches (or the
|
||||||
// object_t's iteration order does not depend on
|
// object_t's iteration order does not depend on
|
||||||
@@ -6423,55 +6483,6 @@ std::string format_as(const NLOHMANN_BASIC_JSON_TPL& j)
|
|||||||
return j.dump();
|
return j.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline namespace literals
|
|
||||||
{
|
|
||||||
inline namespace json_literals
|
|
||||||
{
|
|
||||||
|
|
||||||
/// @brief user-defined string literal for JSON values
|
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/
|
|
||||||
JSON_HEDLEY_NON_NULL(1)
|
|
||||||
#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
|
|
||||||
inline nlohmann::json operator""_json(const char* s, std::size_t n)
|
|
||||||
#else
|
|
||||||
// GCC 4.8 requires a space between "" and suffix
|
|
||||||
inline nlohmann::json operator"" _json(const char* s, std::size_t n)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return nlohmann::json::parse(s, s + n);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__cpp_char8_t)
|
|
||||||
JSON_HEDLEY_NON_NULL(1)
|
|
||||||
inline nlohmann::json operator""_json(const char8_t* s, std::size_t n)
|
|
||||||
{
|
|
||||||
return nlohmann::json::parse(reinterpret_cast<const char*>(s),
|
|
||||||
reinterpret_cast<const char*>(s) + n);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// @brief user-defined string literal for JSON pointer
|
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/
|
|
||||||
JSON_HEDLEY_NON_NULL(1)
|
|
||||||
#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
|
|
||||||
inline nlohmann::json::json_pointer operator""_json_pointer(const char* s, std::size_t n)
|
|
||||||
#else
|
|
||||||
// GCC 4.8 requires a space between "" and suffix
|
|
||||||
inline nlohmann::json::json_pointer operator"" _json_pointer(const char* s, std::size_t n)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return nlohmann::json::json_pointer(std::string(s, n));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__cpp_char8_t)
|
|
||||||
inline nlohmann::json::json_pointer operator""_json_pointer(const char8_t* s, std::size_t n)
|
|
||||||
{
|
|
||||||
return nlohmann::json::json_pointer(std::string(reinterpret_cast<const char*>(s), n));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace json_literals
|
|
||||||
} // namespace literals
|
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
///////////////////////
|
///////////////////////
|
||||||
@@ -6606,17 +6617,6 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
|
|||||||
|
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
#if JSON_USE_GLOBAL_UDLS
|
|
||||||
#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
|
|
||||||
using nlohmann::literals::json_literals::operator""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
|
|
||||||
using nlohmann::literals::json_literals::operator""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
|
|
||||||
#else
|
|
||||||
// GCC 4.8 requires a space between "" and suffix
|
|
||||||
using nlohmann::literals::json_literals::operator"" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
|
|
||||||
using nlohmann::literals::json_literals::operator"" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <nlohmann/detail/macro_unscope.hpp>
|
#include <nlohmann/detail/macro_unscope.hpp>
|
||||||
|
|
||||||
// End of GCC diagnostic pragmas for C++ modules support
|
// End of GCC diagnostic pragmas for C++ modules support
|
||||||
@@ -6624,4 +6624,13 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
|
|||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// The user-defined string literals are in a separate header, because their
|
||||||
|
// bodies instantiate the parser in every translation unit that includes them.
|
||||||
|
// Define JSON_NO_AUTOMATIC_UDLS to include <nlohmann/json_literals.hpp> only
|
||||||
|
// where needed.
|
||||||
|
#ifndef JSON_NO_AUTOMATIC_UDLS
|
||||||
|
// NOLINTNEXTLINE(misc-header-include-cycle): json_literals.hpp includes this header
|
||||||
|
#include <nlohmann/json_literals.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // INCLUDE_NLOHMANN_JSON_HPP_
|
#endif // INCLUDE_NLOHMANN_JSON_HPP_
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#ifndef INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
|
||||||
|
#define INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
|
||||||
|
|
||||||
|
#include <cstddef> // size_t
|
||||||
|
#include <string> // string
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-header-include-cycle): json.hpp includes this header at its end
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
// This header is included at the end of <nlohmann/json.hpp> unless
|
||||||
|
// JSON_NO_AUTOMATIC_UDLS is defined, and can be included on its own after that.
|
||||||
|
// Either way, the library's internal macros are no longer defined here (and the
|
||||||
|
// amalgamation inlines macro_scope.hpp only once), so only standard and public
|
||||||
|
// macros may be used below.
|
||||||
|
|
||||||
|
// declares the literal operator for the given suffix; GCC 4.8 requires a space
|
||||||
|
// between "" and the suffix, which newer compilers deprecate (CWG 2521)
|
||||||
|
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
|
||||||
|
#define NLOHMANN_JSON_LITERAL_OPERATOR(suffix) operator""##suffix
|
||||||
|
#else
|
||||||
|
#define NLOHMANN_JSON_LITERAL_OPERATOR(suffix) operator"" suffix
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
inline namespace literals
|
||||||
|
{
|
||||||
|
inline namespace json_literals
|
||||||
|
{
|
||||||
|
|
||||||
|
/// @brief user-defined string literal for JSON values
|
||||||
|
/// @sa https://json.nlohmann.me/api/operator_literal_json/
|
||||||
|
inline nlohmann::json NLOHMANN_JSON_LITERAL_OPERATOR(_json)(const char* s, std::size_t n)
|
||||||
|
{
|
||||||
|
return nlohmann::json::parse(s, s + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cpp_char8_t)
|
||||||
|
inline nlohmann::json operator""_json(const char8_t* s, std::size_t n)
|
||||||
|
{
|
||||||
|
return nlohmann::json::parse(reinterpret_cast<const char*>(s),
|
||||||
|
reinterpret_cast<const char*>(s) + n);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// @brief user-defined string literal for JSON pointer
|
||||||
|
/// @sa https://json.nlohmann.me/api/operator_literal_json_pointer/
|
||||||
|
inline nlohmann::json::json_pointer NLOHMANN_JSON_LITERAL_OPERATOR(_json_pointer)(const char* s, std::size_t n)
|
||||||
|
{
|
||||||
|
return nlohmann::json::json_pointer(std::string(s, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cpp_char8_t)
|
||||||
|
inline nlohmann::json::json_pointer operator""_json_pointer(const char8_t* s, std::size_t n)
|
||||||
|
{
|
||||||
|
return nlohmann::json::json_pointer(std::string(reinterpret_cast<const char*>(s), n));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace json_literals
|
||||||
|
} // namespace literals
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#if !defined(JSON_USE_GLOBAL_UDLS) || JSON_USE_GLOBAL_UDLS
|
||||||
|
using nlohmann::literals::json_literals::NLOHMANN_JSON_LITERAL_OPERATOR(_json); // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
|
||||||
|
using nlohmann::literals::json_literals::NLOHMANN_JSON_LITERAL_OPERATOR(_json_pointer); //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef NLOHMANN_JSON_LITERAL_OPERATOR
|
||||||
|
|
||||||
|
#endif // INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
|
||||||
@@ -8,13 +8,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm> // max, min
|
||||||
#include <functional> // equal_to, less
|
#include <functional> // equal_to, less
|
||||||
#include <initializer_list> // initializer_list
|
#include <initializer_list> // initializer_list
|
||||||
#include <iterator> // input_iterator_tag, iterator_traits
|
#include <iterator> // input_iterator_tag, iterator_traits
|
||||||
#include <memory> // allocator
|
#include <memory> // allocator
|
||||||
#include <stdexcept> // for out_of_range
|
#include <stdexcept> // for out_of_range
|
||||||
#include <type_traits> // enable_if, is_convertible
|
#include <tuple> // forward_as_tuple
|
||||||
#include <utility> // pair
|
#include <type_traits> // enable_if, integral_constant, is_convertible, is_nothrow_move_constructible
|
||||||
|
#include <utility> // forward, move, pair, piecewise_construct
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
@@ -79,7 +81,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return {it, false};
|
return {it, false};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Container::emplace_back(key, std::forward<T>(t));
|
append(key, std::forward<T>(t));
|
||||||
return {std::prev(this->end()), true};
|
return {std::prev(this->end()), true};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +96,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return {it, false};
|
return {it, false};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
|
append(std::forward<KeyType>(key), std::forward<T>(t));
|
||||||
return {std::prev(this->end()), true};
|
return {std::prev(this->end()), true};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +370,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return {it, false};
|
return {it, false};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Container::push_back(value);
|
append(value);
|
||||||
return {--this->end(), true};
|
return {--this->end(), true};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,6 +388,64 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*!
|
||||||
|
@brief add an element whose key is not yet contained at the end
|
||||||
|
|
||||||
|
A std::vector copies all elements when it grows, because their const keys
|
||||||
|
make them not nothrow move constructible. For ordered_json, this is a deep
|
||||||
|
copy of every value. Where the strong exception guarantee can be kept, grow
|
||||||
|
the storage here instead, copying only the keys and moving the values.
|
||||||
|
*/
|
||||||
|
template<typename... Args>
|
||||||
|
void append(Args&& ... args)
|
||||||
|
{
|
||||||
|
// evaluated here rather than at class scope, because T is still
|
||||||
|
// incomplete when basic_json instantiates its object_t
|
||||||
|
using move_values = std::integral_constant<bool, detail::conjunction<
|
||||||
|
detail::negation<std::is_nothrow_move_constructible<value_type>>,
|
||||||
|
std::is_copy_constructible<key_type>,
|
||||||
|
detail::is_default_constructible<mapped_type>,
|
||||||
|
std::is_nothrow_move_assignable<mapped_type>>::value>;
|
||||||
|
append_impl(move_values{}, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void append_impl(std::true_type /*unused*/, Args&& ... args)
|
||||||
|
{
|
||||||
|
if (this->size() < this->capacity())
|
||||||
|
{
|
||||||
|
Container::emplace_back(std::forward<Args>(args)...);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. May throw, but only changes tmp: copy the keys, value-initialize
|
||||||
|
// the values, and add the new element. The arguments may refer to
|
||||||
|
// elements of this container, so they are used before any value is
|
||||||
|
// moved out of it.
|
||||||
|
Container tmp(this->get_allocator()); // equal allocators, so swap() is valid
|
||||||
|
tmp.reserve((std::min)(this->max_size(), (std::max)(size_type{1}, 2 * this->size())));
|
||||||
|
for (const auto& element : *this)
|
||||||
|
{
|
||||||
|
tmp.emplace_back(std::piecewise_construct, std::forward_as_tuple(element.first), std::forward_as_tuple());
|
||||||
|
}
|
||||||
|
tmp.emplace_back(std::forward<Args>(args)...);
|
||||||
|
|
||||||
|
// 2. Cannot throw: move the values over and adopt the new storage.
|
||||||
|
auto it = tmp.begin();
|
||||||
|
for (auto& element : *this)
|
||||||
|
{
|
||||||
|
it->second = std::move(element.second);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
Container::swap(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void append_impl(std::false_type /*unused*/, Args&& ... args)
|
||||||
|
{
|
||||||
|
Container::emplace_back(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
|
JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ nlohmann_json_multiple_headers = declare_dependency(
|
|||||||
if not meson.is_subproject()
|
if not meson.is_subproject()
|
||||||
install_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann')
|
install_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann')
|
||||||
install_headers('single_include/nlohmann/json_fwd.hpp', subdir: 'nlohmann')
|
install_headers('single_include/nlohmann/json_fwd.hpp', subdir: 'nlohmann')
|
||||||
|
install_headers('single_include/nlohmann/json_literals.hpp', subdir: 'nlohmann')
|
||||||
|
|
||||||
pkgc = import('pkgconfig')
|
pkgc = import('pkgconfig')
|
||||||
pkgc.generate(name: 'nlohmann_json',
|
pkgc.generate(name: 'nlohmann_json',
|
||||||
|
|||||||
+1857
-483
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,78 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#ifndef INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
|
||||||
|
#define INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
|
||||||
|
|
||||||
|
#include <cstddef> // size_t
|
||||||
|
#include <string> // string
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-header-include-cycle): json.hpp includes this header at its end
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
// This header is included at the end of <nlohmann/json.hpp> unless
|
||||||
|
// JSON_NO_AUTOMATIC_UDLS is defined, and can be included on its own after that.
|
||||||
|
// Either way, the library's internal macros are no longer defined here (and the
|
||||||
|
// amalgamation inlines macro_scope.hpp only once), so only standard and public
|
||||||
|
// macros may be used below.
|
||||||
|
|
||||||
|
// declares the literal operator for the given suffix; GCC 4.8 requires a space
|
||||||
|
// between "" and the suffix, which newer compilers deprecate (CWG 2521)
|
||||||
|
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
|
||||||
|
#define NLOHMANN_JSON_LITERAL_OPERATOR(suffix) operator""##suffix
|
||||||
|
#else
|
||||||
|
#define NLOHMANN_JSON_LITERAL_OPERATOR(suffix) operator"" suffix
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
inline namespace literals
|
||||||
|
{
|
||||||
|
inline namespace json_literals
|
||||||
|
{
|
||||||
|
|
||||||
|
/// @brief user-defined string literal for JSON values
|
||||||
|
/// @sa https://json.nlohmann.me/api/operator_literal_json/
|
||||||
|
inline nlohmann::json NLOHMANN_JSON_LITERAL_OPERATOR(_json)(const char* s, std::size_t n)
|
||||||
|
{
|
||||||
|
return nlohmann::json::parse(s, s + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cpp_char8_t)
|
||||||
|
inline nlohmann::json operator""_json(const char8_t* s, std::size_t n)
|
||||||
|
{
|
||||||
|
return nlohmann::json::parse(reinterpret_cast<const char*>(s),
|
||||||
|
reinterpret_cast<const char*>(s) + n);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// @brief user-defined string literal for JSON pointer
|
||||||
|
/// @sa https://json.nlohmann.me/api/operator_literal_json_pointer/
|
||||||
|
inline nlohmann::json::json_pointer NLOHMANN_JSON_LITERAL_OPERATOR(_json_pointer)(const char* s, std::size_t n)
|
||||||
|
{
|
||||||
|
return nlohmann::json::json_pointer(std::string(s, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cpp_char8_t)
|
||||||
|
inline nlohmann::json::json_pointer operator""_json_pointer(const char8_t* s, std::size_t n)
|
||||||
|
{
|
||||||
|
return nlohmann::json::json_pointer(std::string(reinterpret_cast<const char*>(s), n));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace json_literals
|
||||||
|
} // namespace literals
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#if !defined(JSON_USE_GLOBAL_UDLS) || JSON_USE_GLOBAL_UDLS
|
||||||
|
using nlohmann::literals::json_literals::NLOHMANN_JSON_LITERAL_OPERATOR(_json); // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
|
||||||
|
using nlohmann::literals::json_literals::NLOHMANN_JSON_LITERAL_OPERATOR(_json_pointer); //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef NLOHMANN_JSON_LITERAL_OPERATOR
|
||||||
|
|
||||||
|
#endif // INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
|
||||||
@@ -18,6 +18,7 @@ module;
|
|||||||
// See: https://github.com/nlohmann/json/issues/5103
|
// See: https://github.com/nlohmann/json/issues/5103
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <nlohmann/json_literals.hpp>
|
||||||
|
|
||||||
export module nlohmann.json;
|
export module nlohmann.json;
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,39 @@ BENCHMARK_CAPTURE(ParseIndented, canada / 4, TEST_DATA_DIRECTORY "/nativej
|
|||||||
BENCHMARK_CAPTURE(ParseIndented, citm_catalog / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", 4);
|
BENCHMARK_CAPTURE(ParseIndented, citm_catalog / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", 4);
|
||||||
BENCHMARK_CAPTURE(ParseIndented, twitter / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", 4);
|
BENCHMARK_CAPTURE(ParseIndented, twitter / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", 4);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// parse JSON from string into an ordered_json
|
||||||
|
//
|
||||||
|
// Same as ParseString above, but with nlohmann::ordered_json, whose objects
|
||||||
|
// keep their members in a vector: the pair of rows shows what preserving the
|
||||||
|
// insertion order costs.
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void ParseStringOrdered(benchmark::State& state, const char* filename)
|
||||||
|
{
|
||||||
|
std::ifstream f(filename);
|
||||||
|
std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
|
state.PauseTiming();
|
||||||
|
auto* j = new nlohmann::ordered_json();
|
||||||
|
state.ResumeTiming();
|
||||||
|
|
||||||
|
*j = nlohmann::ordered_json::parse(str);
|
||||||
|
|
||||||
|
state.PauseTiming();
|
||||||
|
delete j;
|
||||||
|
state.ResumeTiming();
|
||||||
|
}
|
||||||
|
|
||||||
|
state.SetBytesProcessed(state.iterations() * str.size());
|
||||||
|
}
|
||||||
|
BENCHMARK_CAPTURE(ParseStringOrdered, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json");
|
||||||
|
BENCHMARK_CAPTURE(ParseStringOrdered, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json");
|
||||||
|
BENCHMARK_CAPTURE(ParseStringOrdered, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json");
|
||||||
|
BENCHMARK_CAPTURE(ParseStringOrdered, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json");
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// serialize JSON
|
// serialize JSON
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -0,0 +1,599 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array> // array
|
||||||
|
#include <cstdint> // uint32_t, uint64_t
|
||||||
|
|
||||||
|
// Number tokens that are hard to round correctly, with the IEEE-754 binary64
|
||||||
|
// and binary32 bits of their correctly rounded values (ties to even; infinity
|
||||||
|
// for an overflow, a signed zero for an underflow).
|
||||||
|
//
|
||||||
|
// For doubles and floats around 0, the smallest normal number, 1, 2^24, 2^53,
|
||||||
|
// 0.1, and the largest finite number, and for random ones, the exact midpoint
|
||||||
|
// m to the next number gives: m, m with one unit more and less in the last
|
||||||
|
// digit, m with "01" and "0...01" appended, m with trailing zeros, and m cut
|
||||||
|
// after 17 to 30 digits (rounded down and up, so that the rounding is decided
|
||||||
|
// after the 19th digit), in fixed and exponent notation, 30% of them negative.
|
||||||
|
// Tokens longer than 80 characters are left out, except for four of 700 digits
|
||||||
|
// and more. Zeros, underflow, overflow, huge exponents, and integers beyond 64
|
||||||
|
// bits complete the set. Of the 508 tokens, 134 (as double) and 150 (as
|
||||||
|
// float) need the exact comparison with the midpoint (detail::digit_comparison()).
|
||||||
|
//
|
||||||
|
// The expected bits were computed with exact rational arithmetic in Python
|
||||||
|
// (fractions.Fraction) and cross-checked with Python's float(); strtod_l and
|
||||||
|
// strtof_l of Apple's libc and of glibc agree. Generated by
|
||||||
|
// compact_hard_cases.py 5 (with hard_cases.py), see the pull request that
|
||||||
|
// added this file.
|
||||||
|
|
||||||
|
namespace float_hard_cases
|
||||||
|
{
|
||||||
|
|
||||||
|
struct hard_case
|
||||||
|
{
|
||||||
|
const char* token;
|
||||||
|
std::uint64_t bits64;
|
||||||
|
std::uint32_t bits32;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const std::array<hard_case, 508>& cases()
|
||||||
|
{
|
||||||
|
static const std::array<hard_case, 508> table =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{"-2.4703282292062327e-324", 0x8000000000000000u, 0x80000000u},
|
||||||
|
{"24703282292062328e-340", 0x0000000000000001u, 0x00000000u},
|
||||||
|
{"247032822920623272e-341", 0x0000000000000000u, 0x00000000u},
|
||||||
|
{"-0.2470328229206232721e-323", 0x8000000000000001u, 0x80000000u},
|
||||||
|
{"-0.24703282292062327208e-323", 0x8000000000000000u, 0x80000000u},
|
||||||
|
{"-2.4703282292062327209e-324", 0x8000000000000001u, 0x80000000u},
|
||||||
|
{"2.47032822920623272088e-324", 0x0000000000000000u, 0x00000000u},
|
||||||
|
{"247032822920623272089e-344", 0x0000000000000001u, 0x00000000u},
|
||||||
|
{"-247032822920623272088284396434e-353", 0x8000000000000000u, 0x80000000u},
|
||||||
|
{"0.247032822920623272088284396435e-323", 0x0000000000000001u, 0x00000000u},
|
||||||
|
{"-74109846876186981e-340", 0x8000000000000001u, 0x80000000u},
|
||||||
|
{"0.74109846876186982e-323", 0x0000000000000002u, 0x00000000u},
|
||||||
|
{"-0.7410984687618698162e-323", 0x8000000000000001u, 0x80000000u},
|
||||||
|
{"-7.410984687618698163e-324", 0x8000000000000002u, 0x80000000u},
|
||||||
|
{"7.4109846876186981626e-324", 0x0000000000000001u, 0x00000000u},
|
||||||
|
{"-74109846876186981627e-343", 0x8000000000000002u, 0x80000000u},
|
||||||
|
{"-741098468761869816264e-344", 0x8000000000000001u, 0x80000000u},
|
||||||
|
{"0.741098468761869816265e-323", 0x0000000000000002u, 0x00000000u},
|
||||||
|
{"0.741098468761869816264853189302e-323", 0x0000000000000001u, 0x00000000u},
|
||||||
|
{"-7.41098468761869816264853189303e-324", 0x8000000000000002u, 0x80000000u},
|
||||||
|
{"0.22250738585072006e-307", 0x000FFFFFFFFFFFFEu, 0x00000000u},
|
||||||
|
{"2.2250738585072007e-308", 0x000FFFFFFFFFFFFFu, 0x00000000u},
|
||||||
|
{"2.225073858507200641e-308", 0x000FFFFFFFFFFFFEu, 0x00000000u},
|
||||||
|
{"-2225073858507200642e-326", 0x800FFFFFFFFFFFFFu, 0x80000000u},
|
||||||
|
{"22250738585072006419e-327", 0x000FFFFFFFFFFFFEu, 0x00000000u},
|
||||||
|
{"0.2225073858507200642e-307", 0x000FFFFFFFFFFFFFu, 0x00000000u},
|
||||||
|
{"0.222507385850720064199e-307", 0x000FFFFFFFFFFFFEu, 0x00000000u},
|
||||||
|
{"2.225073858507200642e-308", 0x000FFFFFFFFFFFFFu, 0x00000000u},
|
||||||
|
{"-2.22507385850720064199176395546e-308", 0x800FFFFFFFFFFFFEu, 0x80000000u},
|
||||||
|
{"222507385850720064199176395547e-337", 0x000FFFFFFFFFFFFFu, 0x00000000u},
|
||||||
|
{"-2.2250738585072011e-308", 0x800FFFFFFFFFFFFFu, 0x80000000u},
|
||||||
|
{"-22250738585072012e-324", 0x8010000000000000u, 0x80000000u},
|
||||||
|
{"-2225073858507201136e-326", 0x800FFFFFFFFFFFFFu, 0x80000000u},
|
||||||
|
{"0.2225073858507201137e-307", 0x0010000000000000u, 0x00000000u},
|
||||||
|
{"0.2225073858507201136e-307", 0x000FFFFFFFFFFFFFu, 0x00000000u},
|
||||||
|
{"-2.2250738585072011361e-308", 0x8010000000000000u, 0x80000000u},
|
||||||
|
{"2.22507385850720113605e-308", 0x000FFFFFFFFFFFFFu, 0x00000000u},
|
||||||
|
{"222507385850720113606e-328", 0x0010000000000000u, 0x00000000u},
|
||||||
|
{"22250738585072011360574097967e-336", 0x000FFFFFFFFFFFFFu, 0x00000000u},
|
||||||
|
{"0.222507385850720113605740979671e-307", 0x0010000000000000u, 0x00000000u},
|
||||||
|
{"22250738585072016e-324", 0x0010000000000000u, 0x00000000u},
|
||||||
|
{"0.22250738585072017e-307", 0x0010000000000001u, 0x00000000u},
|
||||||
|
{"0.222507385850720163e-307", 0x0010000000000000u, 0x00000000u},
|
||||||
|
{"2.225073858507201631e-308", 0x0010000000000001u, 0x00000000u},
|
||||||
|
{"-2.2250738585072016301e-308", 0x8010000000000000u, 0x80000000u},
|
||||||
|
{"22250738585072016302e-327", 0x0010000000000001u, 0x00000000u},
|
||||||
|
{"-222507385850720163012e-328", 0x8010000000000000u, 0x80000000u},
|
||||||
|
{"0.222507385850720163013e-307", 0x0010000000000001u, 0x00000000u},
|
||||||
|
{"0.222507385850720163012305563795e-307", 0x0010000000000000u, 0x00000000u},
|
||||||
|
{"-2.22507385850720163012305563796e-308", 0x8010000000000001u, 0x80000000u},
|
||||||
|
{"0.17976931348623156E+309", 0x7FEFFFFFFFFFFFFEu, 0x7F800000u},
|
||||||
|
{"1.7976931348623157e308", 0x7FEFFFFFFFFFFFFFu, 0x7F800000u},
|
||||||
|
{"1.797693134862315608e308", 0x7FEFFFFFFFFFFFFEu, 0x7F800000u},
|
||||||
|
{"-1797693134862315609e290", 0xFFEFFFFFFFFFFFFFu, 0xFF800000u},
|
||||||
|
{"-17976931348623156083e289", 0xFFEFFFFFFFFFFFFEu, 0xFF800000u},
|
||||||
|
{"-0.17976931348623156084E+309", 0xFFEFFFFFFFFFFFFFu, 0xFF800000u},
|
||||||
|
{"0.179769313486231560835E+309", 0x7FEFFFFFFFFFFFFEu, 0x7F800000u},
|
||||||
|
{"-1.79769313486231560836e308", 0xFFEFFFFFFFFFFFFFu, 0xFF800000u},
|
||||||
|
{"1.79769313486231560835325876058e308", 0x7FEFFFFFFFFFFFFEu, 0x7F800000u},
|
||||||
|
{"179769313486231560835325876059e279", 0x7FEFFFFFFFFFFFFFu, 0x7F800000u},
|
||||||
|
{"1.7976931348623158e308", 0x7FEFFFFFFFFFFFFFu, 0x7F800000u},
|
||||||
|
{"17976931348623159e292", 0x7FF0000000000000u, 0x7F800000u},
|
||||||
|
{"1797693134862315807e290", 0x7FEFFFFFFFFFFFFFu, 0x7F800000u},
|
||||||
|
{"0.1797693134862315808E+309", 0x7FF0000000000000u, 0x7F800000u},
|
||||||
|
{"0.17976931348623158079E+309", 0x7FEFFFFFFFFFFFFFu, 0x7F800000u},
|
||||||
|
{"-1.797693134862315808e308", 0xFFF0000000000000u, 0xFF800000u},
|
||||||
|
{"1.79769313486231580793e308", 0x7FEFFFFFFFFFFFFFu, 0x7F800000u},
|
||||||
|
{"179769313486231580794e288", 0x7FF0000000000000u, 0x7F800000u},
|
||||||
|
{"179769313486231580793728971405e279", 0x7FEFFFFFFFFFFFFFu, 0x7F800000u},
|
||||||
|
{"-0.179769313486231580793728971406E+309", 0xFFF0000000000000u, 0xFF800000u},
|
||||||
|
{"100000000000000011102230246251565404236316680908203125e-53", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"-1.00000000000000011102230246251565404236316680908203126", 0xBFF0000000000001u, 0xBF800000u},
|
||||||
|
{"1.00000000000000011102230246251565404236316680908203124e0", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"10000000000000001110223024625156540423631668090820312501e-55", 0x3FF0000000000001u, 0x3F800000u},
|
||||||
|
{"1.00000000000000011102230246251565404236316680908203125000000000000000000001", 0x3FF0000000000001u, 0x3F800000u},
|
||||||
|
{"10000000000000001e-16", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"1.0000000000000002", 0x3FF0000000000001u, 0x3F800000u},
|
||||||
|
{"1.000000000000000111", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"1.000000000000000112e0", 0x3FF0000000000001u, 0x3F800000u},
|
||||||
|
{"1.000000000000000111e0", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"-10000000000000001111e-19", 0xBFF0000000000001u, 0xBF800000u},
|
||||||
|
{"-100000000000000011102e-20", 0xBFF0000000000000u, 0xBF800000u},
|
||||||
|
{"-1.00000000000000011103", 0xBFF0000000000001u, 0xBF800000u},
|
||||||
|
{"1.00000000000000011102230246251", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"1.00000000000000011102230246252e0", 0x3FF0000000000001u, 0x3F800000u},
|
||||||
|
{"-0.999999999999999944488848768742172978818416595458984375", 0xBFF0000000000000u, 0xBF800000u},
|
||||||
|
{"-9.99999999999999944488848768742172978818416595458984376e-1", 0xBFF0000000000000u, 0xBF800000u},
|
||||||
|
{"999999999999999944488848768742172978818416595458984374e-54", 0x3FEFFFFFFFFFFFFFu, 0x3F800000u},
|
||||||
|
{"0.99999999999999994448884876874217297881841659545898437501", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"9.99999999999999944488848768742172978818416595458984375000000000000000000001e-1", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"-0.99999999999999994", 0xBFEFFFFFFFFFFFFFu, 0xBF800000u},
|
||||||
|
{"9.9999999999999995e-1", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"9.999999999999999444e-1", 0x3FEFFFFFFFFFFFFFu, 0x3F800000u},
|
||||||
|
{"9999999999999999445e-19", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"99999999999999994448e-20", 0x3FEFFFFFFFFFFFFFu, 0x3F800000u},
|
||||||
|
{"-0.99999999999999994449", 0xBFF0000000000000u, 0xBF800000u},
|
||||||
|
{"0.999999999999999944488", 0x3FEFFFFFFFFFFFFFu, 0x3F800000u},
|
||||||
|
{"-9.99999999999999944489e-1", 0xBFF0000000000000u, 0xBF800000u},
|
||||||
|
{"9.99999999999999944488848768742e-1", 0x3FEFFFFFFFFFFFFFu, 0x3F800000u},
|
||||||
|
{"999999999999999944488848768743e-30", 0x3FF0000000000000u, 0x3F800000u},
|
||||||
|
{"-9.007199254740993e15", 0xC340000000000000u, 0xDA000000u},
|
||||||
|
{"9007199254740994e0", 0x4340000000000001u, 0x5A000000u},
|
||||||
|
{"9007199254740992", 0x4340000000000000u, 0x5A000000u},
|
||||||
|
{"9.00719925474099301e15", 0x4340000000000001u, 0x5A000000u},
|
||||||
|
{"9007199254740993000000000000000000001e-21", 0x4340000000000001u, 0x5A000000u},
|
||||||
|
{"-9007199254740993.000000000000000000000000000000", 0xC340000000000000u, 0xDA000000u},
|
||||||
|
{"90071992547409915e-1", 0x4340000000000000u, 0x5A000000u},
|
||||||
|
{"-9007199254740991.6", 0xC340000000000000u, 0xDA000000u},
|
||||||
|
{"9.0071992547409914e15", 0x433FFFFFFFFFFFFFu, 0x5A000000u},
|
||||||
|
{"-9007199254740991501e-3", 0xC340000000000000u, 0xDA000000u},
|
||||||
|
{"9007199254740991.5000000000000000000001", 0x4340000000000000u, 0x5A000000u},
|
||||||
|
{"9.0071992547409915000000000000000000000000000000e15", 0x4340000000000000u, 0x5A000000u},
|
||||||
|
{"0.100000000000000012490009027033011079765856266021728515625", 0x3FB999999999999Au, 0x3DCCCCCDu},
|
||||||
|
{"1.00000000000000012490009027033011079765856266021728515626e-1", 0x3FB999999999999Bu, 0x3DCCCCCDu},
|
||||||
|
{"100000000000000012490009027033011079765856266021728515624e-57", 0x3FB999999999999Au, 0x3DCCCCCDu},
|
||||||
|
{"0.10000000000000001249000902703301107976585626602172851562501", 0x3FB999999999999Bu, 0x3DCCCCCDu},
|
||||||
|
{"0.10000000000000001", 0x3FB999999999999Au, 0x3DCCCCCDu},
|
||||||
|
{"1.0000000000000002e-1", 0x3FB999999999999Bu, 0x3DCCCCCDu},
|
||||||
|
{"-1.000000000000000124e-1", 0xBFB999999999999Au, 0xBDCCCCCDu},
|
||||||
|
{"1000000000000000125e-19", 0x3FB999999999999Bu, 0x3DCCCCCDu},
|
||||||
|
{"-10000000000000001249e-20", 0xBFB999999999999Au, 0xBDCCCCCDu},
|
||||||
|
{"0.1000000000000000125", 0x3FB999999999999Bu, 0x3DCCCCCDu},
|
||||||
|
{"0.10000000000000001249", 0x3FB999999999999Au, 0x3DCCCCCDu},
|
||||||
|
{"1.00000000000000012491e-1", 0x3FB999999999999Bu, 0x3DCCCCCDu},
|
||||||
|
{"1.00000000000000012490009027033e-1", 0x3FB999999999999Au, 0x3DCCCCCDu},
|
||||||
|
{"100000000000000012490009027034e-30", 0x3FB999999999999Bu, 0x3DCCCCCDu},
|
||||||
|
{"2.45134755833537796875e14", 0x42EBDE5C4164D83Au, 0x575EF2E2u},
|
||||||
|
{"-245134755833537796876e-6", 0xC2EBDE5C4164D83Au, 0xD75EF2E2u},
|
||||||
|
{"-245134755833537.796874", 0xC2EBDE5C4164D839u, 0xD75EF2E2u},
|
||||||
|
{"2.4513475583353779687501e14", 0x42EBDE5C4164D83Au, 0x575EF2E2u},
|
||||||
|
{"245134755833537796875000000000000000000001e-27", 0x42EBDE5C4164D83Au, 0x575EF2E2u},
|
||||||
|
{"245134755833537.796875000000000000000000000000000000", 0x42EBDE5C4164D83Au, 0x575EF2E2u},
|
||||||
|
{"2.4513475583353779e14", 0x42EBDE5C4164D839u, 0x575EF2E2u},
|
||||||
|
{"2451347558335378e-1", 0x42EBDE5C4164D83Au, 0x575EF2E2u},
|
||||||
|
{"2451347558335377968e-4", 0x42EBDE5C4164D839u, 0x575EF2E2u},
|
||||||
|
{"245134755833537.7969", 0x42EBDE5C4164D83Au, 0x575EF2E2u},
|
||||||
|
{"245134755833537.79687", 0x42EBDE5C4164D839u, 0x575EF2E2u},
|
||||||
|
{"2.4513475583353779688e14", 0x42EBDE5C4164D83Au, 0x575EF2E2u},
|
||||||
|
{"181510327827821147441864013671875e-23", 0x41DB0C11CB91CE38u, 0x4ED8608Eu},
|
||||||
|
{"-1815103278.27821147441864013671876", 0xC1DB0C11CB91CE38u, 0xCED8608Eu},
|
||||||
|
{"1.81510327827821147441864013671874e9", 0x41DB0C11CB91CE37u, 0x4ED8608Eu},
|
||||||
|
{"18151032782782114744186401367187501e-25", 0x41DB0C11CB91CE38u, 0x4ED8608Eu},
|
||||||
|
{"1815103278.27821147441864013671875000000000000000000001", 0x41DB0C11CB91CE38u, 0x4ED8608Eu},
|
||||||
|
{"-1.81510327827821147441864013671875000000000000000000000000000000e9", 0xC1DB0C11CB91CE38u, 0xCED8608Eu},
|
||||||
|
{"18151032782782114e-7", 0x41DB0C11CB91CE37u, 0x4ED8608Eu},
|
||||||
|
{"1815103278.2782115", 0x41DB0C11CB91CE38u, 0x4ED8608Eu},
|
||||||
|
{"1815103278.278211474", 0x41DB0C11CB91CE37u, 0x4ED8608Eu},
|
||||||
|
{"-1.815103278278211475e9", 0xC1DB0C11CB91CE38u, 0xCED8608Eu},
|
||||||
|
{"1.8151032782782114744e9", 0x41DB0C11CB91CE37u, 0x4ED8608Eu},
|
||||||
|
{"-18151032782782114745e-10", 0xC1DB0C11CB91CE38u, 0xCED8608Eu},
|
||||||
|
{"181510327827821147441e-11", 0x41DB0C11CB91CE37u, 0x4ED8608Eu},
|
||||||
|
{"1815103278.27821147442", 0x41DB0C11CB91CE38u, 0x4ED8608Eu},
|
||||||
|
{"1815103278.27821147441864013671", 0x41DB0C11CB91CE37u, 0x4ED8608Eu},
|
||||||
|
{"1.81510327827821147441864013672e9", 0x41DB0C11CB91CE38u, 0x4ED8608Eu},
|
||||||
|
{"3809325632181785344", 0x43CA6EB8BD69FE2Au, 0x5E5375C6u},
|
||||||
|
{"3.809325632181785345e18", 0x43CA6EB8BD69FE2Au, 0x5E5375C6u},
|
||||||
|
{"3809325632181785343e0", 0x43CA6EB8BD69FE29u, 0x5E5375C6u},
|
||||||
|
{"3809325632181785344.01", 0x43CA6EB8BD69FE2Au, 0x5E5375C6u},
|
||||||
|
{"3.809325632181785344000000000000000000001e18", 0x43CA6EB8BD69FE2Au, 0x5E5375C6u},
|
||||||
|
{"3809325632181785344000000000000000000000000000000e-30", 0x43CA6EB8BD69FE2Au, 0x5E5375C6u},
|
||||||
|
{"3809325632181785300", 0x43CA6EB8BD69FE29u, 0x5E5375C6u},
|
||||||
|
{"3.8093256321817854e18", 0x43CA6EB8BD69FE2Au, 0x5E5375C6u},
|
||||||
|
{"4.046966549916366943359375e12", 0x428D7210076CE2F0u, 0x546B9080u},
|
||||||
|
{"4046966549916366943359376e-12", 0x428D7210076CE2F0u, 0x546B9080u},
|
||||||
|
{"4046966549916.366943359374", 0x428D7210076CE2EFu, 0x546B9080u},
|
||||||
|
{"4.04696654991636694335937501e12", 0x428D7210076CE2F0u, 0x546B9080u},
|
||||||
|
{"4046966549916366943359375000000000000000000001e-33", 0x428D7210076CE2F0u, 0x546B9080u},
|
||||||
|
{"-4046966549916.366943359375000000000000000000000000000000", 0xC28D7210076CE2F0u, 0xD46B9080u},
|
||||||
|
{"4.0469665499163669e12", 0x428D7210076CE2EFu, 0x546B9080u},
|
||||||
|
{"4046966549916367e-3", 0x428D7210076CE2F0u, 0x546B9080u},
|
||||||
|
{"4046966549916366943e-6", 0x428D7210076CE2EFu, 0x546B9080u},
|
||||||
|
{"4046966549916.366944", 0x428D7210076CE2F0u, 0x546B9080u},
|
||||||
|
{"4046966549916.3669433", 0x428D7210076CE2EFu, 0x546B9080u},
|
||||||
|
{"4.0469665499163669434e12", 0x428D7210076CE2F0u, 0x546B9080u},
|
||||||
|
{"-4.04696654991636694335e12", 0xC28D7210076CE2EFu, 0xD46B9080u},
|
||||||
|
{"404696654991636694336e-8", 0x428D7210076CE2F0u, 0x546B9080u},
|
||||||
|
{"28093802557000874e154", 0x63529C3B77330BDBu, 0x7F800000u},
|
||||||
|
{"0.28093802557000875E+171", 0x63529C3B77330BDCu, 0x7F800000u},
|
||||||
|
{"0.2809380255700087447E+171", 0x63529C3B77330BDBu, 0x7F800000u},
|
||||||
|
{"2.809380255700087448e170", 0x63529C3B77330BDCu, 0x7F800000u},
|
||||||
|
{"2.8093802557000874472e170", 0x63529C3B77330BDBu, 0x7F800000u},
|
||||||
|
{"28093802557000874473e151", 0x63529C3B77330BDCu, 0x7F800000u},
|
||||||
|
{"280938025570008744728e150", 0x63529C3B77330BDBu, 0x7F800000u},
|
||||||
|
{"-0.280938025570008744729E+171", 0xE3529C3B77330BDCu, 0xFF800000u},
|
||||||
|
{"-0.280938025570008744728403667979E+171", 0xE3529C3B77330BDBu, 0xFF800000u},
|
||||||
|
{"2.8093802557000874472840366798e170", 0x63529C3B77330BDCu, 0x7F800000u},
|
||||||
|
{"0.39523280297734525e-154", 0x1FE0F51BF17FD374u, 0x00000000u},
|
||||||
|
{"-3.9523280297734526e-155", 0x9FE0F51BF17FD375u, 0x80000000u},
|
||||||
|
{"3.952328029773452547e-155", 0x1FE0F51BF17FD374u, 0x00000000u},
|
||||||
|
{"3952328029773452548e-173", 0x1FE0F51BF17FD375u, 0x00000000u},
|
||||||
|
{"-39523280297734525478e-174", 0x9FE0F51BF17FD374u, 0x80000000u},
|
||||||
|
{"0.39523280297734525479e-154", 0x1FE0F51BF17FD375u, 0x00000000u},
|
||||||
|
{"-0.395232802977345254787e-154", 0x9FE0F51BF17FD374u, 0x80000000u},
|
||||||
|
{"-3.95232802977345254788e-155", 0x9FE0F51BF17FD375u, 0x80000000u},
|
||||||
|
{"-3.95232802977345254787245825501e-155", 0x9FE0F51BF17FD374u, 0x80000000u},
|
||||||
|
{"395232802977345254787245825502e-184", 0x1FE0F51BF17FD375u, 0x00000000u},
|
||||||
|
{"-1.0790205420931879e-276", 0x86A3209CA6233255u, 0x80000000u},
|
||||||
|
{"-1079020542093188e-291", 0x86A3209CA6233256u, 0x80000000u},
|
||||||
|
{"-1079020542093187947e-294", 0x86A3209CA6233255u, 0x80000000u},
|
||||||
|
{"0.1079020542093187948e-275", 0x06A3209CA6233256u, 0x00000000u},
|
||||||
|
{"0.1079020542093187947e-275", 0x06A3209CA6233255u, 0x00000000u},
|
||||||
|
{"1.0790205420931879471e-276", 0x06A3209CA6233256u, 0x00000000u},
|
||||||
|
{"1.07902054209318794701e-276", 0x06A3209CA6233255u, 0x00000000u},
|
||||||
|
{"-107902054209318794702e-296", 0x86A3209CA6233256u, 0x80000000u},
|
||||||
|
{"107902054209318794701153285302e-305", 0x06A3209CA6233255u, 0x00000000u},
|
||||||
|
{"-0.107902054209318794701153285303e-275", 0x86A3209CA6233256u, 0x80000000u},
|
||||||
|
{"58530471071351308e-228", 0x1413B446E6A16A3Bu, 0x00000000u},
|
||||||
|
{"-0.58530471071351309e-211", 0x9413B446E6A16A3Cu, 0x80000000u},
|
||||||
|
{"0.5853047107135130893e-211", 0x1413B446E6A16A3Bu, 0x00000000u},
|
||||||
|
{"-5.853047107135130894e-212", 0x9413B446E6A16A3Cu, 0x80000000u},
|
||||||
|
{"5.853047107135130893e-212", 0x1413B446E6A16A3Bu, 0x00000000u},
|
||||||
|
{"58530471071351308931e-231", 0x1413B446E6A16A3Cu, 0x00000000u},
|
||||||
|
{"-585304710713513089304e-232", 0x9413B446E6A16A3Bu, 0x80000000u},
|
||||||
|
{"0.585304710713513089305e-211", 0x1413B446E6A16A3Cu, 0x00000000u},
|
||||||
|
{"-0.585304710713513089304248824438e-211", 0x9413B446E6A16A3Bu, 0x80000000u},
|
||||||
|
{"5.85304710713513089304248824439e-212", 0x1413B446E6A16A3Cu, 0x00000000u},
|
||||||
|
{"0.19334214893983531e-78", 0x2F96ECBF1CFB10F6u, 0x00000000u},
|
||||||
|
{"1.9334214893983532e-79", 0x2F96ECBF1CFB10F7u, 0x00000000u},
|
||||||
|
{"1.933421489398353102e-79", 0x2F96ECBF1CFB10F6u, 0x00000000u},
|
||||||
|
{"1933421489398353103e-97", 0x2F96ECBF1CFB10F7u, 0x00000000u},
|
||||||
|
{"19334214893983531023e-98", 0x2F96ECBF1CFB10F6u, 0x00000000u},
|
||||||
|
{"0.19334214893983531024e-78", 0x2F96ECBF1CFB10F7u, 0x00000000u},
|
||||||
|
{"0.193342148939835310231e-78", 0x2F96ECBF1CFB10F6u, 0x00000000u},
|
||||||
|
{"1.93342148939835310232e-79", 0x2F96ECBF1CFB10F7u, 0x00000000u},
|
||||||
|
{"-1.93342148939835310231359014704e-79", 0xAF96ECBF1CFB10F6u, 0x80000000u},
|
||||||
|
{"193342148939835310231359014705e-108", 0x2F96ECBF1CFB10F7u, 0x00000000u},
|
||||||
|
{"2.9873358928024455e227", 0x6F2938807814E8A2u, 0x7F800000u},
|
||||||
|
{"29873358928024456e211", 0x6F2938807814E8A3u, 0x7F800000u},
|
||||||
|
{"298733589280244551e210", 0x6F2938807814E8A2u, 0x7F800000u},
|
||||||
|
{"0.2987335892802445511E+228", 0x6F2938807814E8A3u, 0x7F800000u},
|
||||||
|
{"0.29873358928024455109E+228", 0x6F2938807814E8A2u, 0x7F800000u},
|
||||||
|
{"2.987335892802445511e227", 0x6F2938807814E8A3u, 0x7F800000u},
|
||||||
|
{"-2.98733589280244551098e227", 0xEF2938807814E8A2u, 0xFF800000u},
|
||||||
|
{"-298733589280244551099e207", 0xEF2938807814E8A3u, 0xFF800000u},
|
||||||
|
{"298733589280244551098081559931e198", 0x6F2938807814E8A2u, 0x7F800000u},
|
||||||
|
{"0.298733589280244551098081559932E+228", 0x6F2938807814E8A3u, 0x7F800000u},
|
||||||
|
{"7.0064923216240853e-46", 0x3690000000000000u, 0x00000000u},
|
||||||
|
{"70064923216240854e-62", 0x3690000000000000u, 0x00000001u},
|
||||||
|
{"7006492321624085354e-64", 0x3690000000000000u, 0x00000000u},
|
||||||
|
{"-0.7006492321624085355e-45", 0xB690000000000000u, 0x80000001u},
|
||||||
|
{"0.70064923216240853546e-45", 0x3690000000000000u, 0x00000000u},
|
||||||
|
{"7.0064923216240853547e-46", 0x3690000000000000u, 0x00000001u},
|
||||||
|
{"7.00649232162408535461e-46", 0x3690000000000000u, 0x00000000u},
|
||||||
|
{"-700649232162408535462e-66", 0xB690000000000000u, 0x80000001u},
|
||||||
|
{"-700649232162408535461864791644e-75", 0xB690000000000000u, 0x80000000u},
|
||||||
|
{"0.700649232162408535461864791645e-45", 0x3690000000000000u, 0x00000001u},
|
||||||
|
{"21019476964872256e-61", 0x36A8000000000000u, 0x00000001u},
|
||||||
|
{"0.21019476964872257e-44", 0x36A8000000000000u, 0x00000002u},
|
||||||
|
{"-0.2101947696487225606e-44", 0xB6A8000000000000u, 0x80000001u},
|
||||||
|
{"-2.101947696487225607e-45", 0xB6A8000000000000u, 0x80000002u},
|
||||||
|
{"2.1019476964872256063e-45", 0x36A8000000000000u, 0x00000001u},
|
||||||
|
{"21019476964872256064e-64", 0x36A8000000000000u, 0x00000002u},
|
||||||
|
{"-210194769648722560638e-65", 0xB6A8000000000000u, 0x80000001u},
|
||||||
|
{"-0.210194769648722560639e-44", 0xB6A8000000000000u, 0x80000002u},
|
||||||
|
{"-0.210194769648722560638559437493e-44", 0xB6A8000000000000u, 0x80000001u},
|
||||||
|
{"2.10194769648722560638559437494e-45", 0x36A8000000000000u, 0x00000002u},
|
||||||
|
{"0.11754941406275178e-37", 0x380FFFFFA0000000u, 0x007FFFFEu},
|
||||||
|
{"1.1754941406275179e-38", 0x380FFFFFA0000000u, 0x007FFFFFu},
|
||||||
|
{"-1.175494140627517859e-38", 0xB80FFFFFA0000000u, 0x807FFFFEu},
|
||||||
|
{"117549414062751786e-55", 0x380FFFFFA0000000u, 0x007FFFFFu},
|
||||||
|
{"-11754941406275178592e-57", 0xB80FFFFFA0000000u, 0x807FFFFEu},
|
||||||
|
{"0.11754941406275178593e-37", 0x380FFFFFA0000000u, 0x007FFFFFu},
|
||||||
|
{"0.117549414062751785924e-37", 0x380FFFFFA0000000u, 0x007FFFFEu},
|
||||||
|
{"1.17549414062751785925e-38", 0x380FFFFFA0000000u, 0x007FFFFFu},
|
||||||
|
{"-1.17549414062751785924617589866e-38", 0xB80FFFFFA0000000u, 0x807FFFFEu},
|
||||||
|
{"117549414062751785924617589867e-67", 0x380FFFFFA0000000u, 0x007FFFFFu},
|
||||||
|
{"1.1754942807573642e-38", 0x380FFFFFDFFFFFFFu, 0x007FFFFFu},
|
||||||
|
{"11754942807573643e-54", 0x380FFFFFE0000000u, 0x00800000u},
|
||||||
|
{"1175494280757364291e-56", 0x380FFFFFE0000000u, 0x007FFFFFu},
|
||||||
|
{"0.1175494280757364292e-37", 0x380FFFFFE0000000u, 0x00800000u},
|
||||||
|
{"0.11754942807573642917e-37", 0x380FFFFFE0000000u, 0x007FFFFFu},
|
||||||
|
{"-1.1754942807573642918e-38", 0xB80FFFFFE0000000u, 0x80800000u},
|
||||||
|
{"-1.17549428075736429172e-38", 0xB80FFFFFE0000000u, 0x807FFFFFu},
|
||||||
|
{"-117549428075736429173e-58", 0xB80FFFFFE0000000u, 0x80800000u},
|
||||||
|
{"117549428075736429172788299103e-67", 0x380FFFFFE0000000u, 0x007FFFFFu},
|
||||||
|
{"0.117549428075736429172788299104e-37", 0x380FFFFFE0000000u, 0x00800000u},
|
||||||
|
{"11754944208872107e-54", 0x3810000010000000u, 0x00800000u},
|
||||||
|
{"-0.11754944208872108e-37", 0xB810000010000000u, 0x80800001u},
|
||||||
|
{"0.1175494420887210724e-37", 0x3810000010000000u, 0x00800000u},
|
||||||
|
{"1.175494420887210725e-38", 0x3810000010000000u, 0x00800001u},
|
||||||
|
{"1.1754944208872107242e-38", 0x3810000010000000u, 0x00800000u},
|
||||||
|
{"-11754944208872107243e-57", 0xB810000010000000u, 0x80800001u},
|
||||||
|
{"-11754944208872107242e-57", 0xB810000010000000u, 0x80800000u},
|
||||||
|
{"0.117549442088721072421e-37", 0x3810000010000000u, 0x00800001u},
|
||||||
|
{"0.11754944208872107242095900834e-37", 0x3810000010000000u, 0x00800000u},
|
||||||
|
{"-1.17549442088721072420959008341e-38", 0xB810000010000000u, 0x80800001u},
|
||||||
|
{"340282336497324057985868971510891282432", 0x47EFFFFFD0000000u, 0x7F7FFFFEu},
|
||||||
|
{"-3.40282336497324057985868971510891282433e38", 0xC7EFFFFFD0000000u, 0xFF7FFFFFu},
|
||||||
|
{"340282336497324057985868971510891282431e0", 0x47EFFFFFD0000000u, 0x7F7FFFFEu},
|
||||||
|
{"340282336497324057985868971510891282432.01", 0x47EFFFFFD0000000u, 0x7F7FFFFFu},
|
||||||
|
{"3.40282336497324057985868971510891282432000000000000000000001e38", 0x47EFFFFFD0000000u, 0x7F7FFFFFu},
|
||||||
|
{"340282336497324057985868971510891282432000000000000000000000000000000e-30", 0x47EFFFFFD0000000u, 0x7F7FFFFEu},
|
||||||
|
{"340282336497324050000000000000000000000", 0x47EFFFFFD0000000u, 0x7F7FFFFEu},
|
||||||
|
{"3.4028233649732406e38", 0x47EFFFFFD0000000u, 0x7F7FFFFFu},
|
||||||
|
{"3.402823364973240579e38", 0x47EFFFFFD0000000u, 0x7F7FFFFEu},
|
||||||
|
{"340282336497324058e21", 0x47EFFFFFD0000000u, 0x7F7FFFFFu},
|
||||||
|
{"34028233649732405798e19", 0x47EFFFFFD0000000u, 0x7F7FFFFEu},
|
||||||
|
{"340282336497324057990000000000000000000", 0x47EFFFFFD0000000u, 0x7F7FFFFFu},
|
||||||
|
{"340282336497324057985000000000000000000", 0x47EFFFFFD0000000u, 0x7F7FFFFEu},
|
||||||
|
{"3.40282336497324057986e38", 0x47EFFFFFD0000000u, 0x7F7FFFFFu},
|
||||||
|
{"3.4028233649732405798586897151e38", 0x47EFFFFFD0000000u, 0x7F7FFFFEu},
|
||||||
|
{"340282336497324057985868971511e9", 0x47EFFFFFD0000000u, 0x7F7FFFFFu},
|
||||||
|
{"3.40282356779733661637539395458142568448e38", 0x47EFFFFFF0000000u, 0x7F800000u},
|
||||||
|
{"-340282356779733661637539395458142568449e0", 0xC7EFFFFFF0000000u, 0xFF800000u},
|
||||||
|
{"340282356779733661637539395458142568447", 0x47EFFFFFF0000000u, 0x7F7FFFFFu},
|
||||||
|
{"3.4028235677973366163753939545814256844801e38", 0x47EFFFFFF0000000u, 0x7F800000u},
|
||||||
|
{"340282356779733661637539395458142568448000000000000000000001e-21", 0x47EFFFFFF0000000u, 0x7F800000u},
|
||||||
|
{"340282356779733661637539395458142568448.000000000000000000000000000000", 0x47EFFFFFF0000000u, 0x7F800000u},
|
||||||
|
{"3.4028235677973366e38", 0x47EFFFFFF0000000u, 0x7F7FFFFFu},
|
||||||
|
{"-34028235677973367e22", 0xC7EFFFFFF0000000u, 0xFF800000u},
|
||||||
|
{"3402823567797336616e20", 0x47EFFFFFF0000000u, 0x7F7FFFFFu},
|
||||||
|
{"340282356779733661700000000000000000000", 0x47EFFFFFF0000000u, 0x7F800000u},
|
||||||
|
{"340282356779733661630000000000000000000", 0x47EFFFFFF0000000u, 0x7F7FFFFFu},
|
||||||
|
{"3.4028235677973366164e38", 0x47EFFFFFF0000000u, 0x7F800000u},
|
||||||
|
{"3.40282356779733661637e38", 0x47EFFFFFF0000000u, 0x7F7FFFFFu},
|
||||||
|
{"340282356779733661638e18", 0x47EFFFFFF0000000u, 0x7F800000u},
|
||||||
|
{"-340282356779733661637539395458e9", 0xC7EFFFFFF0000000u, 0xFF7FFFFFu},
|
||||||
|
{"340282356779733661637539395459000000000", 0x47EFFFFFF0000000u, 0x7F800000u},
|
||||||
|
{"-1000000059604644775390625e-24", 0xBFF0000010000000u, 0xBF800000u},
|
||||||
|
{"-1.000000059604644775390626", 0xBFF0000010000000u, 0xBF800001u},
|
||||||
|
{"-1.000000059604644775390624e0", 0xBFF0000010000000u, 0xBF800000u},
|
||||||
|
{"100000005960464477539062501e-26", 0x3FF0000010000000u, 0x3F800001u},
|
||||||
|
{"1.000000059604644775390625000000000000000000001", 0x3FF0000010000000u, 0x3F800001u},
|
||||||
|
{"1.000000059604644775390625000000000000000000000000000000e0", 0x3FF0000010000000u, 0x3F800000u},
|
||||||
|
{"-10000000596046447e-16", 0xBFF0000010000000u, 0xBF800000u},
|
||||||
|
{"1.0000000596046448", 0x3FF0000010000000u, 0x3F800001u},
|
||||||
|
{"1.000000059604644775", 0x3FF0000010000000u, 0x3F800000u},
|
||||||
|
{"-1.000000059604644776e0", 0xBFF0000010000000u, 0xBF800001u},
|
||||||
|
{"-1.0000000596046447753e0", 0xBFF0000010000000u, 0xBF800000u},
|
||||||
|
{"10000000596046447754e-19", 0x3FF0000010000000u, 0x3F800001u},
|
||||||
|
{"100000005960464477539e-20", 0x3FF0000010000000u, 0x3F800000u},
|
||||||
|
{"-1.0000000596046447754", 0xBFF0000010000000u, 0xBF800001u},
|
||||||
|
{"0.9999999701976776123046875", 0x3FEFFFFFF0000000u, 0x3F800000u},
|
||||||
|
{"9.999999701976776123046876e-1", 0x3FEFFFFFF0000000u, 0x3F800000u},
|
||||||
|
{"9999999701976776123046874e-25", 0x3FEFFFFFF0000000u, 0x3F7FFFFFu},
|
||||||
|
{"0.999999970197677612304687501", 0x3FEFFFFFF0000000u, 0x3F800000u},
|
||||||
|
{"-9.999999701976776123046875000000000000000000001e-1", 0xBFEFFFFFF0000000u, 0xBF800000u},
|
||||||
|
{"-9999999701976776123046875000000000000000000000000000000e-55", 0xBFEFFFFFF0000000u, 0xBF800000u},
|
||||||
|
{"0.99999997019767761", 0x3FEFFFFFF0000000u, 0x3F7FFFFFu},
|
||||||
|
{"-9.9999997019767762e-1", 0xBFEFFFFFF0000000u, 0xBF800000u},
|
||||||
|
{"-9.999999701976776123e-1", 0xBFEFFFFFF0000000u, 0xBF7FFFFFu},
|
||||||
|
{"9999999701976776124e-19", 0x3FEFFFFFF0000000u, 0x3F800000u},
|
||||||
|
{"9999999701976776123e-19", 0x3FEFFFFFF0000000u, 0x3F7FFFFFu},
|
||||||
|
{"0.99999997019767761231", 0x3FEFFFFFF0000000u, 0x3F800000u},
|
||||||
|
{"-0.999999970197677612304", 0xBFEFFFFFF0000000u, 0xBF7FFFFFu},
|
||||||
|
{"9.99999970197677612305e-1", 0x3FEFFFFFF0000000u, 0x3F800000u},
|
||||||
|
{"-1.6777217e7", 0xC170000010000000u, 0xCB800000u},
|
||||||
|
{"16777218e0", 0x4170000020000000u, 0x4B800001u},
|
||||||
|
{"16777216", 0x4170000000000000u, 0x4B800000u},
|
||||||
|
{"-1.677721701e7", 0xC17000001028F5C3u, 0xCB800001u},
|
||||||
|
{"-16777217000000000000000000001e-21", 0xC170000010000000u, 0xCB800001u},
|
||||||
|
{"16777217.000000000000000000000000000000", 0x4170000010000000u, 0x4B800000u},
|
||||||
|
{"167772155e-1", 0x416FFFFFF0000000u, 0x4B800000u},
|
||||||
|
{"16777215.6", 0x416FFFFFF3333333u, 0x4B800000u},
|
||||||
|
{"1.67772154e7", 0x416FFFFFECCCCCCDu, 0x4B7FFFFFu},
|
||||||
|
{"16777215501e-3", 0x416FFFFFF0083127u, 0x4B800000u},
|
||||||
|
{"-16777215.5000000000000000000001", 0xC16FFFFFF0000000u, 0xCB800000u},
|
||||||
|
{"-1.67772155000000000000000000000000000000e7", 0xC16FFFFFF0000000u, 0xCB800000u},
|
||||||
|
{"0.1000000052154064178466796875", 0x3FB99999B0000000u, 0x3DCCCCCEu},
|
||||||
|
{"1.000000052154064178466796876e-1", 0x3FB99999B0000000u, 0x3DCCCCCEu},
|
||||||
|
{"-1000000052154064178466796874e-28", 0xBFB99999B0000000u, 0xBDCCCCCDu},
|
||||||
|
{"0.100000005215406417846679687501", 0x3FB99999B0000000u, 0x3DCCCCCEu},
|
||||||
|
{"1.000000052154064178466796875000000000000000000001e-1", 0x3FB99999B0000000u, 0x3DCCCCCEu},
|
||||||
|
{"-1000000052154064178466796875000000000000000000000000000000e-58", 0xBFB99999B0000000u, 0xBDCCCCCEu},
|
||||||
|
{"-0.10000000521540641", 0xBFB99999AFFFFFFFu, 0xBDCCCCCDu},
|
||||||
|
{"-1.0000000521540642e-1", 0xBFB99999B0000000u, 0xBDCCCCCEu},
|
||||||
|
{"1.000000052154064178e-1", 0x3FB99999B0000000u, 0x3DCCCCCDu},
|
||||||
|
{"-1000000052154064179e-19", 0xBFB99999B0000000u, 0xBDCCCCCEu},
|
||||||
|
{"10000000521540641784e-20", 0x3FB99999B0000000u, 0x3DCCCCCDu},
|
||||||
|
{"0.10000000521540641785", 0x3FB99999B0000000u, 0x3DCCCCCEu},
|
||||||
|
{"0.100000005215406417846", 0x3FB99999B0000000u, 0x3DCCCCCDu},
|
||||||
|
{"1.00000005215406417847e-1", 0x3FB99999B0000000u, 0x3DCCCCCEu},
|
||||||
|
{"5.429001220703125e3", 0x40B5350050000000u, 0x45A9A802u},
|
||||||
|
{"-5429001220703126e-12", 0xC0B5350050000001u, 0xC5A9A803u},
|
||||||
|
{"-5429.001220703124", 0xC0B535004FFFFFFFu, 0xC5A9A802u},
|
||||||
|
{"5.42900122070312501e3", 0x40B5350050000000u, 0x45A9A803u},
|
||||||
|
{"5429001220703125000000000000000000001e-33", 0x40B5350050000000u, 0x45A9A803u},
|
||||||
|
{"-5429.001220703125000000000000000000000000000000", 0xC0B5350050000000u, 0xC5A9A802u},
|
||||||
|
{"503719056e0", 0x41BE062490000000u, 0x4DF03124u},
|
||||||
|
{"503719057", 0x41BE062491000000u, 0x4DF03125u},
|
||||||
|
{"5.03719055e8", 0x41BE06248F000000u, 0x4DF03124u},
|
||||||
|
{"50371905601e-2", 0x41BE062490028F5Cu, 0x4DF03125u},
|
||||||
|
{"503719056.000000000000000000001", 0x41BE062490000000u, 0x4DF03125u},
|
||||||
|
{"5.03719056000000000000000000000000000000e8", 0x41BE062490000000u, 0x4DF03124u},
|
||||||
|
{"-92331620", 0xC196037990000000u, 0xCCB01BCCu},
|
||||||
|
{"9.233163e7", 0x41960379B8000000u, 0x4CB01BCEu},
|
||||||
|
{"9233161e1", 0x4196037968000000u, 0x4CB01BCBu},
|
||||||
|
{"92331620.1", 0x4196037990666666u, 0x4CB01BCDu},
|
||||||
|
{"9.233162000000000000000000001e7", 0x4196037990000000u, 0x4CB01BCDu},
|
||||||
|
{"9233162000000000000000000000000000000e-29", 0x4196037990000000u, 0x4CB01BCCu},
|
||||||
|
{"3.002458625e6", 0x4146E82D50000000u, 0x4A37416Au},
|
||||||
|
{"3002458626e-3", 0x4146E82D5020C49Cu, 0x4A37416Bu},
|
||||||
|
{"3002458.624", 0x4146E82D4FDF3B64u, 0x4A37416Au},
|
||||||
|
{"-3.00245862501e6", 0xC146E82D500053E3u, 0xCA37416Bu},
|
||||||
|
{"3002458625000000000000000000001e-24", 0x4146E82D50000000u, 0x4A37416Bu},
|
||||||
|
{"3002458.625000000000000000000000000000000", 0x4146E82D50000000u, 0x4A37416Au},
|
||||||
|
{"-1095485584696182596504479582065262592e1", 0xC7A07BA830000000u, 0xFD03DD42u},
|
||||||
|
{"10954855846961825965044795820652625930", 0x47A07BA830000000u, 0x7D03DD42u},
|
||||||
|
{"1.095485584696182596504479582065262591e37", 0x47A07BA830000000u, 0x7D03DD41u},
|
||||||
|
{"109548558469618259650447958206526259201e-1", 0x47A07BA830000000u, 0x7D03DD42u},
|
||||||
|
{"-10954855846961825965044795820652625920.00000000000000000001", 0xC7A07BA830000000u, 0xFD03DD42u},
|
||||||
|
{"1.095485584696182596504479582065262592000000000000000000000000000000e37", 0x47A07BA830000000u, 0x7D03DD42u},
|
||||||
|
{"10954855846961825e21", 0x47A07BA830000000u, 0x7D03DD41u},
|
||||||
|
{"10954855846961826000000000000000000000", 0x47A07BA830000000u, 0x7D03DD42u},
|
||||||
|
{"10954855846961825960000000000000000000", 0x47A07BA830000000u, 0x7D03DD41u},
|
||||||
|
{"1.095485584696182597e37", 0x47A07BA830000000u, 0x7D03DD42u},
|
||||||
|
{"1.0954855846961825965e37", 0x47A07BA830000000u, 0x7D03DD41u},
|
||||||
|
{"-10954855846961825966e18", 0xC7A07BA830000000u, 0xFD03DD42u},
|
||||||
|
{"10954855846961825965e18", 0x47A07BA830000000u, 0x7D03DD41u},
|
||||||
|
{"10954855846961825965100000000000000000", 0x47A07BA830000000u, 0x7D03DD42u},
|
||||||
|
{"10954855846961825965044795820600000000", 0x47A07BA830000000u, 0x7D03DD41u},
|
||||||
|
{"-1.09548558469618259650447958207e37", 0xC7A07BA830000000u, 0xFD03DD42u},
|
||||||
|
{"1.6449216019182103706535606608388384863861375606575165875256061553955078126e-21", 0x3B9F125A50000000u, 0x1CF892D3u},
|
||||||
|
{"-16449216019182103706535606608388384863861375606575165875256061553955078124e-94", 0xBB9F125A50000000u, 0x9CF892D2u},
|
||||||
|
{"-0.0000000000000000000016449216019182103", 0xBB9F125A50000000u, 0x9CF892D2u},
|
||||||
|
{"-1.6449216019182104e-21", 0xBB9F125A50000000u, 0x9CF892D3u},
|
||||||
|
{"-1.64492160191821037e-21", 0xBB9F125A50000000u, 0x9CF892D2u},
|
||||||
|
{"-1644921601918210371e-39", 0xBB9F125A50000000u, 0x9CF892D3u},
|
||||||
|
{"-16449216019182103706e-40", 0xBB9F125A50000000u, 0x9CF892D2u},
|
||||||
|
{"0.0000000000000000000016449216019182103707", 0x3B9F125A50000000u, 0x1CF892D3u},
|
||||||
|
{"0.00000000000000000000164492160191821037065", 0x3B9F125A50000000u, 0x1CF892D2u},
|
||||||
|
{"1.64492160191821037066e-21", 0x3B9F125A50000000u, 0x1CF892D3u},
|
||||||
|
{"1.64492160191821037065356066083e-21", 0x3B9F125A50000000u, 0x1CF892D2u},
|
||||||
|
{"164492160191821037065356066084e-50", 0x3B9F125A50000000u, 0x1CF892D3u},
|
||||||
|
{"6.565061509609222412109375e-1", 0x3FE5021930000000u, 0x3F2810CAu},
|
||||||
|
{"6565061509609222412109376e-25", 0x3FE5021930000000u, 0x3F2810CAu},
|
||||||
|
{"0.6565061509609222412109374", 0x3FE5021930000000u, 0x3F2810C9u},
|
||||||
|
{"6.56506150960922241210937501e-1", 0x3FE5021930000000u, 0x3F2810CAu},
|
||||||
|
{"6565061509609222412109375000000000000000000001e-46", 0x3FE5021930000000u, 0x3F2810CAu},
|
||||||
|
{"-0.6565061509609222412109375000000000000000000000000000000", 0xBFE5021930000000u, 0xBF2810CAu},
|
||||||
|
{"6.5650615096092224e-1", 0x3FE5021930000000u, 0x3F2810C9u},
|
||||||
|
{"-65650615096092225e-17", 0xBFE5021930000000u, 0xBF2810CAu},
|
||||||
|
{"6565061509609222412e-19", 0x3FE5021930000000u, 0x3F2810C9u},
|
||||||
|
{"0.6565061509609222413", 0x3FE5021930000000u, 0x3F2810CAu},
|
||||||
|
{"0.65650615096092224121", 0x3FE5021930000000u, 0x3F2810C9u},
|
||||||
|
{"6.5650615096092224122e-1", 0x3FE5021930000000u, 0x3F2810CAu},
|
||||||
|
{"-6.5650615096092224121e-1", 0xBFE5021930000000u, 0xBF2810C9u},
|
||||||
|
{"656506150960922241211e-21", 0x3FE5021930000000u, 0x3F2810CAu},
|
||||||
|
{"18014627239033005156980393746124491372029297053813934326171875e-77", 0x3CA9F63970000000u, 0x254FB1CCu},
|
||||||
|
{"0.00000000000000018014627239033005156980393746124491372029297053813934326171876", 0x3CA9F63970000000u, 0x254FB1CCu},
|
||||||
|
{"-1.8014627239033005156980393746124491372029297053813934326171874e-16", 0xBCA9F63970000000u, 0xA54FB1CBu},
|
||||||
|
{"1801462723903300515698039374612449137202929705381393432617187501e-79", 0x3CA9F63970000000u, 0x254FB1CCu},
|
||||||
|
{"18014627239033005e-32", 0x3CA9F63970000000u, 0x254FB1CBu},
|
||||||
|
{"0.00000000000000018014627239033006", 0x3CA9F63970000000u, 0x254FB1CCu},
|
||||||
|
{"0.0000000000000001801462723903300515", 0x3CA9F63970000000u, 0x254FB1CBu},
|
||||||
|
{"-1.801462723903300516e-16", 0xBCA9F63970000000u, 0xA54FB1CCu},
|
||||||
|
{"-1.8014627239033005156e-16", 0xBCA9F63970000000u, 0xA54FB1CBu},
|
||||||
|
{"18014627239033005157e-35", 0x3CA9F63970000000u, 0x254FB1CCu},
|
||||||
|
{"180146272390330051569e-36", 0x3CA9F63970000000u, 0x254FB1CBu},
|
||||||
|
{"-0.00000000000000018014627239033005157", 0xBCA9F63970000000u, 0xA54FB1CCu},
|
||||||
|
{"0.000000000000000180146272390330051569803937461", 0x3CA9F63970000000u, 0x254FB1CBu},
|
||||||
|
{"1.80146272390330051569803937462e-16", 0x3CA9F63970000000u, 0x254FB1CCu},
|
||||||
|
{"0.05534819327294826507568359375", 0x3FAC569930000000u, 0x3D62B4CAu},
|
||||||
|
{"-5.534819327294826507568359376e-2", 0xBFAC569930000000u, 0xBD62B4CAu},
|
||||||
|
{"5534819327294826507568359374e-29", 0x3FAC569930000000u, 0x3D62B4C9u},
|
||||||
|
{"-0.0553481932729482650756835937501", 0xBFAC569930000000u, 0xBD62B4CAu},
|
||||||
|
{"5.534819327294826507568359375000000000000000000001e-2", 0x3FAC569930000000u, 0x3D62B4CAu},
|
||||||
|
{"5534819327294826507568359375000000000000000000000000000000e-59", 0x3FAC569930000000u, 0x3D62B4CAu},
|
||||||
|
{"0.055348193272948265", 0x3FAC569930000000u, 0x3D62B4C9u},
|
||||||
|
{"5.5348193272948266e-2", 0x3FAC569930000000u, 0x3D62B4CAu},
|
||||||
|
{"5.534819327294826507e-2", 0x3FAC569930000000u, 0x3D62B4C9u},
|
||||||
|
{"5534819327294826508e-20", 0x3FAC569930000000u, 0x3D62B4CAu},
|
||||||
|
{"55348193272948265075e-21", 0x3FAC569930000000u, 0x3D62B4C9u},
|
||||||
|
{"-0.055348193272948265076", 0xBFAC569930000000u, 0xBD62B4CAu},
|
||||||
|
{"0.0553481932729482650756", 0x3FAC569930000000u, 0x3D62B4C9u},
|
||||||
|
{"-5.53481932729482650757e-2", 0xBFAC569930000000u, 0xBD62B4CAu},
|
||||||
|
{"5.179692133247783258005389047985340416e36", 0x478F2C9450000000u, 0x7C7964A2u},
|
||||||
|
{"5179692133247783258005389047985340417e0", 0x478F2C9450000000u, 0x7C7964A3u},
|
||||||
|
{"5179692133247783258005389047985340415", 0x478F2C9450000000u, 0x7C7964A2u},
|
||||||
|
{"-5.17969213324778325800538904798534041601e36", 0xC78F2C9450000000u, 0xFC7964A3u},
|
||||||
|
{"-5179692133247783258005389047985340416000000000000000000001e-21", 0xC78F2C9450000000u, 0xFC7964A3u},
|
||||||
|
{"-5179692133247783258005389047985340416.000000000000000000000000000000", 0xC78F2C9450000000u, 0xFC7964A2u},
|
||||||
|
{"5.1796921332477832e36", 0x478F2C9450000000u, 0x7C7964A2u},
|
||||||
|
{"51796921332477833e20", 0x478F2C9450000000u, 0x7C7964A3u},
|
||||||
|
{"-5179692133247783258e18", 0xC78F2C9450000000u, 0xFC7964A2u},
|
||||||
|
{"5179692133247783259000000000000000000", 0x478F2C9450000000u, 0x7C7964A3u},
|
||||||
|
{"5179692133247783258000000000000000000", 0x478F2C9450000000u, 0x7C7964A2u},
|
||||||
|
{"5.1796921332477832581e36", 0x478F2C9450000000u, 0x7C7964A3u},
|
||||||
|
{"-5.179692133247783258e36", 0xC78F2C9450000000u, 0xFC7964A2u},
|
||||||
|
{"-517969213324778325801e16", 0xC78F2C9450000000u, 0xFC7964A3u},
|
||||||
|
{"517969213324778325800538904798e7", 0x478F2C9450000000u, 0x7C7964A2u},
|
||||||
|
{"5179692133247783258005389047990000000", 0x478F2C9450000000u, 0x7C7964A3u},
|
||||||
|
{
|
||||||
|
"0.22250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350"
|
||||||
|
"8791414915891303962110687008643869459464552765720740782062174337998814106326732925355228688137214901"
|
||||||
|
"2981122451451889849057222307285255133155755015914397476397983411801999323962548289017107081850690630"
|
||||||
|
"6666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050"
|
||||||
|
"5108060994073026293712895895000358379996720725430436028407889577179615094551674824347103070260914462"
|
||||||
|
"1572289880258182545180325707018860872113128079512233426288368622321503775666622503982534335974568884"
|
||||||
|
"4239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704"
|
||||||
|
"2756718644338377048603786162277173854562306587467901408672332763671875e-307", 0x0010000000000000u, 0x00000000u
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
|
||||||
|
"7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
|
||||||
|
"9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
|
||||||
|
"6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505"
|
||||||
|
"1080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621"
|
||||||
|
"5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844"
|
||||||
|
"2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042"
|
||||||
|
"756718644338377048603786162277173854562306587467901408672332763671875000000000000000000001e-308", 0x0010000000000000u, 0x00000000u
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"0.11754942807573642917278829910357665133228589927589904276829631184250030649651730385585324256680905"
|
||||||
|
"8189392089843750000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"00000000000000000000000000000000000000000000000000000000000000000e-37", 0x380FFFFFE0000000u, 0x00800000u
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"1175494280757364291727882991035766513322858992758990427682963118425003064965173038558532425668090581"
|
||||||
|
"8939208984375000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
"00000000000001e-751", 0x380FFFFFE0000000u, 0x00800000u
|
||||||
|
},
|
||||||
|
{"0", 0x0000000000000000u, 0x00000000u},
|
||||||
|
{"-0", 0x8000000000000000u, 0x80000000u},
|
||||||
|
{"0.0", 0x0000000000000000u, 0x00000000u},
|
||||||
|
{"-0.0", 0x8000000000000000u, 0x80000000u},
|
||||||
|
{"0e999999999999999999999", 0x0000000000000000u, 0x00000000u},
|
||||||
|
{"-0.000e-99999", 0x8000000000000000u, 0x80000000u},
|
||||||
|
{"1e-400", 0x0000000000000000u, 0x00000000u},
|
||||||
|
{"-1e-400", 0x8000000000000000u, 0x80000000u},
|
||||||
|
{"1e400", 0x7FF0000000000000u, 0x7F800000u},
|
||||||
|
{"-1e400", 0xFFF0000000000000u, 0xFF800000u},
|
||||||
|
{"1e-50", 0x358DEE7A4AD4B81Fu, 0x00000000u},
|
||||||
|
{"-1e-50", 0xB58DEE7A4AD4B81Fu, 0x80000000u},
|
||||||
|
{"1e39", 0x48078287F49C4A1Du, 0x7F800000u},
|
||||||
|
{"-1e39", 0xC8078287F49C4A1Du, 0xFF800000u},
|
||||||
|
{"1e99999999999999999999999999", 0x7FF0000000000000u, 0x7F800000u},
|
||||||
|
{"1e-99999999999999999999999999", 0x0000000000000000u, 0x00000000u},
|
||||||
|
{"1e0000000000000000000000000000000000000000308", 0x7FE1CCF385EBC8A0u, 0x7F800000u},
|
||||||
|
{"123456789012345678901234567890e-30", 0x3FBF9ADD3746F65Fu, 0x3DFCD6EAu},
|
||||||
|
{"18446744073709551615", 0x43F0000000000000u, 0x5F800000u},
|
||||||
|
{"18446744073709551616", 0x43F0000000000000u, 0x5F800000u},
|
||||||
|
{"-9223372036854775808", 0xC3E0000000000000u, 0xDF000000u},
|
||||||
|
{"-9223372036854775809", 0xC3E0000000000000u, 0xDF000000u},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace float_hard_cases
|
||||||
@@ -276,6 +276,133 @@ TEST_CASE("controlled bad_alloc")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// counts every allocation made on behalf of a basic_json value (of its own
|
||||||
|
// object_t/array_t/string_t/binary_t or of its own type), and can be told to
|
||||||
|
// fail one of them: the n-th call to allocate() throws std::bad_alloc instead
|
||||||
|
// of allocating, whichever type it is allocating for
|
||||||
|
std::size_t alloc_call_count = 0;
|
||||||
|
long fail_at_alloc_call = -1; // -1: never fail
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct nth_alloc_fails_allocator : std::allocator<T>
|
||||||
|
{
|
||||||
|
using std::allocator<T>::allocator;
|
||||||
|
|
||||||
|
T* allocate(std::size_t n)
|
||||||
|
{
|
||||||
|
const auto index = alloc_call_count++;
|
||||||
|
if (fail_at_alloc_call >= 0 && index == static_cast<std::size_t>(fail_at_alloc_call))
|
||||||
|
{
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
return std::allocator<T>::allocate(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
using other = nth_alloc_fails_allocator<U>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// builds a value nested more than 128 levels deep - the bound the copy
|
||||||
|
// constructor descends into before it continues without the call stack - and
|
||||||
|
// checks that a copy survives any single allocation of it failing: every
|
||||||
|
// attempt either throws std::bad_alloc, without crashing or leaving the
|
||||||
|
// source altered, or completes the copy
|
||||||
|
template<class BasicJsonType>
|
||||||
|
void check_deep_copy_survives_failing_allocation(bool nest_objects)
|
||||||
|
{
|
||||||
|
CAPTURE(nest_objects);
|
||||||
|
|
||||||
|
fail_at_alloc_call = -1;
|
||||||
|
|
||||||
|
// [[[ ... [1] ... ]]], or the same nesting with objects, 130 levels deep
|
||||||
|
BasicJsonType src = 1;
|
||||||
|
for (std::size_t i = 0; i < 130; ++i)
|
||||||
|
{
|
||||||
|
if (nest_objects)
|
||||||
|
{
|
||||||
|
BasicJsonType wrapper = BasicJsonType::object();
|
||||||
|
wrapper["a"] = std::move(src);
|
||||||
|
src = std::move(wrapper);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src = BasicJsonType::array({std::move(src)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string original_dump = src.dump();
|
||||||
|
|
||||||
|
// first measure how many allocations an unhindered copy takes
|
||||||
|
alloc_call_count = 0;
|
||||||
|
{
|
||||||
|
// NOLINTNEXTLINE(performance-unnecessary-copy-initialization): the copy is what is measured
|
||||||
|
const BasicJsonType measure(src);
|
||||||
|
}
|
||||||
|
const std::size_t total_allocations = alloc_call_count;
|
||||||
|
REQUIRE(total_allocations > 0);
|
||||||
|
REQUIRE(src.dump() == original_dump);
|
||||||
|
|
||||||
|
// let the 0th, 1st, 2nd, ... allocation of the copy fail in turn; every
|
||||||
|
// such copy must throw std::bad_alloc rather than crash, and the source
|
||||||
|
// must come out exactly as it went in
|
||||||
|
for (std::size_t n = 0; n < total_allocations; ++n)
|
||||||
|
{
|
||||||
|
CAPTURE(n);
|
||||||
|
alloc_call_count = 0;
|
||||||
|
fail_at_alloc_call = static_cast<long>(n);
|
||||||
|
|
||||||
|
CHECK_THROWS_AS(BasicJsonType(src), std::bad_alloc&);
|
||||||
|
|
||||||
|
fail_at_alloc_call = -1;
|
||||||
|
CHECK(src.dump() == original_dump);
|
||||||
|
}
|
||||||
|
|
||||||
|
// once no allocation is made to fail, the copy itself must succeed
|
||||||
|
fail_at_alloc_call = -1;
|
||||||
|
const BasicJsonType copy(src);
|
||||||
|
CHECK(copy.dump() == original_dump);
|
||||||
|
CHECK(src.dump() == original_dump);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("copy of a deeply nested value survives a failing allocation (#5640)")
|
||||||
|
{
|
||||||
|
SECTION("std::map-backed object_t")
|
||||||
|
{
|
||||||
|
using bad_alloc_json = nlohmann::basic_json<std::map,
|
||||||
|
std::vector,
|
||||||
|
std::string,
|
||||||
|
bool,
|
||||||
|
std::int64_t,
|
||||||
|
std::uint64_t,
|
||||||
|
double,
|
||||||
|
nth_alloc_fails_allocator>;
|
||||||
|
|
||||||
|
check_deep_copy_survives_failing_allocation<bad_alloc_json>(false);
|
||||||
|
check_deep_copy_survives_failing_allocation<bad_alloc_json>(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("ordered_map-backed object_t")
|
||||||
|
{
|
||||||
|
using bad_alloc_ordered_json = nlohmann::basic_json<nlohmann::ordered_map,
|
||||||
|
std::vector,
|
||||||
|
std::string,
|
||||||
|
bool,
|
||||||
|
std::int64_t,
|
||||||
|
std::uint64_t,
|
||||||
|
double,
|
||||||
|
nth_alloc_fails_allocator>;
|
||||||
|
|
||||||
|
check_deep_copy_survives_failing_allocation<bad_alloc_ordered_json>(false);
|
||||||
|
check_deep_copy_survives_failing_allocation<bad_alloc_ordered_json>(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// counts the allocations of pairs with a non-const first member: the object
|
// counts the allocations of pairs with a non-const first member: the object
|
||||||
|
|||||||
@@ -174,6 +174,15 @@ bool operator<(const char* op1, const alt_string& op2) noexcept
|
|||||||
return op1 < op2.str_impl;
|
return op1 < op2.str_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class alt_color { red, green };
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(alt_color,
|
||||||
|
{
|
||||||
|
{alt_color::red, "red"},
|
||||||
|
{alt_color::green, "green"},
|
||||||
|
})
|
||||||
|
|
||||||
TEST_CASE("alternative string type")
|
TEST_CASE("alternative string type")
|
||||||
{
|
{
|
||||||
SECTION("binary formats")
|
SECTION("binary formats")
|
||||||
@@ -343,6 +352,41 @@ TEST_CASE("alternative string type")
|
|||||||
CHECK(j2.flatten().unflatten() == j2);
|
CHECK(j2.flatten().unflatten() == j2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("contains(json_pointer)")
|
||||||
|
{
|
||||||
|
// contains(json_pointer) must compile and work with a string_t that has
|
||||||
|
// no c_str() and no comparison with const char* (see #5666)
|
||||||
|
auto j = alt_json::parse(R"({"foo": ["bar", "baz"]})");
|
||||||
|
|
||||||
|
// present: object key and array indices
|
||||||
|
CHECK(j.contains(alt_json::json_pointer("/foo")));
|
||||||
|
CHECK(j.contains(alt_json::json_pointer("/foo/0")));
|
||||||
|
CHECK(j.contains(alt_json::json_pointer("/foo/1")));
|
||||||
|
|
||||||
|
// missing: absent object key and out-of-range array index
|
||||||
|
CHECK_FALSE(j.contains(alt_json::json_pointer("/bar")));
|
||||||
|
CHECK_FALSE(j.contains(alt_json::json_pointer("/foo/2")));
|
||||||
|
|
||||||
|
// "-" always fails the range check
|
||||||
|
CHECK_FALSE(j.contains(alt_json::json_pointer("/foo/-")));
|
||||||
|
|
||||||
|
// an array index must not have a leading zero
|
||||||
|
CHECK_FALSE(j.contains(alt_json::json_pointer("/foo/01")));
|
||||||
|
|
||||||
|
// a reference token that is not a number
|
||||||
|
CHECK_FALSE(j.contains(alt_json::json_pointer("/foo/bar")));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("operator/(std::size_t)")
|
||||||
|
{
|
||||||
|
// json_pointer::operator/=(std::size_t) must compile without string_t
|
||||||
|
// being constructible from std::string (see #5666)
|
||||||
|
auto j = alt_json::parse(R"({"foo": ["bar", "baz"]})");
|
||||||
|
|
||||||
|
CHECK(j.at(alt_json::json_pointer("/foo") / std::size_t(0)) == j["foo"][0]);
|
||||||
|
CHECK(j.at(alt_json::json_pointer("/foo") / std::size_t(1)) == j["foo"][1]);
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("patch")
|
SECTION("patch")
|
||||||
{
|
{
|
||||||
alt_json const patch1 = alt_json::parse(R"([{ "op": "add", "path": "/a/b", "value": [ "foo", "bar" ] }])");
|
alt_json const patch1 = alt_json::parse(R"([{ "op": "add", "path": "/a/b", "value": [ "foo", "bar" ] }])");
|
||||||
@@ -374,4 +418,19 @@ TEST_CASE("alternative string type")
|
|||||||
const auto j2 = j.flatten();
|
const auto j2 = j.flatten();
|
||||||
CHECK(j2.dump() == R"({"/foo/0":"bar","/foo/1":"baz"})");
|
CHECK(j2.dump() == R"({"/foo/0":"bar","/foo/1":"baz"})");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("strict enum")
|
||||||
|
{
|
||||||
|
// regression test for #5667: NLOHMANN_JSON_SERIALIZE_ENUM_STRICT's from_json
|
||||||
|
// built its exception message with "..." + j.dump(), which does not compile
|
||||||
|
// when j.dump() returns a custom string_t (here alt_string) instead of
|
||||||
|
// std::string
|
||||||
|
alt_json doc;
|
||||||
|
doc = "red";
|
||||||
|
CHECK(doc.get<alt_color>() == alt_color::red);
|
||||||
|
|
||||||
|
alt_json _;
|
||||||
|
doc = "blue";
|
||||||
|
CHECK_THROWS_WITH_AS(_ = doc.get<alt_color>(), "[json.exception.out_of_range.410] enum value out of range for alt_color: \"blue\"", alt_json::out_of_range&);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-1
@@ -797,7 +797,11 @@ TEST_CASE("regression test - BSON binary subtype rejects a value that doesn't fi
|
|||||||
CHECK(json::from_bson(json::to_bson(doc255))["b"].get_binary().subtype() == 255);
|
CHECK(json::from_bson(json::to_bson(doc255))["b"].get_binary().subtype() == 255);
|
||||||
|
|
||||||
CHECK_THROWS_AS(json::to_bson(json{{"b", json::binary({1, 2}, 256)}}), json::out_of_range);
|
CHECK_THROWS_AS(json::to_bson(json{{"b", json::binary({1, 2}, 256)}}), json::out_of_range);
|
||||||
CHECK_THROWS_WITH_AS(json::to_bson(json{{"b", json::binary({1, 2}, 300)}}), "[json.exception.out_of_range.415] subtype 300 is too large for the BSON binary subtype (max 255)", json::out_of_range);
|
#if JSON_DIAGNOSTICS
|
||||||
|
CHECK_THROWS_WITH_AS(json::to_bson(json {{"b", json::binary({1, 2}, 300)}}), "[json.exception.out_of_range.415] (/b) subtype 300 is too large for the BSON binary subtype (max 255)", json::out_of_range);
|
||||||
|
#else
|
||||||
|
CHECK_THROWS_WITH_AS(json::to_bson(json {{"b", json::binary({1, 2}, 300)}}), "[json.exception.out_of_range.415] subtype 300 is too large for the BSON binary subtype (max 255)", json::out_of_range);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("BSON input/output_adapters")
|
TEST_CASE("BSON input/output_adapters")
|
||||||
@@ -1805,6 +1809,21 @@ value = depth % 2 == 0 ? json{{"a", std::move(value)}, {"b", {1, "x"}}} :
|
|||||||
CHECK(output.empty());
|
CHECK(output.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("a binary subtype that doesn't fit a byte is rejected before anything is written (#5675)")
|
||||||
|
{
|
||||||
|
// the offending value is nested, so this also covers that the check
|
||||||
|
// is not limited to a directly written value's own document
|
||||||
|
json const j = {{"a", {{"b", json::binary({1, 2}, 300)}}}};
|
||||||
|
|
||||||
|
std::vector<std::uint8_t> vector_output;
|
||||||
|
CHECK_THROWS_AS(json::to_bson(j, vector_output), json::out_of_range&);
|
||||||
|
CHECK(vector_output.empty());
|
||||||
|
|
||||||
|
std::string string_output;
|
||||||
|
CHECK_THROWS_AS(json::to_bson(j, string_output), json::out_of_range&);
|
||||||
|
CHECK(string_output.empty());
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("values nested too deeply for the call stack (#5392)")
|
SECTION("values nested too deeply for the call stack (#5392)")
|
||||||
{
|
{
|
||||||
// serializing recursed once per nesting level, and computed every
|
// serializing recursed once per nesting level, and computed every
|
||||||
|
|||||||
+1108
-46
File diff suppressed because it is too large
Load Diff
@@ -645,6 +645,30 @@ TEST_CASE("parser class")
|
|||||||
// carries a compiler-appended trailing '\0') still works,
|
// carries a compiler-appended trailing '\0') still works,
|
||||||
// even though a NUL byte is now rejected everywhere else
|
// even though a NUL byte is now rejected everywhere else
|
||||||
CHECK(json::parse("123") == json(123));
|
CHECK(json::parse("123") == json(123));
|
||||||
|
|
||||||
|
// regression test for issue #5658: the same holds for wide,
|
||||||
|
// UTF-16, UTF-32, and (C++20) UTF-8 string literals, whose
|
||||||
|
// compiler-appended trailing '\0' is not of type `char`
|
||||||
|
CHECK(json::parse(L"[1]") == json({1}));
|
||||||
|
CHECK(json::accept(L"[1]"));
|
||||||
|
CHECK(json::parse(u"[1]") == json({1}));
|
||||||
|
CHECK(json::accept(u"[1]"));
|
||||||
|
CHECK(json::parse(U"[1]") == json({1}));
|
||||||
|
CHECK(json::accept(U"[1]"));
|
||||||
|
#if defined(__cpp_char8_t)
|
||||||
|
CHECK(json::parse(u8"[1]") == json({1}));
|
||||||
|
CHECK(json::accept(u8"[1]"));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// a NUL byte inside such a literal, as opposed to the single
|
||||||
|
// compiler-appended trailing one, is still rejected
|
||||||
|
{
|
||||||
|
json _; // NOLINT(readability-identifier-naming)
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::parse(L"[1\0]"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing array - invalid literal; last read: '1<U+0000>'; expected ']'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_FALSE(json::accept(L"[1\0]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1966,6 +1990,102 @@ TEST_CASE("parser class")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("no callback for the content of a discarded container (#5643)")
|
||||||
|
{
|
||||||
|
// discarding a container at its start event must also hide
|
||||||
|
// everything inside it from the callback: none of the nested
|
||||||
|
// keys, values, or nested containers' own start/end events may
|
||||||
|
// be reported
|
||||||
|
std::vector<std::string> log;
|
||||||
|
bool first = true;
|
||||||
|
const json j = json::parse(R"({"skip": {"k1": 1, "k2": [2, {"k3": 3}]}, "keep": 1})",
|
||||||
|
[&](int depth, json::parse_event_t event, json & parsed)
|
||||||
|
{
|
||||||
|
static const char* const names[] = {"object_start", "object_end", "array_start", "array_end", "key", "value"};
|
||||||
|
log.push_back(std::to_string(depth) + " " + names[static_cast<int>(event)] + " " + parsed.dump());
|
||||||
|
|
||||||
|
if (depth == 1 && event == json::parse_event_t::object_start && first)
|
||||||
|
{
|
||||||
|
// discard "skip" right at its object_start event
|
||||||
|
first = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
CHECK(log == std::vector<std::string>
|
||||||
|
{
|
||||||
|
"0 object_start <discarded>",
|
||||||
|
"1 key \"skip\"",
|
||||||
|
"1 object_start <discarded>",
|
||||||
|
"1 key \"keep\"",
|
||||||
|
"1 value 1",
|
||||||
|
"0 object_end {\"keep\":1}"
|
||||||
|
});
|
||||||
|
CHECK(j == json({{"keep", 1}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("callback still called inside a container whose key was rejected (#5643)")
|
||||||
|
{
|
||||||
|
// rejecting a key does not discard its value's container at the
|
||||||
|
// container's own start event, so the callback is still called
|
||||||
|
// for that container's content; only storing the container
|
||||||
|
// under the rejected key is skipped
|
||||||
|
// (documented for parser_callback_t: "the callback is still
|
||||||
|
// called for the associated value, but its return value has no
|
||||||
|
// further effect")
|
||||||
|
const auto record = [](std::vector<std::string>& log, int depth, json::parse_event_t event, const json & parsed)
|
||||||
|
{
|
||||||
|
static const char* const names[] = {"object_start", "object_end", "array_start", "array_end", "key", "value"};
|
||||||
|
log.push_back(std::to_string(depth) + " " + names[static_cast<int>(event)] + " " + parsed.dump());
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> log_object;
|
||||||
|
const json j_object = json::parse(R"({"skip": {"k1": 1}, "keep": 2})",
|
||||||
|
[&](int depth, json::parse_event_t event, json & parsed)
|
||||||
|
{
|
||||||
|
record(log_object, depth, event, parsed);
|
||||||
|
return !(event == json::parse_event_t::key && parsed == json("skip"));
|
||||||
|
});
|
||||||
|
|
||||||
|
CHECK(log_object == std::vector<std::string>
|
||||||
|
{
|
||||||
|
"0 object_start <discarded>",
|
||||||
|
"1 key \"skip\"",
|
||||||
|
"1 object_start <discarded>",
|
||||||
|
"2 key \"k1\"",
|
||||||
|
"2 value 1",
|
||||||
|
"1 key \"keep\"",
|
||||||
|
"1 value 2",
|
||||||
|
"0 object_end {\"keep\":2}"
|
||||||
|
});
|
||||||
|
CHECK(j_object == json({{"keep", 2}}));
|
||||||
|
|
||||||
|
// same for a rejected key whose value is an array rather than an object
|
||||||
|
std::vector<std::string> log_array;
|
||||||
|
const json j_array = json::parse(R"({"skip": [1, {"k1": 2}], "keep": 2})",
|
||||||
|
[&](int depth, json::parse_event_t event, json & parsed)
|
||||||
|
{
|
||||||
|
record(log_array, depth, event, parsed);
|
||||||
|
return !(event == json::parse_event_t::key && parsed == json("skip"));
|
||||||
|
});
|
||||||
|
|
||||||
|
CHECK(log_array == std::vector<std::string>
|
||||||
|
{
|
||||||
|
"0 object_start <discarded>",
|
||||||
|
"1 key \"skip\"",
|
||||||
|
"1 array_start <discarded>",
|
||||||
|
"2 value 1",
|
||||||
|
"2 object_start <discarded>",
|
||||||
|
"3 key \"k1\"",
|
||||||
|
"3 value 2",
|
||||||
|
"1 key \"keep\"",
|
||||||
|
"1 value 2",
|
||||||
|
"0 object_end {\"keep\":2}"
|
||||||
|
});
|
||||||
|
CHECK(j_array == json({{"keep", 2}}));
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("special cases")
|
SECTION("special cases")
|
||||||
{
|
{
|
||||||
// the following test cases cover the situation in which an empty
|
// the following test cases cover the situation in which an empty
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -825,6 +826,24 @@ Json nest(Json j, const std::size_t depth)
|
|||||||
}
|
}
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// orders keys case-insensitively, so "key" and "KEY" compare equivalent
|
||||||
|
// (neither less than the other) although they are not equal
|
||||||
|
struct case_insensitive_less
|
||||||
|
{
|
||||||
|
bool operator()(const std::string& a, const std::string& b) const
|
||||||
|
{
|
||||||
|
return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(),
|
||||||
|
[](unsigned char x, unsigned char y)
|
||||||
|
{
|
||||||
|
return std::tolower(x) < std::tolower(y);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Key, class Value, class /*Compare*/, class Allocator>
|
||||||
|
using case_insensitive_map = std::map<Key, Value, case_insensitive_less, Allocator>;
|
||||||
|
using ci_json = nlohmann::basic_json<case_insensitive_map>;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST_CASE("equality of objects whose entries have no fixed order")
|
TEST_CASE("equality of objects whose entries have no fixed order")
|
||||||
@@ -872,6 +891,33 @@ TEST_CASE("equality of objects whose entries have no fixed order")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("equality of an object whose comparator treats different keys as equivalent")
|
||||||
|
{
|
||||||
|
// https://github.com/nlohmann/json/issues/5655: past the nesting bound,
|
||||||
|
// the entries are compared without the call stack, and a key that finds
|
||||||
|
// no counterpart at the same position is looked up with find(), which
|
||||||
|
// uses the object's own comparator. A case-insensitive comparator then
|
||||||
|
// finds "KEY" for "key" and must not accept that pair as a match - the
|
||||||
|
// object type's own operator==, like std::map's, compares keys with ==.
|
||||||
|
ci_json a = ci_json::object();
|
||||||
|
a["key"] = 1;
|
||||||
|
ci_json b = ci_json::object();
|
||||||
|
b["KEY"] = 1;
|
||||||
|
|
||||||
|
// sanity check: the object type's own comparison already disagrees
|
||||||
|
CHECK_FALSE(a.get_ref<const ci_json::object_t&>() == b.get_ref<const ci_json::object_t&>());
|
||||||
|
|
||||||
|
for (const std::size_t depth : std::vector<std::size_t> {0, 127, 128, 200})
|
||||||
|
{
|
||||||
|
CAPTURE(depth);
|
||||||
|
|
||||||
|
const ci_json x = nest(a, depth);
|
||||||
|
const ci_json y = nest(b, depth);
|
||||||
|
CHECK_FALSE(x == y);
|
||||||
|
CHECK(x != y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("containers are compared element by element")
|
TEST_CASE("containers are compared element by element")
|
||||||
{
|
{
|
||||||
// Containers nested deeper than a bound are compared without the call
|
// Containers nested deeper than a bound are compared without the call
|
||||||
|
|||||||
@@ -1648,6 +1648,20 @@ TEST_CASE("constructors")
|
|||||||
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("binary")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
json j = json::binary({1, 2, 3});
|
||||||
|
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
json const j = json::binary({1, 2, 3});
|
||||||
|
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1358,6 +1358,14 @@ TEST_CASE("value conversion")
|
|||||||
CHECK(json(value_1).get<c_enum>() == value_1);
|
CHECK(json(value_1).get<c_enum>() == value_1);
|
||||||
CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
|
CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("get an enum with underlying type bool (#5671)")
|
||||||
|
{
|
||||||
|
enum class bool_enum : bool { off, on };
|
||||||
|
|
||||||
|
CHECK(json(bool_enum::off).get<bool_enum>() == bool_enum::off);
|
||||||
|
CHECK(json(bool_enum::on).get<bool_enum>() == bool_enum::on);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SECTION("more involved conversions")
|
SECTION("more involved conversions")
|
||||||
@@ -1740,6 +1748,12 @@ TEST_CASE("Strict JSON to enum mapping")
|
|||||||
|
|
||||||
// conversion of unmapped enum -> exception thrown
|
// conversion of unmapped enum -> exception thrown
|
||||||
CHECK_THROWS_WITH_AS(json(strict_cards::andere), "[json.exception.out_of_range.410] enum value out of range for strict_cards", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(json(strict_cards::andere), "[json.exception.out_of_range.410] enum value out of range for strict_cards", json::out_of_range&);
|
||||||
|
|
||||||
|
// invalid UTF-8 -> out_of_range.410, not the type_error.316 thrown while building the
|
||||||
|
// message (regression test for #5667); such strings can reach get<Enum>() unvalidated,
|
||||||
|
// e.g. from from_cbor()/from_msgpack() (#5529)
|
||||||
|
const json j_invalid_utf8 = "\xFF";
|
||||||
|
CHECK_THROWS_WITH_AS(_ = j_invalid_utf8.get<strict_cards>(), "[json.exception.out_of_range.410] enum value out of range for strict_cards: \"\xEF\xBF\xBD\"", json::out_of_range&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("traditional enum")
|
SECTION("traditional enum")
|
||||||
@@ -1826,6 +1840,21 @@ TEST_CASE("std::u8string")
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// a type whose to_json reports an error by throwing, used below to check that
|
||||||
|
// converting a std::optional<T> to JSON propagates an exception thrown while
|
||||||
|
// converting its contained value instead of calling std::terminate (#5642)
|
||||||
|
struct throwing_to_json_type {};
|
||||||
|
|
||||||
|
[[noreturn]] void to_json(json& /*unused*/, const throwing_to_json_type& /*unused*/)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("cannot serialize throwing_to_json_type");
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_CASE("std::optional")
|
TEST_CASE("std::optional")
|
||||||
{
|
{
|
||||||
SECTION("null")
|
SECTION("null")
|
||||||
@@ -1908,6 +1937,23 @@ TEST_CASE("std::optional")
|
|||||||
CHECK(json(opt_object) == j_object);
|
CHECK(json(opt_object) == j_object);
|
||||||
CHECK(std::map<std::string, std::optional<int>>(j_object) == opt_object);
|
CHECK(std::map<std::string, std::optional<int>>(j_object) == opt_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
|
SECTION("exception from contained value's to_json propagates (#5642)")
|
||||||
|
{
|
||||||
|
// to_json(BasicJsonType&, const std::optional<T>&) must not be
|
||||||
|
// noexcept: it calls T's to_json, which may throw (a user-defined
|
||||||
|
// to_json that reports an error, or std::bad_alloc for T =
|
||||||
|
// std::string/vector/json). Before the fix, this called
|
||||||
|
// std::terminate() instead of letting the exception propagate.
|
||||||
|
const std::optional<throwing_to_json_type> opt = throwing_to_json_type{};
|
||||||
|
CHECK_THROWS_WITH_AS(json(opt), "cannot serialize throwing_to_json_type", std::runtime_error&);
|
||||||
|
|
||||||
|
// the conversion is noexcept exactly when converting the contained value is
|
||||||
|
static_assert(!std::is_nothrow_constructible<json, const std::optional<throwing_to_json_type>&>::value, "");
|
||||||
|
static_assert(std::is_nothrow_constructible<json, const std::optional<int>&>::value, "");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,22 @@ TEST_CASE("array type without capacity()")
|
|||||||
CHECK(nested.flatten().unflatten() == nested);
|
CHECK(nested.flatten().unflatten() == nested);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("insert(pos, initializer_list) compiles and works without reserve()")
|
||||||
|
{
|
||||||
|
// std::deque has no reserve() either; insert(pos, ilist) must not
|
||||||
|
// require it (regression test for #5656, which also covers an ilist
|
||||||
|
// that refers to elements of the array being inserted into)
|
||||||
|
deque_json j = deque_json::array();
|
||||||
|
j.push_back("a");
|
||||||
|
j.push_back("b");
|
||||||
|
j.push_back("c");
|
||||||
|
|
||||||
|
const deque_json& cj = j;
|
||||||
|
auto it = j.insert(j.begin(), {cj[0], cj[1]});
|
||||||
|
CHECK(*it == deque_json("a"));
|
||||||
|
CHECK(j == deque_json({"a", "b", "a", "b", "c"}));
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("references stay valid while the array grows")
|
SECTION("references stay valid while the array grows")
|
||||||
{
|
{
|
||||||
deque_json j = deque_json::array();
|
deque_json j = deque_json::array();
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
@@ -180,6 +182,76 @@ TEST_CASE("JSON Node Metadata")
|
|||||||
CHECK(val.metadata().at(1) == 2);
|
CHECK(val.metadata().at(1) == 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SECTION("member swap")
|
||||||
|
{
|
||||||
|
using json = json_with_metadata<int>;
|
||||||
|
json a = 1;
|
||||||
|
a.metadata() = 100;
|
||||||
|
json b = 2;
|
||||||
|
b.metadata() = 200;
|
||||||
|
|
||||||
|
a.swap(b);
|
||||||
|
|
||||||
|
CHECK(a.get<int>() == 2);
|
||||||
|
CHECK(b.get<int>() == 1);
|
||||||
|
CHECK(a.metadata() == 200);
|
||||||
|
CHECK(b.metadata() == 100);
|
||||||
|
}
|
||||||
|
SECTION("nonmember swap")
|
||||||
|
{
|
||||||
|
using json = json_with_metadata<int>;
|
||||||
|
json a = 1;
|
||||||
|
a.metadata() = 100;
|
||||||
|
json b = 2;
|
||||||
|
b.metadata() = 200;
|
||||||
|
|
||||||
|
using std::swap;
|
||||||
|
swap(a, b);
|
||||||
|
|
||||||
|
CHECK(a.get<int>() == 2);
|
||||||
|
CHECK(b.get<int>() == 1);
|
||||||
|
CHECK(a.metadata() == 200);
|
||||||
|
CHECK(b.metadata() == 100);
|
||||||
|
}
|
||||||
|
SECTION("std::swap")
|
||||||
|
{
|
||||||
|
using json = json_with_metadata<int>;
|
||||||
|
json a = 1;
|
||||||
|
a.metadata() = 100;
|
||||||
|
json b = 2;
|
||||||
|
b.metadata() = 200;
|
||||||
|
|
||||||
|
std::swap(a, b);
|
||||||
|
|
||||||
|
CHECK(a.get<int>() == 2);
|
||||||
|
CHECK(b.get<int>() == 1);
|
||||||
|
CHECK(a.metadata() == 200);
|
||||||
|
CHECK(b.metadata() == 100);
|
||||||
|
}
|
||||||
|
SECTION("std::sort keeps metadata attached to its value")
|
||||||
|
{
|
||||||
|
// std::sort mixes swap() with moves; each value's metadata must
|
||||||
|
// travel with it, just as it does for copy, move, and assignment
|
||||||
|
using json = json_with_metadata<int>;
|
||||||
|
std::vector<json> values;
|
||||||
|
for (int v :
|
||||||
|
{
|
||||||
|
5, 3, 9, 1, 7, 2, 8, 4, 6, 0, 15, 13, 19, 11, 17, 12, 18, 14, 16, 10,
|
||||||
|
25, 23, 29, 21, 27, 22, 28, 24, 26, 20, 35, 33
|
||||||
|
})
|
||||||
|
{
|
||||||
|
json value = v;
|
||||||
|
value.metadata() = v;
|
||||||
|
values.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(values.begin(), values.end());
|
||||||
|
|
||||||
|
for (const auto& value : values)
|
||||||
|
{
|
||||||
|
CHECK(value.metadata() == value.get<int>());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test extending nlohmann::json by using a custom base class.
|
// Test extending nlohmann::json by using a custom base class.
|
||||||
|
|||||||
@@ -388,6 +388,37 @@ TEST_CASE("deserialization")
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("stream with eofbit in its exception mask (issue #5646)")
|
||||||
|
{
|
||||||
|
// reaching EOF while parsing a value that fills the whole input
|
||||||
|
// (e.g., a number, or any value under strict parsing) makes
|
||||||
|
// get_character() call std::istream::clear() to record eofbit;
|
||||||
|
// with eofbit in the exception mask, that clear() itself throws
|
||||||
|
// std::ios_base::failure - it must propagate to the caller instead
|
||||||
|
// of ~input_stream_adapter() throwing a second exception while the
|
||||||
|
// first is still unwinding, which would call std::terminate
|
||||||
|
json _;
|
||||||
|
|
||||||
|
std::istringstream is1("1");
|
||||||
|
is1.exceptions(std::ios::eofbit);
|
||||||
|
CHECK_THROWS_AS(_ = json::parse(is1), std::ios_base::failure&);
|
||||||
|
|
||||||
|
// the same holds for the common std::ifstream::exceptions(failbit |
|
||||||
|
// badbit | eofbit) pattern, because only eofbit ends up set
|
||||||
|
std::istringstream is2("1");
|
||||||
|
is2.exceptions(std::ios::failbit | std::ios::badbit | std::ios::eofbit);
|
||||||
|
CHECK_THROWS_AS(_ = json::parse(is2), std::ios_base::failure&);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("stream without a streambuf (issue #5646)")
|
||||||
|
{
|
||||||
|
// std::istream(nullptr) has badbit set and rdbuf() == nullptr;
|
||||||
|
// get_character() must not dereference that null streambuf
|
||||||
|
std::istream is(nullptr);
|
||||||
|
json _;
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::parse(is), "[json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
json::string_t const s = R"(["foo",1,2,3,false,{"one":1})";
|
json::string_t const s = R"(["foo",1,2,3,false,{"one":1})";
|
||||||
|
|||||||
@@ -17,6 +17,10 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
TEST_CASE("Better diagnostics")
|
TEST_CASE("Better diagnostics")
|
||||||
{
|
{
|
||||||
SECTION("empty JSON Pointer")
|
SECTION("empty JSON Pointer")
|
||||||
@@ -101,6 +105,12 @@ TEST_CASE("Regression tests for extended diagnostics")
|
|||||||
CHECK_THROWS_WITH_AS(j.unflatten(), "[json.exception.type_error.315] (/~1foo) values in object must be primitive", json::type_error);
|
CHECK_THROWS_WITH_AS(j.unflatten(), "[json.exception.type_error.315] (/~1foo) values in object must be primitive", json::type_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("Regression test for issue #5675 - to_bson: out_of_range.415 has no diagnostics context")
|
||||||
|
{
|
||||||
|
json const j = {{"a", {{"b", json::binary({1, 2}, 300)}}}};
|
||||||
|
CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.out_of_range.415] (/a/b) subtype 300 is too large for the BSON binary subtype (max 255)", json::out_of_range);
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("Regression test for issue #2838 - Assertion failure when inserting into arrays with JSON_DIAGNOSTICS set")
|
SECTION("Regression test for issue #2838 - Assertion failure when inserting into arrays with JSON_DIAGNOSTICS set")
|
||||||
{
|
{
|
||||||
// void push_back(basic_json&& val)
|
// void push_back(basic_json&& val)
|
||||||
@@ -331,6 +341,28 @@ TEST_CASE("Regression tests for extended diagnostics")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("Regression test for issue #5668 - wrong path for std::map/unordered_map with non-string keys")
|
||||||
|
{
|
||||||
|
// a map with non-string keys is read from an array of [key, value] arrays;
|
||||||
|
// element 2 of "m" is not an array, so the path must point at "m/2", not "m"
|
||||||
|
json j;
|
||||||
|
j["outer"]["m"] = json::array({json::array({1, 2}), json::array({3, 4}), 5});
|
||||||
|
|
||||||
|
SECTION("std::map")
|
||||||
|
{
|
||||||
|
CHECK_THROWS_WITH_AS((j["outer"]["m"].get<std::map<int, int>>()),
|
||||||
|
"[json.exception.type_error.302] (/outer/m/2) type must be array, "
|
||||||
|
"but is number", json::type_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("std::unordered_map")
|
||||||
|
{
|
||||||
|
CHECK_THROWS_WITH_AS((j["outer"]["m"].get<std::unordered_map<int, int>>()),
|
||||||
|
"[json.exception.type_error.302] (/outer/m/2) type must be array, "
|
||||||
|
"but is number", json::type_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("Regression test - swap(array_t&)/swap(object_t&) must update JSON_DIAGNOSTICS parent pointers")
|
SECTION("Regression test - swap(array_t&)/swap(object_t&) must update JSON_DIAGNOSTICS parent pointers")
|
||||||
{
|
{
|
||||||
// swap(array_t&)
|
// swap(array_t&)
|
||||||
@@ -461,6 +493,21 @@ TEST_CASE("Regression tests for extended diagnostics")
|
|||||||
CHECK(copy == j);
|
CHECK(copy == j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("Regression test for issue #5652 - operator>> leaves a partial value in its target on a parse error")
|
||||||
|
{
|
||||||
|
json j = "old value";
|
||||||
|
std::istringstream is("[1, x");
|
||||||
|
CHECK_THROWS_WITH_AS(is >> j, "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: '1, x'", json::parse_error);
|
||||||
|
|
||||||
|
// j must be left unchanged, as json::parse() guarantees for its result
|
||||||
|
CHECK(j == "old value");
|
||||||
|
|
||||||
|
// copying j must not trigger assert_invariant(): a failed parse must
|
||||||
|
// not leave array/object elements without a parent pointer
|
||||||
|
json const copy = j; // NOLINT(performance-unnecessary-copy-initialization)
|
||||||
|
CHECK(copy == j);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Better diagnostics past the descent bound of update() and merge_patch()")
|
TEST_CASE("Better diagnostics past the descent bound of update() and merge_patch()")
|
||||||
|
|||||||
@@ -46,6 +46,24 @@ TEST_CASE("Tests with disabled exceptions")
|
|||||||
CHECK(*sax_no_exception::error_string == "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
|
CHECK(*sax_no_exception::error_string == "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
|
||||||
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
|
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("growing an ordered_json object")
|
||||||
|
{
|
||||||
|
auto j = nlohmann::ordered_json::object();
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
j[std::to_string(i)] = {{"nested", i}};
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(j.size() == 100);
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& element : j.items())
|
||||||
|
{
|
||||||
|
CHECK(element.key() == std::to_string(i));
|
||||||
|
CHECK(element.value()["nested"] == i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
||||||
|
|||||||
@@ -147,6 +147,24 @@ TEST_CASE("element access 1")
|
|||||||
CHECK(j_const[7] == json({1, 2, 3}));
|
CHECK(j_const[7] == json({1, 2, 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("SIZE_MAX index (#5647)")
|
||||||
|
{
|
||||||
|
// idx + 1 must not be computed for idx == SIZE_MAX: it wraps to 0,
|
||||||
|
// which would empty the array and then write out of bounds instead
|
||||||
|
// of growing it; reject it like an oversized resize() would and
|
||||||
|
// leave the array unchanged
|
||||||
|
const auto max_idx = (std::numeric_limits<json::size_type>::max)();
|
||||||
|
const std::string expected = "array index " + std::to_string(max_idx) + " exceeds size_type";
|
||||||
|
const json j_before = j; // NOLINT(performance-unnecessary-copy-initialization)
|
||||||
|
|
||||||
|
CHECK_THROWS_WITH_AS(j[max_idx] = 1, expected.c_str(), std::length_error&);
|
||||||
|
CHECK(j == j_before);
|
||||||
|
|
||||||
|
json j_empty = json::array();
|
||||||
|
CHECK_THROWS_WITH_AS(j_empty[max_idx] = 1, expected.c_str(), std::length_error&);
|
||||||
|
CHECK(j_empty == json::array());
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("access on non-array type")
|
SECTION("access on non-array type")
|
||||||
{
|
{
|
||||||
SECTION("null")
|
SECTION("null")
|
||||||
|
|||||||
@@ -16,6 +16,40 @@
|
|||||||
// build test with C++14
|
// build test with C++14
|
||||||
// JSON_HAS_CPP_14
|
// JSON_HAS_CPP_14
|
||||||
|
|
||||||
|
// used to check at compile time (via is_detected) whether a call is well-formed; see
|
||||||
|
// https://github.com/nlohmann/json/issues/5657
|
||||||
|
//
|
||||||
|
// note: an integer *literal* (rather than a std::declval<T>() of integral type T) is required to
|
||||||
|
// reproduce the bug, because only a null pointer constant--an integer literal with value zero, not
|
||||||
|
// merely a runtime value that happens to be zero--implicitly converts to a null const char*; that is
|
||||||
|
// why can_call_*_with_0 below hard-code the literal 0 instead of taking it as a template argument
|
||||||
|
template<typename BasicJsonType, typename T>
|
||||||
|
using can_call_find = decltype(std::declval<BasicJsonType>().find(std::declval<T>()));
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename T>
|
||||||
|
using can_call_count = decltype(std::declval<BasicJsonType>().count(std::declval<T>()));
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename T>
|
||||||
|
using can_call_contains = decltype(std::declval<BasicJsonType>().contains(std::declval<T>()));
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename KeyType, typename ValueType>
|
||||||
|
using can_call_value = decltype(std::declval<BasicJsonType>().value(std::declval<KeyType>(), std::declval<ValueType>()));
|
||||||
|
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
using can_call_find_with_0 = decltype(std::declval<BasicJsonType>().find(0));
|
||||||
|
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
using can_call_count_with_0 = decltype(std::declval<BasicJsonType>().count(0));
|
||||||
|
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
using can_call_contains_with_0 = decltype(std::declval<BasicJsonType>().contains(0));
|
||||||
|
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
using can_call_contains_with_0L = decltype(std::declval<BasicJsonType>().contains(0L));
|
||||||
|
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
using can_call_value_with_0 = decltype(std::declval<BasicJsonType>().value(0, 1));
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_json) // NOLINT(readability-math-missing-parentheses, bugprone-throwing-static-initialization)
|
TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_json) // NOLINT(readability-math-missing-parentheses, bugprone-throwing-static-initialization)
|
||||||
{
|
{
|
||||||
SECTION("object")
|
SECTION("object")
|
||||||
@@ -1493,6 +1527,53 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("integral keys for object lookup are rejected at compile time")
|
||||||
|
{
|
||||||
|
// https://github.com/nlohmann/json/issues/5657: an integer literal like 0 is a null pointer
|
||||||
|
// constant, which used to convert to a null const char* and from there--via undefined
|
||||||
|
// behavior in the std::string constructor--to key_type, so contains(0), find(0), and
|
||||||
|
// count(0) used to compile and then crash instead of failing to compile
|
||||||
|
using nlohmann::detail::is_detected;
|
||||||
|
|
||||||
|
CHECK_FALSE(is_detected<can_call_find_with_0, Json&>::value);
|
||||||
|
CHECK_FALSE(is_detected<can_call_find_with_0, const Json&>::value);
|
||||||
|
CHECK_FALSE(is_detected<can_call_count_with_0, Json&>::value);
|
||||||
|
CHECK_FALSE(is_detected<can_call_contains_with_0, Json&>::value);
|
||||||
|
// value(0, ...) is only affected in C++11, where the comparator is not transparent; with a
|
||||||
|
// transparent comparator (C++14 and later), int is already rejected for lacking a
|
||||||
|
// comparison with the key type, independently of this fix
|
||||||
|
CHECK_FALSE(is_detected<can_call_value_with_0, const Json&>::value);
|
||||||
|
|
||||||
|
// another integral literal type must be rejected as well, not just int
|
||||||
|
CHECK_FALSE(is_detected<can_call_contains_with_0L, Json&>::value);
|
||||||
|
|
||||||
|
// the valid overloads must remain callable
|
||||||
|
CHECK(is_detected<can_call_find, Json&, const char*>::value);
|
||||||
|
CHECK(is_detected<can_call_find, Json&, std::string>::value);
|
||||||
|
CHECK(is_detected<can_call_count, Json&, const char*>::value);
|
||||||
|
CHECK(is_detected<can_call_contains, Json&, const char*>::value);
|
||||||
|
CHECK(is_detected<can_call_contains, Json&, typename Json::json_pointer>::value);
|
||||||
|
CHECK(is_detected<can_call_value, const Json&, const char*, int>::value);
|
||||||
|
CHECK(is_detected<can_call_value, const Json&, typename Json::json_pointer, int>::value);
|
||||||
|
|
||||||
|
#ifdef JSON_HAS_CPP_17
|
||||||
|
CHECK(is_detected<can_call_find, Json&, std::string_view>::value);
|
||||||
|
CHECK(is_detected<can_call_count, Json&, std::string_view>::value);
|
||||||
|
CHECK(is_detected<can_call_contains, Json&, std::string_view>::value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// the neighboring size_type overloads for array access are unaffected by the new
|
||||||
|
// integral-key overloads above (at(), operator[](), and erase() take a size_type)
|
||||||
|
Json arr = {10, 20, 30};
|
||||||
|
const Json arr_const = arr;
|
||||||
|
CHECK(arr.at(0) == 10);
|
||||||
|
CHECK(arr_const.at(0) == 10);
|
||||||
|
CHECK(arr[0] == 10);
|
||||||
|
CHECK(arr_const[0] == 10);
|
||||||
|
arr.erase(0);
|
||||||
|
CHECK(arr.size() == 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(JSON_NOEXCEPTION)
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
|
|||||||
@@ -1752,6 +1752,58 @@ TEST_CASE("JSON patch - diff emits array removals in descending index order")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("JSON patch - diff() takes the fast path for non-reorderable object types (regression #5639)")
|
||||||
|
{
|
||||||
|
// #5465 added an order check to diff()'s object handling so a
|
||||||
|
// member-by-member diff is only used when it would also reproduce
|
||||||
|
// target's member *order* -- needed for ordered_json, whose object_t
|
||||||
|
// keeps insertion order and whose patch() "add" op appends a new
|
||||||
|
// member at the end. For json's default object_t (std::map, which
|
||||||
|
// orders members by key regardless of insertion history), that check
|
||||||
|
// could still fail: a new key that sorts before an existing common key
|
||||||
|
// makes target's iteration interleave the new key between common keys,
|
||||||
|
// even though nothing else about the object changed. That sent the
|
||||||
|
// whole object through the slow (remove-every-member,
|
||||||
|
// re-add-every-member) path instead of the minimal one.
|
||||||
|
SECTION("json: added key sorts before an existing common key")
|
||||||
|
{
|
||||||
|
const json source = {{"a", 1}, {"c", {{"x", 1}, {"y", 2}}}};
|
||||||
|
const json target = {{"a", 1}, {"b", 0}, {"c", {{"x", 1}, {"y", 2}}}};
|
||||||
|
|
||||||
|
const json patch = json::diff(source, target);
|
||||||
|
|
||||||
|
// only the new key is added; "a" and "c" are left alone instead of
|
||||||
|
// being removed and re-added
|
||||||
|
const json expected = R"([{"op": "add", "path": "/b", "value": 0}])"_json;
|
||||||
|
CHECK(patch == expected);
|
||||||
|
CHECK(source.patch(patch) == target);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("ordered_json: reordering behavior from #5465 is unchanged")
|
||||||
|
{
|
||||||
|
using nlohmann::ordered_json;
|
||||||
|
|
||||||
|
// same key/value shape as the json case above, but for ordered_json
|
||||||
|
// the *target*'s member order must be reproduced, so the slow path
|
||||||
|
// is still required here.
|
||||||
|
ordered_json source;
|
||||||
|
source["a"] = 1;
|
||||||
|
source["c"] = ordered_json{{"x", 1}, {"y", 2}};
|
||||||
|
|
||||||
|
ordered_json target;
|
||||||
|
target["a"] = 1;
|
||||||
|
target["b"] = 0;
|
||||||
|
target["c"] = ordered_json{{"x", 1}, {"y", 2}};
|
||||||
|
|
||||||
|
const ordered_json patch = ordered_json::diff(source, target);
|
||||||
|
|
||||||
|
// unlike the json case: every member is still removed and re-added
|
||||||
|
// so the result ends up in target's order (2 removes + 3 adds)
|
||||||
|
CHECK(patch.size() == 5);
|
||||||
|
CHECK(source.patch(patch) == target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("JSON patch - every operation on ordered_json")
|
TEST_CASE("JSON patch - every operation on ordered_json")
|
||||||
{
|
{
|
||||||
using nlohmann::ordered_json;
|
using nlohmann::ordered_json;
|
||||||
|
|||||||
@@ -380,6 +380,26 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
||||||
|
|
||||||
|
{
|
||||||
|
// contains() must not throw for an empty reference token if the current
|
||||||
|
// value is an array (cf. #5395) -- at() still reports out_of_range.404
|
||||||
|
json j_nested = {{"a", {1, 2}}};
|
||||||
|
const json& j_nested_const = j_nested;
|
||||||
|
json::json_pointer const jp("/a/");
|
||||||
|
std::string const throw_msg = "[json.exception.out_of_range.404] unresolved reference token ''";
|
||||||
|
|
||||||
|
CHECK_THROWS_WITH_AS(j_nested.at(jp), throw_msg.c_str(), json::out_of_range&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nested_const.at(jp), throw_msg.c_str(), json::out_of_range&);
|
||||||
|
|
||||||
|
CHECK(j_nested.contains(json::json_pointer("/a/1")));
|
||||||
|
CHECK(!j_nested.contains(jp));
|
||||||
|
CHECK(!j_nested_const.contains(jp));
|
||||||
|
|
||||||
|
// same for an empty reference token on a top-level array
|
||||||
|
CHECK(!j.contains(json::json_pointer("/")));
|
||||||
|
CHECK(!j_const.contains(json::json_pointer("/")));
|
||||||
|
}
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j.at("/one"_json_pointer) = 1,
|
CHECK_THROWS_WITH_AS(j.at("/one"_json_pointer) = 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index 'one' is not a number", json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const.at("/one"_json_pointer) == 1,
|
CHECK_THROWS_WITH_AS(j_const.at("/one"_json_pointer) == 1,
|
||||||
@@ -858,6 +878,25 @@ TEST_CASE("JSON pointers")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("value(json_pointer, default) with ordered_json #5664")
|
||||||
|
{
|
||||||
|
// ordered_json's transparent object comparator made value()'s
|
||||||
|
// is_comparable_with_object_key check (which passes the pointer as
|
||||||
|
// a reference) instantiate the deprecated json_pointer/string
|
||||||
|
// comparison; this must compile without relying on it. The
|
||||||
|
// deprecation warning itself is not observable here, since the
|
||||||
|
// unit test build disables -Wdeprecated-declarations (see
|
||||||
|
// cmake/clang_flags.cmake); it was checked manually instead.
|
||||||
|
const nlohmann::ordered_json j = {{"n", 1}, {"s", "text"}};
|
||||||
|
const nlohmann::ordered_json::json_pointer ptr_n("/n");
|
||||||
|
const nlohmann::ordered_json::json_pointer ptr_s("/s");
|
||||||
|
const nlohmann::ordered_json::json_pointer ptr_missing("/missing");
|
||||||
|
|
||||||
|
CHECK(j.value(ptr_n, 0) == 1);
|
||||||
|
CHECK(j.value(ptr_s, std::string("x")) == "text");
|
||||||
|
CHECK(j.value(ptr_missing, 42) == 42);
|
||||||
|
}
|
||||||
|
|
||||||
// build with C++20
|
// build with C++20
|
||||||
// JSON_HAS_CPP_20
|
// JSON_HAS_CPP_20
|
||||||
#if defined(__cpp_char8_t)
|
#if defined(__cpp_char8_t)
|
||||||
|
|||||||
@@ -257,10 +257,11 @@ struct LocaleSwitchingSax final: public nlohmann::json_sax<json>
|
|||||||
|
|
||||||
TEST_CASE("locale changes between lexer construction and number conversion (#5198)")
|
TEST_CASE("locale changes between lexer construction and number conversion (#5198)")
|
||||||
{
|
{
|
||||||
// The numbers are chosen so that the conversion also takes the strtod
|
// float and double are converted without the locale. A long double that
|
||||||
// fallback, which honors the locale that is current at conversion time:
|
// is not binary64 can take the strtold fallback, which honors the locale
|
||||||
// too many significant digits for Clinger's fast path, an underflow that
|
// that is current at conversion time. The numbers are chosen so that it
|
||||||
// std::from_chars rejects, and a plain value.
|
// does: too many significant digits for Clinger's fast path, an underflow
|
||||||
|
// that std::from_chars rejects, and a plain value.
|
||||||
const std::vector<std::string> numbers = {"3.14159265358979323846", "1.5e-400", "12.34", "-0.000123456789012345678"};
|
const std::vector<std::string> numbers = {"3.14159265358979323846", "1.5e-400", "12.34", "-0.000123456789012345678"};
|
||||||
std::string text = "[";
|
std::string text = "[";
|
||||||
for (const auto& n : numbers)
|
for (const auto& n : numbers)
|
||||||
@@ -324,7 +325,8 @@ TEST_CASE("locale changes between lexer construction and number conversion (#519
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// a long double goes through std::strtold unless std::from_chars supports it
|
// a long double goes through std::strtold unless it is binary64 or
|
||||||
|
// std::from_chars supports it
|
||||||
{
|
{
|
||||||
bool switched = false;
|
bool switched = false;
|
||||||
const auto cb = [&](int /*depth*/, long_double_json::parse_event_t event, long_double_json& /*parsed*/) noexcept
|
const auto cb = [&](int /*depth*/, long_double_json::parse_event_t event, long_double_json& /*parsed*/) noexcept
|
||||||
@@ -350,8 +352,15 @@ TEST_CASE("locale with a multi-byte decimal point")
|
|||||||
{
|
{
|
||||||
// Some locales use a decimal point that is not a single character, e.g.
|
// Some locales use a decimal point that is not a single character, e.g.
|
||||||
// U+066B ARABIC DECIMAL SEPARATOR (two bytes in UTF-8). It cannot be
|
// U+066B ARABIC DECIMAL SEPARATOR (two bytes in UTF-8). It cannot be
|
||||||
// substituted in place for '.', so the strtod fallback stops early. The
|
// substituted in place for '.', so the strtold fallback (only for long
|
||||||
// conversion must still terminate rather than retry forever.
|
// double formats other than binary64) converts a copy of the token with
|
||||||
|
// the whole decimal point instead (#5660). The values must be those of the
|
||||||
|
// "C" locale.
|
||||||
|
using long_double_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, long double>;
|
||||||
|
const char* const long_double_numbers = "[3.14159265358979323846, 1.5e-400, -0.000123456789012345678]";
|
||||||
|
REQUIRE(std::setlocale(LC_NUMERIC, "C") != nullptr);
|
||||||
|
const long_double_json expected_long_double = long_double_json::parse(long_double_numbers);
|
||||||
|
|
||||||
const std::array<const char*, 6> names = {{"ar_EG.UTF-8", "ar_SA.UTF-8", "fa_IR.UTF-8", "ps_AF.UTF-8", "ar_EG", "fa_IR"}};
|
const std::array<const char*, 6> names = {{"ar_EG.UTF-8", "ar_SA.UTF-8", "fa_IR.UTF-8", "ps_AF.UTF-8", "ar_EG", "fa_IR"}};
|
||||||
bool tested = false;
|
bool tested = false;
|
||||||
for (const char* name : names)
|
for (const char* name : names)
|
||||||
@@ -369,12 +378,20 @@ TEST_CASE("locale with a multi-byte decimal point")
|
|||||||
tested = true;
|
tested = true;
|
||||||
|
|
||||||
// too many significant digits for Clinger's fast path, and an underflow
|
// too many significant digits for Clinger's fast path, and an underflow
|
||||||
// that std::from_chars rejects: both reach the strtod fallback
|
// that std::from_chars rejects: double does not depend on the locale
|
||||||
json j;
|
json j;
|
||||||
CHECK_NOTHROW(j = json::parse("[3.14159265358979323846, 1.5e-400, -0.000123456789012345678]"));
|
CHECK_NOTHROW(j = json::parse("[3.14159265358979323846, 1.5e-400, -0.000123456789012345678]"));
|
||||||
CHECK(j.is_array());
|
CHECK(j.is_array());
|
||||||
|
CHECK(j[0] == 3.14159265358979323846);
|
||||||
|
CHECK(j[1] == 0.0);
|
||||||
|
CHECK(j[2] == -0.000123456789012345678);
|
||||||
CHECK(json::accept("3.14159265358979323846"));
|
CHECK(json::accept("3.14159265358979323846"));
|
||||||
|
|
||||||
|
// a long double that reaches the strtold fallback is not truncated
|
||||||
|
long_double_json ld;
|
||||||
|
CHECK_NOTHROW(ld = long_double_json::parse(long_double_numbers));
|
||||||
|
CHECK(ld == expected_long_double);
|
||||||
|
|
||||||
// a value the locale-independent paths convert is not affected
|
// a value the locale-independent paths convert is not affected
|
||||||
CHECK(json::parse("12.5") == 12.5);
|
CHECK(json::parse("12.5") == 12.5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,6 +155,18 @@ TEST_CASE("modifiers")
|
|||||||
CHECK(j == json(json::value_t::binary));
|
CHECK(j == json(json::value_t::binary));
|
||||||
CHECK(j == json(k.type()));
|
CHECK(j == json(k.type()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("filled binary with subtype")
|
||||||
|
{
|
||||||
|
json j = json::binary({1, 2, 3, 4, 5}, 42);
|
||||||
|
json const k = j;
|
||||||
|
|
||||||
|
j.clear();
|
||||||
|
CHECK(!j.empty());
|
||||||
|
CHECK(!j.get_binary().has_subtype());
|
||||||
|
CHECK(j == json(json::value_t::binary));
|
||||||
|
CHECK(j == json(k.type()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("number (integer)")
|
SECTION("number (integer)")
|
||||||
@@ -761,6 +773,34 @@ TEST_CASE("modifiers")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("initializer list referring to the array's own elements (#5656)")
|
||||||
|
{
|
||||||
|
SECTION("sufficient capacity (no reallocation)")
|
||||||
|
{
|
||||||
|
json j_own = json::array();
|
||||||
|
j_own.get_ref<json::array_t&>().reserve(8);
|
||||||
|
j_own.push_back("a");
|
||||||
|
j_own.push_back("b");
|
||||||
|
j_own.push_back("c");
|
||||||
|
|
||||||
|
const json& j_own_cref = j_own;
|
||||||
|
auto it = j_own.insert(j_own.begin(), {j_own_cref[0], j_own_cref[1]});
|
||||||
|
CHECK(*it == json("a"));
|
||||||
|
CHECK(j_own == json({"a", "b", "a", "b", "c"}));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("insufficient capacity (reallocation)")
|
||||||
|
{
|
||||||
|
json j_own = {"a", "b", "c"};
|
||||||
|
j_own.get_ref<json::array_t&>().shrink_to_fit();
|
||||||
|
|
||||||
|
const json& j_own_cref = j_own;
|
||||||
|
auto it = j_own.insert(j_own.begin(), {j_own_cref[2]});
|
||||||
|
CHECK(*it == json("c"));
|
||||||
|
CHECK(j_own == json({"c", "a", "b", "c"}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("invalid iterator")
|
SECTION("invalid iterator")
|
||||||
{
|
{
|
||||||
// pass iterator to a different array
|
// pass iterator to a different array
|
||||||
|
|||||||
@@ -2475,3 +2475,60 @@ TEST_CASE("MessagePack lengths beyond UINT32_MAX cannot be serialized")
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("MessagePack numbers use the active union member (see #5644)")
|
||||||
|
{
|
||||||
|
// when number_integer_t is narrower than number_unsigned_t, to_msgpack()
|
||||||
|
// used to read the union member that was not the active one, writing
|
||||||
|
// wrong bytes for some values; std::int64_t/std::uint64_t (the default
|
||||||
|
// types, where both members have the same width) were not affected
|
||||||
|
using int32_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int32_t, std::uint64_t, double>;
|
||||||
|
using int16_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int16_t, std::uint64_t, double>;
|
||||||
|
|
||||||
|
SECTION("number_integer_t = std::int32_t")
|
||||||
|
{
|
||||||
|
SECTION("6442450944 (uint 64; the low 32 bits used to be sign-extended)")
|
||||||
|
{
|
||||||
|
const int32_json j = 6442450944ULL;
|
||||||
|
CHECK(j.is_number_unsigned());
|
||||||
|
|
||||||
|
std::vector<uint8_t> const expected{0xcf, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00};
|
||||||
|
const auto result = int32_json::to_msgpack(j);
|
||||||
|
CHECK(result == expected);
|
||||||
|
CHECK(int32_json::from_msgpack(result) == j);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("4294967496 (uint 64; the low 32 bits used to be the whole value)")
|
||||||
|
{
|
||||||
|
const int32_json j = 4294967496ULL;
|
||||||
|
CHECK(j.is_number_unsigned());
|
||||||
|
|
||||||
|
std::vector<uint8_t> const expected{0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc8};
|
||||||
|
const auto result = int32_json::to_msgpack(j);
|
||||||
|
CHECK(result == expected);
|
||||||
|
CHECK(int32_json::from_msgpack(result) == j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("number_integer_t = std::int16_t, 98304 (uint 32)")
|
||||||
|
{
|
||||||
|
const int16_json j = 98304ULL;
|
||||||
|
CHECK(j.is_number_unsigned());
|
||||||
|
|
||||||
|
std::vector<uint8_t> const expected{0xce, 0x00, 0x01, 0x80, 0x00};
|
||||||
|
const auto result = int16_json::to_msgpack(j);
|
||||||
|
CHECK(result == expected);
|
||||||
|
CHECK(int16_json::from_msgpack(result) == j);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("default types (std::int64_t/std::uint64_t) are unaffected")
|
||||||
|
{
|
||||||
|
const json j = 4294967496ULL;
|
||||||
|
CHECK(j.is_number_unsigned());
|
||||||
|
|
||||||
|
std::vector<uint8_t> const expected{0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc8};
|
||||||
|
const auto result = json::to_msgpack(j);
|
||||||
|
CHECK(result == expected);
|
||||||
|
CHECK(json::from_msgpack(result) == j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
// This translation unit checks JSON_NO_AUTOMATIC_UDLS, which keeps
|
||||||
|
// <nlohmann/json.hpp> from including <nlohmann/json_literals.hpp> and thereby
|
||||||
|
// leaves out the user-defined string literals operator""_json and
|
||||||
|
// operator""_json_pointer (see #5294), and that including
|
||||||
|
// <nlohmann/json_literals.hpp> afterwards brings them back.
|
||||||
|
#define JSON_NO_AUTOMATIC_UDLS 1
|
||||||
|
|
||||||
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
// An argument type whose associated namespace is the library namespace, so
|
||||||
|
// argument-dependent lookup of a literal operator called by its function name
|
||||||
|
// also searches the inline namespaces nlohmann::literals::json_literals.
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
struct no_automatic_udls_probe
|
||||||
|
{
|
||||||
|
operator const char* () const // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// The calls below use a dependent argument, so a literal operator that is not
|
||||||
|
// declared at all is a substitution failure rather than a hard error: lookup is
|
||||||
|
// deferred to the point of instantiation, where it considers the declarations
|
||||||
|
// visible from here (the global using-declarations of JSON_USE_GLOBAL_UDLS) plus
|
||||||
|
// argument-dependent lookup (the literals in the library namespace).
|
||||||
|
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
|
||||||
|
template<typename T>
|
||||||
|
using json_udl_t = decltype(operator""_json(std::declval<T>(), std::size_t()));
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using json_pointer_udl_t = decltype(operator""_json_pointer(std::declval<T>(), std::size_t()));
|
||||||
|
#else
|
||||||
|
// GCC 4.8 requires a space between "" and suffix
|
||||||
|
template<typename T>
|
||||||
|
using json_udl_t = decltype(operator"" _json(std::declval<T>(), std::size_t()));
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using json_pointer_udl_t = decltype(operator"" _json_pointer(std::declval<T>(), std::size_t()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using has_json_udl = nlohmann::detail::is_detected<json_udl_t, T>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using has_json_pointer_udl = nlohmann::detail::is_detected<json_pointer_udl_t, T>;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("JSON_NO_AUTOMATIC_UDLS")
|
||||||
|
{
|
||||||
|
SECTION("literals are not declared")
|
||||||
|
{
|
||||||
|
// global namespace (JSON_USE_GLOBAL_UDLS defaults to 1)
|
||||||
|
CHECK_FALSE(has_json_udl<const char*>::value);
|
||||||
|
CHECK_FALSE(has_json_pointer_udl<const char*>::value);
|
||||||
|
|
||||||
|
// nlohmann::literals::json_literals
|
||||||
|
CHECK_FALSE(has_json_udl<nlohmann::no_automatic_udls_probe>::value);
|
||||||
|
CHECK_FALSE(has_json_pointer_udl<nlohmann::no_automatic_udls_probe>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("the rest of the library keeps working")
|
||||||
|
{
|
||||||
|
const json j = json::parse(R"({"foo": {"bar": 42}})");
|
||||||
|
CHECK(j.dump() == R"({"foo":{"bar":42}})");
|
||||||
|
|
||||||
|
const json::json_pointer ptr("/foo/bar");
|
||||||
|
CHECK(j.at(ptr) == 42);
|
||||||
|
CHECK(j.contains(ptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the literals can still be added where they are needed
|
||||||
|
#include <nlohmann/json_literals.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("JSON_NO_AUTOMATIC_UDLS with <nlohmann/json_literals.hpp>")
|
||||||
|
{
|
||||||
|
#if !defined(JSON_USE_GLOBAL_UDLS) || JSON_USE_GLOBAL_UDLS
|
||||||
|
SECTION("global namespace")
|
||||||
|
{
|
||||||
|
CHECK("[1,2]"_json == json({1, 2}));
|
||||||
|
CHECK("/a/0"_json_pointer == json::json_pointer("/a/0"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SECTION("nlohmann::literals::json_literals")
|
||||||
|
{
|
||||||
|
using namespace nlohmann::literals::json_literals; // NOLINT(google-build-using-namespace)
|
||||||
|
CHECK(R"({"a":[42]})"_json.at("/a/0"_json_pointer) == 42);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,97 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::ordered_map;
|
using nlohmann::ordered_map;
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// The EDG front end (Intel icpc, NVIDIA nvc++) considers the defaulted move
|
||||||
|
// constructor of std::pair<const Key, T> noexcept even if copying Key can
|
||||||
|
// throw. std::vector then moves such elements itself when it grows (and calls
|
||||||
|
// std::terminate if a key copy throws), so ordered_map leaves growing to it.
|
||||||
|
#if defined(__EDG__)
|
||||||
|
#define JSON_TEST_PAIR_MOVE_IS_NOEXCEPT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// number of copies made of counted values
|
||||||
|
int value_copies = 0;
|
||||||
|
|
||||||
|
// a mapped type that counts its copies; moving from it leaves -1 behind
|
||||||
|
struct counted // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
|
||||||
|
{
|
||||||
|
int payload = 0;
|
||||||
|
|
||||||
|
counted() = default;
|
||||||
|
explicit counted(int p) noexcept : payload(p) {}
|
||||||
|
counted(const counted& other) : payload(other.payload)
|
||||||
|
{
|
||||||
|
++value_copies;
|
||||||
|
}
|
||||||
|
counted(counted&& other) noexcept : payload(other.payload)
|
||||||
|
{
|
||||||
|
other.payload = -1;
|
||||||
|
}
|
||||||
|
counted& operator=(const counted&) = delete;
|
||||||
|
counted& operator=(counted&& other) noexcept
|
||||||
|
{
|
||||||
|
payload = other.payload;
|
||||||
|
other.payload = -1;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(JSON_NOEXCEPTION) && !defined(JSON_TEST_PAIR_MOVE_IS_NOEXCEPT)
|
||||||
|
// number of throwing_key copies that still succeed; the next one throws
|
||||||
|
// (a negative value means that copies never throw)
|
||||||
|
int key_copies_until_throw = -1;
|
||||||
|
|
||||||
|
// a key type whose copy constructor can be made to throw
|
||||||
|
struct throwing_key // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
|
||||||
|
{
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
explicit throwing_key(int i) noexcept : id(i) {}
|
||||||
|
throwing_key(const throwing_key& other) : id(other.id)
|
||||||
|
{
|
||||||
|
if (key_copies_until_throw == 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("key copy failed");
|
||||||
|
}
|
||||||
|
if (key_copies_until_throw > 0)
|
||||||
|
{
|
||||||
|
--key_copies_until_throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throwing_key& operator=(const throwing_key&) = delete;
|
||||||
|
|
||||||
|
friend bool operator==(const throwing_key& lhs, const throwing_key& rhs) noexcept
|
||||||
|
{
|
||||||
|
return lhs.id == rhs.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// a mapped type that cannot be default-constructed
|
||||||
|
struct no_default
|
||||||
|
{
|
||||||
|
explicit no_default(int v) noexcept : value(v) {}
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ordered_json must keep moving its values when an object grows
|
||||||
|
using ordered_object_t = nlohmann::ordered_json::object_t;
|
||||||
|
#if !defined(JSON_TEST_PAIR_MOVE_IS_NOEXCEPT)
|
||||||
|
static_assert(!std::is_nothrow_move_constructible<ordered_object_t::value_type>::value, "std::vector would move the elements itself");
|
||||||
|
#endif
|
||||||
|
static_assert(std::is_copy_constructible<ordered_object_t::key_type>::value, "keys must be copyable");
|
||||||
|
static_assert(std::is_default_constructible<ordered_object_t::mapped_type>::value, "values must be default-constructible");
|
||||||
|
static_assert(std::is_nothrow_move_assignable<ordered_object_t::mapped_type>::value, "values must be nothrow move-assignable");
|
||||||
|
} // namespace
|
||||||
|
|
||||||
TEST_CASE("ordered_map")
|
TEST_CASE("ordered_map")
|
||||||
{
|
{
|
||||||
SECTION("constructor")
|
SECTION("constructor")
|
||||||
@@ -313,3 +404,270 @@ TEST_CASE("ordered_map")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ordered_map growth")
|
||||||
|
{
|
||||||
|
SECTION("values are moved, not copied, when the storage grows")
|
||||||
|
{
|
||||||
|
ordered_map<std::string, counted> om;
|
||||||
|
std::size_t growths = 0;
|
||||||
|
value_copies = 0;
|
||||||
|
|
||||||
|
// inserts 100 elements with the given function and counts the growths
|
||||||
|
const auto fill = [&om, &growths](void (*insert)(ordered_map<std::string, counted>&, int))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
const auto old_capacity = om.capacity();
|
||||||
|
insert(om, i);
|
||||||
|
if (om.capacity() > old_capacity)
|
||||||
|
{
|
||||||
|
++growths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// checks that the elements are in insertion order with their values
|
||||||
|
const auto check_contents = [&om]
|
||||||
|
{
|
||||||
|
CHECK(om.size() == 100);
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& element : om)
|
||||||
|
{
|
||||||
|
CHECK(element.first == std::to_string(i));
|
||||||
|
CHECK(element.second.payload == i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SECTION("emplace")
|
||||||
|
{
|
||||||
|
fill([](ordered_map<std::string, counted>& m, int i)
|
||||||
|
{
|
||||||
|
m.emplace(std::to_string(i), counted(i));
|
||||||
|
});
|
||||||
|
CHECK(growths >= 3);
|
||||||
|
CHECK(value_copies == 0);
|
||||||
|
check_contents();
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("operator[]")
|
||||||
|
{
|
||||||
|
fill([](ordered_map<std::string, counted>& m, int i)
|
||||||
|
{
|
||||||
|
m[std::to_string(i)] = counted(i);
|
||||||
|
});
|
||||||
|
CHECK(growths >= 3);
|
||||||
|
CHECK(value_copies == 0);
|
||||||
|
check_contents();
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("insert(value_type&&)")
|
||||||
|
{
|
||||||
|
fill([](ordered_map<std::string, counted>& m, int i)
|
||||||
|
{
|
||||||
|
m.insert({std::to_string(i), counted(i)});
|
||||||
|
});
|
||||||
|
CHECK(growths >= 3);
|
||||||
|
CHECK(value_copies == 0);
|
||||||
|
check_contents();
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("insert(const value_type&)")
|
||||||
|
{
|
||||||
|
fill([](ordered_map<std::string, counted>& m, int i)
|
||||||
|
{
|
||||||
|
const std::pair<const std::string, counted> value(std::to_string(i), counted(i));
|
||||||
|
m.insert(value);
|
||||||
|
});
|
||||||
|
CHECK(growths >= 3);
|
||||||
|
// only the inserted values are copied
|
||||||
|
CHECK(value_copies == 100);
|
||||||
|
check_contents();
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("insert(first, last)")
|
||||||
|
{
|
||||||
|
std::vector<std::pair<const std::string, counted>> values;
|
||||||
|
values.reserve(100);
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
values.emplace_back(std::to_string(i), counted(i));
|
||||||
|
}
|
||||||
|
value_copies = 0;
|
||||||
|
|
||||||
|
om.insert(values.cbegin(), values.cend());
|
||||||
|
// only the inserted values are copied
|
||||||
|
CHECK(value_copies == 100);
|
||||||
|
check_contents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("elements keep their order and values over many growths")
|
||||||
|
{
|
||||||
|
ordered_map<std::string, counted> om;
|
||||||
|
for (int i = 0; i < 1000; ++i)
|
||||||
|
{
|
||||||
|
om.emplace(std::to_string(i), counted(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(om.size() == 1000);
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& element : om)
|
||||||
|
{
|
||||||
|
CHECK(element.first == std::to_string(i));
|
||||||
|
CHECK(element.second.payload == i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("arguments may refer to elements of the full container")
|
||||||
|
{
|
||||||
|
SECTION("moving a value out of the container")
|
||||||
|
{
|
||||||
|
ordered_map<std::string, counted> om;
|
||||||
|
om.reserve(4);
|
||||||
|
while (om.size() < om.capacity())
|
||||||
|
{
|
||||||
|
const auto i = static_cast<int>(om.size());
|
||||||
|
om.emplace(std::to_string(i), counted(i));
|
||||||
|
}
|
||||||
|
const auto size = om.size();
|
||||||
|
|
||||||
|
om.emplace("new", std::move(om.at("0")));
|
||||||
|
CHECK(om.size() == size + 1);
|
||||||
|
CHECK(om.at("new").payload == 0);
|
||||||
|
CHECK(om.at("0").payload == -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("using a value as key")
|
||||||
|
{
|
||||||
|
ordered_map<std::string, std::string> om;
|
||||||
|
om.reserve(4);
|
||||||
|
while (om.size() < om.capacity())
|
||||||
|
{
|
||||||
|
const auto i = std::to_string(om.size());
|
||||||
|
om.emplace("k" + i, "v" + i);
|
||||||
|
}
|
||||||
|
const auto size = om.size();
|
||||||
|
|
||||||
|
om.emplace(om.at("k0"), std::string("x"));
|
||||||
|
CHECK(om.size() == size + 1);
|
||||||
|
CHECK(om.at("k0") == "v0");
|
||||||
|
CHECK(om.at("v0") == "x");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("ordered_json")
|
||||||
|
{
|
||||||
|
auto j = nlohmann::ordered_json::object();
|
||||||
|
auto& object = j.get_ref<nlohmann::ordered_json::object_t&>();
|
||||||
|
object.reserve(4);
|
||||||
|
while (object.size() < object.capacity())
|
||||||
|
{
|
||||||
|
const auto i = std::to_string(object.size());
|
||||||
|
j[i] = "a value that is too long for the small string optimization " + i;
|
||||||
|
}
|
||||||
|
const auto size = j.size();
|
||||||
|
|
||||||
|
j.emplace("new", std::move(j["0"]));
|
||||||
|
CHECK(j.size() == size + 1);
|
||||||
|
CHECK(j["new"] == "a value that is too long for the small string optimization 0");
|
||||||
|
CHECK(j["0"].is_null());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(JSON_NOEXCEPTION) && !defined(JSON_TEST_PAIR_MOVE_IS_NOEXCEPT)
|
||||||
|
SECTION("the container is unchanged if growing it throws")
|
||||||
|
{
|
||||||
|
ordered_map<throwing_key, counted> om;
|
||||||
|
om.reserve(4);
|
||||||
|
while (om.size() < om.capacity())
|
||||||
|
{
|
||||||
|
const auto i = static_cast<int>(om.size());
|
||||||
|
om.emplace(throwing_key(i), counted(i));
|
||||||
|
}
|
||||||
|
const auto size = om.size();
|
||||||
|
const auto capacity = om.capacity();
|
||||||
|
|
||||||
|
// checks that the elements are unchanged
|
||||||
|
const auto check_unchanged = [&om, size, capacity]
|
||||||
|
{
|
||||||
|
CHECK(om.size() == size);
|
||||||
|
CHECK(om.capacity() == capacity);
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& element : om)
|
||||||
|
{
|
||||||
|
CHECK(element.first.id == i);
|
||||||
|
CHECK(element.second.payload == i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SECTION("emplace")
|
||||||
|
{
|
||||||
|
// growing copies the existing keys and then the new one; let each of these copies throw
|
||||||
|
for (std::size_t k = 0; k <= size; ++k)
|
||||||
|
{
|
||||||
|
counted value(100);
|
||||||
|
key_copies_until_throw = static_cast<int>(k);
|
||||||
|
CHECK_THROWS_AS(om.emplace(throwing_key(100), std::move(value)), std::runtime_error);
|
||||||
|
key_copies_until_throw = -1;
|
||||||
|
|
||||||
|
check_unchanged();
|
||||||
|
CHECK(value.payload == 100); // NOLINT(bugprone-use-after-move,hicpp-invalid-access-moved)
|
||||||
|
}
|
||||||
|
|
||||||
|
om.emplace(throwing_key(100), counted(100));
|
||||||
|
CHECK(om.size() == size + 1);
|
||||||
|
CHECK(om.capacity() > capacity);
|
||||||
|
CHECK(om.at(throwing_key(100)).payload == 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("insert(const value_type&)")
|
||||||
|
{
|
||||||
|
const std::pair<const throwing_key, counted> value(throwing_key(100), counted(100));
|
||||||
|
value_copies = 0;
|
||||||
|
|
||||||
|
key_copies_until_throw = static_cast<int>(size / 2);
|
||||||
|
CHECK_THROWS_AS(om.insert(value), std::runtime_error);
|
||||||
|
key_copies_until_throw = -1;
|
||||||
|
|
||||||
|
check_unchanged();
|
||||||
|
CHECK(value_copies == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SECTION("elements that std::vector moves, or that cannot be moved back")
|
||||||
|
{
|
||||||
|
SECTION("nothrow move-constructible elements")
|
||||||
|
{
|
||||||
|
ordered_map<int, counted> om;
|
||||||
|
value_copies = 0;
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
om.emplace(i, counted(i));
|
||||||
|
}
|
||||||
|
CHECK(om.size() == 100);
|
||||||
|
CHECK(value_copies == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("mapped type without default constructor")
|
||||||
|
{
|
||||||
|
ordered_map<std::string, no_default> om;
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
om.emplace(std::to_string(i), no_default(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(om.size() == 100);
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& element : om)
|
||||||
|
{
|
||||||
|
CHECK(element.first == std::to_string(i));
|
||||||
|
CHECK(element.second.value == i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -234,4 +234,33 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION")
|
|||||||
CHECK(j == json(1));
|
CHECK(j == json(1));
|
||||||
CHECK(remaining(is) == "true");
|
CHECK(remaining(is) == "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("stream with eofbit in its exception mask (issue #5646)")
|
||||||
|
{
|
||||||
|
// with JSON_PRECISE_STREAM_POSITION, get_character() peeks via
|
||||||
|
// sb->sgetc() rather than consuming via sb->sbumpc(), but it still
|
||||||
|
// calls std::istream::clear() to record eofbit once the streambuf is
|
||||||
|
// exhausted; with eofbit in the exception mask, that clear() itself
|
||||||
|
// throws std::ios_base::failure, which must propagate to the caller
|
||||||
|
// instead of ~input_stream_adapter() throwing a second exception
|
||||||
|
// while the first is still unwinding (which would call std::terminate)
|
||||||
|
json _;
|
||||||
|
|
||||||
|
std::istringstream is1("1");
|
||||||
|
is1.exceptions(std::ios::eofbit);
|
||||||
|
CHECK_THROWS_AS(_ = json::parse(is1), std::ios_base::failure&);
|
||||||
|
|
||||||
|
std::istringstream is2("1");
|
||||||
|
is2.exceptions(std::ios::failbit | std::ios::badbit | std::ios::eofbit);
|
||||||
|
CHECK_THROWS_AS(_ = json::parse(is2), std::ios_base::failure&);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("stream without a streambuf (issue #5646)")
|
||||||
|
{
|
||||||
|
// std::istream(nullptr) has badbit set and rdbuf() == nullptr;
|
||||||
|
// get_character() must not dereference that null streambuf
|
||||||
|
std::istream is(nullptr);
|
||||||
|
json _;
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::parse(is), "[json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,3 +8,6 @@ The following changes have been made to the code with respect to <https://github
|
|||||||
- membership check
|
- membership check
|
||||||
- made function from `_is_within`
|
- made function from `_is_within`
|
||||||
- removed unused variable `actual_path`
|
- removed unused variable `actual_path`
|
||||||
|
- Added the optional config key `external`: include paths listed there are kept as
|
||||||
|
`#include` directives instead of being inlined (the first directive per path; the
|
||||||
|
repeated ones are commented out).
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ Python v.2.7.0 or higher is required.
|
|||||||
amalgamation. Have a look at `test/source.c.json` and `test/include.h.json`
|
amalgamation. Have a look at `test/source.c.json` and `test/include.h.json`
|
||||||
to see two examples.
|
to see two examples.
|
||||||
|
|
||||||
|
The optional `external` list names include paths that are kept as `#include`
|
||||||
|
directives instead of being inlined, e.g. `["nlohmann/json.hpp"]` for a header
|
||||||
|
that includes another amalgamated header. Only the first directive for each
|
||||||
|
of these paths is kept; the repeated ones are commented out.
|
||||||
|
|
||||||
* The `-s, --source` option should specify the path to the source directory.
|
* The `-s, --source` option should specify the path to the source directory.
|
||||||
This is useful for supporting separate source and build directories.
|
This is useful for supporting separate source and build directories.
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ class Amalgamation(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
|
# include paths that are kept as #include directives instead of
|
||||||
|
# being inlined (e.g. a header amalgamated on its own)
|
||||||
|
self.external = []
|
||||||
|
self.included_external = []
|
||||||
with open(args.config, 'r') as f:
|
with open(args.config, 'r') as f:
|
||||||
config = json.loads(f.read())
|
config = json.loads(f.read())
|
||||||
for key in config:
|
for key in config:
|
||||||
@@ -220,11 +224,14 @@ class TranslationUnit(object):
|
|||||||
while include_match:
|
while include_match:
|
||||||
if not _is_within(include_match, skippable_contexts):
|
if not _is_within(include_match, skippable_contexts):
|
||||||
include_path = include_match.group("path")
|
include_path = include_match.group("path")
|
||||||
search_same_dir = include_match.group(1) == '"'
|
if include_path in self.amalgamation.external:
|
||||||
found_included_path = self.amalgamation.find_included_file(
|
includes.append((include_match, None))
|
||||||
include_path, self.file_dir if search_same_dir else None)
|
else:
|
||||||
if found_included_path:
|
search_same_dir = include_match.group(1) == '"'
|
||||||
includes.append((include_match, found_included_path))
|
found_included_path = self.amalgamation.find_included_file(
|
||||||
|
include_path, self.file_dir if search_same_dir else None)
|
||||||
|
if found_included_path:
|
||||||
|
includes.append((include_match, found_included_path))
|
||||||
|
|
||||||
include_match = self.include_pattern.search(self.content,
|
include_match = self.include_pattern.search(self.content,
|
||||||
include_match.end())
|
include_match.end())
|
||||||
@@ -235,6 +242,17 @@ class TranslationUnit(object):
|
|||||||
for include in includes:
|
for include in includes:
|
||||||
include_match, found_included_path = include
|
include_match, found_included_path = include
|
||||||
tmp_content += self.content[prev_end:include_match.start()]
|
tmp_content += self.content[prev_end:include_match.start()]
|
||||||
|
if found_included_path is None:
|
||||||
|
# an external header: keep the first directive and comment
|
||||||
|
# out the repeated ones
|
||||||
|
include_path = include_match.group("path")
|
||||||
|
if include_path in self.amalgamation.included_external:
|
||||||
|
tmp_content += "// {0}".format(include_match.group(0))
|
||||||
|
else:
|
||||||
|
self.amalgamation.included_external.append(include_path)
|
||||||
|
tmp_content += include_match.group(0)
|
||||||
|
prev_end = include_match.end()
|
||||||
|
continue
|
||||||
tmp_content += "// {0}\n".format(include_match.group(0))
|
tmp_content += "// {0}\n".format(include_match.group(0))
|
||||||
if found_included_path not in self.amalgamation.included_files:
|
if found_included_path not in self.amalgamation.included_files:
|
||||||
t = TranslationUnit(found_included_path, self.amalgamation, False)
|
t = TranslationUnit(found_included_path, self.amalgamation, False)
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"project": "JSON for Modern C++",
|
||||||
|
"target": "single_include/nlohmann/json_view.hpp",
|
||||||
|
"sources": [
|
||||||
|
"include/nlohmann/json_view.hpp"
|
||||||
|
],
|
||||||
|
"include_paths": ["include"],
|
||||||
|
"external": ["nlohmann/json.hpp"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user