mirror of
https://github.com/nlohmann/json.git
synced 2026-07-09 20:15:12 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cb7f1ae838 | |||
| fc7fde6910 | |||
| d0de6a9111 | |||
| f8e99e856c | |||
| 521a084827 | |||
| ca91678af1 | |||
| ff34a3fd2f |
@@ -234,11 +234,22 @@ jobs:
|
||||
|
||||
ci_cuda_example:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/nlohmann/json-ci:v2.4.0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# 11.8.0: newest pre-C++20 CUDA release, exercises the C++17 fallback
|
||||
# path (tests/cuda_example/CMakeLists.txt picks the standard per nvcc
|
||||
# version); 12.1.1: permanent regression guard for #3907 (nvcc 12.0/12.1
|
||||
# choke on enable_borrowed_range at C++20, fixed in 12.2); 12.6.3: recent
|
||||
# CUDA/C++20 coverage.
|
||||
cuda: ['11.8.0', '12.1.1', '12.6.3']
|
||||
container: nvidia/cuda:${{ matrix.cuda }}-devel-ubuntu22.04
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@f5b8fbb4d77cec1acc5a5f9f0df4beffaf5d98d9 # v4.3.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
|
||||
+6
-2
@@ -669,7 +669,6 @@ add_custom_target(ci_test_compiler_default
|
||||
add_custom_target(ci_cuda_example
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||
-DCMAKE_CUDA_HOST_COMPILER=g++-8
|
||||
-S${PROJECT_SOURCE_DIR}/tests/cuda_example -B${PROJECT_BINARY_DIR}/build_cuda_example
|
||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_cuda_example
|
||||
)
|
||||
@@ -720,6 +719,11 @@ add_custom_target(ci_icpx
|
||||
# to zero and does not honor NaN ordering; -Kieee restores strict IEEE 754 behavior
|
||||
# (needed for the dtoa/grisu and NaN-comparison code paths).
|
||||
#
|
||||
# -tp=px pins the target processor to the generic x86-64 baseline (SSE2-only) to avoid
|
||||
# a nvc++ 25.5 / LLVM issue: when nvc++ auto-detects -tp from the runner's CPU (e.g. -tp znver4),
|
||||
# certain attribute combinations trigger an llc instruction-selection crash on std::ldexp<unsigned>.
|
||||
# Pinning to px removes this variability and is robust to future llc/nvc++ updates.
|
||||
#
|
||||
# The following tests are excluded as they trigger known nvc++ 25.5 defects (not
|
||||
# library bugs); see https://github.com/nlohmann/json for tracking. Only the
|
||||
# affected language-standard variants are excluded so coverage is otherwise kept:
|
||||
@@ -733,7 +737,7 @@ add_custom_target(ci_nvhpc
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||
-DCMAKE_C_COMPILER=nvc -DCMAKE_CXX_COMPILER=nvc++
|
||||
-DCMAKE_CXX_FLAGS=-Kieee
|
||||
-DCMAKE_CXX_FLAGS="-Kieee;-tp=px"
|
||||
-DJSON_BuildTests=ON -DJSON_FastTests=ON
|
||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_nvhpc
|
||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_nvhpc
|
||||
|
||||
@@ -35,7 +35,8 @@ Unlike the [`parse()`](parse.md) function, this function neither throws an excep
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters (throws if null)
|
||||
- a `std::string`
|
||||
- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type, for instance.
|
||||
@@ -109,7 +110,8 @@ A UTF-8 byte order mark is silently ignored.
|
||||
- Added in version 3.0.0.
|
||||
- Ignoring comments via `ignore_comments` added in version 3.9.0.
|
||||
- Changed [runtime assertion](../../features/assertions.md) in case of `FILE*` null pointers to exception in version 3.12.0.
|
||||
- Added `ignore_trailing_commas` in version 3.12.x.
|
||||
- Added `ignore_trailing_commas` in version 3.13.0.
|
||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -92,4 +92,4 @@ std::string format_as(const BasicJsonType& j)
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.12.x.
|
||||
- Added in version 3.13.0.
|
||||
|
||||
@@ -29,7 +29,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../
|
||||
- a `FILE` pointer
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters
|
||||
- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type
|
||||
@@ -101,3 +102,4 @@ Linear in the size of the input.
|
||||
## Version history
|
||||
|
||||
- Added in version 3.11.0.
|
||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||
|
||||
@@ -29,7 +29,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../
|
||||
- a `FILE` pointer
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters
|
||||
- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type
|
||||
@@ -101,6 +102,7 @@ Linear in the size of the input.
|
||||
## Version history
|
||||
|
||||
- Added in version 3.4.0.
|
||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../
|
||||
- a `FILE` pointer
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters
|
||||
- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type
|
||||
@@ -111,6 +112,7 @@ Linear in the size of the input.
|
||||
- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0.
|
||||
- Added `allow_exceptions` parameter in version 3.2.0.
|
||||
- Added `tag_handler` parameter in version 3.9.0.
|
||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../
|
||||
- a `FILE` pointer
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters
|
||||
- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type
|
||||
@@ -103,6 +104,7 @@ Linear in the size of the input.
|
||||
- Parameter `start_index` since version 2.1.1.
|
||||
- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0.
|
||||
- Added `allow_exceptions` parameter in version 3.2.0.
|
||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../
|
||||
- a `FILE` pointer
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters
|
||||
- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type
|
||||
@@ -102,6 +103,7 @@ Linear in the size of the input.
|
||||
|
||||
- Added in version 3.1.0.
|
||||
- Added `allow_exceptions` parameter in version 3.2.0.
|
||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -114,6 +114,13 @@ overload (3).
|
||||
See [Number conversion](../../features/types/number_handling.md#number-conversion)
|
||||
for more information.
|
||||
|
||||
!!! note "`std::optional` conversions"
|
||||
|
||||
Prior to version 3.13.0, `#!cpp get<std::optional<T>>()` (and other conversions to `std::optional<T>`) failed to
|
||||
compile in every configuration, due to an internal implementation bug that made the `from_json` overload for
|
||||
`std::optional` unreachable regardless of the [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md)
|
||||
setting. This has been fixed.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
@@ -251,5 +251,6 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
||||
1. Added in version 1.0.0.
|
||||
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3)
|
||||
in version 3.11.0.
|
||||
3. Added in version 3.11.0.
|
||||
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
|
||||
already supported by [`at`](at.md), [`value`](value.md), [`find`](find.md), and other lookup functions.
|
||||
4. Added in version 2.0.0.
|
||||
|
||||
@@ -34,7 +34,8 @@ static basic_json parse(IteratorType first, IteratorType last,
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters (throws if null)
|
||||
- a `std::string`
|
||||
- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type, for instance.
|
||||
@@ -235,7 +236,8 @@ Invalid Unicode escapes and unpaired surrogates in the input are reported as
|
||||
- Overload for contiguous containers (1) added in version 2.0.3.
|
||||
- Ignoring comments via `ignore_comments` added in version 3.9.0.
|
||||
- Changed [runtime assertion](../../features/assertions.md) in case of `FILE*` null pointers to exception in version 3.12.0.
|
||||
- Added `ignore_trailing_commas` in version 3.12.x.
|
||||
- Added `ignore_trailing_commas` in version 3.13.0.
|
||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -74,4 +74,4 @@ is thrown. In any case, the original value is not changed: the patch is applied
|
||||
|
||||
- Added in version 2.0.0.
|
||||
- Added [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's
|
||||
target location has a non-object/non-array parent in version 3.12.x.
|
||||
target location has a non-object/non-array parent in version 3.13.0.
|
||||
|
||||
@@ -71,4 +71,4 @@ function throws an exception.
|
||||
|
||||
- Added in version 3.11.0.
|
||||
- Added [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's
|
||||
target location has a non-object/non-array parent in version 3.12.x.
|
||||
target location has a non-object/non-array parent in version 3.13.0.
|
||||
|
||||
@@ -39,8 +39,8 @@ The SAX event lister must follow the interface of [`json_sax`](../json_sax/index
|
||||
- a `FILE` pointer
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters
|
||||
- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of
|
||||
iterators.
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
`IteratorType`
|
||||
: a compatible iterator type for overload (2); a pair of character iterators whose `value_type` is an integral type
|
||||
@@ -126,7 +126,8 @@ A UTF-8 byte order mark is silently ignored.
|
||||
|
||||
- Added in version 3.2.0.
|
||||
- Ignoring comments via `ignore_comments` added in version 3.9.0.
|
||||
- Added `ignore_trailing_commas` in version 3.12.x.
|
||||
- Added `ignore_trailing_commas` in version 3.13.0.
|
||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
|
||||
@@ -54,4 +54,4 @@ provides `<format>`, controlled by the [`JSON_HAS_STD_FORMAT`](../macros/json_ha
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.12.x.
|
||||
- Added in version 3.13.0.
|
||||
|
||||
@@ -21,6 +21,12 @@ a string representation of the type ([`value_t`](value_t.md)):
|
||||
| array | `"array"` |
|
||||
| binary | `"binary"` |
|
||||
| discarded | `"discarded"` |
|
||||
| invalid (corrupted value) | `"invalid"` |
|
||||
|
||||
!!! note "The \"invalid\" type"
|
||||
|
||||
The `"invalid"` return value indicates a corrupted JSON value — this can occur if an enum value falls outside the
|
||||
range of valid `value_t` values. This is useful for diagnosing data corruption or internal errors.
|
||||
|
||||
## Exception safety
|
||||
|
||||
@@ -52,3 +58,4 @@ Constant.
|
||||
- Part of the public API version since 2.1.0.
|
||||
- Changed return value to `const char*` and added `noexcept` in version 3.0.0.
|
||||
- Added support for binary type in version 3.8.0.
|
||||
- Added `"invalid"` return value for corrupted JSON values in version 3.13.0.
|
||||
|
||||
@@ -184,4 +184,6 @@ changes to any JSON value.
|
||||
|
||||
1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version 3.11.0.
|
||||
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.12.x.
|
||||
3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0, including fixing an issue where resolving
|
||||
`ptr` through an array unexpectedly threw `out_of_range` instead of returning the resolved element (or
|
||||
`default_value`, as documented).
|
||||
|
||||
@@ -36,4 +36,4 @@ Constant.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.12.x.
|
||||
- Added in version 3.13.0.
|
||||
|
||||
@@ -32,4 +32,4 @@ Linear in the number of reference tokens in the `json_pointer`.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.12.x.
|
||||
- Added in version 3.13.0.
|
||||
|
||||
@@ -35,4 +35,4 @@ Linear in the number of reference tokens in the `json_pointer`.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.12.x.
|
||||
- Added in version 3.13.0.
|
||||
|
||||
@@ -92,4 +92,4 @@ The default value is `0` (disabled — existing behavior is preserved).
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.12.x.
|
||||
- Added in version 3.13.0.
|
||||
|
||||
@@ -44,4 +44,4 @@ The default value is detected based on preprocessor macros such as `#!cpp __cplu
|
||||
|
||||
- Added in version 3.10.5.
|
||||
- Added `JSON_HAS_CPP_23` in version 3.12.0.
|
||||
- Added `JSON_HAS_CPP_26` in version 3.12.x.
|
||||
- Added `JSON_HAS_CPP_26` in version 3.13.0.
|
||||
|
||||
@@ -19,6 +19,20 @@ The default value is detected based on the preprocessor macros `#!cpp __cpp_lib_
|
||||
`#!cpp __cpp_lib_experimental_filesystem`, `#!cpp __has_include(<filesystem>)`, or
|
||||
`#!cpp __has_include(<experimental/filesystem>)`.
|
||||
|
||||
!!! info "Known compiler/stdlib exclusions"
|
||||
|
||||
Even when the feature-test macro indicates filesystem support is available, the library disables it on the following broken toolchains:
|
||||
|
||||
- **MinGW + GCC 8** — disabled entirely (broken `std::filesystem` implementation; [MinGW-w64 bug 737](https://sourceforge.net/p/mingw-w64/bugs/737/))
|
||||
- **GCC (non-Clang) < 8** — disabled (no filesystem support)
|
||||
- **Clang < 7** — disabled (no filesystem support)
|
||||
- **MSVC < 19.14** — disabled (no filesystem support)
|
||||
- **iOS < 13** — disabled (no filesystem support)
|
||||
- **macOS < Catalina (10.15)** — disabled (no filesystem support)
|
||||
|
||||
If `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` is `0` despite `__cpp_lib_filesystem` being defined, one
|
||||
of the exclusions above likely applies to your toolchain.
|
||||
|
||||
## Notes
|
||||
|
||||
- Note that older compilers or older versions of libstdc++ also require the library `stdc++fs` to be linked to for
|
||||
|
||||
@@ -13,6 +13,18 @@ The default value is detected based on the preprocessor macro `#!cpp __cpp_lib_r
|
||||
|
||||
When the macro is not defined, the library will define it to its default value.
|
||||
|
||||
!!! info "Known compiler/stdlib exclusions"
|
||||
|
||||
Even when the feature-test macro `__cpp_lib_ranges` indicates ranges support is available, the library disables it on
|
||||
the following incomplete or broken toolchains:
|
||||
|
||||
- **GCC 11.1.0** — disabled (the shipped `<ranges>` header has a syntax error; [issue #4440](https://github.com/nlohmann/json/issues/4440))
|
||||
- **libstdc++ < 11** — disabled (incomplete C++20 ranges support; [issue #4440](https://github.com/nlohmann/json/issues/4440))
|
||||
- **Clang < 16 with libstdc++** — disabled (incomplete ranges support; [issue #4440](https://github.com/nlohmann/json/issues/4440))
|
||||
- **libc++ < 160000** — disabled (incomplete C++20 ranges support; [issue #4440](https://github.com/nlohmann/json/issues/4440))
|
||||
|
||||
If `JSON_HAS_RANGES` is `0` despite `__cpp_lib_ranges` being defined, one of the exclusions above likely applies to your toolchain.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
@@ -38,4 +38,4 @@ When the macro is not defined, the library will define it to its default value.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.12.x.
|
||||
- Added in version 3.13.0.
|
||||
|
||||
@@ -75,4 +75,4 @@ For further information please refer to the corresponding macros without `WITH_N
|
||||
|
||||
## Version history
|
||||
|
||||
1. Added in version 3.12.x.
|
||||
1. Added in version 3.13.0.
|
||||
|
||||
@@ -102,4 +102,4 @@ inline void from_json(const BasicJsonType& j, type& e);
|
||||
|
||||
## Version history
|
||||
|
||||
Added in version 3.12.x.
|
||||
Added in version 3.13.0.
|
||||
|
||||
@@ -64,4 +64,4 @@ Linear.
|
||||
|
||||
- Added in version 1.0.0.
|
||||
- Moved to namespace `nlohmann::literals::json_literals` in 3.11.0.
|
||||
- Added `char8_t*` overload in 3.12.x.
|
||||
- Added `char8_t*` overload in 3.13.0.
|
||||
|
||||
@@ -63,4 +63,4 @@ Linear.
|
||||
|
||||
- Added in version 2.0.0.
|
||||
- Moved to namespace `nlohmann::literals::json_literals` in 3.11.0.
|
||||
- Added `char8_t*` overload in 3.12.x.
|
||||
- Added `char8_t*` overload in 3.13.0.
|
||||
|
||||
@@ -10,6 +10,10 @@ violations will result in a failed build.
|
||||
|
||||
Any compiler with complete C++11 support can compile the library without warnings.
|
||||
|
||||
Note: C++20 modules support may hit compiler-specific issues not covered by the general compiler matrix below. See [Modules](../features/modules.md#known-issues) for known issues and workarounds.
|
||||
|
||||
Note: Some modern features (like C++20 ranges or filesystem support) may be disabled on specific broken or incomplete toolchains even when standard feature-test macros indicate support. See [`JSON_HAS_RANGES`](../api/macros/json_has_ranges.md) and [`JSON_HAS_FILESYSTEM`](../api/macros/json_has_filesystem.md) for details on known exclusions.
|
||||
|
||||
- [x] The library is compiled with 50+ different C++ compilers with different operating systems and platforms,
|
||||
including the oldest versions known to compile the library.
|
||||
|
||||
@@ -62,7 +66,9 @@ violations will result in a failed build.
|
||||
| Clang 20.1.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||
| Clang 20.1.8 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub |
|
||||
| Clang 21.1.8 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||
| CUDA 11.0.221 (nvcc) | x86_64 | Ubuntu 20.04 LTS | GitHub |
|
||||
| CUDA 11.8.0 (nvcc) | x86_64 | Ubuntu 22.04 LTS | GitHub |
|
||||
| CUDA 12.1.1 (nvcc) | x86_64 | Ubuntu 22.04 LTS | GitHub |
|
||||
| CUDA 12.6.3 (nvcc) | x86_64 | Ubuntu 22.04 LTS | GitHub |
|
||||
| Emscripten 4.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||
| GNU 4.8.5 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||
| GNU 4.9.3 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||
|
||||
@@ -66,7 +66,15 @@ see "binary" cells in the table above.
|
||||
|
||||
!!! info "NaN/infinity handling"
|
||||
|
||||
If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the normal JSON serialization which serializes NaN or Infinity to `null`.
|
||||
`NaN`, `Infinity`, and `-Infinity` are serialized as a CBOR half-precision float (type 0xF9, 3 bytes total):
|
||||
`NaN` as `0xF9 0x7E 0x00`, `Infinity` as `0xF9 0x7C 0x00`, and `-Infinity` as `0xF9 0xFC 0x00`. This behavior
|
||||
differs from the normal JSON serialization which serializes NaN or Infinity to `null`.
|
||||
|
||||
!!! note
|
||||
|
||||
Prior to version 3.13.0, NaN and Infinity were instead serialized as a CBOR double-precision float (type 0xFB,
|
||||
9 bytes total), because the check used to select a smaller encoding compared magnitudes with NaN, which is
|
||||
always `false` and caused the intended half-precision path to be skipped.
|
||||
|
||||
!!! info "Unused CBOR types"
|
||||
|
||||
@@ -160,6 +168,13 @@ The library maps CBOR types to JSON value types as follows:
|
||||
- simple values (0xE0..0xF3, 0xF8)
|
||||
- undefined (0xF7)
|
||||
|
||||
!!! warning "Negative integer overflow"
|
||||
|
||||
CBOR negative integers (major type 1) are decoded as `-1 - n`. If the encoded magnitude `n` is too large for the
|
||||
result to fit into `number_integer_t` (`std::int64_t` by default), parsing fails with a
|
||||
[`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) exception rather than overflowing
|
||||
silently.
|
||||
|
||||
!!! warning "Object keys"
|
||||
|
||||
CBOR allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than UTF-8 strings are rejected.
|
||||
|
||||
@@ -67,8 +67,15 @@ specification:
|
||||
|
||||
!!! info "NaN/infinity handling"
|
||||
|
||||
If NaN or Infinity are stored inside a JSON number, they are serialized properly in contrast to the
|
||||
[dump](../../api/basic_json/dump.md) function which serializes NaN or Infinity to `null`.
|
||||
`NaN`, `Infinity`, and `-Infinity` are serialized as a MessagePack float 32 (type 0xCA, 5 bytes total),
|
||||
regardless of magnitude, in contrast to the [dump](../../api/basic_json/dump.md) function which serializes NaN
|
||||
or Infinity to `null`.
|
||||
|
||||
!!! note
|
||||
|
||||
Prior to version 3.13.0, NaN and Infinity were instead serialized as a MessagePack float 64 (type 0xCB, 9 bytes
|
||||
total), because the check used to select the smaller float 32 encoding compared magnitudes with NaN, which is
|
||||
always `false` and caused the float 32 path to be skipped.
|
||||
|
||||
??? example
|
||||
|
||||
|
||||
@@ -66,6 +66,24 @@ which forces the explicit `get` form and can catch unintended conversions at com
|
||||
floating-point value as an integer truncates it, and narrowing conversions may overflow. See
|
||||
[number conversion](types/number_handling.md#number-conversion) for details and how to guard against it.
|
||||
|
||||
!!! warning "std::optional direct construction from JSON null throws"
|
||||
|
||||
Constructing or assigning `std::optional<T>` directly from a JSON value does not correctly produce
|
||||
`std::nullopt` for a JSON `null`:
|
||||
|
||||
```cpp
|
||||
json j_null;
|
||||
std::optional<std::string> opt = j_null; // ❌ throws type_error 302
|
||||
```
|
||||
|
||||
This is due to C++ language rules: `std::optional<T>` has its own converting constructor that is chosen over
|
||||
`basic_json::operator T()` when both are viable. Use `get<std::optional<T>>()` or `get_to()` instead:
|
||||
|
||||
```cpp
|
||||
auto opt = j_null.get<std::optional<std::string>>(); // ✅ std::nullopt
|
||||
j_null.get_to(opt); // ✅ std::nullopt
|
||||
```
|
||||
|
||||
## Putting values in
|
||||
|
||||
The reverse direction works the same way: assigning or constructing a `json` from a C++ value converts it to JSON.
|
||||
|
||||
@@ -27,6 +27,7 @@ json data = json::parse(f);
|
||||
It should be noted that as modules do not export macros, the `nlohmann.json` module will not export any macros.
|
||||
|
||||
## Exported symbols
|
||||
|
||||
Only the following symbols are exported from `nlohmann.json`:
|
||||
|
||||
- `nlohmann::adl_serializer`
|
||||
@@ -38,3 +39,21 @@ Only the following symbols are exported from `nlohmann.json`:
|
||||
- `nlohmann::to_string`
|
||||
- `nlohmann::literals::json_literals::operator""_json`
|
||||
- `nlohmann::literals::json_literals::operator""_json_pointer`
|
||||
|
||||
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,
|
||||
and should not be used directly:
|
||||
|
||||
- `nlohmann::detail::json_sax_dom_callback_parser`
|
||||
- `nlohmann::detail::unknown_size`
|
||||
|
||||
## Known issues
|
||||
|
||||
C++20 modules support is exercised in CI against current GCC and Clang on Ubuntu, and the default MSVC toolset on Windows Server 2022 — there is no documented minimum compiler version, unlike feature-test-macro-gated features such as [`JSON_HAS_RANGES`](../api/macros/json_has_ranges.md).
|
||||
|
||||
!!! info "Known compiler issues"
|
||||
|
||||
- **GCC** may emit "redefinition" errors when `#include <nlohmann/json.hpp>` appears in a module preamble together with other imports. This is an upstream GCC bug, not yet resolved as of GCC 16. Workarounds: include `nlohmann/json.hpp` before other `#include`s, use `import nlohmann.json;` instead, or upgrade GCC. ([issue #5103](https://github.com/nlohmann/json/issues/5103))
|
||||
- **MSVC** could fail with `C2039: 'json_sax_dom_callback_parser' is not a member of ... detail`; fixed by exporting the required internal symbols from `json.cppm` (see [Exported symbols](#exported-symbols) above). ([issue #3970](https://github.com/nlohmann/json/issues/3970))
|
||||
|
||||
If you hit a different module-related build failure, search [existing issues](https://github.com/nlohmann/json/issues?q=is%3Aissue+modules) before filing a new one.
|
||||
|
||||
@@ -63,6 +63,10 @@ In the default [`json`](../../api/json.md) type, numbers are stored as `#!c std:
|
||||
number without loss of precision. If this is impossible (e.g., if the number is too large), the number is stored as
|
||||
`#!c double`.
|
||||
|
||||
Positive integers are stored as `#!c std::uint64_t`, while negative integers are stored as `#!c std::int64_t`. This
|
||||
distinction is determined at parse time: if the JSON number has a leading minus sign, it uses signed integer storage;
|
||||
otherwise, it uses unsigned integer storage.
|
||||
|
||||
!!! info "Notes"
|
||||
|
||||
- Numbers with a decimal digit or scientific notation are always stored as `#!c double`.
|
||||
|
||||
@@ -326,6 +326,9 @@ An unexpected byte was read in a [binary format](../features/binary_formats/inde
|
||||
```
|
||||
[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1
|
||||
```
|
||||
```
|
||||
[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: negative integer overflow
|
||||
```
|
||||
|
||||
### json.exception.parse_error.113
|
||||
|
||||
@@ -893,7 +896,7 @@ A JSON Patch `add` operation cannot be applied because the target location's par
|
||||
|
||||
!!! note
|
||||
|
||||
This exception was added in version 3.12.x. Before that, this situation hit an internal assertion (aborting the program in debug builds) or was silently ignored when assertions were disabled.
|
||||
This exception was added in version 3.13.0. Before that, this situation hit an internal assertion (aborting the program in debug builds) or was silently ignored when assertions were disabled.
|
||||
|
||||
## Further exceptions
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ See [this section](../features/types/number_handling.md#number-serialization) on
|
||||
- Can I use `std::format("{}", j)` on a JSON value?
|
||||
- Can I use `fmt::format("{}", j)` or `fmt::print("{}", j)` (the [{fmt}](https://github.com/fmtlib/fmt) library) on a JSON value?
|
||||
|
||||
`std::format` works out of the box since version 3.12.x, as long as the standard library provides
|
||||
`std::format` works out of the box since version 3.13.0, as long as the standard library provides
|
||||
`<format>` (see [`JSON_HAS_STD_FORMAT`](../api/macros/json_has_std_format.md)); see
|
||||
[`std::formatter<basic_json>`](../api/basic_json/std_formatter.md) for details, including the `#!cpp "{:#}"`
|
||||
pretty-print spec, indent widths (`#!cpp "{:2}"`), and custom indent characters (`#!cpp "{:.>#}"`).
|
||||
|
||||
@@ -517,18 +517,19 @@ struct container_input_adapter_factory< ContainerType,
|
||||
{
|
||||
using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
|
||||
|
||||
static adapter_type create(const ContainerType& container)
|
||||
static adapter_type create(ContainerType&& container)
|
||||
{
|
||||
return input_adapter(begin(container), end(container));
|
||||
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace container_input_adapter_factory_impl
|
||||
|
||||
template<typename ContainerType>
|
||||
typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
|
||||
auto input_adapter(ContainerType&& container)
|
||||
-> typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type
|
||||
{
|
||||
return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
|
||||
return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(std::forward<ContainerType>(container));
|
||||
}
|
||||
|
||||
// specialization for std::string
|
||||
|
||||
@@ -146,6 +146,11 @@
|
||||
#define JSON_HAS_RANGES 0
|
||||
#elif defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 160000
|
||||
#define JSON_HAS_RANGES 0
|
||||
// nvcc CUDA 12.0/12.1 chokes on the enable_borrowed_range variable-template
|
||||
// syntax when compiling as CUDA source; fixed in CUDA 12.2 (issue #3907)
|
||||
#elif defined(__CUDACC__) && defined(__CUDACC_VER_MAJOR__) && __CUDACC_VER_MAJOR__ == 12 \
|
||||
&& defined(__CUDACC_VER_MINOR__) && (__CUDACC_VER_MINOR__ == 0 || __CUDACC_VER_MINOR__ == 1)
|
||||
#define JSON_HAS_RANGES 0
|
||||
#elif defined(__cpp_lib_ranges)
|
||||
#define JSON_HAS_RANGES 1
|
||||
#else
|
||||
|
||||
@@ -2520,6 +2520,11 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
||||
#define JSON_HAS_RANGES 0
|
||||
#elif defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 160000
|
||||
#define JSON_HAS_RANGES 0
|
||||
// nvcc CUDA 12.0/12.1 chokes on the enable_borrowed_range variable-template
|
||||
// syntax when compiling as CUDA source; fixed in CUDA 12.2 (issue #3907)
|
||||
#elif defined(__CUDACC__) && defined(__CUDACC_VER_MAJOR__) && __CUDACC_VER_MAJOR__ == 12 \
|
||||
&& defined(__CUDACC_VER_MINOR__) && (__CUDACC_VER_MINOR__ == 0 || __CUDACC_VER_MINOR__ == 1)
|
||||
#define JSON_HAS_RANGES 0
|
||||
#elif defined(__cpp_lib_ranges)
|
||||
#define JSON_HAS_RANGES 1
|
||||
#else
|
||||
@@ -7349,18 +7354,19 @@ struct container_input_adapter_factory< ContainerType,
|
||||
{
|
||||
using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
|
||||
|
||||
static adapter_type create(const ContainerType& container)
|
||||
static adapter_type create(ContainerType&& container)
|
||||
{
|
||||
return input_adapter(begin(container), end(container));
|
||||
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace container_input_adapter_factory_impl
|
||||
|
||||
template<typename ContainerType>
|
||||
typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
|
||||
auto input_adapter(ContainerType&& container)
|
||||
-> typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type
|
||||
{
|
||||
return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
|
||||
return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(std::forward<ContainerType>(container));
|
||||
}
|
||||
|
||||
// specialization for std::string
|
||||
|
||||
@@ -3,7 +3,18 @@ project(json_cuda LANGUAGES CUDA)
|
||||
|
||||
add_executable(json_cuda json_cuda.cu)
|
||||
target_include_directories(json_cuda PRIVATE ../../include)
|
||||
target_compile_features(json_cuda PUBLIC cuda_std_11)
|
||||
|
||||
# nvcc added C++20 support in CUDA 12.0 and C++17 in CUDA 11.0; pick the
|
||||
# newest standard the detected compiler actually supports (see #3907)
|
||||
# instead of hard-requiring one standard for every CUDA version.
|
||||
if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0)
|
||||
set(json_cuda_std 20)
|
||||
elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0)
|
||||
set(json_cuda_std 17)
|
||||
else()
|
||||
set(json_cuda_std 11)
|
||||
endif()
|
||||
target_compile_features(json_cuda PUBLIC cuda_std_${json_cuda_std})
|
||||
set_target_properties(json_cuda PROPERTIES
|
||||
CUDA_EXTENSIONS OFF
|
||||
CUDA_STANDARD_REQUIRED ON
|
||||
|
||||
@@ -16,4 +16,20 @@ int main()
|
||||
// regression for #3013 (ordered_json::reset() compile error with nvcc)
|
||||
nlohmann::ordered_json metadata;
|
||||
metadata.erase("key");
|
||||
|
||||
// exercise comparisons (operator==/operator<=>, gated by
|
||||
// JSON_HAS_THREE_WAY_COMPARISON, independent of JSON_HAS_RANGES) and
|
||||
// range-based iteration (exercises iteration_proxy/ranges machinery
|
||||
// beyond just the enable_borrowed_range specialization) — see #3907
|
||||
nlohmann::json a = {1, 2, 3};
|
||||
nlohmann::json b = {1, 2, 3};
|
||||
static_cast<void>(a == b);
|
||||
#if JSON_HAS_THREE_WAY_COMPARISON
|
||||
static_cast<void>(a <=> b); // *NOPAD*
|
||||
static_cast<void>(a <=> 1); // *NOPAD*
|
||||
#endif
|
||||
for (const auto& element : a)
|
||||
{
|
||||
static_cast<void>(element);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1761,16 +1761,27 @@ TEST_CASE("std::filesystem::path")
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !JSON_USE_IMPLICIT_CONVERSIONS
|
||||
TEST_CASE("std::optional")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j_null;
|
||||
std::optional<std::string> opt_null;
|
||||
const json j_null;
|
||||
const std::optional<std::string> opt_null;
|
||||
|
||||
CHECK(json(opt_null) == j_null);
|
||||
CHECK(j_null.get<std::optional<std::string>>() == std::nullopt);
|
||||
|
||||
// Constructing std::optional<T> directly from JSON null throws because
|
||||
// std::optional's own converting constructor is chosen over basic_json's
|
||||
// operator T(). This is a language-level limitation (std::optional<T> is
|
||||
// constructible from T, and T is constructible from basic_json via the
|
||||
// operator); there is no SFINAE path that distinguishes "call from inside
|
||||
// std::optional's constructor" from "direct call". Use get<std::optional<T>>()
|
||||
// or get_to() instead for correct null handling. See #4864 and #5246.
|
||||
CHECK_THROWS_WITH_AS(std::optional<std::string>(j_null),
|
||||
"[json.exception.type_error.302] type must be string, but is null", json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(std::optional<int>(j_null),
|
||||
"[json.exception.type_error.302] type must be number, but is null", json::type_error&);
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
@@ -1819,7 +1830,6 @@ TEST_CASE("std::optional")
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#undef JSON_HAS_CPP_17
|
||||
|
||||
@@ -54,6 +54,47 @@ TEST_CASE("Custom container non-member begin/end")
|
||||
|
||||
}
|
||||
|
||||
struct MyContainerNonConstADL
|
||||
{
|
||||
char* data;
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
char* begin(MyContainerNonConstADL& c)
|
||||
{
|
||||
return c.data;
|
||||
}
|
||||
|
||||
char* end(MyContainerNonConstADL& c)
|
||||
{
|
||||
return c.data + c.size; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
}
|
||||
|
||||
TEST_CASE("Custom container non-member non-const begin/end")
|
||||
{
|
||||
// Container with lvalue-only non-const ADL begin/end (bug reproduction)
|
||||
char raw_data[] = "[1,2,3,4]";
|
||||
MyContainerNonConstADL data{raw_data, sizeof(raw_data) - 1};
|
||||
const json as_json = json::parse(data);
|
||||
CHECK(as_json.at(0) == 1);
|
||||
CHECK(as_json.at(1) == 2);
|
||||
CHECK(as_json.at(2) == 3);
|
||||
CHECK(as_json.at(3) == 4);
|
||||
|
||||
// Same container with accept()
|
||||
CHECK(json::accept(data));
|
||||
}
|
||||
|
||||
TEST_CASE("Custom container non-member begin/end, rvalue")
|
||||
{
|
||||
// Regression check: rvalue container parsing should still work
|
||||
const json as_json = json::parse(MyContainer{"[1,2,3,4]"});
|
||||
CHECK(as_json.at(0) == 1);
|
||||
CHECK(as_json.at(1) == 2);
|
||||
CHECK(as_json.at(2) == 3);
|
||||
CHECK(as_json.at(3) == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("Custom container member begin/end")
|
||||
{
|
||||
struct MyContainer2
|
||||
|
||||
Reference in New Issue
Block a user