Unverified Commit 4a16e559 by Niels Lohmann

Merge branch 'develop' of https://github.com/nlohmann/json into string_view

Conflicts: include/nlohmann/detail/meta/type_traits.hpp single_include/nlohmann/json.hpp
parents ea4891fb d4f44659
...@@ -58,7 +58,7 @@ To make changes, you need to edit the following files: ...@@ -58,7 +58,7 @@ To make changes, you need to edit the following files:
- Specifically, I am aware of compilation problems with **Microsoft Visual Studio** (there even is an [issue label](https://github.com/nlohmann/json/issues?utf8=✓&q=label%3A%22visual+studio%22+) for these kind of bugs). I understand that even in 2016, complete C++11 support isn't there yet. But please also understand that I do not want to drop features or uglify the code just to make Microsoft's sub-standard compiler happy. The past has shown that there are ways to express the functionality such that the code compiles with the most recent MSVC - unfortunately, this is not the main objective of the project. - Specifically, I am aware of compilation problems with **Microsoft Visual Studio** (there even is an [issue label](https://github.com/nlohmann/json/issues?utf8=✓&q=label%3A%22visual+studio%22+) for these kind of bugs). I understand that even in 2016, complete C++11 support isn't there yet. But please also understand that I do not want to drop features or uglify the code just to make Microsoft's sub-standard compiler happy. The past has shown that there are ways to express the functionality such that the code compiles with the most recent MSVC - unfortunately, this is not the main objective of the project.
- Please refrain from proposing changes that would **break [JSON](https://json.org) conformance**. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension. - Please refrain from proposing changes that would **break [JSON](https://json.org) conformance**. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension.
- We shall not extend the library to **support comments**. There is quite some [controversy](https://www.reddit.com/r/programming/comments/4v6chu/why_json_doesnt_support_comments_douglas_crockford/) around this topic, and there were quite some [issues](https://github.com/nlohmann/json/issues/376) on this. We believe that JSON is fine without comments. - We shall not extend the library to **support comments**. There is quite some [controversy](https://www.reddit.com/r/programming/comments/4v6chu/why_json_doesnt_support_comments_douglas_crockford/) around this topic, and there were quite some [issues](https://github.com/nlohmann/json/issues/376) on this. We believe that JSON is fine without comments.
- We do not preserve the **insertion order of object elements**. The [JSON standard](https://tools.ietf.org/html/rfc7159.html) defines objects as "an unordered collection of zero or more name/value pairs". To this end, this library does not preserve insertion order of name/value pairs. (In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default.) Note this behavior conforms to the standard, and we shall not change it to any other order. If you do want to preserve the insertion order, you can specialize the object type with containers like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map). - We do not preserve the **insertion order of object elements**. The [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". To this end, this library does not preserve insertion order of name/value pairs. (In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default.) Note this behavior conforms to the standard, and we shall not change it to any other order. If you do want to preserve the insertion order, you can specialize the object type with containers like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map).
- Please do not open pull requests that address **multiple issues**. - Please do not open pull requests that address **multiple issues**.
......
...@@ -44,7 +44,7 @@ jobs: ...@@ -44,7 +44,7 @@ jobs:
container: nlohmann/json-ci:latest container: nlohmann/json-ci:latest
strategy: strategy:
matrix: matrix:
target: [ci_clang_tidy, ci_cppcheck, ci_test_valgrind, ci_test_clang_sanitizer, ci_test_amalgamation, ci_clang_analyze, ci_cpplint, ci_cmake_flags, ci_single_binaries, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata] target: [ci_clang_tidy, ci_cppcheck, ci_test_valgrind, ci_test_clang_sanitizer, ci_test_amalgamation, ci_clang_analyze, ci_cpplint, ci_cmake_flags, ci_single_binaries, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_infer]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: cmake - name: cmake
...@@ -90,7 +90,7 @@ jobs: ...@@ -90,7 +90,7 @@ jobs:
container: nlohmann/json-ci:latest container: nlohmann/json-ci:latest
strategy: strategy:
matrix: matrix:
compiler: [g++-4.8, g++-4.9, g++-5, g++-7, g++-8, g++-9, g++-10, clang++-3.5, clang++-3.6, clang++-3.7, clang++-3.8, clang++-3.9, clang++-4.0, clang++-5.0, clang++-6.0, clang++-7, clang++-8, clang++-9, clang++-10] compiler: [g++-4.8, g++-4.9, g++-5, g++-7, g++-8, g++-9, g++-10, clang++-3.5, clang++-3.6, clang++-3.7, clang++-3.8, clang++-3.9, clang++-4.0, clang++-5.0, clang++-6.0, clang++-7, clang++-8, clang++-9, clang++-10, clang++-11]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: cmake - name: cmake
......
...@@ -142,7 +142,7 @@ target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json) ...@@ -142,7 +142,7 @@ target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
Since CMake v3.11, Since CMake v3.11,
[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can [FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
be used to automatically download the repository as a dependency at configure type. be used to automatically download the repository as a dependency at configure time.
Example: Example:
```cmake ```cmake
...@@ -1201,8 +1201,8 @@ auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE ...@@ -1201,8 +1201,8 @@ auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE
Though it's 2021 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work: Though it's 2021 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
- GCC 4.8 - 11.0 (and possibly later) - GCC 4.8 - 11.0 (and possibly later)
- Clang 3.4 - 11.0 (and possibly later) - Clang 3.4 - 12.0 (and possibly later)
- Apple Clang 9.1 - 12.3 (and possibly later) - Apple Clang 9.1 - 12.4 (and possibly later)
- Intel C++ Compiler 17.0.2 (and possibly later) - Intel C++ Compiler 17.0.2 (and possibly later)
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later) - Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later) - Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
...@@ -1271,7 +1271,8 @@ The following compilers are currently used in continuous integration at [Travis] ...@@ -1271,7 +1271,8 @@ The following compilers are currently used in continuous integration at [Travis]
| Clang 10.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions | | Clang 10.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions |
| Clang 11.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions | | Clang 11.0.0 with GNU-like command-line | Windows-10.0.17763 | GitHub Actions |
| Clang 11.0.0 with MSVC-like command-line | Windows-10.0.17763 | GitHub Actions | | Clang 11.0.0 with MSVC-like command-line | Windows-10.0.17763 | GitHub Actions |
| Clang 11.1.0 (11.1.0-++20210204121720+1fdec59bffc1-1~exp1~20210203232336.162 | Ubuntu 20.04.2 LTS | GitHub Actions | | Clang 11.0.0 (11.0.0-2~ubuntu20.04.1) | Ubuntu 20.04.2 LTS | GitHub Actions |
| Clang 12.1.0 (12.0.1-++20210423082613+072c90a863aa-1~exp1~20210423063319.76 | Ubuntu 20.04.2 LTS | GitHub Actions |
| Visual Studio 14 2015 MSVC 19.0.24241.7 (Build Engine version 14.0.25420.1) | Windows-6.3.9600 | AppVeyor | | Visual Studio 14 2015 MSVC 19.0.24241.7 (Build Engine version 14.0.25420.1) | Windows-6.3.9600 | AppVeyor |
| Visual Studio 15 2017 MSVC 19.16.27035.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | AppVeyor | | Visual Studio 15 2017 MSVC 19.16.27035.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | AppVeyor |
| Visual Studio 15 2017 MSVC 19.16.27045.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | GitHub Actions | | Visual Studio 15 2017 MSVC 19.16.27045.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | GitHub Actions |
......
...@@ -13,12 +13,12 @@ execute_process(COMMAND ${ASTYLE_TOOL} --version OUTPUT_VARIABLE ASTYLE_TOOL_VER ...@@ -13,12 +13,12 @@ execute_process(COMMAND ${ASTYLE_TOOL} --version OUTPUT_VARIABLE ASTYLE_TOOL_VER
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" ASTYLE_TOOL_VERSION "${ASTYLE_TOOL_VERSION}") string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" ASTYLE_TOOL_VERSION "${ASTYLE_TOOL_VERSION}")
message(STATUS "🔖 Artistic Style ${ASTYLE_TOOL_VERSION} (${ASTYLE_TOOL})") message(STATUS "🔖 Artistic Style ${ASTYLE_TOOL_VERSION} (${ASTYLE_TOOL})")
find_program(CLANG_TOOL NAMES clang++-HEAD clang++-11 clang++) find_program(CLANG_TOOL NAMES clang++-HEAD clang++-12 clang++-11 clang++)
execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION) execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION)
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}") string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}")
message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})") message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})")
find_program(CLANG_TIDY_TOOL NAMES clang-tidy-11 clang-tidy) find_program(CLANG_TIDY_TOOL NAMES clang-tidy-12 clang-tidy-11 clang-tidy)
execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION) execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION)
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}") string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}")
message(STATUS "🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})") message(STATUS "🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})")
...@@ -487,7 +487,7 @@ add_custom_target(ci_test_coverage ...@@ -487,7 +487,7 @@ add_custom_target(ci_test_coverage
# Sanitizers. # Sanitizers.
############################################################################### ###############################################################################
set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fsanitize-recover=unsigned-integer-overflow") set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base")
add_custom_target(ci_test_clang_sanitizer add_custom_target(ci_test_clang_sanitizer
COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND} COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND}
...@@ -638,7 +638,7 @@ add_custom_target(ci_pvs_studio ...@@ -638,7 +638,7 @@ add_custom_target(ci_pvs_studio
add_custom_target(ci_infer add_custom_target(ci_infer
COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_infer COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_infer
COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} compile -- ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${PROJECT_SOURCE_DIR} -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} compile -- ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${PROJECT_SOURCE_DIR} -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON
COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} run -- make --parallel ${N} COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} run -- make
COMMENT "Check code with Infer" COMMENT "Check code with Infer"
) )
......
...@@ -12,7 +12,7 @@ prepare_files: clean ...@@ -12,7 +12,7 @@ prepare_files: clean
# create subfolders # create subfolders
mkdir docs/images docs/examples mkdir docs/images docs/examples
# copy images # copy images
cp -vr ../json.gif ../images/range-begin-end.svg ../images/range-rbegin-rend.svg ../images/callback_events.png docs/images cp -vr ../json.gif ../images/range-begin-end.svg ../images/range-rbegin-rend.svg ../images/callback_events.png ../images/json_syntax_number.png docs/images
# copy examples # copy examples
cp -vr ../examples/*.cpp ../examples/*.output docs/examples cp -vr ../examples/*.cpp ../examples/*.output docs/examples
......
...@@ -6,7 +6,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>; ...@@ -6,7 +6,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
The type used to store JSON arrays. The type used to store JSON arrays.
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:
> An array is an ordered sequence of zero or more values. > An array is an ordered sequence of zero or more values.
To store objects in C++, a type is defined by the template parameters explained below. To store objects in C++, a type is defined by the template parameters explained below.
...@@ -35,7 +35,7 @@ std::vector< ...@@ -35,7 +35,7 @@ std::vector<
#### Limits #### Limits
[RFC 7159](http://rfc7159.net/rfc7159) specifies: [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the maximum depth of nesting. > An implementation may set limits on the maximum depth of nesting.
In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be
......
...@@ -6,7 +6,7 @@ using boolean_t = BooleanType; ...@@ -6,7 +6,7 @@ using boolean_t = BooleanType;
The type used to store JSON booleans. The type used to store JSON booleans.
[RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a type which differentiates the two literals [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals
`#!json true` and `#!json false`. `#!json true` and `#!json false`.
To store objects in C++, a type is defined by the template parameter `BooleanType` which chooses the type to use. To store objects in C++, a type is defined by the template parameter `BooleanType` which chooses the type to use.
......
...@@ -6,7 +6,7 @@ using number_float_t = NumberFloatType; ...@@ -6,7 +6,7 @@ using number_float_t = NumberFloatType;
The type used to store JSON numbers (floating-point). The type used to store JSON numbers (floating-point).
[RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
> The representation of numbers is similar to that used in most programming languages. A number is represented in base > The representation of numbers is similar to that used in most programming languages. A number is represented in base
> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may > 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may
> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that > be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that
...@@ -35,7 +35,7 @@ With the default values for `NumberFloatType` (`double`), the default value for ...@@ -35,7 +35,7 @@ With the default values for `NumberFloatType` (`double`), the default value for
#### Limits #### Limits
[RFC 7159](http://rfc7159.net/rfc7159) states: [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software > This specification allows implementations to set limits on the range and precision of numbers accepted. Since software
> that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good > that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good
> interoperability can be achieved by implementations that expect no more precision or range than these provide, in the > interoperability can be achieved by implementations that expect no more precision or range than these provide, in the
......
...@@ -6,7 +6,7 @@ using number_integer_t = NumberIntegerType; ...@@ -6,7 +6,7 @@ using number_integer_t = NumberIntegerType;
The type used to store JSON numbers (integers). The type used to store JSON numbers (integers).
[RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
> The representation of numbers is similar to that used in most programming languages. A number is represented in base > The representation of numbers is similar to that used in most programming languages. A number is represented in base
> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may > 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may
> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that > be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that
...@@ -36,7 +36,7 @@ With the default values for `NumberIntegerType` (`std::int64_t`), the default va ...@@ -36,7 +36,7 @@ With the default values for `NumberIntegerType` (`std::int64_t`), the default va
#### Limits #### Limits
[RFC 7159](http://rfc7159.net/rfc7159) specifies: [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the range and precision of numbers. > An implementation may set limits on the range and precision of numbers.
When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and
...@@ -44,7 +44,7 @@ the minimal integer number that can be stored is `-9223372036854775808` (INT64_M ...@@ -44,7 +44,7 @@ the minimal integer number that can be stored is `-9223372036854775808` (INT64_M
range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers
will be automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [`number_float_t`](number_float_t.md). will be automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [`number_float_t`](number_float_t.md).
[RFC 7159](http://rfc7159.net/rfc7159) further states: [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
> Note that when such software is used, numbers that are integers and are in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are > Note that when such software is used, numbers that are integers and are in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are
> interoperable in the sense that implementations will agree exactly on their numeric values. > interoperable in the sense that implementations will agree exactly on their numeric values.
......
...@@ -6,7 +6,7 @@ using number_unsigned_t = NumberUnsignedType; ...@@ -6,7 +6,7 @@ using number_unsigned_t = NumberUnsignedType;
The type used to store JSON numbers (unsigned). The type used to store JSON numbers (unsigned).
[RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
> The representation of numbers is similar to that used in most programming languages. A number is represented in base > The representation of numbers is similar to that used in most programming languages. A number is represented in base
> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may > 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may
> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that > be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that
...@@ -36,7 +36,7 @@ With the default values for `NumberUnsignedType` (`std::uint64_t`), the default ...@@ -36,7 +36,7 @@ With the default values for `NumberUnsignedType` (`std::uint64_t`), the default
#### Limits #### Limits
[RFC 7159](http://rfc7159.net/rfc7159) specifies: [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the range and precision of numbers. > An implementation may set limits on the range and precision of numbers.
When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and
...@@ -44,7 +44,7 @@ the minimal integer number that can be stored is `0`. Integer numbers that are o ...@@ -44,7 +44,7 @@ the minimal integer number that can be stored is `0`. Integer numbers that are o
when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored
as [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_t.md). as [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_t.md).
[RFC 7159](http://rfc7159.net/rfc7159) further states: [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
> Note that when such software is used, numbers that are integers and are in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are > Note that when such software is used, numbers that are integers and are in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are
> interoperable in the sense that implementations will agree exactly on their numeric values. > interoperable in the sense that implementations will agree exactly on their numeric values.
......
...@@ -9,7 +9,7 @@ using object_t = ObjectType<StringType, ...@@ -9,7 +9,7 @@ using object_t = ObjectType<StringType,
The type used to store JSON objects. The type used to store JSON objects.
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:
> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a > An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a
> string, number, boolean, null, object, or array. > string, number, boolean, null, object, or array.
...@@ -73,7 +73,7 @@ behavior: ...@@ -73,7 +73,7 @@ behavior:
#### Limits #### Limits
[RFC 7159](http://rfc7159.net/rfc7159) specifies: [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the maximum depth of nesting. > An implementation may set limits on the maximum depth of nesting.
In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be
...@@ -90,7 +90,7 @@ Objects are stored as pointers in a `basic_json` type. That is, for any access t ...@@ -90,7 +90,7 @@ Objects are stored as pointers in a `basic_json` type. That is, for any access t
The order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may The order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may
return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in
alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to
[RFC 7159](http://rfc7159.net/rfc7159), because any order implements the specified "unordered" nature of JSON objects. [RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON objects.
## Version history ## Version history
......
...@@ -6,7 +6,7 @@ using string_t = StringType; ...@@ -6,7 +6,7 @@ using string_t = StringType;
The type used to store JSON strings. The type used to store JSON strings.
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:
> A string is a sequence of zero or more Unicode characters. > A string is a sequence of zero or more Unicode characters.
To store objects in C++, a type is defined by the template parameter described below. Unicode values are split by the To store objects in C++, a type is defined by the template parameter described below. Unicode values are split by the
...@@ -31,7 +31,7 @@ the number of bytes in the string rather than the number of characters or glyphs ...@@ -31,7 +31,7 @@ the number of bytes in the string rather than the number of characters or glyphs
#### String comparison #### String comparison
[RFC 7159](http://rfc7159.net/rfc7159) states: [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
> Software implementations are typically required to test names of object members for equality. Implementations that > Software implementations are typically required to test names of object members for equality. Implementations that
> transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, > transform the textual representation into sequences of Unicode code units and then perform the comparison numerically,
> code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or > code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or
......
...@@ -10,7 +10,7 @@ As for other containers, `begin()` returns an iterator to the first value and `e ...@@ -10,7 +10,7 @@ As for other containers, `begin()` returns an iterator to the first value and `e
### Iteration order for objects ### Iteration order for objects
When iterating over objects, values are ordered with respect to the `object_comparator_t` type which defaults to `std::less`. See the [types documentation](types.md#key-order) for more information. When iterating over objects, values are ordered with respect to the `object_comparator_t` type which defaults to `std::less`. See the [types documentation](types/index.md#key-order) for more information.
??? example ??? example
......
...@@ -20,6 +20,10 @@ When enabled, exception messages contain a [JSON Pointer](json_pointer.md) to th ...@@ -20,6 +20,10 @@ When enabled, exception messages contain a [JSON Pointer](json_pointer.md) to th
The diagnostics messages can also be controlled with the CMake option `JSON_Diagnostics` (`OFF` by default) which sets `JSON_DIAGNOSTICS` accordingly. The diagnostics messages can also be controlled with the CMake option `JSON_Diagnostics` (`OFF` by default) which sets `JSON_DIAGNOSTICS` accordingly.
## `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`
The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view` support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly.
## `JSON_NOEXCEPTION` ## `JSON_NOEXCEPTION`
Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`.
......
# Types # Overview
This page gives an overview how JSON values are stored and how this can be configured. This page gives an overview how JSON values are stored and how this can be configured.
...@@ -107,7 +107,7 @@ using binary_t = nlohmann::byte_container_with_subtype<BinaryType>; ...@@ -107,7 +107,7 @@ using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
## Objects ## Objects
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:
> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array. > An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.
...@@ -135,11 +135,11 @@ The choice of `object_t` influences the behavior of the JSON class. With the def ...@@ -135,11 +135,11 @@ The choice of `object_t` influences the behavior of the JSON class. With the def
### Key order ### Key order
The order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to [RFC 7159](http://rfc7159.net/rfc7159), because any order implements the specified "unordered" nature of JSON objects. The order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to [RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON objects.
### Limits ### Limits
[RFC 7159](http://rfc7159.net/rfc7159) specifies: [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the maximum depth of nesting. > An implementation may set limits on the maximum depth of nesting.
...@@ -152,7 +152,7 @@ Objects are stored as pointers in a `basic_json` type. That is, for any access t ...@@ -152,7 +152,7 @@ Objects are stored as pointers in a `basic_json` type. That is, for any access t
## Arrays ## Arrays
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:
> An array is an ordered sequence of zero or more values. > An array is an ordered sequence of zero or more values.
...@@ -169,7 +169,7 @@ std::vector< ...@@ -169,7 +169,7 @@ std::vector<
### Limits ### Limits
[RFC 7159](http://rfc7159.net/rfc7159) specifies: [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the maximum depth of nesting. > An implementation may set limits on the maximum depth of nesting.
...@@ -182,7 +182,7 @@ Arrays are stored as pointers in a `basic_json` type. That is, for any access to ...@@ -182,7 +182,7 @@ Arrays are stored as pointers in a `basic_json` type. That is, for any access to
## Strings ## Strings
[RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows: [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:
> A string is a sequence of zero or more Unicode characters. > A string is a sequence of zero or more Unicode characters.
...@@ -198,7 +198,7 @@ Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::si ...@@ -198,7 +198,7 @@ Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::si
### String comparison ### String comparison
[RFC 7159](http://rfc7159.net/rfc7159) states: [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
> Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal. > Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal.
...@@ -211,7 +211,7 @@ String values are stored as pointers in a `basic_json` type. That is, for any ac ...@@ -211,7 +211,7 @@ String values are stored as pointers in a `basic_json` type. That is, for any ac
## Booleans ## Booleans
[RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a type which differentiates the two literals `true` and `false`. [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals `true` and `false`.
### Default type ### Default type
...@@ -223,7 +223,9 @@ Boolean values are stored directly inside a `basic_json` type. ...@@ -223,7 +223,9 @@ Boolean values are stored directly inside a `basic_json` type.
## Numbers ## Numbers
[RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: See the [number handling](number_handling.md) article for a detailed discussion on how numbers are handled by this library.
[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. > The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.
...@@ -242,7 +244,7 @@ With the default values for *NumberFloatType* (`#!cpp double`), the default valu ...@@ -242,7 +244,7 @@ With the default values for *NumberFloatType* (`#!cpp double`), the default valu
### Limits ### Limits
[RFC 7159](http://rfc7159.net/rfc7159) specifies: [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the range and precision of numbers. > An implementation may set limits on the range and precision of numbers.
...@@ -250,13 +252,13 @@ When the default type is used, the maximal integer number that can be stored is ...@@ -250,13 +252,13 @@ When the default type is used, the maximal integer number that can be stored is
When the default type is used, the maximal unsigned integer number that can be stored is `#!c 18446744073709551615` (`UINT64_MAX`) and the minimal integer number that can be stored is `#!c 0`. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored as `number_integer_t` or `number_float_t`. When the default type is used, the maximal unsigned integer number that can be stored is `#!c 18446744073709551615` (`UINT64_MAX`) and the minimal integer number that can be stored is `#!c 0`. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored as `number_integer_t` or `number_float_t`.
[RFC 7159](http://rfc7159.net/rfc7159) further states: [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the sense that implementations will agree exactly on their numeric values. > Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the sense that implementations will agree exactly on their numeric values.
As this range is a subrange of the exactly supported range [`INT64_MIN`, `INT64_MAX`], this class's integer type is interoperable. As this range is a subrange of the exactly supported range [`INT64_MIN`, `INT64_MAX`], this class's integer type is interoperable.
[RFC 7159](http://rfc7159.net/rfc7159) states: [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. > This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.
......
...@@ -1167,7 +1167,7 @@ As `noexcept` and `constexpr` specifier have been added to several functions, th ...@@ -1167,7 +1167,7 @@ As `noexcept` and `constexpr` specifier have been added to several functions, th
- Parser error messages are still very vague and contain no information on the error location. - Parser error messages are still very vague and contain no information on the error location.
- The implemented `diff` function is rather primitive and does not create minimal diffs. - The implemented `diff` function is rather primitive and does not create minimal diffs.
- The name of function `iteration_wrapper` may change in the future and the function will be deprecated in the next release. - The name of function `iteration_wrapper` may change in the future and the function will be deprecated in the next release.
- Roundtripping (i.e., parsing a JSON value from a string, serializing it, and comparing the strings) of floating-point numbers is not 100% accurate. Note that [RFC 7159](https://tools.ietf.org/html/rfc7159) defines no format to internally represent numbers and states not requirement for roundtripping. Nevertheless, benchmarks like [Native JSON Benchmark](https://github.com/miloyip/nativejson-benchmark) treat roundtripping deviations as conformance errors. - Roundtripping (i.e., parsing a JSON value from a string, serializing it, and comparing the strings) of floating-point numbers is not 100% accurate. Note that [RFC 8259](https://tools.ietf.org/html/rfc8259) defines no format to internally represent numbers and states not requirement for roundtripping. Nevertheless, benchmarks like [Native JSON Benchmark](https://github.com/miloyip/nativejson-benchmark) treat roundtripping deviations as conformance errors.
## v1.1.0 ## v1.1.0
......
...@@ -9,7 +9,7 @@ repo_url: https://github.com/nlohmann/json ...@@ -9,7 +9,7 @@ repo_url: https://github.com/nlohmann/json
edit_uri: edit/develop/doc/mkdocs/docs edit_uri: edit/develop/doc/mkdocs/docs
# Copyright # Copyright
copyright: Copyright &copy; 2013 - 2020 Niels Lohmann copyright: Copyright &copy; 2013 - 2021 Niels Lohmann
# Configuration # Configuration
theme: theme:
...@@ -62,7 +62,9 @@ nav: ...@@ -62,7 +62,9 @@ nav:
- features/parsing/sax_interface.md - features/parsing/sax_interface.md
- features/enum_conversion.md - features/enum_conversion.md
- features/macros.md - features/macros.md
- features/types.md - Types:
- features/types/index.md
- features/types/number_handling.md
- Integration: - Integration:
- integration/index.md - integration/index.md
- integration/cmake.md - integration/cmake.md
......
#pragma once #pragma once
#include <type_traits>
#include <utility> #include <utility>
#include <nlohmann/detail/conversions/from_json.hpp> #include <nlohmann/detail/conversions/from_json.hpp>
#include <nlohmann/detail/conversions/to_json.hpp> #include <nlohmann/detail/conversions/to_json.hpp>
#include <nlohmann/detail/meta/identity_tag.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
namespace nlohmann namespace nlohmann
{ {
template<typename, typename> template<typename ValueType, typename>
struct adl_serializer struct adl_serializer
{ {
/*! /*!
...@@ -17,11 +20,13 @@ struct adl_serializer ...@@ -17,11 +20,13 @@ struct adl_serializer
This function is usually called by the `get()` function of the This function is usually called by the `get()` function of the
@ref basic_json class (either explicit or via conversion operators). @ref basic_json class (either explicit or via conversion operators).
@note This function is chosen for default-constructible value types.
@param[in] j JSON value to read from @param[in] j JSON value to read from
@param[in,out] val value to write to @param[in,out] val value to write to
*/ */
template<typename BasicJsonType, typename ValueType> template<typename BasicJsonType, typename TargetType = ValueType>
static auto from_json(BasicJsonType&& j, ValueType& val) noexcept( static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void()) -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
{ {
...@@ -29,6 +34,26 @@ struct adl_serializer ...@@ -29,6 +34,26 @@ struct adl_serializer
} }
/*! /*!
@brief convert a JSON value to any value type
This function is usually called by the `get()` function of the
@ref basic_json class (either explicit or via conversion operators).
@note This function is chosen for value types which are not default-constructible.
@param[in] j JSON value to read from
@return copy of the JSON value, converted to @a ValueType
*/
template<typename BasicJsonType, typename TargetType = ValueType>
static auto from_json(BasicJsonType && j) noexcept(
noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
{
return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
}
/*!
@brief convert any value type to a JSON value @brief convert any value type to a JSON value
This function is usually called by the constructors of the @ref basic_json This function is usually called by the constructors of the @ref basic_json
...@@ -37,13 +62,12 @@ struct adl_serializer ...@@ -37,13 +62,12 @@ struct adl_serializer
@param[in,out] j JSON value to write to @param[in,out] j JSON value to write to
@param[in] val value to read from @param[in] val value to read from
*/ */
template<typename BasicJsonType, typename ValueType> template<typename BasicJsonType, typename TargetType = ValueType>
static auto to_json(BasicJsonType& j, ValueType&& val) noexcept( static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val)))) noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
-> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void()) -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
{ {
::nlohmann::to_json(j, std::forward<ValueType>(val)); ::nlohmann::to_json(j, std::forward<TargetType>(val));
} }
}; };
} // namespace nlohmann } // namespace nlohmann
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <nlohmann/detail/exceptions.hpp> #include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/identity_tag.hpp>
#include <nlohmann/detail/meta/type_traits.hpp> #include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
...@@ -187,7 +188,10 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, ...@@ -187,7 +188,10 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
} }
} }
template<typename BasicJsonType, typename ConstructibleArrayType> template<typename BasicJsonType, typename ConstructibleArrayType,
enable_if_t<
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
int> = 0>
auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
-> decltype( -> decltype(
arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()), arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
...@@ -208,7 +212,10 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p ...@@ -208,7 +212,10 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
arr = std::move(ret); arr = std::move(ret);
} }
template<typename BasicJsonType, typename ConstructibleArrayType> template<typename BasicJsonType, typename ConstructibleArrayType,
enable_if_t<
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
int> = 0>
void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
priority_tag<0> /*unused*/) priority_tag<0> /*unused*/)
{ {
...@@ -247,6 +254,25 @@ void()) ...@@ -247,6 +254,25 @@ void())
from_json_array_impl(j, arr, priority_tag<3> {}); from_json_array_impl(j, arr, priority_tag<3> {});
} }
template < typename BasicJsonType, typename T, std::size_t... Idx >
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
{
return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
}
template < typename BasicJsonType, typename T, std::size_t N >
auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
}
return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
}
template<typename BasicJsonType> template<typename BasicJsonType>
void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
{ {
...@@ -322,22 +348,47 @@ void from_json(const BasicJsonType& j, ArithmeticType& val) ...@@ -322,22 +348,47 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
} }
} }
template<typename BasicJsonType, typename... Args, std::size_t... Idx>
std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
{
return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
}
template < typename BasicJsonType, class A1, class A2 >
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
{
return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
std::forward<BasicJsonType>(j).at(1).template get<A2>()};
}
template<typename BasicJsonType, typename A1, typename A2> template<typename BasicJsonType, typename A1, typename A2>
void from_json(const BasicJsonType& j, std::pair<A1, A2>& p) void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
{ {
p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()}; p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
} }
template<typename BasicJsonType, typename Tuple, std::size_t... Idx> template<typename BasicJsonType, typename... Args>
void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/) std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
{ {
t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...); return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
} }
template<typename BasicJsonType, typename... Args> template<typename BasicJsonType, typename... Args>
void from_json(const BasicJsonType& j, std::tuple<Args...>& t) void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
{ {
from_json_tuple_impl(j, t, index_sequence_for<Args...> {}); t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
}
template<typename BasicJsonType, typename TupleRelated>
auto from_json(BasicJsonType&& j, TupleRelated&& t)
-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
}
return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
} }
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
...@@ -383,11 +434,11 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE ...@@ -383,11 +434,11 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
struct from_json_fn struct from_json_fn
{ {
template<typename BasicJsonType, typename T> template<typename BasicJsonType, typename T>
auto operator()(const BasicJsonType& j, T& val) const auto operator()(const BasicJsonType& j, T&& val) const
noexcept(noexcept(from_json(j, val))) noexcept(noexcept(from_json(j, std::forward<T>(val))))
-> decltype(from_json(j, val), void()) -> decltype(from_json(j, std::forward<T>(val)))
{ {
return from_json(j, val); return from_json(j, std::forward<T>(val));
} }
}; };
} // namespace detail } // namespace detail
......
...@@ -231,7 +231,7 @@ class lexer : public lexer_base<BasicJsonType> ...@@ -231,7 +231,7 @@ class lexer : public lexer_base<BasicJsonType>
/*! /*!
@brief scan a string literal @brief scan a string literal
This function scans a string according to Sect. 7 of RFC 7159. While This function scans a string according to Sect. 7 of RFC 8259. While
scanning, bytes are escaped and copied into buffer token_buffer. Then the scanning, bytes are escaped and copied into buffer token_buffer. Then the
function returns successfully, token_buffer is *not* null-terminated (as it function returns successfully, token_buffer is *not* null-terminated (as it
may contain \0 bytes), and token_buffer.size() is the number of bytes in the may contain \0 bytes), and token_buffer.size() is the number of bytes in the
...@@ -921,10 +921,10 @@ class lexer : public lexer_base<BasicJsonType> ...@@ -921,10 +921,10 @@ class lexer : public lexer_base<BasicJsonType>
/*! /*!
@brief scan a number literal @brief scan a number literal
This function scans a string according to Sect. 6 of RFC 7159. This function scans a string according to Sect. 6 of RFC 8259.
The function is realized with a deterministic finite state machine derived The function is realized with a deterministic finite state machine derived
from the grammar described in RFC 7159. Starting in state "init", the from the grammar described in RFC 8259. Starting in state "init", the
input is read and used to determined the next state. Only state "done" input is read and used to determined the next state. Only state "done"
accepts the number. State "error" is a trap state to model errors. In the accepts the number. State "error" is a trap state to model errors. In the
table below, "anything" means any character but the ones listed before. table below, "anything" means any character but the ones listed before.
......
...@@ -20,15 +20,20 @@ ...@@ -20,15 +20,20 @@
#endif #endif
// C++ language standard detection // C++ language standard detection
#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) // if the user manually specified the used c++ version this is skipped
#define JSON_HAS_CPP_20 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
#define JSON_HAS_CPP_17 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
#define JSON_HAS_CPP_14 #define JSON_HAS_CPP_20
#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 #define JSON_HAS_CPP_17
#define JSON_HAS_CPP_17 #define JSON_HAS_CPP_14
#define JSON_HAS_CPP_14 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) #define JSON_HAS_CPP_17
#define JSON_HAS_CPP_14 #define JSON_HAS_CPP_14
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
#define JSON_HAS_CPP_14
#endif
// the cpp 11 flag is always specified because it is the minimal required version
#define JSON_HAS_CPP_11
#endif #endif
// disable documentation warnings on clang // disable documentation warnings on clang
......
...@@ -12,8 +12,10 @@ ...@@ -12,8 +12,10 @@
#undef JSON_THROW #undef JSON_THROW
#undef JSON_TRY #undef JSON_TRY
#undef JSON_PRIVATE_UNLESS_TESTED #undef JSON_PRIVATE_UNLESS_TESTED
#undef JSON_HAS_CPP_11
#undef JSON_HAS_CPP_14 #undef JSON_HAS_CPP_14
#undef JSON_HAS_CPP_17 #undef JSON_HAS_CPP_17
#undef JSON_HAS_CPP_20
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
#undef NLOHMANN_BASIC_JSON_TPL #undef NLOHMANN_BASIC_JSON_TPL
#undef JSON_EXPLICIT #undef JSON_EXPLICIT
......
#pragma once
namespace nlohmann
{
namespace detail
{
// dispatching helper struct
template <class T> struct identity_tag {};
} // namespace detail
} // namespace nlohmann
...@@ -106,8 +106,7 @@ struct is_getable ...@@ -106,8 +106,7 @@ struct is_getable
}; };
template<typename BasicJsonType, typename T> template<typename BasicJsonType, typename T>
struct has_from_json < BasicJsonType, T, struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
enable_if_t < !is_basic_json<T>::value >>
{ {
using serializer = typename BasicJsonType::template json_serializer<T, void>; using serializer = typename BasicJsonType::template json_serializer<T, void>;
...@@ -151,6 +150,52 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> ...@@ -151,6 +150,52 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
// is_ functions // // is_ functions //
/////////////////// ///////////////////
// https://en.cppreference.com/w/cpp/types/conjunction
template<class...> struct conjunction : std::true_type { };
template<class B1> struct conjunction<B1> : B1 { };
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
template <typename T>
struct is_default_constructible : std::is_default_constructible<T> {};
template <typename T1, typename T2>
struct is_default_constructible<std::pair<T1, T2>>
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
template <typename T1, typename T2>
struct is_default_constructible<const std::pair<T1, T2>>
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
template <typename... Ts>
struct is_default_constructible<std::tuple<Ts...>>
: conjunction<is_default_constructible<Ts>...> {};
template <typename... Ts>
struct is_default_constructible<const std::tuple<Ts...>>
: conjunction<is_default_constructible<Ts>...> {};
template <typename T, typename... Args>
struct is_constructible : std::is_constructible<T, Args...> {};
template <typename T1, typename T2>
struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
template <typename T1, typename T2>
struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
template <typename... Ts>
struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
template <typename... Ts>
struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
template<typename T, typename = void> template<typename T, typename = void>
struct is_iterator_traits : std::false_type {}; struct is_iterator_traits : std::false_type {};
...@@ -193,9 +238,9 @@ struct is_compatible_object_type_impl < ...@@ -193,9 +238,9 @@ struct is_compatible_object_type_impl <
// macOS's is_constructible does not play well with nonesuch... // macOS's is_constructible does not play well with nonesuch...
static constexpr bool value = static constexpr bool value =
std::is_constructible<typename object_t::key_type, is_constructible<typename object_t::key_type,
typename CompatibleObjectType::key_type>::value && typename CompatibleObjectType::key_type>::value &&
std::is_constructible<typename object_t::mapped_type, is_constructible<typename object_t::mapped_type,
typename CompatibleObjectType::mapped_type>::value; typename CompatibleObjectType::mapped_type>::value;
}; };
...@@ -216,10 +261,10 @@ struct is_constructible_object_type_impl < ...@@ -216,10 +261,10 @@ struct is_constructible_object_type_impl <
using object_t = typename BasicJsonType::object_t; using object_t = typename BasicJsonType::object_t;
static constexpr bool value = static constexpr bool value =
(std::is_default_constructible<ConstructibleObjectType>::value && (is_default_constructible<ConstructibleObjectType>::value &&
(std::is_move_assignable<ConstructibleObjectType>::value || (std::is_move_assignable<ConstructibleObjectType>::value ||
std::is_copy_assignable<ConstructibleObjectType>::value) && std::is_copy_assignable<ConstructibleObjectType>::value) &&
(std::is_constructible<typename ConstructibleObjectType::key_type, (is_constructible<typename ConstructibleObjectType::key_type,
typename object_t::key_type>::value && typename object_t::key_type>::value &&
std::is_same < std::is_same <
typename object_t::mapped_type, typename object_t::mapped_type,
...@@ -247,7 +292,7 @@ struct is_compatible_string_type_impl < ...@@ -247,7 +292,7 @@ struct is_compatible_string_type_impl <
value_type_t, CompatibleStringType>::value >> value_type_t, CompatibleStringType>::value >>
{ {
static constexpr auto value = static constexpr auto value =
std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value; is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
}; };
template<typename BasicJsonType, typename ConstructibleStringType> template<typename BasicJsonType, typename ConstructibleStringType>
...@@ -265,7 +310,7 @@ struct is_constructible_string_type_impl < ...@@ -265,7 +310,7 @@ struct is_constructible_string_type_impl <
value_type_t, ConstructibleStringType>::value >> value_type_t, ConstructibleStringType>::value >>
{ {
static constexpr auto value = static constexpr auto value =
std::is_constructible<ConstructibleStringType, is_constructible<ConstructibleStringType,
typename BasicJsonType::string_t>::value; typename BasicJsonType::string_t>::value;
}; };
...@@ -288,7 +333,7 @@ struct is_compatible_array_type_impl < ...@@ -288,7 +333,7 @@ struct is_compatible_array_type_impl <
iterator_traits<CompatibleArrayType >>::value >> iterator_traits<CompatibleArrayType >>::value >>
{ {
static constexpr bool value = static constexpr bool value =
std::is_constructible<BasicJsonType, is_constructible<BasicJsonType,
typename CompatibleArrayType::value_type>::value; typename CompatibleArrayType::value_type>::value;
}; };
...@@ -311,7 +356,7 @@ struct is_constructible_array_type_impl < ...@@ -311,7 +356,7 @@ struct is_constructible_array_type_impl <
BasicJsonType, ConstructibleArrayType, BasicJsonType, ConstructibleArrayType,
enable_if_t < !std::is_same<ConstructibleArrayType, enable_if_t < !std::is_same<ConstructibleArrayType,
typename BasicJsonType::value_type>::value&& typename BasicJsonType::value_type>::value&&
std::is_default_constructible<ConstructibleArrayType>::value&& is_default_constructible<ConstructibleArrayType>::value&&
(std::is_move_assignable<ConstructibleArrayType>::value || (std::is_move_assignable<ConstructibleArrayType>::value ||
std::is_copy_assignable<ConstructibleArrayType>::value)&& std::is_copy_assignable<ConstructibleArrayType>::value)&&
is_detected<value_type_t, ConstructibleArrayType>::value&& is_detected<value_type_t, ConstructibleArrayType>::value&&
...@@ -355,7 +400,7 @@ struct is_compatible_integer_type_impl < ...@@ -355,7 +400,7 @@ struct is_compatible_integer_type_impl <
using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>; using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
static constexpr auto value = static constexpr auto value =
std::is_constructible<RealIntegerType, is_constructible<RealIntegerType,
CompatibleNumberIntegerType>::value && CompatibleNumberIntegerType>::value &&
CompatibleLimits::is_integer && CompatibleLimits::is_integer &&
RealLimits::is_signed == CompatibleLimits::is_signed; RealLimits::is_signed == CompatibleLimits::is_signed;
...@@ -382,18 +427,11 @@ template<typename BasicJsonType, typename CompatibleType> ...@@ -382,18 +427,11 @@ template<typename BasicJsonType, typename CompatibleType>
struct is_compatible_type struct is_compatible_type
: is_compatible_type_impl<BasicJsonType, CompatibleType> {}; : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
// https://en.cppreference.com/w/cpp/types/conjunction
template<class...> struct conjunction : std::true_type { };
template<class B1> struct conjunction<B1> : B1 { };
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template<typename T1, typename T2> template<typename T1, typename T2>
struct is_constructible_tuple : std::false_type {}; struct is_constructible_tuple : std::false_type {};
template<typename T1, typename... Args> template<typename T1, typename... Args>
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {}; struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
/// type to check if KeyType can be used as object key /// type to check if KeyType can be used as object key
template<typename BasicJsonType, typename KeyType> template<typename BasicJsonType, typename KeyType>
...@@ -407,6 +445,5 @@ struct is_key_type ...@@ -407,6 +445,5 @@ struct is_key_type
&& !std::is_same<KeyType, typename BasicJsonType::iterator>::value && !std::is_same<KeyType, typename BasicJsonType::iterator>::value
&& !std::is_same<KeyType, typename BasicJsonType::const_iterator>::value; && !std::is_same<KeyType, typename BasicJsonType::const_iterator>::value;
}; };
} // namespace detail } // namespace detail
} // namespace nlohmann } // namespace nlohmann
...@@ -589,7 +589,7 @@ TEST_CASE("parser class") ...@@ -589,7 +589,7 @@ TEST_CASE("parser class")
SECTION("edge cases") SECTION("edge cases")
{ {
// From RFC7159, Section 6: // From RFC8259, Section 6:
// Note that when such software is used, numbers that are // Note that when such software is used, numbers that are
// integers and are in the range [-(2**53)+1, (2**53)-1] // integers and are in the range [-(2**53)+1, (2**53)-1]
// are interoperable in the sense that implementations will // are interoperable in the sense that implementations will
...@@ -603,7 +603,7 @@ TEST_CASE("parser class") ...@@ -603,7 +603,7 @@ TEST_CASE("parser class")
SECTION("over the edge cases") // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers) SECTION("over the edge cases") // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers)
{ {
// While RFC7159, Section 6 specifies a preference for support // While RFC8259, Section 6 specifies a preference for support
// for ranges in range of IEEE 754-2008 binary64 (double precision) // for ranges in range of IEEE 754-2008 binary64 (double precision)
// this does not accommodate 64 bit integers without loss of accuracy. // this does not accommodate 64 bit integers without loss of accuracy.
// As 64 bit integers are now widely used in software, it is desirable // As 64 bit integers are now widely used in software, it is desirable
...@@ -888,7 +888,7 @@ TEST_CASE("parser class") ...@@ -888,7 +888,7 @@ TEST_CASE("parser class")
SECTION("edge cases") SECTION("edge cases")
{ {
// From RFC7159, Section 6: // From RFC8259, Section 6:
// Note that when such software is used, numbers that are // Note that when such software is used, numbers that are
// integers and are in the range [-(2**53)+1, (2**53)-1] // integers and are in the range [-(2**53)+1, (2**53)-1]
// are interoperable in the sense that implementations will // are interoperable in the sense that implementations will
...@@ -902,7 +902,7 @@ TEST_CASE("parser class") ...@@ -902,7 +902,7 @@ TEST_CASE("parser class")
SECTION("over the edge cases") // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers) SECTION("over the edge cases") // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers)
{ {
// While RFC7159, Section 6 specifies a preference for support // While RFC8259, Section 6 specifies a preference for support
// for ranges in range of IEEE 754-2008 binary64 (double precision) // for ranges in range of IEEE 754-2008 binary64 (double precision)
// this does not accommodate 64 bit integers without loss of accuracy. // this does not accommodate 64 bit integers without loss of accuracy.
// As 64 bit integers are now widely used in software, it is desirable // As 64 bit integers are now widely used in software, it is desirable
......
...@@ -134,6 +134,29 @@ struct NotSerializableData ...@@ -134,6 +134,29 @@ struct NotSerializableData
}; };
/////////////////////////////////////////////////////////////////////
// for #2574
/////////////////////////////////////////////////////////////////////
struct NonDefaultConstructible
{
explicit NonDefaultConstructible (int a) : x(a) { }
int x;
};
namespace nlohmann
{
template <>
struct adl_serializer<NonDefaultConstructible>
{
static NonDefaultConstructible from_json (json const& j)
{
return NonDefaultConstructible(j.get<int>());
}
};
} // namespace nlohmann
TEST_CASE("regression tests 2") TEST_CASE("regression tests 2")
{ {
SECTION("issue #1001 - Fix memory leak during parser callback") SECTION("issue #1001 - Fix memory leak during parser callback")
...@@ -501,4 +524,74 @@ TEST_CASE("regression tests 2") ...@@ -501,4 +524,74 @@ TEST_CASE("regression tests 2")
CHECK(j.dump() == "\"Hello, world!\""); CHECK(j.dump() == "\"Hello, world!\"");
} }
#endif #endif
SECTION("issue #2574 - Deserialization to std::array, std::pair, and std::tuple with non-default constructable types fails")
{
SECTION("std::array")
{
{
json j = { 7, 4 };
auto arr = j.get<std::array<NonDefaultConstructible, 2>>();
CHECK(arr[0].x == 7);
CHECK(arr[1].x == 4);
}
{
json j = 7;
CHECK_THROWS_AS((j.get<std::array<NonDefaultConstructible, 1>>()), json::type_error);
}
}
SECTION("std::pair")
{
{
json j = { 3, 8 };
auto p = j.get<std::pair<NonDefaultConstructible, NonDefaultConstructible>>();
CHECK(p.first.x == 3);
CHECK(p.second.x == 8);
}
{
json j = { 4, 1 };
auto p = j.get<std::pair<int, NonDefaultConstructible>>();
CHECK(p.first == 4);
CHECK(p.second.x == 1);
}
{
json j = { 6, 7 };
auto p = j.get<std::pair<NonDefaultConstructible, int>>();
CHECK(p.first.x == 6);
CHECK(p.second == 7);
}
{
json j = 7;
CHECK_THROWS_AS((j.get<std::pair<NonDefaultConstructible, int>>()), json::type_error);
}
}
SECTION("std::tuple")
{
{
json j = { 9 };
auto t = j.get<std::tuple<NonDefaultConstructible>>();
CHECK(std::get<0>(t).x == 9);
}
{
json j = { 9, 8, 7 };
auto t = j.get<std::tuple<NonDefaultConstructible, int, NonDefaultConstructible>>();
CHECK(std::get<0>(t).x == 9);
CHECK(std::get<1>(t) == 8);
CHECK(std::get<2>(t).x == 7);
}
{
json j = 7;
CHECK_THROWS_AS((j.get<std::tuple<NonDefaultConstructible>>()), json::type_error);
}
}
}
} }
...@@ -418,9 +418,9 @@ TEST_CASE("json.org examples") ...@@ -418,9 +418,9 @@ TEST_CASE("json.org examples")
} }
} }
TEST_CASE("RFC 7159 examples") TEST_CASE("RFC 8259 examples")
{ {
// here, we list all JSON values from the RFC 7159 document // here, we list all JSON values from the RFC 8259 document
SECTION("7. Strings") SECTION("7. Strings")
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment