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

Conflicts:
	include/nlohmann/detail/input/binary_reader.hpp
	single_include/nlohmann/json.hpp
	src/unit-bson.cpp
This commit is contained in:
Julian Becker 2018-10-17 19:06:22 +02:00
commit 2a63869159
110 changed files with 2497 additions and 1418 deletions

View file

@ -54,7 +54,7 @@ To make changes, you need to edit the following files:
## Please don't ## Please don't
- The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.8 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means. - The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means.
- 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](http://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](http://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.

View file

@ -13,7 +13,7 @@ Read the [Contribution Guidelines](https://github.com/nlohmann/json/blob/develop
## Please don't ## Please don't
- The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.8 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means. - The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means.
- 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](http://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](http://json.org) conformance**. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension.
- Please do not open pull requests that address **multiple issues**. - Please do not open pull requests that address **multiple issues**.

View file

@ -161,11 +161,22 @@ matrix:
- os: osx - os: osx
osx_image: xcode9.4 osx_image: xcode9.4
- os: osx
osx_image: xcode10
# Linux / GCC # Linux / GCC
- os: linux - os: linux
compiler: gcc compiler: gcc
env: COMPILER=g++-4.9 env: compiler=g++-4.8
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8', 'ninja-build']
- os: linux
compiler: gcc
env: compiler=g++-4.9
addons: addons:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']

View file

@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.8)
## PROJECT ## PROJECT
## name and version ## name and version
## ##
project(nlohmann_json VERSION 3.2.0 LANGUAGES CXX) project(nlohmann_json VERSION 3.3.0 LANGUAGES CXX)
## ##
## INCLUDE ## INCLUDE
@ -86,10 +86,10 @@ include(CMakePackageConfigHelpers)
write_basic_package_version_file( write_basic_package_version_file(
${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE} COMPATIBILITY SameMajorVersion ${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE} COMPATIBILITY SameMajorVersion
) )
configure_package_config_file( configure_file(
${NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE} ${NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE}
${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE} ${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE}
INSTALL_DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR} @ONLY
) )
install( install(
@ -121,4 +121,3 @@ install(
NAMESPACE ${PROJECT_NAME}:: NAMESPACE ${PROJECT_NAME}::
DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR} DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR}
) )
export(PACKAGE ${PROJECT_NAME})

View file

@ -1,7 +1,75 @@
# Change Log # Change Log
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
## [v3.2.0](https://github.com/nlohmann/json/releases/tag/v3.2.0) (2018-08-18) ## [v3.3.0](https://github.com/nlohmann/json/releases/tag/v3.3.0) (2018-10-05)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.2.0...v3.3.0)
- When key is not found print the key name into error too [\#1273](https://github.com/nlohmann/json/issues/1273)
- Visual Studio 2017 15.8.5 "conditional expression is constant" warning on Line 1851 in json.hpp [\#1268](https://github.com/nlohmann/json/issues/1268)
- how can we get this working on WSL? [\#1264](https://github.com/nlohmann/json/issues/1264)
- Help needed [\#1259](https://github.com/nlohmann/json/issues/1259)
- A way to get to a JSON values "key" [\#1258](https://github.com/nlohmann/json/issues/1258)
- Two blackslashes on json output file [\#1253](https://github.com/nlohmann/json/issues/1253)
- Including nlohmann the badwrong way. [\#1250](https://github.com/nlohmann/json/issues/1250)
- how to build with clang? [\#1247](https://github.com/nlohmann/json/issues/1247)
- Cmake target\_link\_libraries unable to find nlohmann\_json since version 3.2.0 [\#1243](https://github.com/nlohmann/json/issues/1243)
- \[Question\] Access to end\(\) iterator reference [\#1242](https://github.com/nlohmann/json/issues/1242)
- Parsing different json format [\#1241](https://github.com/nlohmann/json/issues/1241)
- Parsing Multiple JSON Files [\#1240](https://github.com/nlohmann/json/issues/1240)
- Doesn't compile under C++17 [\#1239](https://github.com/nlohmann/json/issues/1239)
- Conversion operator for nlohmann::json is not SFINAE friendly [\#1237](https://github.com/nlohmann/json/issues/1237)
- Custom deserialization of number\_float\_t [\#1236](https://github.com/nlohmann/json/issues/1236)
- Move tests to a separate repo [\#1235](https://github.com/nlohmann/json/issues/1235)
- deprecated-declarations warnings when compiling tests with GCC 8.2.1. [\#1233](https://github.com/nlohmann/json/issues/1233)
- Incomplete type with json\_fwd.hpp [\#1232](https://github.com/nlohmann/json/issues/1232)
- Parse Error [\#1229](https://github.com/nlohmann/json/issues/1229)
- json::get function with argument [\#1227](https://github.com/nlohmann/json/issues/1227)
- questions regarding from\_json [\#1226](https://github.com/nlohmann/json/issues/1226)
- Lambda in unevaluated context [\#1225](https://github.com/nlohmann/json/issues/1225)
- NLohmann doesn't compile when enabling strict warning policies [\#1224](https://github.com/nlohmann/json/issues/1224)
- Creating array of objects [\#1223](https://github.com/nlohmann/json/issues/1223)
- Somewhat unhelpful error message "cannot use operator\[\] with object" [\#1220](https://github.com/nlohmann/json/issues/1220)
- single\_include json.hpp [\#1218](https://github.com/nlohmann/json/issues/1218)
- Maps with enum class keys which are convertible to JSON strings should be converted to JSON dictionaries [\#1217](https://github.com/nlohmann/json/issues/1217)
- Adding JSON Array to the Array [\#1216](https://github.com/nlohmann/json/issues/1216)
- Best way to output a vector of a given type to json [\#1215](https://github.com/nlohmann/json/issues/1215)
- compiler warning: double definition of macro JSON\_INTERNAL\_CATCH [\#1213](https://github.com/nlohmann/json/issues/1213)
- Compilation error when using MOCK\_METHOD1 from GMock and nlohmann::json [\#1212](https://github.com/nlohmann/json/issues/1212)
- Issues parsing a previously encoded binary \(non-UTF8\) string. [\#1211](https://github.com/nlohmann/json/issues/1211)
- Yet another ordering question: char \* and parse\(\) [\#1209](https://github.com/nlohmann/json/issues/1209)
- Error using gcc 8.1.0 on Ubuntu 14.04 [\#1207](https://github.com/nlohmann/json/issues/1207)
- "type must be string, but is " std::string\(j.type\_name\(\) [\#1206](https://github.com/nlohmann/json/issues/1206)
- Returning empty json object from a function of type const json& ? [\#1205](https://github.com/nlohmann/json/issues/1205)
- VS2017 compiler suggests using constexpr if [\#1204](https://github.com/nlohmann/json/issues/1204)
- Template instatiation error on compiling [\#1203](https://github.com/nlohmann/json/issues/1203)
- Soften the landing when dumping non-UTF8 strings \(type\_error.316 exception\) [\#1198](https://github.com/nlohmann/json/issues/1198)
- BUG - json dump field with unicode -\> array of ints \(instead of string\) [\#1197](https://github.com/nlohmann/json/issues/1197)
- Compile error using Code::Blocks // mingw-w64 GCC 8.1.0 - "Incomplete Type" [\#1193](https://github.com/nlohmann/json/issues/1193)
- SEGFAULT on arm target [\#1190](https://github.com/nlohmann/json/issues/1190)
- Compiler crash with old Clang [\#1179](https://github.com/nlohmann/json/issues/1179)
- Custom Precision on floating point numbers [\#1170](https://github.com/nlohmann/json/issues/1170)
- Can we have a json\_view class like std::string\_view? [\#1158](https://github.com/nlohmann/json/issues/1158)
- improve error handling [\#1152](https://github.com/nlohmann/json/issues/1152)
- We should remove static\_asserts [\#960](https://github.com/nlohmann/json/issues/960)
- Fix warning C4127: conditional expression is constant [\#1272](https://github.com/nlohmann/json/pull/1272) ([antonioborondo](https://github.com/antonioborondo))
- Turn off additional deprecation warnings for GCC. [\#1271](https://github.com/nlohmann/json/pull/1271) ([chuckatkins](https://github.com/chuckatkins))
- docs: Add additional CMake documentation [\#1270](https://github.com/nlohmann/json/pull/1270) ([chuckatkins](https://github.com/chuckatkins))
- unit-testsuites.cpp: fix hangup if file not found [\#1262](https://github.com/nlohmann/json/pull/1262) ([knilch0r](https://github.com/knilch0r))
- Fix broken cmake imported target alias [\#1260](https://github.com/nlohmann/json/pull/1260) ([chuckatkins](https://github.com/chuckatkins))
- GCC 48 [\#1257](https://github.com/nlohmann/json/pull/1257) ([henryiii](https://github.com/henryiii))
- Add version and license to meson.build [\#1252](https://github.com/nlohmann/json/pull/1252) ([koponomarenko](https://github.com/koponomarenko))
- \#1179 Reordered the code. It seems to stop clang 3.4.2 in RHEL 7 from crash… [\#1249](https://github.com/nlohmann/json/pull/1249) ([LEgregius](https://github.com/LEgregius))
- Use a version check to provide backwards comatible CMake imported target names [\#1245](https://github.com/nlohmann/json/pull/1245) ([chuckatkins](https://github.com/chuckatkins))
- Fix issue \#1237 [\#1238](https://github.com/nlohmann/json/pull/1238) ([theodelrieu](https://github.com/theodelrieu))
- Add a get overload taking a parameter. [\#1231](https://github.com/nlohmann/json/pull/1231) ([theodelrieu](https://github.com/theodelrieu))
- Move lambda out of unevaluated context [\#1230](https://github.com/nlohmann/json/pull/1230) ([mandreyel](https://github.com/mandreyel))
- Remove static asserts [\#1228](https://github.com/nlohmann/json/pull/1228) ([theodelrieu](https://github.com/theodelrieu))
- Better error 305 [\#1221](https://github.com/nlohmann/json/pull/1221) ([rivertam](https://github.com/rivertam))
- Fix \#1213 [\#1214](https://github.com/nlohmann/json/pull/1214) ([simnalamburt](https://github.com/simnalamburt))
- Export package to allow builds without installing [\#1202](https://github.com/nlohmann/json/pull/1202) ([dennisfischer](https://github.com/dennisfischer))
## [v3.2.0](https://github.com/nlohmann/json/releases/tag/v3.2.0) (2018-08-20)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.2...v3.2.0) [Full Changelog](https://github.com/nlohmann/json/compare/v3.1.2...v3.2.0)
- Am I doing this wrong? Getting an empty string [\#1199](https://github.com/nlohmann/json/issues/1199) - Am I doing this wrong? Getting an empty string [\#1199](https://github.com/nlohmann/json/issues/1199)
@ -964,7 +1032,6 @@ All notable changes to this project will be documented in this file. This projec
- json::diff generates incorrect patch when removing multiple array elements. [\#269](https://github.com/nlohmann/json/issues/269) - json::diff generates incorrect patch when removing multiple array elements. [\#269](https://github.com/nlohmann/json/issues/269)
- Docs - What does Json\[key\] return? [\#267](https://github.com/nlohmann/json/issues/267) - Docs - What does Json\[key\] return? [\#267](https://github.com/nlohmann/json/issues/267)
- Compiler Errors With JSON.hpp [\#265](https://github.com/nlohmann/json/issues/265) - Compiler Errors With JSON.hpp [\#265](https://github.com/nlohmann/json/issues/265)
- Throw exception instead of crashing my app [\#264](https://github.com/nlohmann/json/issues/264)
- Ambiguous push\_back and operator+= overloads [\#263](https://github.com/nlohmann/json/issues/263) - Ambiguous push\_back and operator+= overloads [\#263](https://github.com/nlohmann/json/issues/263)
- Preseving order of items in json [\#262](https://github.com/nlohmann/json/issues/262) - Preseving order of items in json [\#262](https://github.com/nlohmann/json/issues/262)
- '\' char problem in strings [\#261](https://github.com/nlohmann/json/issues/261) - '\' char problem in strings [\#261](https://github.com/nlohmann/json/issues/261)

View file

@ -12,6 +12,7 @@ SRCS = include/nlohmann/json.hpp \
include/nlohmann/detail/input/json_sax.hpp \ include/nlohmann/detail/input/json_sax.hpp \
include/nlohmann/detail/input/lexer.hpp \ include/nlohmann/detail/input/lexer.hpp \
include/nlohmann/detail/input/parser.hpp \ include/nlohmann/detail/input/parser.hpp \
include/nlohmann/detail/input/position_t.hpp \
include/nlohmann/detail/iterators/internal_iterator.hpp \ include/nlohmann/detail/iterators/internal_iterator.hpp \
include/nlohmann/detail/iterators/iter_impl.hpp \ include/nlohmann/detail/iterators/iter_impl.hpp \
include/nlohmann/detail/iterators/iteration_proxy.hpp \ include/nlohmann/detail/iterators/iteration_proxy.hpp \

102
README.md
View file

@ -5,6 +5,7 @@
[![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json) [![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json) [![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade)
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/nlohmann/json.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/nlohmann/json/context:cpp)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/TarF5pPn9NtHQjhf) [![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/TarF5pPn9NtHQjhf)
[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json) [![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
@ -15,6 +16,8 @@
- [Design goals](#design-goals) - [Design goals](#design-goals)
- [Integration](#integration) - [Integration](#integration)
- [CMake](#cmake)
- [Package Managers](#package-managers)
- [Examples](#examples) - [Examples](#examples)
- [JSON as first-class data type](#json-as-first-class-data-type) - [JSON as first-class data type](#json-as-first-class-data-type)
- [Serialization / Deserialization](#serialization--deserialization) - [Serialization / Deserialization](#serialization--deserialization)
@ -68,6 +71,71 @@ to the files you want to process JSON and set the necessary switches to enable C
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`. You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.
### CMake
You can also use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.
#### External
To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:
```cmake
# CMakeLists.txt
find_package(nlohmann_json 3.2.0 REQUIRED)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.
#### Embedded
To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:
```cmake
# Typically you don't care so much for a third party library's tests to be
# run from your own project's code.
set(JSON_BuildTests OFF CACHE INTERNAL "")
# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
# inintended consequences that will break the build. It's generally
# discouraged (although not necessarily well documented as such) to use
# include(...) for pulling in other CMake projects anyways.
add_subdirectory(nlohmann_json)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
#### Supporting Both
To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:
``` cmake
# Top level CMakeLists.txt
project(FOO)
...
option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
...
add_subdirectory(thirdparty)
...
add_library(foo ...)
...
# Note that the namespaced target will always be available regardless of the
# import method
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
```cmake
# thirdparty/CMakeLists.txt
...
if(FOO_USE_EXTERNAL_JSON)
find_package(nlohmann_json 3.2.0 REQUIRED)
else()
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)
endif()
...
```
`thirdparty/nlohmann_json` is then a complete copy of this source tree.
### Package Managers ### Package Managers
:beer: If you are using OS X and [Homebrew](http://brew.sh), just type `brew tap nlohmann/json` and `brew install nlohmann_json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann_json --HEAD`. :beer: If you are using OS X and [Homebrew](http://brew.sh), just type `brew tap nlohmann/json` and `brew install nlohmann_json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann_json --HEAD`.
@ -226,12 +294,15 @@ json j_string = "this is a string";
std::string cpp_string = j_string; std::string cpp_string = j_string;
// retrieve the string value (explicit JSON to std::string conversion) // retrieve the string value (explicit JSON to std::string conversion)
auto cpp_string2 = j_string.get<std::string>(); auto cpp_string2 = j_string.get<std::string>();
// retrieve the string value (alternative explicit JSON to std::string conversion)
std::string cpp_string3;
j_string.get_to(cpp_string3);
// retrieve the serialized value (explicit JSON serialization) // retrieve the serialized value (explicit JSON serialization)
std::string serialized_string = j_string.dump(); std::string serialized_string = j_string.dump();
// output of original string // output of original string
std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << '\n'; std::cout << cpp_string << " == " << cpp_string2 << " == " << cpp_string3 << " == " << j_string.get<std::string>() << '\n';
// output of serialized value // output of serialized value
std::cout << j_string << " == " << serialized_string << std::endl; std::cout << j_string << " == " << serialized_string << std::endl;
``` ```
@ -642,15 +713,15 @@ namespace ns {
} }
void from_json(const json& j, person& p) { void from_json(const json& j, person& p) {
p.name = j.at("name").get<std::string>(); j.at("name").get_to(p.name);
p.address = j.at("address").get<std::string>(); j.at("address").get_to(p.address);
p.age = j.at("age").get<int>(); j.at("age").get_to(p.age);
} }
} // namespace ns } // namespace ns
``` ```
That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called. That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
Likewise, when calling `get<your_type>()`, the `from_json` method will be called. Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
Some important things: Some important things:
@ -658,9 +729,8 @@ Some important things:
* Those methods **MUST** be available (e.g., properly headers must be included) everywhere you use the implicit conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise. * Those methods **MUST** be available (e.g., properly headers must be included) everywhere you use the implicit conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.) * When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior. * In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
* In case your type contains several `operator=` definitions, code like `your_variable = your_json;` [may not compile](https://github.com/nlohmann/json/issues/667). You need to write `your_variable = your_json.get<decltype your_variable>();` instead. * In case your type contains several `operator=` definitions, code like `your_variable = your_json;` [may not compile](https://github.com/nlohmann/json/issues/667). You need to write `your_variable = your_json.get<decltype(your_variable)>();` or `your_json.get_to(your_variable);` instead.
* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these. * You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
* Be careful with the definition order of the `from_json`/`to_json` functions: If a type `B` has a member of type `A`, you **MUST** define `to_json(A)` before `to_json(B)`. Look at [issue 561](https://github.com/nlohmann/json/issues/561) for more details.
#### How do I convert third-party types? #### How do I convert third-party types?
@ -842,7 +912,7 @@ json j_from_ubjson = json::from_ubjson(v_ubjson);
Though it's 2018 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work: Though it's 2018 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
- GCC 4.9 - 8.2 (and possibly later) - GCC 4.8 - 8.2 (and possibly later)
- Clang 3.4 - 6.1 (and possibly later) - Clang 3.4 - 6.1 (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)
@ -852,7 +922,7 @@ I would be happy to learn about other compilers/versions.
Please note: Please note:
- GCC 4.8 does not work because of two bugs ([55817](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55817) and [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)) in the C++11 support. Note there is a [pull request](https://github.com/nlohmann/json/pull/212) to fix some of the issues. - GCC 4.8 has a bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)): multiline raw strings cannot be the arguments to macros. Don't use multiline raw strings directly in macros with this compiler.
- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default. - Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.
``` ```
@ -871,6 +941,7 @@ The following compilers are currently used in continuous integration at [Travis]
| Compiler | Operating System | Version String | | Compiler | Operating System | Version String |
|-----------------|------------------------------|----------------| |-----------------|------------------------------|----------------|
| GCC 4.8.5 | Ubuntu 14.04.5 LTS | g++-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.2) 4.8.5 |
| GCC 4.9.4 | Ubuntu 14.04.1 LTS | g++-4.9 (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4 | | GCC 4.9.4 | Ubuntu 14.04.1 LTS | g++-4.9 (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4 |
| GCC 5.5.0 | Ubuntu 14.04.1 LTS | g++-5 (Ubuntu 5.5.0-12ubuntu1~14.04) 5.5.0 20171010 | | GCC 5.5.0 | Ubuntu 14.04.1 LTS | g++-5 (Ubuntu 5.5.0-12ubuntu1~14.04) 5.5.0 20171010 |
| GCC 6.4.0 | Ubuntu 14.04.1 LTS | g++-6 (Ubuntu 6.4.0-17ubuntu1~14.04) 6.4.0 20180424 | | GCC 6.4.0 | Ubuntu 14.04.1 LTS | g++-6 (Ubuntu 6.4.0-17ubuntu1~14.04) 6.4.0 20180424 |
@ -895,6 +966,7 @@ The following compilers are currently used in continuous integration at [Travis]
| Clang Xcode 9.1 | OSX 10.12.6 | Apple LLVM version 9.0.0 (clang-900.0.38) | | Clang Xcode 9.1 | OSX 10.12.6 | Apple LLVM version 9.0.0 (clang-900.0.38) |
| Clang Xcode 9.2 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.1) | | Clang Xcode 9.2 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.1) |
| Clang Xcode 9.3 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.2) | | Clang Xcode 9.3 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.2) |
| Clang Xcode 10.0 | OSX 10.13.3 | Apple LLVM version 10.0.0 (clang-1000.11.45.2) |
| Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25420.1, MSVC 19.0.24215.1 | | Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25420.1, MSVC 19.0.24215.1 |
| Visual Studio 2017 | Windows Server 2016 | Microsoft (R) Build Engine version 15.7.180.61344, MSVC 19.14.26433.0 | | Visual Studio 2017 | Windows Server 2016 | Microsoft (R) Build Engine version 15.7.180.61344, MSVC 19.14.26433.0 |
@ -1045,7 +1117,7 @@ I deeply appreciate the help of the following people.
- [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io). - [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io).
- [Carlos O'Ryan](https://github.com/coryan) fixed a typo. - [Carlos O'Ryan](https://github.com/coryan) fixed a typo.
- [James Upjohn](https://github.com/jammehcow) fixed a version number in the compilers section. - [James Upjohn](https://github.com/jammehcow) fixed a version number in the compilers section.
- [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines - [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration.
- [Jan Schöppach](https://github.com/dns13) fixed a typo. - [Jan Schöppach](https://github.com/dns13) fixed a typo.
- [martin-mfg](https://github.com/martin-mfg) fixed a typo. - [martin-mfg](https://github.com/martin-mfg) fixed a typo.
- [Matthias Möller](https://github.com/TinyTinni) removed the dependency from `std::stringstream`. - [Matthias Möller](https://github.com/TinyTinni) removed the dependency from `std::stringstream`.
@ -1056,6 +1128,16 @@ I deeply appreciate the help of the following people.
- [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases. - [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases.
- [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library. - [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library.
- [thyu](https://github.com/thyu) fixed a compiler warning. - [thyu](https://github.com/thyu) fixed a compiler warning.
- [David Guthrie](https://github.com/LEgregius) fixed a subtle compilation error with Clang 3.4.2.
- [Dennis Fischer](https://github.com/dennisfischer) allowed to call `find_package` without installing the library.
- [Hyeon Kim](https://github.com/simnalamburt) fixed an issue with a double macro definition.
- [Ben Berman](https://github.com/rivertam) made some error messages more understandable.
- [zakalibit](https://github.com/zakalibit) fixed a compilation problem with the Intel C++ compiler.
- [mandreyel](https://github.com/mandreyel) fixed a compilation problem.
- [Kostiantyn Ponomarenko](https://github.com/koponomarenko) added version and license information to the Meson build file.
- [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8.
- [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory.
- [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning.
Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone. Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.

View file

@ -140,7 +140,7 @@ else()
if (GCC_RANLIB) if (GCC_RANLIB)
set(CMAKE_RANLIB ${GCC_RANLIB}) set(CMAKE_RANLIB ${GCC_RANLIB})
endif() endif()
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") elseif("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
include(llvm-toolchain) include(llvm-toolchain)
endif() endif()
endif() endif()
@ -165,7 +165,7 @@ else()
endif() endif()
if (BENCHMARK_USE_LIBCXX) if (BENCHMARK_USE_LIBCXX)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
add_cxx_compiler_flag(-stdlib=libc++) add_cxx_compiler_flag(-stdlib=libc++)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")

View file

@ -7,7 +7,7 @@ macro(build_external_gtest)
include(ExternalProject) include(ExternalProject)
set(GTEST_FLAGS "") set(GTEST_FLAGS "")
if (BENCHMARK_USE_LIBCXX) if (BENCHMARK_USE_LIBCXX)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
list(APPEND GTEST_FLAGS -stdlib=libc++) list(APPEND GTEST_FLAGS -stdlib=libc++)
else() else()
message(WARNING "Unsupported compiler (${CMAKE_CXX_COMPILER}) when using libc++") message(WARNING "Unsupported compiler (${CMAKE_CXX_COMPILER}) when using libc++")

View file

@ -1,5 +1,15 @@
@PACKAGE_INIT@ include(FindPackageHandleStandardArgs)
set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE})
find_package_handle_standard_args(@PROJECT_NAME@ CONFIG_MODE)
if(NOT TARGET @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@) if(NOT TARGET @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@)
include("${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_TARGETS_EXPORT_NAME@.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_TARGETS_EXPORT_NAME@.cmake")
if((NOT TARGET @NLOHMANN_JSON_TARGET_NAME@) AND
(NOT @PROJECT_NAME@_FIND_VERSION OR
@PROJECT_NAME@_FIND_VERSION VERSION_LESS 3.2.0))
add_library(@NLOHMANN_JSON_TARGET_NAME@ INTERFACE IMPORTED)
set_target_properties(@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
INTERFACE_LINK_LIBRARIES @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@
)
endif()
endif() endif()
check_required_components("@PROJECT_NAME@")

View file

@ -5,7 +5,7 @@
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8 DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "JSON for Modern C++" PROJECT_NAME = "JSON for Modern C++"
PROJECT_NUMBER = 3.2.0 PROJECT_NUMBER = 3.3.0
PROJECT_BRIEF = PROJECT_BRIEF =
PROJECT_LOGO = PROJECT_LOGO =
OUTPUT_DIRECTORY = . OUTPUT_DIRECTORY = .

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 KiB

After

Width:  |  Height:  |  Size: 726 KiB

View file

@ -1 +1 @@
<a target="_blank" href="https://wandbox.org/permlink/VexEaSCbbvOOXsPt"><b>online</b></a> <a target="_blank" href="https://wandbox.org/permlink/RWX63GizBsDZ5EnQ"><b>online</b></a>

60
doc/examples/get_to.cpp Normal file
View file

@ -0,0 +1,60 @@
#include <iostream>
#include <unordered_map>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
// create a JSON value with different types
json json_types =
{
{"boolean", true},
{
"number", {
{"integer", 42},
{"floating-point", 17.23}
}
},
{"string", "Hello, world!"},
{"array", {1, 2, 3, 4, 5}},
{"null", nullptr}
};
bool v1;
int v2;
short v3;
float v4;
int v5;
std::string v6;
std::vector<short> v7;
std::unordered_map<std::string, json> v8;
// use explicit conversions
json_types["boolean"].get_to(v1);
json_types["number"]["integer"].get_to(v2);
json_types["number"]["integer"].get_to(v3);
json_types["number"]["floating-point"].get_to(v4);
json_types["number"]["floating-point"].get_to(v5);
json_types["string"].get_to(v6);
json_types["array"].get_to(v7);
json_types.get_to(v8);
// print the conversion results
std::cout << v1 << '\n';
std::cout << v2 << ' ' << v3 << '\n';
std::cout << v4 << ' ' << v5 << '\n';
std::cout << v6 << '\n';
for (auto i : v7)
{
std::cout << i << ' ';
}
std::cout << "\n\n";
for (auto i : v8)
{
std::cout << i.first << ": " << i.second << '\n';
}
}

1
doc/examples/get_to.link Normal file
View file

@ -0,0 +1 @@
<a target="_blank" href="https://wandbox.org/permlink/QxtxaO6JZAMJPutC"><b>online</b></a>

View file

@ -0,0 +1,11 @@
1
42 42
17.23 17
Hello, world!
1 2 3 4 5
string: "Hello, world!"
number: {"floating-point":17.23,"integer":42}
null: null
boolean: true
array: [1,2,3,4,5]

View file

@ -1,3 +1,3 @@
[json.exception.parse_error.107] parse error at 1: JSON pointer must be empty or begin with '/' - was: 'foo' [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'
[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'

View file

@ -2,7 +2,7 @@
"compiler": { "compiler": {
"c++": "201103", "c++": "201103",
"family": "clang", "family": "clang",
"version": "9.1.0 (clang-902.0.39.2)" "version": "10.0.0 (clang-1000.10.43.1)"
}, },
"copyright": "(C) 2013-2017 Niels Lohmann", "copyright": "(C) 2013-2017 Niels Lohmann",
"name": "JSON for Modern C++", "name": "JSON for Modern C++",
@ -10,8 +10,8 @@
"url": "https://github.com/nlohmann/json", "url": "https://github.com/nlohmann/json",
"version": { "version": {
"major": 3, "major": 3,
"minor": 2, "minor": 3,
"patch": 0, "patch": 0,
"string": "3.2.0" "string": "3.3.0"
} }
} }

View file

@ -1,3 +1,3 @@
message: [json.exception.parse_error.101] parse error at 8: syntax error - unexpected ']'; expected '[', '{', or a literal message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal
exception id: 101 exception id: 101
byte position of error: 8 byte position of error: 8

View file

@ -306,4 +306,4 @@ Note that this table only lists those exceptions thrown due to the type. For ins
@author [Niels Lohmann](http://nlohmann.me) @author [Niels Lohmann](http://nlohmann.me)
@see https://github.com/nlohmann/json to download the source code @see https://github.com/nlohmann/json to download the source code
@version 3.2.0 @version 3.3.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View file

@ -46,4 +46,4 @@ struct adl_serializer
::nlohmann::to_json(j, std::forward<ValueType>(val)); ::nlohmann::to_json(j, std::forward<ValueType>(val));
} }
}; };
} } // namespace nlohmann

View file

@ -299,7 +299,7 @@ void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
} }
template<typename BasicJsonType, typename Tuple, std::size_t... Idx> template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>) void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
{ {
t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...); t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
} }
@ -358,7 +358,7 @@ struct from_json_fn
return from_json(j, val); return from_json(j, val);
} }
}; };
} } // namespace detail
/// namespace to hold default `from_json` function /// namespace to hold default `from_json` function
/// to see why this is required: /// to see why this is required:
@ -366,5 +366,5 @@ struct from_json_fn
namespace namespace
{ {
constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
} } // namespace
} } // namespace nlohmann

View file

@ -47,10 +47,9 @@ struct diyfp // f * 2^e
{ {
static constexpr int kPrecision = 64; // = q static constexpr int kPrecision = 64; // = q
uint64_t f; uint64_t f = 0;
int e; int e = 0;
constexpr diyfp() noexcept : f(0), e(0) {}
constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {} constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
/*! /*!
@ -62,7 +61,7 @@ struct diyfp // f * 2^e
assert(x.e == y.e); assert(x.e == y.e);
assert(x.f >= y.f); assert(x.f >= y.f);
return diyfp(x.f - y.f, x.e); return {x.f - y.f, x.e};
} }
/*! /*!
@ -127,7 +126,7 @@ struct diyfp // f * 2^e
const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32); const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
return diyfp(h, x.e + y.e + 64); return {h, x.e + y.e + 64};
} }
/*! /*!
@ -158,7 +157,7 @@ struct diyfp // f * 2^e
assert(delta >= 0); assert(delta >= 0);
assert(((x.f << delta) >> delta) == x.f); assert(((x.f << delta) >> delta) == x.f);
return diyfp(x.f << delta, target_exponent); return {x.f << delta, target_exponent};
} }
}; };
@ -461,7 +460,7 @@ inline cached_power get_cached_power_for_binary_exponent(int e)
assert(e >= -1500); assert(e >= -1500);
assert(e <= 1500); assert(e <= 1500);
const int f = kAlpha - e - 1; const int f = kAlpha - e - 1;
const int k = (f * 78913) / (1 << 18) + (f > 0); const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep; const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
assert(index >= 0); assert(index >= 0);
@ -609,7 +608,7 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e); const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
uint32_t p1 = static_cast<uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.) auto p1 = static_cast<uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
// 1) // 1)
@ -928,7 +927,7 @@ inline char* append_exponent(char* buf, int e)
*buf++ = '+'; *buf++ = '+';
} }
uint32_t k = static_cast<uint32_t>(e); auto k = static_cast<uint32_t>(e);
if (k < 10) if (k < 10)
{ {
// Always print at least two digits in the exponent. // Always print at least two digits in the exponent.
@ -1046,7 +1045,7 @@ format. Returns an iterator pointing past-the-end of the decimal representation.
@note The result is NOT null-terminated. @note The result is NOT null-terminated.
*/ */
template <typename FloatType> template <typename FloatType>
char* to_chars(char* first, char* last, FloatType value) char* to_chars(char* first, const char* last, FloatType value)
{ {
static_cast<void>(last); // maybe unused - fix warning static_cast<void>(last); // maybe unused - fix warning
assert(std::isfinite(value)); assert(std::isfinite(value));

View file

@ -306,13 +306,13 @@ void to_json(BasicJsonType& j, const std::pair<Args...>& p)
// for https://github.com/nlohmann/json/pull/1134 // for https://github.com/nlohmann/json/pull/1134
template<typename BasicJsonType, typename T, template<typename BasicJsonType, typename T,
enable_if_t<std::is_same<T, typename iteration_proxy<typename BasicJsonType::iterator>::iteration_proxy_internal>::value, int> = 0> enable_if_t<std::is_same<T, typename iteration_proxy<typename BasicJsonType::iterator>::iteration_proxy_internal>::value, int> = 0>
void to_json(BasicJsonType& j, T b) noexcept void to_json(BasicJsonType& j, const T& b)
{ {
j = {{b.key(), b.value()}}; j = {{b.key(), b.value()}};
} }
template<typename BasicJsonType, typename Tuple, std::size_t... Idx> template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>) void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
{ {
j = {std::get<Idx>(t)...}; j = {std::get<Idx>(t)...};
} }
@ -332,11 +332,11 @@ struct to_json_fn
return to_json(j, std::forward<T>(val)); return to_json(j, std::forward<T>(val));
} }
}; };
} } // namespace detail
/// namespace to hold default `to_json` function /// namespace to hold default `to_json` function
namespace namespace
{ {
constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
} } // namespace
} } // namespace nlohmann

View file

@ -4,6 +4,8 @@
#include <stdexcept> // runtime_error #include <stdexcept> // runtime_error
#include <string> // to_string #include <string> // to_string
#include <nlohmann/detail/input/position_t.hpp>
namespace nlohmann namespace nlohmann
{ {
namespace detail namespace detail
@ -115,15 +117,23 @@ class parse_error : public exception
/*! /*!
@brief create a parse error exception @brief create a parse error exception
@param[in] id_ the id of the exception @param[in] id_ the id of the exception
@param[in] byte_ the byte index where the error occurred (or 0 if the @param[in] position the position where the error occurred (or with
position cannot be determined) chars_read_total=0 if the position cannot be
determined)
@param[in] what_arg the explanatory string @param[in] what_arg the explanatory string
@return parse_error object @return parse_error object
*/ */
static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
{
std::string w = exception::name("parse_error", id_) + "parse error" +
position_string(pos) + ": " + what_arg;
return parse_error(id_, pos.chars_read_total, w.c_str());
}
static parse_error create(int id_, std::size_t byte_, const std::string& what_arg) static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
{ {
std::string w = exception::name("parse_error", id_) + "parse error" + std::string w = exception::name("parse_error", id_) + "parse error" +
(byte_ != 0 ? (" at " + std::to_string(byte_)) : "") + (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
": " + what_arg; ": " + what_arg;
return parse_error(id_, byte_, w.c_str()); return parse_error(id_, byte_, w.c_str());
} }
@ -142,6 +152,12 @@ class parse_error : public exception
private: private:
parse_error(int id_, std::size_t byte_, const char* what_arg) parse_error(int id_, std::size_t byte_, const char* what_arg)
: exception(id_, what_arg), byte(byte_) {} : exception(id_, what_arg), byte(byte_) {}
static std::string position_string(const position_t& pos)
{
return " at line " + std::to_string(pos.lines_read + 1) +
", column " + std::to_string(pos.chars_read_current_line);
}
}; };
/*! /*!
@ -329,5 +345,5 @@ class other_error : public exception
private: private:
other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -104,7 +104,8 @@ class binary_reader
if (JSON_UNLIKELY(current != std::char_traits<char>::eof())) if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
{ {
return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, "expected end of input")); return sax->parse_error(chars_read, get_token_string(),
parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
} }
} }
@ -139,7 +140,7 @@ class binary_reader
while (true) while (true)
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
{ {
return false; return false;
} }
@ -165,7 +166,7 @@ class binary_reader
template <typename NumberType> template <typename NumberType>
bool get_bson_string(const NumberType len, string_t& result) bool get_bson_string(const NumberType len, string_t& result)
{ {
return get_string(len - static_cast<NumberType>(1), result) return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result)
&& get() != std::char_traits<char>::eof(); && get() != std::char_traits<char>::eof();
} }
@ -195,14 +196,14 @@ class binary_reader
case 0x01: // double case 0x01: // double
{ {
double number; double number;
return get_number<double, true>(number) return get_number<double, true>(input_format_t::bson, number)
&& sax->number_float(static_cast<number_float_t>(number), ""); && sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0x02: // string case 0x02: // string
{ {
std::int32_t len; std::int32_t len;
string_t value; string_t value;
return get_number<std::int32_t, true>(len) return get_number<std::int32_t, true>(input_format_t::bson, len)
&& get_bson_string(len, value) && get_bson_string(len, value)
&& sax->string(value); && sax->string(value);
} }
@ -213,13 +214,13 @@ class binary_reader
case 0x10: // int32 case 0x10: // int32
{ {
std::int32_t value; std::int32_t value;
return get_number<std::int32_t, true>(value) return get_number<std::int32_t, true>(input_format_t::bson, value)
&& sax->number_integer(static_cast<std::int32_t>(value)); && sax->number_integer(static_cast<std::int32_t>(value));
} }
case 0x12: // int64 case 0x12: // int64
{ {
std::int64_t value; std::int64_t value;
return get_number<std::int64_t, true>(value) return get_number<std::int64_t, true>(input_format_t::bson, value)
&& sax->number_integer(static_cast<std::int64_t>(value)); && sax->number_integer(static_cast<std::int64_t>(value));
} }
case 0x0A: // null case 0x0A: // null
@ -256,7 +257,7 @@ class binary_reader
{ {
while (auto element_type = get()) while (auto element_type = get())
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
{ {
return false; return false;
} }
@ -288,7 +289,7 @@ class binary_reader
bool parse_bson_array() bool parse_bson_array()
{ {
std::int32_t documentSize; std::int32_t documentSize;
get_number<std::int32_t, true>(documentSize); get_number<std::int32_t, true>(input_format_t::bson, documentSize);
if (JSON_UNLIKELY(not sax->start_array(-1))) if (JSON_UNLIKELY(not sax->start_array(-1)))
{ {
@ -310,7 +311,7 @@ class binary_reader
bool parse_bson_internal() bool parse_bson_internal()
{ {
std::int32_t documentSize; std::int32_t documentSize;
get_number<std::int32_t, true>(documentSize); get_number<std::int32_t, true>(input_format_t::bson, documentSize);
if (JSON_UNLIKELY(not sax->start_object(-1))) if (JSON_UNLIKELY(not sax->start_object(-1)))
{ {
@ -338,7 +339,7 @@ class binary_reader
{ {
// EOF // EOF
case std::char_traits<char>::eof(): case std::char_traits<char>::eof():
return unexpect_eof(); return unexpect_eof(input_format_t::cbor, "value");
// Integer 0x00..0x17 (0..23) // Integer 0x00..0x17 (0..23)
case 0x00: case 0x00:
@ -370,25 +371,25 @@ class binary_reader
case 0x18: // Unsigned integer (one-byte uint8_t follows) case 0x18: // Unsigned integer (one-byte uint8_t follows)
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x19: // Unsigned integer (two-byte uint16_t follows) case 0x19: // Unsigned integer (two-byte uint16_t follows)
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x1A: // Unsigned integer (four-byte uint32_t follows) case 0x1A: // Unsigned integer (four-byte uint32_t follows)
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x1B: // Unsigned integer (eight-byte uint64_t follows) case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
// Negative integer -1-0x00..-1-0x17 (-1..-24) // Negative integer -1-0x00..-1-0x17 (-1..-24)
@ -421,25 +422,25 @@ class binary_reader
case 0x38: // Negative integer (one-byte uint8_t follows) case 0x38: // Negative integer (one-byte uint8_t follows)
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x39: // Negative integer -1-n (two-byte uint16_t follows) case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
- static_cast<number_integer_t>(number)); - static_cast<number_integer_t>(number));
} }
@ -508,25 +509,25 @@ class binary_reader
case 0x98: // array (one-byte uint8_t for n follows) case 0x98: // array (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x99: // array (two-byte uint16_t for n follow) case 0x99: // array (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9A: // array (four-byte uint32_t for n follow) case 0x9A: // array (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9B: // array (eight-byte uint64_t for n follow) case 0x9B: // array (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9F: // array (indefinite length) case 0x9F: // array (indefinite length)
@ -562,25 +563,25 @@ class binary_reader
case 0xB8: // map (one-byte uint8_t for n follows) case 0xB8: // map (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xB9: // map (two-byte uint16_t for n follow) case 0xB9: // map (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBA: // map (four-byte uint32_t for n follow) case 0xBA: // map (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBB: // map (eight-byte uint64_t for n follow) case 0xBB: // map (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBF: // map (indefinite length) case 0xBF: // map (indefinite length)
@ -597,17 +598,20 @@ class binary_reader
case 0xF9: // Half-Precision Float (two-byte IEEE 754) case 0xF9: // Half-Precision Float (two-byte IEEE 754)
{ {
const int byte1 = get(); const int byte1_raw = get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
{ {
return false; return false;
} }
const int byte2 = get(); const int byte2_raw = get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
{ {
return false; return false;
} }
const auto byte1 = static_cast<unsigned char>(byte1_raw);
const auto byte2 = static_cast<unsigned char>(byte2_raw);
// code from RFC 7049, Appendix D, Figure 3: // code from RFC 7049, Appendix D, Figure 3:
// As half-precision floating-point numbers were only added // As half-precision floating-point numbers were only added
// to IEEE 754 in 2008, today's programming platforms often // to IEEE 754 in 2008, today's programming platforms often
@ -643,19 +647,19 @@ class binary_reader
case 0xFA: // Single-Precision Float (four-byte IEEE 754) case 0xFA: // Single-Precision Float (four-byte IEEE 754)
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xFB: // Double-Precision Float (eight-byte IEEE 754) case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
default: // anything else (0xFF is handled inside the other types) default: // anything else (0xFF is handled inside the other types)
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -669,7 +673,7 @@ class binary_reader
{ {
// EOF // EOF
case std::char_traits<char>::eof(): case std::char_traits<char>::eof():
return unexpect_eof(); return unexpect_eof(input_format_t::msgpack, "value");
// positive fixint // positive fixint
case 0x00: case 0x00:
@ -890,61 +894,61 @@ class binary_reader
case 0xCA: // float 32 case 0xCA: // float 32
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xCB: // float 64 case 0xCB: // float 64
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xCC: // uint 8 case 0xCC: // uint 8
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCD: // uint 16 case 0xCD: // uint 16
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCE: // uint 32 case 0xCE: // uint 32
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCF: // uint 64 case 0xCF: // uint 64
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xD0: // int 8 case 0xD0: // int 8
{ {
int8_t number; int8_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD1: // int 16 case 0xD1: // int 16
{ {
int16_t number; int16_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD2: // int 32 case 0xD2: // int 32
{ {
int32_t number; int32_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD3: // int 64 case 0xD3: // int 64
{ {
int64_t number; int64_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD9: // str 8 case 0xD9: // str 8
@ -958,25 +962,25 @@ class binary_reader
case 0xDC: // array 16 case 0xDC: // array 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
} }
case 0xDD: // array 32 case 0xDD: // array 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
} }
case 0xDE: // map 16 case 0xDE: // map 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
} }
case 0xDF: // map 32 case 0xDF: // map 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
} }
// negative fixint // negative fixint
@ -1017,7 +1021,7 @@ class binary_reader
default: // anything else default: // anything else
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading MessagePack; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -1067,6 +1071,7 @@ class binary_reader
@brief read a number from the input @brief read a number from the input
@tparam NumberType the type of the number @tparam NumberType the type of the number
@param[in] format the current format (for diagnostics)
@param[out] result number of type @a NumberType @param[out] result number of type @a NumberType
@return whether conversion completed @return whether conversion completed
@ -1076,14 +1081,14 @@ class binary_reader
(big endian) and therefore need reordering on little endian systems. (big endian) and therefore need reordering on little endian systems.
*/ */
template<typename NumberType, bool InputIsLittleEndian = false> template<typename NumberType, bool InputIsLittleEndian = false>
bool get_number(NumberType& result) bool get_number(const input_format_t format, NumberType& result)
{ {
// step 1: read input into array with system's byte order // step 1: read input into array with system's byte order
std::array<uint8_t, sizeof(NumberType)> vec; std::array<uint8_t, sizeof(NumberType)> vec;
for (std::size_t i = 0; i < sizeof(NumberType); ++i) for (std::size_t i = 0; i < sizeof(NumberType); ++i)
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
{ {
return false; return false;
} }
@ -1109,8 +1114,9 @@ class binary_reader
@brief create a string by reading characters from the input @brief create a string by reading characters from the input
@tparam NumberType the type of the number @tparam NumberType the type of the number
@param[in] format the current format (for diagnostics)
@param[in] len number of characters to read @param[in] len number of characters to read
@param[out] string created by reading @a len bytes @param[out] result string created by reading @a len bytes
@return whether string creation completed @return whether string creation completed
@ -1119,13 +1125,13 @@ class binary_reader
the input before we run out of string memory. the input before we run out of string memory.
*/ */
template<typename NumberType> template<typename NumberType>
bool get_string(const NumberType len, string_t& result) bool get_string(const input_format_t format, const NumberType len, string_t& result)
{ {
bool success = true; bool success = true;
std::generate_n(std::back_inserter(result), len, [this, &success]() std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
{ {
success = false; success = false;
} }
@ -1147,7 +1153,7 @@ class binary_reader
*/ */
bool get_cbor_string(string_t& result) bool get_cbor_string(string_t& result)
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
{ {
return false; return false;
} }
@ -1180,31 +1186,31 @@ class binary_reader
case 0x76: case 0x76:
case 0x77: case 0x77:
{ {
return get_string(current & 0x1F, result); return get_string(input_format_t::cbor, current & 0x1F, result);
} }
case 0x78: // UTF-8 string (one-byte uint8_t for n follows) case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x79: // UTF-8 string (two-byte uint16_t for n follow) case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7F: // UTF-8 string (indefinite length) case 0x7F: // UTF-8 string (indefinite length)
@ -1224,7 +1230,7 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
} }
} }
} }
@ -1242,6 +1248,7 @@ class binary_reader
} }
if (len != std::size_t(-1)) if (len != std::size_t(-1))
{
for (std::size_t i = 0; i < len; ++i) for (std::size_t i = 0; i < len; ++i)
{ {
if (JSON_UNLIKELY(not parse_cbor_internal())) if (JSON_UNLIKELY(not parse_cbor_internal()))
@ -1249,6 +1256,7 @@ class binary_reader
return false; return false;
} }
} }
}
else else
{ {
while (get() != 0xFF) while (get() != 0xFF)
@ -1325,7 +1333,7 @@ class binary_reader
*/ */
bool get_msgpack_string(string_t& result) bool get_msgpack_string(string_t& result)
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
{ {
return false; return false;
} }
@ -1366,31 +1374,31 @@ class binary_reader
case 0xBE: case 0xBE:
case 0xBF: case 0xBF:
{ {
return get_string(current & 0x1F, result); return get_string(input_format_t::msgpack, current & 0x1F, result);
} }
case 0xD9: // str 8 case 0xD9: // str 8
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
case 0xDA: // str 16 case 0xDA: // str 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
case 0xDB: // str 32 case 0xDB: // str 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a MessagePack string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
} }
} }
} }
@ -1468,7 +1476,7 @@ class binary_reader
get(); // TODO: may we ignore N here? get(); // TODO: may we ignore N here?
} }
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
{ {
return false; return false;
} }
@ -1478,36 +1486,36 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'i': case 'i':
{ {
int8_t len; int8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'I': case 'I':
{ {
int16_t len; int16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'l': case 'l':
{ {
int32_t len; int32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'L': case 'L':
{ {
int64_t len; int64_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
default: default:
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a UBJSON string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
} }
} }
@ -1522,7 +1530,7 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t number; uint8_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1533,7 +1541,7 @@ class binary_reader
case 'i': case 'i':
{ {
int8_t number; int8_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1544,7 +1552,7 @@ class binary_reader
case 'I': case 'I':
{ {
int16_t number; int16_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1555,7 +1563,7 @@ class binary_reader
case 'l': case 'l':
{ {
int32_t number; int32_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1566,7 +1574,7 @@ class binary_reader
case 'L': case 'L':
{ {
int64_t number; int64_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1577,7 +1585,7 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "byte after '#' must denote a number type; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
} }
} }
} }
@ -1602,7 +1610,7 @@ class binary_reader
if (current == '$') if (current == '$')
{ {
result.second = get(); // must not ignore 'N', because 'N' maybe the type result.second = get(); // must not ignore 'N', because 'N' maybe the type
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
{ {
return false; return false;
} }
@ -1610,12 +1618,12 @@ class binary_reader
get_ignore_noop(); get_ignore_noop();
if (JSON_UNLIKELY(current != '#')) if (JSON_UNLIKELY(current != '#'))
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
{ {
return false; return false;
} }
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "expected '#' after UBJSON type information; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
} }
return get_ubjson_size_value(result.first); return get_ubjson_size_value(result.first);
@ -1636,7 +1644,7 @@ class binary_reader
switch (prefix) switch (prefix)
{ {
case std::char_traits<char>::eof(): // EOF case std::char_traits<char>::eof(): // EOF
return unexpect_eof(); return unexpect_eof(input_format_t::ubjson, "value");
case 'T': // true case 'T': // true
return sax->boolean(true); return sax->boolean(true);
@ -1649,56 +1657,56 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
} }
case 'i': case 'i':
{ {
int8_t number; int8_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'I': case 'I':
{ {
int16_t number; int16_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'l': case 'l':
{ {
int32_t number; int32_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'L': case 'L':
{ {
int64_t number; int64_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'd': case 'd':
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 'D': case 'D':
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 'C': // char case 'C': // char
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
{ {
return false; return false;
} }
if (JSON_UNLIKELY(current > 127)) if (JSON_UNLIKELY(current > 127))
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
} }
string_t s(1, static_cast<char>(current)); string_t s(1, static_cast<char>(current));
return sax->string(s); return sax->string(s);
@ -1719,7 +1727,7 @@ class binary_reader
default: // anything else default: // anything else
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading UBJSON; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -1862,13 +1870,16 @@ class binary_reader
} }
/*! /*!
@param[in] format the current format (for diagnostics)
@param[in] context further context information (for diagnostics)
@return whether the last read character is not EOF @return whether the last read character is not EOF
*/ */
bool unexpect_eof() const bool unexpect_eof(const input_format_t format, const char* context) const
{ {
if (JSON_UNLIKELY(current == std::char_traits<char>::eof())) if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
{ {
return sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, "unexpected end of input")); return sax->parse_error(chars_read, "<end of file>",
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
} }
return true; return true;
} }
@ -1884,6 +1895,45 @@ class binary_reader
} }
private: private:
/*!
@param[in] format the current format
@param[in] detail a detailed error message
@param[in] context further contect information
@return a message string to use in the parse_error exceptions
*/
std::string exception_message(const input_format_t format,
const std::string& detail,
const std::string& context) const
{
std::string error_msg = "syntax error while parsing ";
switch (format)
{
case input_format_t::cbor:
error_msg += "CBOR";
break;
case input_format_t::msgpack:
error_msg += "MessagePack";
break;
case input_format_t::ubjson:
error_msg += "UBJSON";
break;
case input_format_t::bson:
error_msg += "BSON";
break;
// LCOV_EXCL_START
default:
assert(false);
// LCOV_EXCL_STOP
}
return error_msg + " " + context + ": " + detail;
}
/// input adapter /// input adapter
input_adapter_t ia = nullptr; input_adapter_t ia = nullptr;
@ -1899,5 +1949,5 @@ class binary_reader
/// the SAX parser /// the SAX parser
json_sax_t* sax = nullptr; json_sax_t* sax = nullptr;
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -71,6 +71,8 @@ class input_stream_adapter : public input_adapter_protocol
// delete because of pointer members // delete because of pointer members
input_stream_adapter(const input_stream_adapter&) = delete; input_stream_adapter(const input_stream_adapter&) = delete;
input_stream_adapter& operator=(input_stream_adapter&) = delete; input_stream_adapter& operator=(input_stream_adapter&) = delete;
input_stream_adapter(input_stream_adapter&&) = delete;
input_stream_adapter& operator=(input_stream_adapter&&) = delete;
// std::istream/std::streambuf use std::char_traits<char>::to_int_type, to // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
// ensure that std::char_traits<char>::eof() and the character 0xFF do not // ensure that std::char_traits<char>::eof() and the character 0xFF do not
@ -97,6 +99,9 @@ class input_buffer_adapter : public input_adapter_protocol
// delete because of pointer members // delete because of pointer members
input_buffer_adapter(const input_buffer_adapter&) = delete; input_buffer_adapter(const input_buffer_adapter&) = delete;
input_buffer_adapter& operator=(input_buffer_adapter&) = delete; input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
input_buffer_adapter(input_buffer_adapter&&) = delete;
input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
~input_buffer_adapter() override = default;
std::char_traits<char>::int_type get_character() noexcept override std::char_traits<char>::int_type get_character() noexcept override
{ {
@ -115,38 +120,11 @@ class input_buffer_adapter : public input_adapter_protocol
const char* const limit; const char* const limit;
}; };
template<typename WideStringType> template<typename WideStringType, size_t T>
class wide_string_input_adapter : public input_adapter_protocol struct wide_string_input_helper
{ {
public: // UTF-32
explicit wide_string_input_adapter(const WideStringType& w) : str(w) {} static void fill_buffer(const WideStringType& str, size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
std::char_traits<char>::int_type get_character() noexcept override
{
// check if buffer needs to be filled
if (utf8_bytes_index == utf8_bytes_filled)
{
if (sizeof(typename WideStringType::value_type) == 2)
{
fill_buffer_utf16();
}
else
{
fill_buffer_utf32();
}
assert(utf8_bytes_filled > 0);
assert(utf8_bytes_index == 0);
}
// use buffer
assert(utf8_bytes_filled > 0);
assert(utf8_bytes_index < utf8_bytes_filled);
return utf8_bytes[utf8_bytes_index++];
}
private:
void fill_buffer_utf16()
{ {
utf8_bytes_index = 0; utf8_bytes_index = 0;
@ -158,7 +136,62 @@ class wide_string_input_adapter : public input_adapter_protocol
else else
{ {
// get the current character // get the current character
const int wc = static_cast<int>(str[current_wchar++]); const auto wc = static_cast<int>(str[current_wchar++]);
// UTF-32 to UTF-8 encoding
if (wc < 0x80)
{
utf8_bytes[0] = wc;
utf8_bytes_filled = 1;
}
else if (wc <= 0x7FF)
{
utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
utf8_bytes[1] = 0x80 | (wc & 0x3F);
utf8_bytes_filled = 2;
}
else if (wc <= 0xFFFF)
{
utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
utf8_bytes[2] = 0x80 | (wc & 0x3F);
utf8_bytes_filled = 3;
}
else if (wc <= 0x10FFFF)
{
utf8_bytes[0] = 0xF0 | ((wc >> 18) & 0x07);
utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
utf8_bytes[3] = 0x80 | (wc & 0x3F);
utf8_bytes_filled = 4;
}
else
{
// unknown character
utf8_bytes[0] = wc;
utf8_bytes_filled = 1;
}
}
}
};
template<typename WideStringType>
struct wide_string_input_helper<WideStringType, 2>
{
// UTF-16
static void fill_buffer(const WideStringType& str, size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
{
utf8_bytes_index = 0;
if (current_wchar == str.size())
{
utf8_bytes[0] = std::char_traits<char>::eof();
utf8_bytes_filled = 1;
}
else
{
// get the current character
const auto wc = static_cast<int>(str[current_wchar++]);
// UTF-16 to UTF-8 encoding // UTF-16 to UTF-8 encoding
if (wc < 0x80) if (wc < 0x80)
@ -183,7 +216,7 @@ class wide_string_input_adapter : public input_adapter_protocol
{ {
if (current_wchar < str.size()) if (current_wchar < str.size())
{ {
const int wc2 = static_cast<int>(str[current_wchar++]); const auto wc2 = static_cast<int>(str[current_wchar++]);
const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF)); const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF));
utf8_bytes[0] = 0xf0 | (charcode >> 18); utf8_bytes[0] = 0xf0 | (charcode >> 18);
utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F); utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F);
@ -201,58 +234,38 @@ class wide_string_input_adapter : public input_adapter_protocol
} }
} }
} }
};
void fill_buffer_utf32() template<typename WideStringType>
{ class wide_string_input_adapter : public input_adapter_protocol
utf8_bytes_index = 0; {
public:
explicit wide_string_input_adapter(const WideStringType& w) : str(w) {}
if (current_wchar == str.size()) std::char_traits<char>::int_type get_character() noexcept override
{ {
utf8_bytes[0] = std::char_traits<char>::eof(); // check if buffer needs to be filled
utf8_bytes_filled = 1; if (utf8_bytes_index == utf8_bytes_filled)
}
else
{ {
// get the current character fill_buffer<sizeof(typename WideStringType::value_type)>();
const int wc = static_cast<int>(str[current_wchar++]);
// UTF-32 to UTF-8 encoding assert(utf8_bytes_filled > 0);
if (wc < 0x80) assert(utf8_bytes_index == 0);
{
utf8_bytes[0] = wc;
utf8_bytes_filled = 1;
}
else if (wc <= 0x7FF)
{
utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
utf8_bytes[1] = 0x80 | (wc & 0x3F);
utf8_bytes_filled = 2;
}
else if (wc <= 0xFFFF)
{
utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
utf8_bytes[2] = 0x80 | (wc & 0x3F);
utf8_bytes_filled = 3;
}
else if (wc <= 0x10FFFF)
{
utf8_bytes[0] = 0xF0 | ((wc >> 18 ) & 0x07);
utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
utf8_bytes[3] = 0x80 | (wc & 0x3F);
utf8_bytes_filled = 4;
}
else
{
// unknown character
utf8_bytes[0] = wc;
utf8_bytes_filled = 1;
}
} }
// use buffer
assert(utf8_bytes_filled > 0);
assert(utf8_bytes_index < utf8_bytes_filled);
return utf8_bytes[utf8_bytes_index++];
} }
private: private:
template<size_t T>
void fill_buffer()
{
wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
}
/// the wstring to process /// the wstring to process
const WideStringType& str; const WideStringType& str;
@ -373,5 +386,5 @@ class input_adapter
/// the actual adapter /// the actual adapter
input_adapter_t ia = nullptr; input_adapter_t ia = nullptr;
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -113,7 +113,7 @@ struct json_sax
@brief a parse error occurred @brief a parse error occurred
@param[in] position the position in the input where the error occurs @param[in] position the position in the input where the error occurs
@param[in] last_token the last read token @param[in] last_token the last read token
@param[in] error_msg a detailed error message @param[in] ex an exception object describing the error
@return whether parsing should proceed (must return false) @return whether parsing should proceed (must return false)
*/ */
virtual bool parse_error(std::size_t position, virtual bool parse_error(std::size_t position,
@ -181,7 +181,7 @@ class json_sax_dom_parser
return true; return true;
} }
bool number_float(number_float_t val, const string_t&) bool number_float(number_float_t val, const string_t& /*unused*/)
{ {
handle_value(val); handle_value(val);
return true; return true;
@ -238,7 +238,7 @@ class json_sax_dom_parser
return true; return true;
} }
bool parse_error(std::size_t, const std::string&, bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
const detail::exception& ex) const detail::exception& ex)
{ {
errored = true; errored = true;
@ -286,9 +286,9 @@ class json_sax_dom_parser
root = BasicJsonType(std::forward<Value>(v)); root = BasicJsonType(std::forward<Value>(v));
return &root; return &root;
} }
else
{
assert(ref_stack.back()->is_array() or ref_stack.back()->is_object()); assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
if (ref_stack.back()->is_array()) if (ref_stack.back()->is_array())
{ {
ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v)); ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
@ -301,7 +301,6 @@ class json_sax_dom_parser
return object_element; return object_element;
} }
} }
}
/// the parsed JSON value /// the parsed JSON value
BasicJsonType& root; BasicJsonType& root;
@ -358,7 +357,7 @@ class json_sax_dom_callback_parser
return true; return true;
} }
bool number_float(number_float_t val, const string_t&) bool number_float(number_float_t val, const string_t& /*unused*/)
{ {
handle_value(val); handle_value(val);
return true; return true;
@ -496,7 +495,7 @@ class json_sax_dom_callback_parser
return true; return true;
} }
bool parse_error(std::size_t, const std::string&, bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
const detail::exception& ex) const detail::exception& ex)
{ {
errored = true; errored = true;
@ -574,8 +573,7 @@ class json_sax_dom_callback_parser
root = std::move(value); root = std::move(value);
return {true, &root}; return {true, &root};
} }
else
{
// skip this value if we already decided to skip the parent // skip this value if we already decided to skip the parent
// (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
if (not ref_stack.back()) if (not ref_stack.back())
@ -583,7 +581,9 @@ class json_sax_dom_callback_parser
return {false, nullptr}; return {false, nullptr};
} }
// we now only expect arrays and objects
assert(ref_stack.back()->is_array() or ref_stack.back()->is_object()); assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
if (ref_stack.back()->is_array()) if (ref_stack.back()->is_array())
{ {
ref_stack.back()->m_value.array->push_back(std::move(value)); ref_stack.back()->m_value.array->push_back(std::move(value));
@ -606,7 +606,6 @@ class json_sax_dom_callback_parser
return {true, object_element}; return {true, object_element};
} }
} }
}
/// the parsed JSON value /// the parsed JSON value
BasicJsonType& root; BasicJsonType& root;
@ -642,37 +641,37 @@ class json_sax_acceptor
return true; return true;
} }
bool boolean(bool) bool boolean(bool /*unused*/)
{ {
return true; return true;
} }
bool number_integer(number_integer_t) bool number_integer(number_integer_t /*unused*/)
{ {
return true; return true;
} }
bool number_unsigned(number_unsigned_t) bool number_unsigned(number_unsigned_t /*unused*/)
{ {
return true; return true;
} }
bool number_float(number_float_t, const string_t&) bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
{ {
return true; return true;
} }
bool string(string_t&) bool string(string_t& /*unused*/)
{ {
return true; return true;
} }
bool start_object(std::size_t = std::size_t(-1)) bool start_object(std::size_t /*unused*/ = std::size_t(-1))
{ {
return true; return true;
} }
bool key(string_t&) bool key(string_t& /*unused*/)
{ {
return true; return true;
} }
@ -682,7 +681,7 @@ class json_sax_acceptor
return true; return true;
} }
bool start_array(std::size_t = std::size_t(-1)) bool start_array(std::size_t /*unused*/ = std::size_t(-1))
{ {
return true; return true;
} }
@ -692,11 +691,11 @@ class json_sax_acceptor
return true; return true;
} }
bool parse_error(std::size_t, const std::string&, const detail::exception&) bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
{ {
return false; return false;
} }
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -10,6 +10,7 @@
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/input/input_adapters.hpp> #include <nlohmann/detail/input/input_adapters.hpp>
#include <nlohmann/detail/input/position_t.hpp>
namespace nlohmann namespace nlohmann
{ {
@ -104,7 +105,10 @@ class lexer
// delete because of pointer members // delete because of pointer members
lexer(const lexer&) = delete; lexer(const lexer&) = delete;
lexer(lexer&&) = delete;
lexer& operator=(lexer&) = delete; lexer& operator=(lexer&) = delete;
lexer& operator=(lexer&&) = delete;
~lexer() = default;
private: private:
///////////////////// /////////////////////
@ -393,39 +397,194 @@ class lexer
// invalid control characters // invalid control characters
case 0x00: case 0x00:
{
error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
return token_type::parse_error;
}
case 0x01: case 0x01:
{
error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
return token_type::parse_error;
}
case 0x02: case 0x02:
{
error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
return token_type::parse_error;
}
case 0x03: case 0x03:
{
error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
return token_type::parse_error;
}
case 0x04: case 0x04:
{
error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
return token_type::parse_error;
}
case 0x05: case 0x05:
{
error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
return token_type::parse_error;
}
case 0x06: case 0x06:
{
error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
return token_type::parse_error;
}
case 0x07: case 0x07:
{
error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
return token_type::parse_error;
}
case 0x08: case 0x08:
{
error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
return token_type::parse_error;
}
case 0x09: case 0x09:
{
error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
return token_type::parse_error;
}
case 0x0A: case 0x0A:
{
error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
return token_type::parse_error;
}
case 0x0B: case 0x0B:
{
error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
return token_type::parse_error;
}
case 0x0C: case 0x0C:
{
error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
return token_type::parse_error;
}
case 0x0D: case 0x0D:
{
error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
return token_type::parse_error;
}
case 0x0E: case 0x0E:
{
error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
return token_type::parse_error;
}
case 0x0F: case 0x0F:
{
error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
return token_type::parse_error;
}
case 0x10: case 0x10:
{
error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
return token_type::parse_error;
}
case 0x11: case 0x11:
{
error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
return token_type::parse_error;
}
case 0x12: case 0x12:
{
error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
return token_type::parse_error;
}
case 0x13: case 0x13:
{
error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
return token_type::parse_error;
}
case 0x14: case 0x14:
{
error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
return token_type::parse_error;
}
case 0x15: case 0x15:
{
error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
return token_type::parse_error;
}
case 0x16: case 0x16:
{
error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
return token_type::parse_error;
}
case 0x17: case 0x17:
{
error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
return token_type::parse_error;
}
case 0x18: case 0x18:
{
error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
return token_type::parse_error;
}
case 0x19: case 0x19:
{
error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
return token_type::parse_error;
}
case 0x1A: case 0x1A:
{
error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
return token_type::parse_error;
}
case 0x1B: case 0x1B:
{
error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
return token_type::parse_error;
}
case 0x1C: case 0x1C:
{
error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
return token_type::parse_error;
}
case 0x1D: case 0x1D:
{
error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
return token_type::parse_error;
}
case 0x1E: case 0x1E:
{
error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
return token_type::parse_error;
}
case 0x1F: case 0x1F:
{ {
error_message = "invalid string: control character must be escaped"; error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
return token_type::parse_error; return token_type::parse_error;
} }
@ -709,7 +868,7 @@ class lexer
locale's decimal point is used instead of `.` to work with the locale's decimal point is used instead of `.` to work with the
locale-dependent converters. locale-dependent converters.
*/ */
token_type scan_number() token_type scan_number() // lgtm [cpp/use-of-goto]
{ {
// reset token_buffer to store the number's bytes // reset token_buffer to store the number's bytes
reset(); reset();
@ -1082,7 +1241,9 @@ scan_number_done:
*/ */
std::char_traits<char>::int_type get() std::char_traits<char>::int_type get()
{ {
++chars_read; ++position.chars_read_total;
++position.chars_read_current_line;
if (next_unget) if (next_unget)
{ {
// just reset the next_unget variable and work with current // just reset the next_unget variable and work with current
@ -1097,6 +1258,13 @@ scan_number_done:
{ {
token_string.push_back(std::char_traits<char>::to_char_type(current)); token_string.push_back(std::char_traits<char>::to_char_type(current));
} }
if (current == '\n')
{
++position.lines_read;
++position.chars_read_current_line = 0;
}
return current; return current;
} }
@ -1104,14 +1272,29 @@ scan_number_done:
@brief unget current character (read it again on next get) @brief unget current character (read it again on next get)
We implement unget by setting variable next_unget to true. The input is not We implement unget by setting variable next_unget to true. The input is not
changed - we just simulate ungetting by modifying chars_read and changed - we just simulate ungetting by modifying chars_read_total,
token_string. The next call to get() will behave as if the unget character chars_read_current_line, and token_string. The next call to get() will
is read again. behave as if the unget character is read again.
*/ */
void unget() void unget()
{ {
next_unget = true; next_unget = true;
--chars_read;
--position.chars_read_total;
// in case we "unget" a newline, we have to also decrement the lines_read
if (position.chars_read_current_line == 0)
{
if (position.lines_read > 0)
{
--position.lines_read;
}
}
else
{
--position.chars_read_current_line;
}
if (JSON_LIKELY(current != std::char_traits<char>::eof())) if (JSON_LIKELY(current != std::char_traits<char>::eof()))
{ {
assert(token_string.size() != 0); assert(token_string.size() != 0);
@ -1159,9 +1342,9 @@ scan_number_done:
///////////////////// /////////////////////
/// return position of last read token /// return position of last read token
constexpr std::size_t get_position() const noexcept constexpr position_t get_position() const noexcept
{ {
return chars_read; return position;
} }
/// return the last read token (for errors only). Will never contain EOF /// return the last read token (for errors only). Will never contain EOF
@ -1208,30 +1391,20 @@ scan_number_done:
{ {
if (get() == 0xEF) if (get() == 0xEF)
{ {
if (get() == 0xBB and get() == 0xBF) // check if we completely parse the BOM
{ return get() == 0xBB and get() == 0xBF;
// we completely parsed the BOM
return true;
} }
else
{
// after reading 0xEF, an unexpected character followed
return false;
}
}
else
{
// the first character is not the beginning of the BOM; unget it to // the first character is not the beginning of the BOM; unget it to
// process is later // process is later
unget(); unget();
return true; return true;
} }
}
token_type scan() token_type scan()
{ {
// initially, skip the BOM // initially, skip the BOM
if (chars_read == 0 and not skip_bom()) if (position.chars_read_total == 0 and not skip_bom())
{ {
error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
return token_type::parse_error; return token_type::parse_error;
@ -1309,8 +1482,8 @@ scan_number_done:
/// whether the next get() call should just return current /// whether the next get() call should just return current
bool next_unget = false; bool next_unget = false;
/// the number of characters read /// the start position of the current token
std::size_t chars_read = 0; position_t position;
/// raw input token string (for error messages) /// raw input token string (for error messages)
std::vector<char> token_string {}; std::vector<char> token_string {};
@ -1329,5 +1502,5 @@ scan_number_done:
/// the decimal point /// the decimal point
const char decimal_point_char = '.'; const char decimal_point_char = '.';
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -91,7 +91,8 @@ class parser
{ {
sdp.parse_error(m_lexer.get_position(), sdp.parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::end_of_input, "value")));
} }
// in case of an error, return discarded value // in case of an error, return discarded value
@ -119,7 +120,8 @@ class parser
{ {
sdp.parse_error(m_lexer.get_position(), sdp.parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::end_of_input, "value")));
} }
// in case of an error, return discarded value // in case of an error, return discarded value
@ -154,7 +156,8 @@ class parser
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::end_of_input, "value")));
} }
return result; return result;
@ -199,22 +202,21 @@ class parser
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::value_string, "object key")));
} }
else
{
if (JSON_UNLIKELY(not sax->key(m_lexer.get_string()))) if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
{ {
return false; return false;
} }
}
// parse separator (:) // parse separator (:)
if (JSON_UNLIKELY(get_token() != token_type::name_separator)) if (JSON_UNLIKELY(get_token() != token_type::name_separator))
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::name_separator, "object separator")));
} }
// remember we are now inside an object // remember we are now inside an object
@ -328,14 +330,16 @@ class parser
// using "uninitialized" to avoid "expected" message // using "uninitialized" to avoid "expected" message
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::uninitialized, "value")));
} }
default: // the last token was unexpected default: // the last token was unexpected
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::literal_or_value, "value")));
} }
} }
} }
@ -383,7 +387,8 @@ class parser
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::end_array, "array")));
} }
} }
else // object else // object
@ -396,7 +401,8 @@ class parser
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::value_string, "object key")));
} }
else else
{ {
@ -411,7 +417,8 @@ class parser
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::name_separator, "object separator")));
} }
// parse values // parse values
@ -440,7 +447,8 @@ class parser
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object))); parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::end_object, "object")));
} }
} }
} }
@ -453,9 +461,17 @@ class parser
return (last_token = m_lexer.scan()); return (last_token = m_lexer.scan());
} }
std::string exception_message(const token_type expected) std::string exception_message(const token_type expected, const std::string& context)
{ {
std::string error_msg = "syntax error - "; std::string error_msg = "syntax error ";
if (not context.empty())
{
error_msg += "while parsing " + context + " ";
}
error_msg += "- ";
if (last_token == token_type::parse_error) if (last_token == token_type::parse_error)
{ {
error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
@ -484,5 +500,5 @@ class parser
/// whether to throw exceptions in case of errors /// whether to throw exceptions in case of errors
const bool allow_exceptions = true; const bool allow_exceptions = true;
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -0,0 +1,27 @@
#pragma once
#include <cstddef> // size_t
namespace nlohmann
{
namespace detail
{
/// struct to capture the start position of the current token
struct position_t
{
/// the total number of characters read
std::size_t chars_read_total = 0;
/// the number of characters read in the current line
std::size_t chars_read_current_line = 0;
/// the number of lines read
std::size_t lines_read = 0;
/// conversion to size_t to preserve SAX interface
constexpr operator size_t() const
{
return chars_read_total;
}
};
}
}

View file

@ -21,5 +21,5 @@ template<typename BasicJsonType> struct internal_iterator
/// generic iterator for all other types /// generic iterator for all other types
primitive_iterator_t primitive_iterator {}; primitive_iterator_t primitive_iterator {};
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -610,5 +610,5 @@ class iter_impl
/// the actual iterator of the associated instance /// the actual iterator of the associated instance
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it; internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -39,9 +39,6 @@ template<typename IteratorType> class iteration_proxy
public: public:
explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {} explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
iteration_proxy_internal(const iteration_proxy_internal&) = default;
iteration_proxy_internal& operator=(const iteration_proxy_internal&) = default;
/// dereference operator (needed for range-based for) /// dereference operator (needed for range-based for)
iteration_proxy_internal& operator*() iteration_proxy_internal& operator*()
{ {
@ -124,5 +121,5 @@ template<typename IteratorType> class iteration_proxy
return iteration_proxy_internal(container.end()); return iteration_proxy_internal(container.end());
} }
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -115,5 +115,5 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
return it.operator * (); return it.operator * ();
} }
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -116,5 +116,5 @@ class primitive_iterator_t
return *this; return *this;
} }
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -506,11 +506,11 @@ class json_pointer
std::size_t slash = reference_string.find_first_of('/', 1), std::size_t slash = reference_string.find_first_of('/', 1),
// set the beginning of the first reference token // set the beginning of the first reference token
start = 1; start = 1;
// we can stop if start == string::npos+1 = 0 // we can stop if start == 0 (if slash == std::string::npos)
start != 0; start != 0;
// set the beginning of the next reference token // set the beginning of the next reference token
// (will eventually be 0 if slash == std::string::npos) // (will eventually be 0 if slash == std::string::npos)
start = slash + 1, start = (slash == std::string::npos) ? 0 : slash + 1,
// find next slash // find next slash
slash = reference_string.find_first_of('/', start)) slash = reference_string.find_first_of('/', start))
{ {
@ -693,4 +693,4 @@ class json_pointer
/// the reference tokens /// the reference tokens
std::vector<std::string> reference_tokens; std::vector<std::string> reference_tokens;
}; };
} } // namespace nlohmann

View file

@ -3,6 +3,8 @@
#include <initializer_list> #include <initializer_list>
#include <utility> #include <utility>
#include <nlohmann/detail/meta/type_traits.hpp>
namespace nlohmann namespace nlohmann
{ {
namespace detail namespace detail
@ -25,15 +27,19 @@ class json_ref
: owned_value(init), value_ref(&owned_value), is_rvalue(true) : owned_value(init), value_ref(&owned_value), is_rvalue(true)
{} {}
template<class... Args> template <
json_ref(Args&& ... args) class... Args,
: owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true) enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
{} json_ref(Args && ... args)
: owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
is_rvalue(true) {}
// class should be movable only // class should be movable only
json_ref(json_ref&&) = default; json_ref(json_ref&&) = default;
json_ref(const json_ref&) = delete; json_ref(const json_ref&) = delete;
json_ref& operator=(const json_ref&) = delete; json_ref& operator=(const json_ref&) = delete;
json_ref& operator=(json_ref&&) = delete;
~json_ref() = default;
value_type moved_or_copied() const value_type moved_or_copied() const
{ {
@ -59,5 +65,5 @@ class json_ref
value_type* value_ref = nullptr; value_type* value_ref = nullptr;
const bool is_rvalue; const bool is_rvalue;
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -10,7 +10,7 @@
#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
#endif #endif
#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
#endif #endif
#endif #endif

View file

@ -59,5 +59,5 @@ struct static_const
template<typename T> template<typename T>
constexpr T static_const<T>::value; constexpr T static_const<T>::value;
} } // namespace detail
} } // namespace nlohmann

View file

@ -52,5 +52,5 @@ using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
template <class To, template <class...> class Op, class... Args> template <class To, template <class...> class Op, class... Args>
using is_detected_convertible = using is_detected_convertible =
std::is_convertible<detected_t<Op, Args...>, To>; std::is_convertible<detected_t<Op, Args...>, To>;
} } // namespace detail
} } // namespace nlohmann

View file

@ -137,5 +137,5 @@ public:
"Missing/invalid function: bool parse_error(std::size_t, const " "Missing/invalid function: bool parse_error(std::size_t, const "
"std::string&, const exception&)"); "std::string&, const exception&)");
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -65,6 +65,9 @@ using to_json_function = decltype(T::to_json(std::declval<Args>()...));
template <typename T, typename... Args> template <typename T, typename... Args>
using from_json_function = decltype(T::from_json(std::declval<Args>()...)); using from_json_function = decltype(T::from_json(std::declval<Args>()...));
template <typename T, typename U>
using get_template_function = decltype(std::declval<T>().template get<U>());
/////////////////// ///////////////////
// is_ functions // // is_ functions //
/////////////////// ///////////////////
@ -185,8 +188,12 @@ struct is_compatible_integer_type
CompatibleNumberIntegerType> {}; CompatibleNumberIntegerType> {};
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
template<typename BasicJsonType, typename T> template <typename BasicJsonType, typename T, typename = void>
struct has_from_json struct has_from_json : std::false_type {};
template <typename BasicJsonType, typename T>
struct has_from_json<BasicJsonType, T,
enable_if_t<not is_basic_json<T>::value>>
{ {
using serializer = typename BasicJsonType::template json_serializer<T, void>; using serializer = typename BasicJsonType::template json_serializer<T, void>;
@ -197,8 +204,11 @@ struct has_from_json
// This trait checks if JSONSerializer<T>::from_json(json const&) exists // This trait checks if JSONSerializer<T>::from_json(json const&) exists
// this overload is used for non-default-constructible user-defined-types // this overload is used for non-default-constructible user-defined-types
template <typename BasicJsonType, typename T, typename = void>
struct has_non_default_from_json : std::false_type {};
template<typename BasicJsonType, typename T> template<typename BasicJsonType, typename T>
struct has_non_default_from_json struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
{ {
using serializer = typename BasicJsonType::template json_serializer<T, void>; using serializer = typename BasicJsonType::template json_serializer<T, void>;
@ -208,8 +218,12 @@ struct has_non_default_from_json
}; };
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
template<typename BasicJsonType, typename T> // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
struct has_to_json template <typename BasicJsonType, typename T, typename = void>
struct has_to_json : std::false_type {};
template <typename BasicJsonType, typename T>
struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
{ {
using serializer = typename BasicJsonType::template json_serializer<T, void>; using serializer = typename BasicJsonType::template json_serializer<T, void>;
@ -233,5 +247,5 @@ struct is_compatible_type_impl <
template <typename BasicJsonType, typename CompatibleType> 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> {};
} } // namespace detail
} } // namespace nlohmann

View file

@ -9,5 +9,5 @@ template <typename ...Ts> struct make_void
using type = void; using type = void;
}; };
template <typename ...Ts> using void_t = typename make_void<Ts...>::type; template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
} } // namespace detail
} } // namespace nlohmann

View file

@ -540,9 +540,11 @@ class binary_writer
case value_t::boolean: case value_t::boolean:
{ {
if (add_prefix) if (add_prefix)
{
oa->write_character(j.m_value.boolean oa->write_character(j.m_value.boolean
? static_cast<CharType>('T') ? static_cast<CharType>('T')
: static_cast<CharType>('F')); : static_cast<CharType>('F'));
}
break; break;
} }
@ -1075,7 +1077,7 @@ class binary_writer
} }
else else
{ {
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
} }
} }
@ -1129,7 +1131,7 @@ class binary_writer
// LCOV_EXCL_START // LCOV_EXCL_START
else else
{ {
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
} }
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }
@ -1159,23 +1161,21 @@ class binary_writer
{ {
return 'i'; return 'i';
} }
else if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)()) if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
{ {
return 'U'; return 'U';
} }
else if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)()) if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
{ {
return 'I'; return 'I';
} }
else if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)()) if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
{ {
return 'l'; return 'l';
} }
else // no check and assume int64_t (see note above) // no check and assume int64_t (see note above)
{
return 'L'; return 'L';
} }
}
case value_t::number_unsigned: case value_t::number_unsigned:
{ {
@ -1183,23 +1183,21 @@ class binary_writer
{ {
return 'i'; return 'i';
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
{ {
return 'U'; return 'U';
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)()) if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
{ {
return 'I'; return 'I';
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)()) if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
{ {
return 'l'; return 'l';
} }
else // no check and assume int64_t (see note above) // no check and assume int64_t (see note above)
{
return 'L'; return 'L';
} }
}
case value_t::number_float: case value_t::number_float:
return get_ubjson_float_prefix(j.m_value.number_float); return get_ubjson_float_prefix(j.m_value.number_float);
@ -1218,32 +1216,32 @@ class binary_writer
} }
} }
static constexpr CharType get_cbor_float_prefix(float) static constexpr CharType get_cbor_float_prefix(float /*unused*/)
{ {
return static_cast<CharType>(0xFA); // Single-Precision Float return static_cast<CharType>(0xFA); // Single-Precision Float
} }
static constexpr CharType get_cbor_float_prefix(double) static constexpr CharType get_cbor_float_prefix(double /*unused*/)
{ {
return static_cast<CharType>(0xFB); // Double-Precision Float return static_cast<CharType>(0xFB); // Double-Precision Float
} }
static constexpr CharType get_msgpack_float_prefix(float) static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
{ {
return static_cast<CharType>(0xCA); // float 32 return static_cast<CharType>(0xCA); // float 32
} }
static constexpr CharType get_msgpack_float_prefix(double) static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
{ {
return static_cast<CharType>(0xCB); // float 64 return static_cast<CharType>(0xCB); // float 64
} }
static constexpr CharType get_ubjson_float_prefix(float) static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
{ {
return 'd'; // float 32 return 'd'; // float 32
} }
static constexpr CharType get_ubjson_float_prefix(double) static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
{ {
return 'D'; // float 64 return 'D'; // float 64
} }
@ -1255,5 +1253,5 @@ class binary_writer
/// the output /// the output
output_adapter_t<CharType> oa = nullptr; output_adapter_t<CharType> oa = nullptr;
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -109,5 +109,5 @@ class output_adapter
private: private:
output_adapter_t<CharType> oa = nullptr; output_adapter_t<CharType> oa = nullptr;
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -53,6 +53,9 @@ class serializer
// delete because of pointer members // delete because of pointer members
serializer(const serializer&) = delete; serializer(const serializer&) = delete;
serializer& operator=(const serializer&) = delete; serializer& operator=(const serializer&) = delete;
serializer(serializer&&) = delete;
serializer& operator=(serializer&&) = delete;
~serializer() = default;
/*! /*!
@brief internal implementation of the serialization function @brief internal implementation of the serialization function
@ -442,7 +445,7 @@ class serializer
return; return;
} }
const bool is_negative = (x <= 0) and (x != 0); // see issue #755 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not (x >= 0); // see issue #755
std::size_t i = 0; std::size_t i = 0;
while (x != 0) while (x != 0)
@ -627,5 +630,5 @@ class serializer
/// the indentation string /// the indentation string
string_t indent_string; string_t indent_string;
}; };
} } // namespace detail
} } // namespace nlohmann

View file

@ -72,5 +72,5 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
const auto r_index = static_cast<std::size_t>(rhs); const auto r_index = static_cast<std::size_t>(rhs);
return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index]; return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
} }
} } // namespace detail
} } // namespace nlohmann

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ __| | __| | | | JSON for Modern C++
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -31,7 +31,7 @@ SOFTWARE.
#define NLOHMANN_JSON_HPP #define NLOHMANN_JSON_HPP
#define NLOHMANN_JSON_VERSION_MAJOR 3 #define NLOHMANN_JSON_VERSION_MAJOR 3
#define NLOHMANN_JSON_VERSION_MINOR 2 #define NLOHMANN_JSON_VERSION_MINOR 3
#define NLOHMANN_JSON_VERSION_PATCH 0 #define NLOHMANN_JSON_VERSION_PATCH 0
#include <algorithm> // all_of, find, for_each #include <algorithm> // all_of, find, for_each
@ -947,7 +947,7 @@ class basic_json
object = nullptr; // silence warning, see #821 object = nullptr; // silence warning, see #821
if (JSON_UNLIKELY(t == value_t::null)) if (JSON_UNLIKELY(t == value_t::null))
{ {
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.2.0")); // LCOV_EXCL_LINE JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.3.0")); // LCOV_EXCL_LINE
} }
break; break;
} }
@ -1866,7 +1866,7 @@ class basic_json
@since version 1.0.0 @since version 1.0.0
*/ */
reference& operator=(basic_json other) noexcept ( basic_json& operator=(basic_json other) noexcept (
std::is_nothrow_move_constructible<value_t>::value and std::is_nothrow_move_constructible<value_t>::value and
std::is_nothrow_move_assignable<value_t>::value and std::is_nothrow_move_assignable<value_t>::value and
std::is_nothrow_move_constructible<json_value>::value and std::is_nothrow_move_constructible<json_value>::value and
@ -2624,51 +2624,50 @@ class basic_json
} }
/*! /*!
@brief get a pointer value (explicit) @brief get a value (explicit)
Explicit pointer access to the internally stored JSON value. No copies are Explicit type conversion between the JSON value and a compatible value.
made. The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
`from_json()` method.
@warning The pointer becomes invalid if the underlying JSON object The function is equivalent to executing
changes. @code {.cpp}
ValueType v;
JSONSerializer<ValueType>::from_json(*this, v);
@endcode
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref This overloads is chosen if:
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, - @a ValueType is not @ref basic_json,
@ref number_unsigned_t, or @ref number_float_t. - @ref json_serializer<ValueType> has a `from_json()` method of the form
`void from_json(const basic_json&, ValueType&)`, and
@return pointer to the internally stored JSON value if the requested @tparam ValueType the input parameter type.
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@complexity Constant. @return the input parameter, allowing chaining calls.
@liveexample{The example below shows how pointers to internal values of a @throw what @ref json_serializer<ValueType> `from_json()` method throws
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
match.,get__PointerType}
@sa @ref get_ptr() for explicit pointer-member access @liveexample{The example below shows several conversions from JSON values
to other types. There a few things to note: (1) Floating-point numbers can
be converted to integers\, (2) A JSON array can be converted to a standard
`std::vector<short>`\, (3) A JSON object can be converted to C++
associative containers such as `std::unordered_map<std::string\,
json>`.,get_to}
@since version 1.0.0 @since version 3.3.0
*/ */
template<typename PointerType, typename std::enable_if< template<typename ValueType,
std::is_pointer<PointerType>::value, int>::type = 0> detail::enable_if_t <
PointerType get() noexcept not detail::is_basic_json<ValueType>::value and
detail::has_from_json<basic_json_t, ValueType>::value,
int> = 0>
ValueType & get_to(ValueType& v) const noexcept(noexcept(
JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
{ {
// delegate the call to get_ptr JSONSerializer<ValueType>::from_json(*this, v);
return get_ptr<PointerType>(); return v;
} }
/*!
@brief get a pointer value (explicit)
@copydoc get()
*/
template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0>
constexpr const PointerType get() const noexcept
{
// delegate the call to get_ptr
return get_ptr<PointerType>();
}
/*! /*!
@brief get a pointer value (implicit) @brief get a pointer value (implicit)
@ -2698,23 +2697,8 @@ class basic_json
*/ */
template<typename PointerType, typename std::enable_if< template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0> std::is_pointer<PointerType>::value, int>::type = 0>
PointerType get_ptr() noexcept auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
{ {
// get the type of the PointerType (remove pointer and const)
using pointee_t = typename std::remove_const<typename
std::remove_pointer<typename
std::remove_const<PointerType>::type>::type>::type;
// make sure the type matches the allowed types
static_assert(
std::is_same<object_t, pointee_t>::value
or std::is_same<array_t, pointee_t>::value
or std::is_same<string_t, pointee_t>::value
or std::is_same<boolean_t, pointee_t>::value
or std::is_same<number_integer_t, pointee_t>::value
or std::is_same<number_unsigned_t, pointee_t>::value
or std::is_same<number_float_t, pointee_t>::value
, "incompatible pointer type");
// delegate the call to get_impl_ptr<>() // delegate the call to get_impl_ptr<>()
return get_impl_ptr(static_cast<PointerType>(nullptr)); return get_impl_ptr(static_cast<PointerType>(nullptr));
} }
@ -2726,27 +2710,59 @@ class basic_json
template<typename PointerType, typename std::enable_if< template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value and std::is_pointer<PointerType>::value and
std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0> std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
constexpr const PointerType get_ptr() const noexcept constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
{ {
// get the type of the PointerType (remove pointer and const)
using pointee_t = typename std::remove_const<typename
std::remove_pointer<typename
std::remove_const<PointerType>::type>::type>::type;
// make sure the type matches the allowed types
static_assert(
std::is_same<object_t, pointee_t>::value
or std::is_same<array_t, pointee_t>::value
or std::is_same<string_t, pointee_t>::value
or std::is_same<boolean_t, pointee_t>::value
or std::is_same<number_integer_t, pointee_t>::value
or std::is_same<number_unsigned_t, pointee_t>::value
or std::is_same<number_float_t, pointee_t>::value
, "incompatible pointer type");
// delegate the call to get_impl_ptr<>() const // delegate the call to get_impl_ptr<>() const
return get_impl_ptr(static_cast<PointerType>(nullptr)); return get_impl_ptr(static_cast<PointerType>(nullptr));
} }
/*!
@brief get a pointer value (explicit)
Explicit pointer access to the internally stored JSON value. No copies are
made.
@warning The pointer becomes invalid if the underlying JSON object
changes.
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
@ref number_unsigned_t, or @ref number_float_t.
@return pointer to the internally stored JSON value if the requested
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@complexity Constant.
@liveexample{The example below shows how pointers to internal values of a
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
match.,get__PointerType}
@sa @ref get_ptr() for explicit pointer-member access
@since version 1.0.0
*/
template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0>
auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
{
// delegate the call to get_ptr
return get_ptr<PointerType>();
}
/*!
@brief get a pointer value (explicit)
@copydoc get()
*/
template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0>
constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
{
// delegate the call to get_ptr
return get_ptr<PointerType>();
}
/*! /*!
@brief get a reference value (implicit) @brief get a reference value (implicit)
@ -2828,12 +2844,14 @@ class basic_json
not std::is_same<ValueType, detail::json_ref<basic_json>>::value and not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
not std::is_same<ValueType, typename string_t::value_type>::value and not std::is_same<ValueType, typename string_t::value_type>::value and
not detail::is_basic_json<ValueType>::value not detail::is_basic_json<ValueType>::value
#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
#if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914 #if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
and not std::is_same<ValueType, typename std::string_view>::value and not std::is_same<ValueType, typename std::string_view>::value
#endif #endif
#endif #endif
and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
, int >::type = 0 > , int >::type = 0 >
operator ValueType() const operator ValueType() const
{ {
@ -3097,7 +3115,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name()))); JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
} }
/*! /*!
@ -3127,7 +3145,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name()))); JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
} }
/*! /*!
@ -3173,7 +3191,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name()))); JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
} }
/*! /*!
@ -3215,7 +3233,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name()))); JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
} }
/*! /*!
@ -3262,7 +3280,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name()))); JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
} }
/*! /*!
@ -3305,7 +3323,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name()))); JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
} }
/*! /*!
@ -4943,6 +4961,26 @@ class basic_json
return {it, res.second}; return {it, res.second};
} }
/// Helper for insertion of an iterator
/// @note: This uses std::distance to support GCC 4.8,
/// see https://github.com/nlohmann/json/pull/1257
template<typename... Args>
iterator insert_iterator(const_iterator pos, Args&& ... args)
{
iterator result(this);
assert(m_value.array != nullptr);
auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
result.m_it.array_iterator = m_value.array->begin() + insert_pos;
// This could have been written as:
// result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
// but the return value of insert is missing in GCC 4.8, so it is written this way instead.
return result;
}
/*! /*!
@brief inserts element @brief inserts element
@ -4977,9 +5015,7 @@ class basic_json
} }
// insert to array and return iterator // insert to array and return iterator
iterator result(this); return insert_iterator(pos, val);
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
return result;
} }
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
@ -5030,9 +5066,7 @@ class basic_json
} }
// insert to array and return iterator // insert to array and return iterator
iterator result(this); return insert_iterator(pos, cnt, val);
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
return result;
} }
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
@ -5094,12 +5128,7 @@ class basic_json
} }
// insert to array and return iterator // insert to array and return iterator
iterator result(this); return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
result.m_it.array_iterator = m_value.array->insert(
pos.m_it.array_iterator,
first.m_it.array_iterator,
last.m_it.array_iterator);
return result;
} }
/*! /*!
@ -5141,9 +5170,7 @@ class basic_json
} }
// insert to array and return iterator // insert to array and return iterator
iterator result(this); return insert_iterator(pos, ilist.begin(), ilist.end());
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
return result;
} }
/*! /*!
@ -5972,6 +5999,8 @@ class basic_json
@param[in] cb a parser callback function of type @ref parser_callback_t @param[in] cb a parser callback function of type @ref parser_callback_t
which is used to control the deserialization by filtering unwanted values which is used to control the deserialization by filtering unwanted values
(optional) (optional)
@param[in] allow_exceptions whether to throw exceptions in case of a
parse error (optional, true by default)
@return result of the deserialization @return result of the deserialization
@ -6367,7 +6396,7 @@ class basic_json
vector in CBOR format.,to_cbor} vector in CBOR format.,to_cbor}
@sa http://cbor.io @sa http://cbor.io
@sa @ref from_cbor(detail::input_adapter, const bool strict) for the @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
analogous deserialization analogous deserialization
@sa @ref to_msgpack(const basic_json&) for the related MessagePack format @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
@ -6464,8 +6493,7 @@ class basic_json
vector in MessagePack format.,to_msgpack} vector in MessagePack format.,to_msgpack}
@sa http://msgpack.org @sa http://msgpack.org
@sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the @sa @ref from_msgpack for the analogous deserialization
analogous deserialization
@sa @ref to_cbor(const basic_json& for the related CBOR format @sa @ref to_cbor(const basic_json& for the related CBOR format
@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
related UBJSON format related UBJSON format
@ -6562,7 +6590,7 @@ class basic_json
vector in UBJSON format.,to_ubjson} vector in UBJSON format.,to_ubjson}
@sa http://ubjson.org @sa http://ubjson.org
@sa @ref from_ubjson(detail::input_adapter, const bool strict) for the @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
analogous deserialization analogous deserialization
@sa @ref to_cbor(const basic_json& for the related CBOR format @sa @ref to_cbor(const basic_json& for the related CBOR format
@sa @ref to_msgpack(const basic_json&) for the related MessagePack format @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
@ -6758,14 +6786,14 @@ class basic_json
@sa http://cbor.io @sa http://cbor.io
@sa @ref to_cbor(const basic_json&) for the analogous serialization @sa @ref to_cbor(const basic_json&) for the analogous serialization
@sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for the @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
related MessagePack format related MessagePack format
@sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for the @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
related UBJSON format related UBJSON format
@since version 2.0.9; parameter @a start_index since 2.1.1; changed to @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
consume input adapters, removed start_index parameter, and added consume input adapters, removed start_index parameter, and added
@a strict parameter since 3.0.0; added @allow_exceptions parameter @a strict parameter since 3.0.0; added @a allow_exceptions parameter
since 3.2.0 since 3.2.0
*/ */
static basic_json from_cbor(detail::input_adapter&& i, static basic_json from_cbor(detail::input_adapter&& i,
@ -6779,7 +6807,7 @@ class basic_json
} }
/*! /*!
@copydoc from_cbor(detail::input_adapter, const bool, const bool) @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
*/ */
template<typename A1, typename A2, template<typename A1, typename A2,
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0> detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
@ -6861,16 +6889,16 @@ class basic_json
@sa http://msgpack.org @sa http://msgpack.org
@sa @ref to_msgpack(const basic_json&) for the analogous serialization @sa @ref to_msgpack(const basic_json&) for the analogous serialization
@sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
related CBOR format related CBOR format
@sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
the related UBJSON format the related UBJSON format
@sa @ref from_bson(detail::input_adapter, const bool, const bool) for @sa @ref from_bson(detail::input_adapter, const bool, const bool) for
the related BSON format the related BSON format
@since version 2.0.9; parameter @a start_index since 2.1.1; changed to @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
consume input adapters, removed start_index parameter, and added consume input adapters, removed start_index parameter, and added
@a strict parameter since 3.0.0; added @allow_exceptions parameter @a strict parameter since 3.0.0; added @a allow_exceptions parameter
since 3.2.0 since 3.2.0
*/ */
static basic_json from_msgpack(detail::input_adapter&& i, static basic_json from_msgpack(detail::input_adapter&& i,
@ -6884,7 +6912,7 @@ class basic_json
} }
/*! /*!
@copydoc from_msgpack(detail::input_adapter, const bool, const bool) @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
*/ */
template<typename A1, typename A2, template<typename A1, typename A2,
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0> detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
@ -6948,14 +6976,14 @@ class basic_json
@sa http://ubjson.org @sa http://ubjson.org
@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
analogous serialization analogous serialization
@sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
related CBOR format related CBOR format
@sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
the related MessagePack format the related MessagePack format
@sa @ref from_bson(detail::input_adapter, const bool, const bool) for @sa @ref from_bson(detail::input_adapter, const bool, const bool) for
the related BSON format the related BSON format
@since version 3.1.0; added @allow_exceptions parameter since 3.2.0 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
*/ */
static basic_json from_ubjson(detail::input_adapter&& i, static basic_json from_ubjson(detail::input_adapter&& i,
const bool strict = true, const bool strict = true,
@ -6968,7 +6996,7 @@ class basic_json
} }
/*! /*!
@copydoc from_ubjson(detail::input_adapter, const bool, const bool) @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
*/ */
template<typename A1, typename A2, template<typename A1, typename A2,
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0> detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
@ -7432,12 +7460,10 @@ class basic_json
// avoid undefined behavior // avoid undefined behavior
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
} }
else
{
// default case: insert add offset // default case: insert add offset
parent.insert(parent.begin() + static_cast<difference_type>(idx), val); parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
} }
}
break; break;
} }
@ -7861,19 +7887,6 @@ class basic_json
// specialization of std::swap, and std::hash // specialization of std::swap, and std::hash
namespace std namespace std
{ {
/*!
@brief exchanges the values of two JSON objects
@since version 1.0.0
*/
template<>
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
is_nothrow_move_constructible<nlohmann::json>::value and
is_nothrow_move_assignable<nlohmann::json>::value
)
{
j1.swap(j2);
}
/// hash value for JSON objects /// hash value for JSON objects
template<> template<>
@ -7909,6 +7922,20 @@ struct less< ::nlohmann::detail::value_t>
} }
}; };
/*!
@brief exchanges the values of two JSON objects
@since version 1.0.0
*/
template<>
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
is_nothrow_move_constructible<nlohmann::json>::value and
is_nothrow_move_assignable<nlohmann::json>::value
)
{
j1.swap(j2);
}
} // namespace std } // namespace std
/*! /*!

View file

@ -59,6 +59,6 @@ uses the standard template types.
@since version 1.0.0 @since version 1.0.0
*/ */
using json = basic_json<>; using json = basic_json<>;
} } // namespace nlohmann
#endif #endif

View file

@ -1,4 +1,8 @@
project('nlohmann_json', 'cpp') project('nlohmann_json',
'cpp',
version : '3.3.0',
license : 'MIT',
)
nlohmann_json_dep = declare_dependency( nlohmann_json_dep = declare_dependency(
include_directories: include_directories('single_include') include_directories: include_directories('single_include')

File diff suppressed because it is too large Load diff

View file

@ -96,22 +96,21 @@ foreach(file ${files})
string(REGEX REPLACE "unit-([^$]+)" "test-\\1" testcase ${file_basename}) string(REGEX REPLACE "unit-([^$]+)" "test-\\1" testcase ${file_basename})
add_executable(${testcase} $<TARGET_OBJECTS:catch_main> ${file}) add_executable(${testcase} $<TARGET_OBJECTS:catch_main> ${file})
set_target_properties(${testcase} PROPERTIES target_compile_definitions(${testcase} PRIVATE
COMPILE_DEFINITIONS "$<$<CXX_COMPILER_ID:MSVC>:_SCL_SECURE_NO_WARNINGS>" CATCH_CONFIG_FAST_COMPILE
COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>" $<$<CXX_COMPILER_ID:MSVC>:_SCL_SECURE_NO_WARNINGS>
)
target_compile_options(${testcase} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
)
target_include_directories(${testcase} PRIVATE
thirdparty/catch
thirdparty/fifo_map
) )
target_compile_definitions(${testcase} PRIVATE CATCH_CONFIG_FAST_COMPILE)
target_compile_features(${testcase} PRIVATE cxx_std_11)
target_include_directories(${testcase} PRIVATE "thirdparty/catch")
target_include_directories(${testcase} PRIVATE "thirdparty/fifo_map")
target_include_directories(${testcase} PRIVATE ${NLOHMANN_JSON_INCLUDE_BUILD_DIR})
target_link_libraries(${testcase} ${NLOHMANN_JSON_TARGET_NAME}) target_link_libraries(${testcase} ${NLOHMANN_JSON_TARGET_NAME})
if(NOT MSVC)
set_target_properties(${testcase} PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wno-float-equal")
endif()
add_test(NAME "${testcase}_default" add_test(NAME "${testcase}_default"
COMMAND ${testcase} ${CATCH_TEST_FILTER} COMMAND ${testcase} ${CATCH_TEST_FILTER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
@ -131,5 +130,11 @@ foreach(file ${files})
) )
set_tests_properties("${testcase}_valgrind" PROPERTIES LABELS "valgrind") set_tests_properties("${testcase}_valgrind" PROPERTIES LABELS "valgrind")
endif() endif()
endforeach() endforeach()
#############################################################################
# Test the generated build configs
#############################################################################
add_subdirectory(cmake_import)
add_subdirectory(cmake_import_minver)
add_subdirectory(cmake_add_subdirectory)

View file

@ -0,0 +1,15 @@
add_test(NAME cmake_add_subdirectory_configure
COMMAND ${CMAKE_COMMAND}
-G "${CMAKE_GENERATOR}"
-Dnlohmann_json_source=${PROJECT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/project
)
add_test(NAME cmake_add_subdirectory_build
COMMAND ${CMAKE_COMMAND} --build .
)
set_tests_properties(cmake_add_subdirectory_configure PROPERTIES
FIXTURES_SETUP cmake_add_subdirectory
)
set_tests_properties(cmake_add_subdirectory_build PROPERTIES
FIXTURES_REQUIRED cmake_add_subdirectory
)

View file

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.8)
project(DummyImport CXX)
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(${nlohmann_json_source}
${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json)
add_executable(with_namespace_target main.cpp)
target_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)
add_executable(without_namespace_target main.cpp)
target_link_libraries(without_namespace_target nlohmann_json)

View file

@ -0,0 +1,8 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
{
nlohmann::json j;
return 0;
}

View file

@ -0,0 +1,15 @@
add_test(NAME cmake_import_configure
COMMAND ${CMAKE_COMMAND}
-G "${CMAKE_GENERATOR}"
-Dnlohmann_json_DIR=${PROJECT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/project
)
add_test(NAME cmake_import_build
COMMAND ${CMAKE_COMMAND} --build .
)
set_tests_properties(cmake_import_configure PROPERTIES
FIXTURES_SETUP cmake_import
)
set_tests_properties(cmake_import_build PROPERTIES
FIXTURES_REQUIRED cmake_import
)

View file

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.8)
project(DummyImport CXX)
find_package(nlohmann_json REQUIRED)
add_executable(with_namespace_target main.cpp)
target_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)
add_executable(without_namespace_target main.cpp)
target_link_libraries(without_namespace_target nlohmann_json)

View file

@ -0,0 +1,8 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
{
nlohmann::json j;
return 0;
}

View file

@ -0,0 +1,15 @@
add_test(NAME cmake_import_minver_configure
COMMAND ${CMAKE_COMMAND}
-G "${CMAKE_GENERATOR}"
-Dnlohmann_json_DIR=${PROJECT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/project
)
add_test(NAME cmake_import_minver_build
COMMAND ${CMAKE_COMMAND} --build .
)
set_tests_properties(cmake_import_minver_configure PROPERTIES
FIXTURES_SETUP cmake_import_minver
)
set_tests_properties(cmake_import_minver_build PROPERTIES
FIXTURES_REQUIRED cmake_import_minver
)

View file

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.8)
project(DummyImportMinVer CXX)
find_package(nlohmann_json 3.2.0 REQUIRED)
add_executable(with_namespace_target main.cpp)
target_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)

View file

@ -0,0 +1,8 @@
#include <nlohmann/json.hpp>
int main(int argc, char **argv)
{
nlohmann::json j;
return 0;
}

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (fuzz test support) __| | __| | | | JSON for Modern C++ (fuzz test support)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (fuzz test support) __| | __| | | | JSON for Modern C++ (fuzz test support)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
This file implements a parser test suitable for fuzz testing. Given a byte This file implements a parser test suitable for fuzz testing. Given a byte

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (fuzz test support) __| | __| | | | JSON for Modern C++ (fuzz test support)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
This file implements a parser test suitable for fuzz testing. Given a byte This file implements a parser test suitable for fuzz testing. Given a byte

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (fuzz test support) __| | __| | | | JSON for Modern C++ (fuzz test support)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
This file implements a parser test suitable for fuzz testing. Given a byte This file implements a parser test suitable for fuzz testing. Given a byte

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (fuzz test support) __| | __| | | | JSON for Modern C++ (fuzz test support)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
This file implements a parser test suitable for fuzz testing. Given a byte This file implements a parser test suitable for fuzz testing. Given a byte

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -679,7 +679,8 @@ TEST_CASE("Incomplete BSON INPUT")
}; };
CHECK_THROWS_WITH(json::from_bson(incomplete_bson), CHECK_THROWS_WITH(json::from_bson(incomplete_bson),
"[json.exception.parse_error.110] parse error at 9: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing BSON cstring: unexpected end of input");
CHECK(json::from_bson(incomplete_bson, true, false).is_discarded()); CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());
SaxCountdown scp(0); SaxCountdown scp(0);
@ -695,7 +696,7 @@ TEST_CASE("Incomplete BSON INPUT 2")
}; };
CHECK_THROWS_WITH(json::from_bson(incomplete_bson), CHECK_THROWS_WITH(json::from_bson(incomplete_bson),
"[json.exception.parse_error.110] parse error at 6: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing BSON cstring: unexpected end of input");
CHECK(json::from_bson(incomplete_bson, true, false).is_discarded()); CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());
SaxCountdown scp(0); SaxCountdown scp(0);
@ -717,7 +718,7 @@ TEST_CASE("Incomplete BSON INPUT 3")
// missing input data... // missing input data...
}; };
CHECK_THROWS_WITH(json::from_bson(incomplete_bson), CHECK_THROWS_WITH(json::from_bson(incomplete_bson),
"[json.exception.parse_error.110] parse error at 28: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 28: syntax error while parsing BSON element list: unexpected end of input");
CHECK(json::from_bson(incomplete_bson, true, false).is_discarded()); CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());
SaxCountdown scp(1); SaxCountdown scp(1);
@ -734,7 +735,7 @@ TEST_CASE("Incomplete BSON INPUT 4")
}; };
CHECK_THROWS_WITH(json::from_bson(incomplete_bson), CHECK_THROWS_WITH(json::from_bson(incomplete_bson),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing BSON number: unexpected end of input");
CHECK(json::from_bson(incomplete_bson, true, false).is_discarded()); CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());
SaxCountdown scp(0); SaxCountdown scp(0);
@ -753,7 +754,7 @@ TEST_CASE("Unsupported BSON input")
}; };
CHECK_THROWS_WITH(json::from_bson(bson), CHECK_THROWS_WITH(json::from_bson(bson),
"[json.exception.parse_error.114] parse error at 5: Unsupported BSON record type 0xFF"); "[json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF");
CHECK(json::from_bson(bson, true, false).is_discarded()); CHECK(json::from_bson(bson, true, false).is_discarded());
SaxCountdown scp(0); SaxCountdown scp(0);

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -831,14 +831,14 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf9})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf9})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf9})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf9})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK(json::from_cbor(std::vector<uint8_t>({0xf9}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0xf9}), true, false).is_discarded());
} }
SECTION("only one byte follows") SECTION("only one byte follows")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
CHECK(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c}), true, false).is_discarded());
} }
} }
@ -1314,7 +1314,7 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>()), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>()), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>()), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>()),
"[json.exception.parse_error.110] parse error at 1: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input");
CHECK(json::from_cbor(std::vector<uint8_t>(), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>(), true, false).is_discarded());
} }
@ -1346,53 +1346,53 @@ TEST_CASE("CBOR")
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0X61})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0X61})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x18})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x18})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 6: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 7: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 8: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 9: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x62})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x62})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x62, 0x60})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x62, 0x60})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x7F})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x7F})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x7F, 0x60})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x7F, 0x60})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x82, 0x01})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x82, 0x01})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x9F, 0x01})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x9F, 0x01})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5})),
"[json.exception.parse_error.110] parse error at 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0x61})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0x61})),
"[json.exception.parse_error.110] parse error at 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61})),
"[json.exception.parse_error.110] parse error at 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input");
CHECK(json::from_cbor(std::vector<uint8_t>({0x18}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0x18}), true, false).is_discarded());
CHECK(json::from_cbor(std::vector<uint8_t>({0x19}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0x19}), true, false).is_discarded());
@ -1426,12 +1426,12 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1c})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1c})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1c})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1c})),
"[json.exception.parse_error.112] parse error at 1: error reading CBOR; last byte: 0x1C"); "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C");
CHECK(json::from_cbor(std::vector<uint8_t>({0x1c}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0x1c}), true, false).is_discarded());
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf8})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf8})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf8})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf8})),
"[json.exception.parse_error.112] parse error at 1: error reading CBOR; last byte: 0xF8"); "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xF8");
CHECK(json::from_cbor(std::vector<uint8_t>({0xf8}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0xf8}), true, false).is_discarded());
} }
@ -1491,7 +1491,7 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})),
"[json.exception.parse_error.113] parse error at 2: expected a CBOR string; last byte: 0xFF"); "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF");
CHECK(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01}), true, false).is_discarded());
} }
@ -1509,7 +1509,7 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec), CHECK_THROWS_WITH(json::from_cbor(vec),
"[json.exception.parse_error.110] parse error at 2: expected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: expected end of input; last byte: 0xF6");
CHECK(json::from_cbor(vec, true, false).is_discarded()); CHECK(json::from_cbor(vec, true, false).is_discarded());
} }
} }

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -313,18 +313,18 @@ TEST_CASE("parser class")
// error: tab in string // error: tab in string
CHECK_THROWS_AS(parser_helper("\"\t\""), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\t\""), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("\"\t\""), CHECK_THROWS_WITH(parser_helper("\"\t\""),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0009>'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t; last read: '\"<U+0009>'");
// error: newline in string // error: newline in string
CHECK_THROWS_AS(parser_helper("\"\n\""), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\n\""), json::parse_error&);
CHECK_THROWS_AS(parser_helper("\"\r\""), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\r\""), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("\"\n\""), CHECK_THROWS_WITH(parser_helper("\"\n\""),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000A>'"); "[json.exception.parse_error.101] parse error at line 2, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"<U+000A>'");
CHECK_THROWS_WITH(parser_helper("\"\r\""), CHECK_THROWS_WITH(parser_helper("\"\r\""),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000D>'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r; last read: '\"<U+000D>'");
// error: backspace in string // error: backspace in string
CHECK_THROWS_AS(parser_helper("\"\b\""), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\b\""), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("\"\b\""), CHECK_THROWS_WITH(parser_helper("\"\b\""),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0008>'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b; last read: '\"<U+0008>'");
// improve code coverage // improve code coverage
CHECK_THROWS_AS(parser_helper("\uFF01"), json::parse_error&); CHECK_THROWS_AS(parser_helper("\uFF01"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("[-4:1,]"), json::parse_error&); CHECK_THROWS_AS(parser_helper("[-4:1,]"), json::parse_error&);
@ -361,38 +361,38 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("\"\x1d\""), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\x1d\""), json::parse_error&);
CHECK_THROWS_AS(parser_helper("\"\x1e\""), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\x1e\""), json::parse_error&);
CHECK_THROWS_AS(parser_helper("\"\x1f\""), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\x1f\""), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("\"\x00\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: missing closing quote; last read: '\"'"); CHECK_THROWS_WITH(parser_helper("\"\x00\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'");
CHECK_THROWS_WITH(parser_helper("\"\x01\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0001>'"); CHECK_THROWS_WITH(parser_helper("\"\x01\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0001 (SOH) must be escaped to \\u0001; last read: '\"<U+0001>'");
CHECK_THROWS_WITH(parser_helper("\"\x02\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0002>'"); CHECK_THROWS_WITH(parser_helper("\"\x02\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0002 (STX) must be escaped to \\u0002; last read: '\"<U+0002>'");
CHECK_THROWS_WITH(parser_helper("\"\x03\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0003>'"); CHECK_THROWS_WITH(parser_helper("\"\x03\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0003 (ETX) must be escaped to \\u0003; last read: '\"<U+0003>'");
CHECK_THROWS_WITH(parser_helper("\"\x04\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0004>'"); CHECK_THROWS_WITH(parser_helper("\"\x04\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0004 (EOT) must be escaped to \\u0004; last read: '\"<U+0004>'");
CHECK_THROWS_WITH(parser_helper("\"\x05\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0005>'"); CHECK_THROWS_WITH(parser_helper("\"\x05\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0005 (ENQ) must be escaped to \\u0005; last read: '\"<U+0005>'");
CHECK_THROWS_WITH(parser_helper("\"\x06\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0006>'"); CHECK_THROWS_WITH(parser_helper("\"\x06\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0006 (ACK) must be escaped to \\u0006; last read: '\"<U+0006>'");
CHECK_THROWS_WITH(parser_helper("\"\x07\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0007>'"); CHECK_THROWS_WITH(parser_helper("\"\x07\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0007 (BEL) must be escaped to \\u0007; last read: '\"<U+0007>'");
CHECK_THROWS_WITH(parser_helper("\"\x08\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0008>'"); CHECK_THROWS_WITH(parser_helper("\"\x08\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b; last read: '\"<U+0008>'");
CHECK_THROWS_WITH(parser_helper("\"\x09\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0009>'"); CHECK_THROWS_WITH(parser_helper("\"\x09\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t; last read: '\"<U+0009>'");
CHECK_THROWS_WITH(parser_helper("\"\x0a\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000A>'"); CHECK_THROWS_WITH(parser_helper("\"\x0a\""), "[json.exception.parse_error.101] parse error at line 2, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"<U+000A>'");
CHECK_THROWS_WITH(parser_helper("\"\x0b\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000B>'"); CHECK_THROWS_WITH(parser_helper("\"\x0b\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000B (VT) must be escaped to \\u000B; last read: '\"<U+000B>'");
CHECK_THROWS_WITH(parser_helper("\"\x0c\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000C>'"); CHECK_THROWS_WITH(parser_helper("\"\x0c\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f; last read: '\"<U+000C>'");
CHECK_THROWS_WITH(parser_helper("\"\x0d\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000D>'"); CHECK_THROWS_WITH(parser_helper("\"\x0d\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r; last read: '\"<U+000D>'");
CHECK_THROWS_WITH(parser_helper("\"\x0e\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000E>'"); CHECK_THROWS_WITH(parser_helper("\"\x0e\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000E (SO) must be escaped to \\u000E; last read: '\"<U+000E>'");
CHECK_THROWS_WITH(parser_helper("\"\x0f\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000F>'"); CHECK_THROWS_WITH(parser_helper("\"\x0f\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000F (SI) must be escaped to \\u000F; last read: '\"<U+000F>'");
CHECK_THROWS_WITH(parser_helper("\"\x10\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0010>'"); CHECK_THROWS_WITH(parser_helper("\"\x10\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0010 (DLE) must be escaped to \\u0010; last read: '\"<U+0010>'");
CHECK_THROWS_WITH(parser_helper("\"\x11\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0011>'"); CHECK_THROWS_WITH(parser_helper("\"\x11\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0011 (DC1) must be escaped to \\u0011; last read: '\"<U+0011>'");
CHECK_THROWS_WITH(parser_helper("\"\x12\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0012>'"); CHECK_THROWS_WITH(parser_helper("\"\x12\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0012 (DC2) must be escaped to \\u0012; last read: '\"<U+0012>'");
CHECK_THROWS_WITH(parser_helper("\"\x13\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0013>'"); CHECK_THROWS_WITH(parser_helper("\"\x13\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0013 (DC3) must be escaped to \\u0013; last read: '\"<U+0013>'");
CHECK_THROWS_WITH(parser_helper("\"\x14\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0014>'"); CHECK_THROWS_WITH(parser_helper("\"\x14\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0014 (DC4) must be escaped to \\u0014; last read: '\"<U+0014>'");
CHECK_THROWS_WITH(parser_helper("\"\x15\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0015>'"); CHECK_THROWS_WITH(parser_helper("\"\x15\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0015 (NAK) must be escaped to \\u0015; last read: '\"<U+0015>'");
CHECK_THROWS_WITH(parser_helper("\"\x16\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0016>'"); CHECK_THROWS_WITH(parser_helper("\"\x16\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0016 (SYN) must be escaped to \\u0016; last read: '\"<U+0016>'");
CHECK_THROWS_WITH(parser_helper("\"\x17\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0017>'"); CHECK_THROWS_WITH(parser_helper("\"\x17\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0017 (ETB) must be escaped to \\u0017; last read: '\"<U+0017>'");
CHECK_THROWS_WITH(parser_helper("\"\x18\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0018>'"); CHECK_THROWS_WITH(parser_helper("\"\x18\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0018 (CAN) must be escaped to \\u0018; last read: '\"<U+0018>'");
CHECK_THROWS_WITH(parser_helper("\"\x19\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0019>'"); CHECK_THROWS_WITH(parser_helper("\"\x19\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0019 (EM) must be escaped to \\u0019; last read: '\"<U+0019>'");
CHECK_THROWS_WITH(parser_helper("\"\x1a\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+001A>'"); CHECK_THROWS_WITH(parser_helper("\"\x1a\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001A (SUB) must be escaped to \\u001A; last read: '\"<U+001A>'");
CHECK_THROWS_WITH(parser_helper("\"\x1b\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+001B>'"); CHECK_THROWS_WITH(parser_helper("\"\x1b\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001B (ESC) must be escaped to \\u001B; last read: '\"<U+001B>'");
CHECK_THROWS_WITH(parser_helper("\"\x1c\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+001C>'"); CHECK_THROWS_WITH(parser_helper("\"\x1c\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001C (FS) must be escaped to \\u001C; last read: '\"<U+001C>'");
CHECK_THROWS_WITH(parser_helper("\"\x1d\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+001D>'"); CHECK_THROWS_WITH(parser_helper("\"\x1d\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001D (GS) must be escaped to \\u001D; last read: '\"<U+001D>'");
CHECK_THROWS_WITH(parser_helper("\"\x1e\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+001E>'"); CHECK_THROWS_WITH(parser_helper("\"\x1e\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001E (RS) must be escaped to \\u001E; last read: '\"<U+001E>'");
CHECK_THROWS_WITH(parser_helper("\"\x1f\""), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+001F>'"); CHECK_THROWS_WITH(parser_helper("\"\x1f\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001F (US) must be escaped to \\u001F; last read: '\"<U+001F>'");
SECTION("additional test for null byte") SECTION("additional test for null byte")
{ {
@ -403,7 +403,7 @@ TEST_CASE("parser class")
std::string s = "\"1\""; std::string s = "\"1\"";
s[1] = '\0'; s[1] = '\0';
CHECK_THROWS_AS(json::parse(s.begin(), s.end()), json::parse_error&); CHECK_THROWS_AS(json::parse(s.begin(), s.end()), json::parse_error&);
CHECK_THROWS_WITH(json::parse(s.begin(), s.end()), "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0000>'"); CHECK_THROWS_WITH(json::parse(s.begin(), s.end()), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0000 (NUL) must be escaped to \\u0000; last read: '\"<U+0000>'");
} }
} }
@ -603,39 +603,39 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("+0"), json::parse_error&); CHECK_THROWS_AS(parser_helper("+0"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("01"), CHECK_THROWS_WITH(parser_helper("01"),
"[json.exception.parse_error.101] parse error at 2: syntax error - unexpected number literal; expected end of input"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected number literal; expected end of input");
CHECK_THROWS_WITH(parser_helper("-01"), CHECK_THROWS_WITH(parser_helper("-01"),
"[json.exception.parse_error.101] parse error at 3: syntax error - unexpected number literal; expected end of input"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - unexpected number literal; expected end of input");
CHECK_THROWS_WITH(parser_helper("--1"), CHECK_THROWS_WITH(parser_helper("--1"),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '--'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '--'");
CHECK_THROWS_WITH(parser_helper("1."), CHECK_THROWS_WITH(parser_helper("1."),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '1.'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '1.'");
CHECK_THROWS_WITH(parser_helper("1E"), CHECK_THROWS_WITH(parser_helper("1E"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'");
CHECK_THROWS_WITH(parser_helper("1E-"), CHECK_THROWS_WITH(parser_helper("1E-"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after exponent sign; last read: '1E-'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '1E-'");
CHECK_THROWS_WITH(parser_helper("1.E1"), CHECK_THROWS_WITH(parser_helper("1.E1"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '1.E'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '1.E'");
CHECK_THROWS_WITH(parser_helper("-1E"), CHECK_THROWS_WITH(parser_helper("-1E"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '-1E'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '-1E'");
CHECK_THROWS_WITH(parser_helper("-0E#"), CHECK_THROWS_WITH(parser_helper("-0E#"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '-0E#'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '-0E#'");
CHECK_THROWS_WITH(parser_helper("-0E-#"), CHECK_THROWS_WITH(parser_helper("-0E-#"),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0E-#'"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '-0E-#'");
CHECK_THROWS_WITH(parser_helper("-0#"), CHECK_THROWS_WITH(parser_helper("-0#"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: '-0#'; expected end of input"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: '-0#'; expected end of input");
CHECK_THROWS_WITH(parser_helper("-0.0:"), CHECK_THROWS_WITH(parser_helper("-0.0:"),
"[json.exception.parse_error.101] parse error at 5: syntax error - unexpected ':'; expected end of input"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - unexpected ':'; expected end of input");
CHECK_THROWS_WITH(parser_helper("-0.0Z"), CHECK_THROWS_WITH(parser_helper("-0.0Z"),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; last read: '-0.0Z'; expected end of input"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: '-0.0Z'; expected end of input");
CHECK_THROWS_WITH(parser_helper("-0E123:"), CHECK_THROWS_WITH(parser_helper("-0E123:"),
"[json.exception.parse_error.101] parse error at 7: syntax error - unexpected ':'; expected end of input"); "[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - unexpected ':'; expected end of input");
CHECK_THROWS_WITH(parser_helper("-0e0-:"), CHECK_THROWS_WITH(parser_helper("-0e0-:"),
"[json.exception.parse_error.101] parse error at 6: syntax error - invalid number; expected digit after '-'; last read: '-:'; expected end of input"); "[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-:'; expected end of input");
CHECK_THROWS_WITH(parser_helper("-0e-:"), CHECK_THROWS_WITH(parser_helper("-0e-:"),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0e-:'"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '-0e-:'");
CHECK_THROWS_WITH(parser_helper("-0f"), CHECK_THROWS_WITH(parser_helper("-0f"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: '-0f'; expected end of input"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: '-0f'; expected end of input");
} }
} }
} }
@ -920,33 +920,33 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("1E/"), json::parse_error&); CHECK_THROWS_AS(parser_helper("1E/"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("1E:"), json::parse_error&); CHECK_THROWS_AS(parser_helper("1E:"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("0."), CHECK_THROWS_WITH(parser_helper("0."),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '0.'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '0.'");
CHECK_THROWS_WITH(parser_helper("-"), CHECK_THROWS_WITH(parser_helper("-"),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-'");
CHECK_THROWS_WITH(parser_helper("--"), CHECK_THROWS_WITH(parser_helper("--"),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '--'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '--'");
CHECK_THROWS_WITH(parser_helper("-0."), CHECK_THROWS_WITH(parser_helper("-0."),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after '.'; last read: '-0.'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected digit after '.'; last read: '-0.'");
CHECK_THROWS_WITH(parser_helper("-."), CHECK_THROWS_WITH(parser_helper("-."),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-.'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-.'");
CHECK_THROWS_WITH(parser_helper("-:"), CHECK_THROWS_WITH(parser_helper("-:"),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-:'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-:'");
CHECK_THROWS_WITH(parser_helper("0.:"), CHECK_THROWS_WITH(parser_helper("0.:"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '0.:'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '0.:'");
CHECK_THROWS_WITH(parser_helper("e."), CHECK_THROWS_WITH(parser_helper("e."),
"[json.exception.parse_error.101] parse error at 1: syntax error - invalid literal; last read: 'e'"); "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'e'");
CHECK_THROWS_WITH(parser_helper("1e."), CHECK_THROWS_WITH(parser_helper("1e."),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e.'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e.'");
CHECK_THROWS_WITH(parser_helper("1e/"), CHECK_THROWS_WITH(parser_helper("1e/"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e/'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e/'");
CHECK_THROWS_WITH(parser_helper("1e:"), CHECK_THROWS_WITH(parser_helper("1e:"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e:'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e:'");
CHECK_THROWS_WITH(parser_helper("1E."), CHECK_THROWS_WITH(parser_helper("1E."),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E.'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E.'");
CHECK_THROWS_WITH(parser_helper("1E/"), CHECK_THROWS_WITH(parser_helper("1E/"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E/'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E/'");
CHECK_THROWS_WITH(parser_helper("1E:"), CHECK_THROWS_WITH(parser_helper("1E:"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E:'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E:'");
// unexpected end of null // unexpected end of null
CHECK_THROWS_AS(parser_helper("n"), json::parse_error&); CHECK_THROWS_AS(parser_helper("n"), json::parse_error&);
@ -955,15 +955,15 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("nulk"), json::parse_error&); CHECK_THROWS_AS(parser_helper("nulk"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("nulm"), json::parse_error&); CHECK_THROWS_AS(parser_helper("nulm"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("n"), CHECK_THROWS_WITH(parser_helper("n"),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 'n'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 'n'");
CHECK_THROWS_WITH(parser_helper("nu"), CHECK_THROWS_WITH(parser_helper("nu"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'nu'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'nu'");
CHECK_THROWS_WITH(parser_helper("nul"), CHECK_THROWS_WITH(parser_helper("nul"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'nul'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nul'");
CHECK_THROWS_WITH(parser_helper("nulk"), CHECK_THROWS_WITH(parser_helper("nulk"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'nulk'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nulk'");
CHECK_THROWS_WITH(parser_helper("nulm"), CHECK_THROWS_WITH(parser_helper("nulm"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'nulm'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nulm'");
// unexpected end of true // unexpected end of true
CHECK_THROWS_AS(parser_helper("t"), json::parse_error&); CHECK_THROWS_AS(parser_helper("t"), json::parse_error&);
@ -972,15 +972,15 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("trud"), json::parse_error&); CHECK_THROWS_AS(parser_helper("trud"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("truf"), json::parse_error&); CHECK_THROWS_AS(parser_helper("truf"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("t"), CHECK_THROWS_WITH(parser_helper("t"),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 't'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 't'");
CHECK_THROWS_WITH(parser_helper("tr"), CHECK_THROWS_WITH(parser_helper("tr"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'tr'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'tr'");
CHECK_THROWS_WITH(parser_helper("tru"), CHECK_THROWS_WITH(parser_helper("tru"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'tru'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'tru'");
CHECK_THROWS_WITH(parser_helper("trud"), CHECK_THROWS_WITH(parser_helper("trud"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'trud'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'trud'");
CHECK_THROWS_WITH(parser_helper("truf"), CHECK_THROWS_WITH(parser_helper("truf"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'truf'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'truf'");
// unexpected end of false // unexpected end of false
CHECK_THROWS_AS(parser_helper("f"), json::parse_error&); CHECK_THROWS_AS(parser_helper("f"), json::parse_error&);
@ -990,17 +990,17 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("falsd"), json::parse_error&); CHECK_THROWS_AS(parser_helper("falsd"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("falsf"), json::parse_error&); CHECK_THROWS_AS(parser_helper("falsf"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("f"), CHECK_THROWS_WITH(parser_helper("f"),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 'f'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 'f'");
CHECK_THROWS_WITH(parser_helper("fa"), CHECK_THROWS_WITH(parser_helper("fa"),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'fa'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'fa'");
CHECK_THROWS_WITH(parser_helper("fal"), CHECK_THROWS_WITH(parser_helper("fal"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'fal'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'fal'");
CHECK_THROWS_WITH(parser_helper("fals"), CHECK_THROWS_WITH(parser_helper("fals"),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; last read: 'fals'"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'fals'");
CHECK_THROWS_WITH(parser_helper("falsd"), CHECK_THROWS_WITH(parser_helper("falsd"),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; last read: 'falsd'"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'falsd'");
CHECK_THROWS_WITH(parser_helper("falsf"), CHECK_THROWS_WITH(parser_helper("falsf"),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; last read: 'falsf'"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'falsf'");
// missing/unexpected end of array // missing/unexpected end of array
CHECK_THROWS_AS(parser_helper("["), json::parse_error&); CHECK_THROWS_AS(parser_helper("["), json::parse_error&);
@ -1009,15 +1009,15 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("[1,]"), json::parse_error&); CHECK_THROWS_AS(parser_helper("[1,]"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("]"), json::parse_error&); CHECK_THROWS_AS(parser_helper("]"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("["), CHECK_THROWS_WITH(parser_helper("["),
"[json.exception.parse_error.101] parse error at 2: syntax error - unexpected end of input; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal");
CHECK_THROWS_WITH(parser_helper("[1"), CHECK_THROWS_WITH(parser_helper("[1"),
"[json.exception.parse_error.101] parse error at 3: syntax error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing array - unexpected end of input; expected ']'");
CHECK_THROWS_WITH(parser_helper("[1,"), CHECK_THROWS_WITH(parser_helper("[1,"),
"[json.exception.parse_error.101] parse error at 4: syntax error - unexpected end of input; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal");
CHECK_THROWS_WITH(parser_helper("[1,]"), CHECK_THROWS_WITH(parser_helper("[1,]"),
"[json.exception.parse_error.101] parse error at 4: syntax error - unexpected ']'; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal");
CHECK_THROWS_WITH(parser_helper("]"), CHECK_THROWS_WITH(parser_helper("]"),
"[json.exception.parse_error.101] parse error at 1: syntax error - unexpected ']'; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal");
// missing/unexpected end of object // missing/unexpected end of object
CHECK_THROWS_AS(parser_helper("{"), json::parse_error&); CHECK_THROWS_AS(parser_helper("{"), json::parse_error&);
@ -1027,17 +1027,17 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("{\"foo\":1,}"), json::parse_error&); CHECK_THROWS_AS(parser_helper("{\"foo\":1,}"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("}"), json::parse_error&); CHECK_THROWS_AS(parser_helper("}"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("{"), CHECK_THROWS_WITH(parser_helper("{"),
"[json.exception.parse_error.101] parse error at 2: syntax error - unexpected end of input; expected string literal"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected end of input; expected string literal");
CHECK_THROWS_WITH(parser_helper("{\"foo\""), CHECK_THROWS_WITH(parser_helper("{\"foo\""),
"[json.exception.parse_error.101] parse error at 7: syntax error - unexpected end of input; expected ':'"); "[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing object separator - unexpected end of input; expected ':'");
CHECK_THROWS_WITH(parser_helper("{\"foo\":"), CHECK_THROWS_WITH(parser_helper("{\"foo\":"),
"[json.exception.parse_error.101] parse error at 8: syntax error - unexpected end of input; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal");
CHECK_THROWS_WITH(parser_helper("{\"foo\":}"), CHECK_THROWS_WITH(parser_helper("{\"foo\":}"),
"[json.exception.parse_error.101] parse error at 8: syntax error - unexpected '}'; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected '}'; expected '[', '{', or a literal");
CHECK_THROWS_WITH(parser_helper("{\"foo\":1,}"), CHECK_THROWS_WITH(parser_helper("{\"foo\":1,}"),
"[json.exception.parse_error.101] parse error at 10: syntax error - unexpected '}'; expected string literal"); "[json.exception.parse_error.101] parse error at line 1, column 10: syntax error while parsing object key - unexpected '}'; expected string literal");
CHECK_THROWS_WITH(parser_helper("}"), CHECK_THROWS_WITH(parser_helper("}"),
"[json.exception.parse_error.101] parse error at 1: syntax error - unexpected '}'; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected '}'; expected '[', '{', or a literal");
// missing/unexpected end of string // missing/unexpected end of string
CHECK_THROWS_AS(parser_helper("\""), json::parse_error&); CHECK_THROWS_AS(parser_helper("\""), json::parse_error&);
@ -1051,25 +1051,25 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("\"\\u01"), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\\u01"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("\"\\u012"), json::parse_error&); CHECK_THROWS_AS(parser_helper("\"\\u012"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("\""), CHECK_THROWS_WITH(parser_helper("\""),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: missing closing quote; last read: '\"'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'");
CHECK_THROWS_WITH(parser_helper("\"\\\""), CHECK_THROWS_WITH(parser_helper("\"\\\""),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: missing closing quote; last read: '\"\\\"'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: missing closing quote; last read: '\"\\\"'");
CHECK_THROWS_WITH(parser_helper("\"\\u\""), CHECK_THROWS_WITH(parser_helper("\"\\u\""),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u\"'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u\"'");
CHECK_THROWS_WITH(parser_helper("\"\\u0\""), CHECK_THROWS_WITH(parser_helper("\"\\u0\""),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0\"'"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0\"'");
CHECK_THROWS_WITH(parser_helper("\"\\u01\""), CHECK_THROWS_WITH(parser_helper("\"\\u01\""),
"[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'"); "[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'");
CHECK_THROWS_WITH(parser_helper("\"\\u012\""), CHECK_THROWS_WITH(parser_helper("\"\\u012\""),
"[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012\"'"); "[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012\"'");
CHECK_THROWS_WITH(parser_helper("\"\\u"), CHECK_THROWS_WITH(parser_helper("\"\\u"),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u'");
CHECK_THROWS_WITH(parser_helper("\"\\u0"), CHECK_THROWS_WITH(parser_helper("\"\\u0"),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0'"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0'");
CHECK_THROWS_WITH(parser_helper("\"\\u01"), CHECK_THROWS_WITH(parser_helper("\"\\u01"),
"[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01'"); "[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01'");
CHECK_THROWS_WITH(parser_helper("\"\\u012"), CHECK_THROWS_WITH(parser_helper("\"\\u012"),
"[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012'"); "[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012'");
// invalid escapes // invalid escapes
for (int c = 1; c < 128; ++c) for (int c = 1; c < 128; ++c)
@ -1106,7 +1106,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parser_helper(s.c_str()), CHECK_THROWS_WITH(parser_helper(s.c_str()),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid string: forbidden character after backslash; last read: '\"\\" + std::string(1, static_cast<char>(c)) + "'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid string: forbidden character after backslash; last read: '\"\\" + std::string(1, static_cast<char>(c)) + "'");
} }
break; break;
} }
@ -1182,7 +1182,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parser_helper(s1.c_str()), CHECK_THROWS_WITH(parser_helper(s1.c_str()),
"[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s1.substr(0, 7) + "'"); "[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s1.substr(0, 7) + "'");
} }
CAPTURE(s2); CAPTURE(s2);
@ -1191,7 +1191,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parser_helper(s2.c_str()), CHECK_THROWS_WITH(parser_helper(s2.c_str()),
"[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s2.substr(0, 6) + "'"); "[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s2.substr(0, 6) + "'");
} }
CAPTURE(s3); CAPTURE(s3);
@ -1200,7 +1200,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parser_helper(s3.c_str()), CHECK_THROWS_WITH(parser_helper(s3.c_str()),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s3.substr(0, 5) + "'"); "[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s3.substr(0, 5) + "'");
} }
CAPTURE(s4); CAPTURE(s4);
@ -1209,7 +1209,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parser_helper(s4.c_str()), CHECK_THROWS_WITH(parser_helper(s4.c_str()),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s4.substr(0, 4) + "'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s4.substr(0, 4) + "'");
} }
} }
} }
@ -1218,17 +1218,17 @@ TEST_CASE("parser class")
// missing part of a surrogate pair // missing part of a surrogate pair
CHECK_THROWS_AS(json::parse("\"\\uD80C\""), json::parse_error&); CHECK_THROWS_AS(json::parse("\"\\uD80C\""), json::parse_error&);
CHECK_THROWS_WITH(json::parse("\"\\uD80C\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\""),
"[json.exception.parse_error.101] parse error at 8: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\"'"); "[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\"'");
// invalid surrogate pair // invalid surrogate pair
CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), json::parse_error&); CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), json::parse_error&);
CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), json::parse_error&); CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), json::parse_error&);
CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), json::parse_error&); CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), json::parse_error&);
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""),
"[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uD80C'"); "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uD80C'");
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""),
"[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\u0000'"); "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\u0000'");
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""),
"[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uFFFF'"); "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uFFFF'");
} }
SECTION("parse errors (accept)") SECTION("parse errors (accept)")
@ -1292,6 +1292,9 @@ TEST_CASE("parser class")
CHECK(accept_helper("\"\\u01") == false); CHECK(accept_helper("\"\\u01") == false);
CHECK(accept_helper("\"\\u012") == false); CHECK(accept_helper("\"\\u012") == false);
// unget of newline
CHECK(parser_helper("\n123\n") == 123);
// invalid escapes // invalid escapes
for (int c = 1; c < 128; ++c) for (int c = 1; c < 128; ++c)
{ {
@ -1419,11 +1422,11 @@ TEST_CASE("parser class")
// test case to make sure no comma preceeds the first key // test case to make sure no comma preceeds the first key
CHECK_THROWS_AS(parser_helper("{,\"key\": false}"), json::parse_error&); CHECK_THROWS_AS(parser_helper("{,\"key\": false}"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("{,\"key\": false}"), CHECK_THROWS_WITH(parser_helper("{,\"key\": false}"),
"[json.exception.parse_error.101] parse error at 2: syntax error - unexpected ','; expected string literal"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected ','; expected string literal");
// test case to make sure an object is properly closed // test case to make sure an object is properly closed
CHECK_THROWS_AS(parser_helper("[{\"key\": false true]"), json::parse_error&); CHECK_THROWS_AS(parser_helper("[{\"key\": false true]"), json::parse_error&);
CHECK_THROWS_WITH(parser_helper("[{\"key\": false true]"), CHECK_THROWS_WITH(parser_helper("[{\"key\": false true]"),
"[json.exception.parse_error.101] parse error at 19: syntax error - unexpected true literal; expected '}'"); "[json.exception.parse_error.101] parse error at line 1, column 19: syntax error while parsing object - unexpected true literal; expected '}'");
// test case to make sure the callback is properly evaluated after reading a key // test case to make sure the callback is properly evaluated after reading a key
{ {
@ -1674,7 +1677,7 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(json::parse("{\"foo\": true:", cb), json::parse_error&); CHECK_THROWS_AS(json::parse("{\"foo\": true:", cb), json::parse_error&);
CHECK_THROWS_WITH(json::parse("{\"foo\": true:", cb), CHECK_THROWS_WITH(json::parse("{\"foo\": true:", cb),
"[json.exception.parse_error.101] parse error at 13: syntax error - unexpected ':'; expected '}'"); "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing object - unexpected ':'; expected '}'");
CHECK_THROWS_AS(json::parse("1.18973e+4932", cb), json::out_of_range&); CHECK_THROWS_AS(json::parse("1.18973e+4932", cb), json::out_of_range&);
CHECK_THROWS_WITH(json::parse("1.18973e+4932", cb), CHECK_THROWS_WITH(json::parse("1.18973e+4932", cb),

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -267,7 +267,7 @@ TEST_CASE("deserialization")
ss5 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss5 << "[\"foo\",1,2,3,false,{\"one\":1}";
CHECK_THROWS_AS(json::parse(ss1), json::parse_error&); CHECK_THROWS_AS(json::parse(ss1), json::parse_error&);
CHECK_THROWS_WITH(json::parse(ss2), CHECK_THROWS_WITH(json::parse(ss2),
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
CHECK(not json::accept(ss3)); CHECK(not json::accept(ss3));
json j_error; json j_error;
@ -291,7 +291,7 @@ TEST_CASE("deserialization")
json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}"; json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}";
CHECK_THROWS_AS(json::parse(s), json::parse_error&); CHECK_THROWS_AS(json::parse(s), json::parse_error&);
CHECK_THROWS_WITH(json::parse(s), CHECK_THROWS_WITH(json::parse(s),
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
CHECK(not json::accept(s)); CHECK(not json::accept(s));
json j_error; json j_error;
@ -318,7 +318,7 @@ TEST_CASE("deserialization")
json j; json j;
CHECK_THROWS_AS(j << ss1, json::parse_error&); CHECK_THROWS_AS(j << ss1, json::parse_error&);
CHECK_THROWS_WITH(j << ss2, CHECK_THROWS_WITH(j << ss2,
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
} }
SECTION("operator>>") SECTION("operator>>")
@ -329,14 +329,14 @@ TEST_CASE("deserialization")
json j; json j;
CHECK_THROWS_AS(ss1 >> j, json::parse_error&); CHECK_THROWS_AS(ss1 >> j, json::parse_error&);
CHECK_THROWS_WITH(ss2 >> j, CHECK_THROWS_WITH(ss2 >> j,
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
} }
SECTION("user-defined string literal") SECTION("user-defined string literal")
{ {
CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error&); CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error&);
CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json, CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json,
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
} }
} }
@ -612,7 +612,7 @@ TEST_CASE("deserialization")
uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
CHECK_THROWS_WITH(json::parse(std::begin(v), std::end(v)), CHECK_THROWS_WITH(json::parse(std::begin(v), std::end(v)),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: ill-formed UTF-8 byte; last read: '\"\x7f\xdf\x7f'"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"\x7f\xdf\x7f'");
CHECK(not json::accept(std::begin(v), std::end(v))); CHECK(not json::accept(std::begin(v), std::end(v)));
json j_error; json j_error;
@ -799,11 +799,11 @@ TEST_CASE("deserialization")
{ {
CHECK_THROWS_AS(json::parse(bom), json::parse_error&); CHECK_THROWS_AS(json::parse(bom), json::parse_error&);
CHECK_THROWS_WITH(json::parse(bom), CHECK_THROWS_WITH(json::parse(bom),
"[json.exception.parse_error.101] parse error at 4: syntax error - unexpected end of input; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal");
CHECK_THROWS_AS(json::parse(std::istringstream(bom)), json::parse_error&); CHECK_THROWS_AS(json::parse(std::istringstream(bom)), json::parse_error&);
CHECK_THROWS_WITH(json::parse(std::istringstream(bom)), CHECK_THROWS_WITH(json::parse(std::istringstream(bom)),
"[json.exception.parse_error.101] parse error at 4: syntax error - unexpected end of input; expected '[', '{', or a literal"); "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal");
SaxEventLogger l; SaxEventLogger l;
CHECK(not json::sax_parse(bom, &l)); CHECK(not json::sax_parse(bom, &l));
@ -838,11 +838,11 @@ TEST_CASE("deserialization")
{ {
CHECK_THROWS_AS(json::parse(bom.substr(0, 2)), json::parse_error&); CHECK_THROWS_AS(json::parse(bom.substr(0, 2)), json::parse_error&);
CHECK_THROWS_WITH(json::parse(bom.substr(0, 2)), CHECK_THROWS_WITH(json::parse(bom.substr(0, 2)),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'");
CHECK_THROWS_AS(json::parse(std::istringstream(bom.substr(0, 2))), json::parse_error&); CHECK_THROWS_AS(json::parse(std::istringstream(bom.substr(0, 2))), json::parse_error&);
CHECK_THROWS_WITH(json::parse(std::istringstream(bom.substr(0, 2))), CHECK_THROWS_WITH(json::parse(std::istringstream(bom.substr(0, 2))),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'"); "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'");
SaxEventLogger l1, l2; SaxEventLogger l1, l2;
CHECK(not json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1)); CHECK(not json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1));
@ -863,11 +863,11 @@ TEST_CASE("deserialization")
{ {
CHECK_THROWS_AS(json::parse(bom.substr(0, 1)), json::parse_error&); CHECK_THROWS_AS(json::parse(bom.substr(0, 1)), json::parse_error&);
CHECK_THROWS_WITH(json::parse(bom.substr(0, 1)), CHECK_THROWS_WITH(json::parse(bom.substr(0, 1)),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'");
CHECK_THROWS_AS(json::parse(std::istringstream(bom.substr(0, 1))), json::parse_error&); CHECK_THROWS_AS(json::parse(std::istringstream(bom.substr(0, 1))), json::parse_error&);
CHECK_THROWS_WITH(json::parse(std::istringstream(bom.substr(0, 1))), CHECK_THROWS_WITH(json::parse(std::istringstream(bom.substr(0, 1))),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'"); "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'");
SaxEventLogger l1, l2; SaxEventLogger l1, l2;
CHECK(not json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1)); CHECK(not json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1));

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -195,7 +195,7 @@ TEST_CASE("element access 1")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_NOTHROW(j_nonarray[0]); CHECK_NOTHROW(j_nonarray[0]);
CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);
CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with null"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with null");
} }
SECTION("implicit transformation to properly filled array") SECTION("implicit transformation to properly filled array")
@ -212,8 +212,8 @@ TEST_CASE("element access 1")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], json::type_error&); CHECK_THROWS_AS(j_nonarray[0], json::type_error&);
CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);
CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with boolean"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean");
CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with boolean"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean");
} }
SECTION("string") SECTION("string")
@ -222,8 +222,8 @@ TEST_CASE("element access 1")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], json::type_error&); CHECK_THROWS_AS(j_nonarray[0], json::type_error&);
CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);
CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with string"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with string");
CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with string"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with string");
} }
SECTION("object") SECTION("object")
@ -232,8 +232,8 @@ TEST_CASE("element access 1")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], json::type_error&); CHECK_THROWS_AS(j_nonarray[0], json::type_error&);
CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);
CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with object"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with object");
CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with object"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with object");
} }
SECTION("number (integer)") SECTION("number (integer)")
@ -242,8 +242,8 @@ TEST_CASE("element access 1")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], json::type_error&); CHECK_THROWS_AS(j_nonarray[0], json::type_error&);
CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);
CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number");
CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
@ -252,8 +252,8 @@ TEST_CASE("element access 1")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], json::type_error&); CHECK_THROWS_AS(j_nonarray[0], json::type_error&);
CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);
CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number");
CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
@ -262,8 +262,8 @@ TEST_CASE("element access 1")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], json::type_error&); CHECK_THROWS_AS(j_nonarray[0], json::type_error&);
CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);
CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number");
CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number");
} }
} }
} }

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -475,9 +475,9 @@ TEST_CASE("element access 2")
CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]); CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]);
CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
CHECK_THROWS_WITH(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with null"); CHECK_THROWS_WITH(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with a string argument with null");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with null"); "[json.exception.type_error.305] cannot use operator[] with a string argument with null");
} }
SECTION("boolean") SECTION("boolean")
@ -489,13 +489,13 @@ TEST_CASE("element access 2")
CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
CHECK_THROWS_WITH(j_nonobject["foo"], CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with boolean"); "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with boolean"); "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
CHECK_THROWS_WITH(j_const_nonobject["foo"], CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with boolean"); "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with boolean"); "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
} }
SECTION("string") SECTION("string")
@ -507,13 +507,13 @@ TEST_CASE("element access 2")
CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
CHECK_THROWS_WITH(j_nonobject["foo"], CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with string"); "[json.exception.type_error.305] cannot use operator[] with a string argument with string");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with string"); "[json.exception.type_error.305] cannot use operator[] with a string argument with string");
CHECK_THROWS_WITH(j_const_nonobject["foo"], CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with string"); "[json.exception.type_error.305] cannot use operator[] with a string argument with string");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with string"); "[json.exception.type_error.305] cannot use operator[] with a string argument with string");
} }
SECTION("array") SECTION("array")
@ -525,12 +525,12 @@ TEST_CASE("element access 2")
CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
CHECK_THROWS_WITH(j_nonobject["foo"], CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with array"); "[json.exception.type_error.305] cannot use operator[] with a string argument with array");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with array"); CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array");
CHECK_THROWS_WITH(j_const_nonobject["foo"], CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with array"); "[json.exception.type_error.305] cannot use operator[] with a string argument with array");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with array"); "[json.exception.type_error.305] cannot use operator[] with a string argument with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
@ -542,13 +542,13 @@ TEST_CASE("element access 2")
CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
CHECK_THROWS_WITH(j_nonobject["foo"], CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_const_nonobject["foo"], CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
@ -560,13 +560,13 @@ TEST_CASE("element access 2")
CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
CHECK_THROWS_WITH(j_nonobject["foo"], CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_const_nonobject["foo"], CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
@ -578,13 +578,13 @@ TEST_CASE("element access 2")
CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error&);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error&);
CHECK_THROWS_WITH(j_nonobject["foo"], CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_const_nonobject["foo"], CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"[json.exception.type_error.305] cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with a string argument with number");
} }
} }
} }

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -63,7 +63,7 @@ TEST_CASE("JSON patch")
// is not an error, because "a" exists, and "b" will be added to // is not an error, because "a" exists, and "b" will be added to
// its value. // its value.
CHECK_NOTHROW(doc1.patch(patch)); CHECK_NOTHROW(doc1.patch(patch));
CHECK(doc1.patch(patch) == R"( auto doc1_ans = R"(
{ {
"a": { "a": {
"foo": 1, "foo": 1,
@ -72,7 +72,8 @@ TEST_CASE("JSON patch")
} }
} }
} }
)"_json); )"_json;
CHECK(doc1.patch(patch) == doc1_ans);
// It is an error in this document: // It is an error in this document:
json doc2 = R"({ "q": { "bar": 2 } })"_json; json doc2 = R"({ "q": { "bar": 2 } })"_json;

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -39,7 +39,7 @@ TEST_CASE("JSON pointers")
{ {
CHECK_THROWS_AS(json::json_pointer("foo"), json::parse_error&); CHECK_THROWS_AS(json::json_pointer("foo"), json::parse_error&);
CHECK_THROWS_WITH(json::json_pointer("foo"), CHECK_THROWS_WITH(json::json_pointer("foo"),
"[json.exception.parse_error.107] parse error at 1: JSON pointer must be empty or begin with '/' - was: 'foo'"); "[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'");
CHECK_THROWS_AS(json::json_pointer("/~~"), json::parse_error&); CHECK_THROWS_AS(json::json_pointer("/~~"), json::parse_error&);
CHECK_THROWS_WITH(json::json_pointer("/~~"), CHECK_THROWS_WITH(json::json_pointer("/~~"),

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -43,9 +43,9 @@ TEST_CASE("version information")
CHECK(j["url"] == "https://github.com/nlohmann/json"); CHECK(j["url"] == "https://github.com/nlohmann/json");
CHECK(j["version"] == json( CHECK(j["version"] == json(
{ {
{"string", "3.2.0"}, {"string", "3.3.0"},
{"major", 3}, {"major", 3},
{"minor", 2}, {"minor", 3},
{"patch", 0} {"patch", 0}
})); }));

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -1124,7 +1124,7 @@ TEST_CASE("MessagePack")
{ {
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>()), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>()), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>()), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>()),
"[json.exception.parse_error.110] parse error at 1: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input");
CHECK(json::from_msgpack(std::vector<uint8_t>(), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>(), true, false).is_discarded());
} }
@ -1151,43 +1151,43 @@ TEST_CASE("MessagePack")
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x87})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x87})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcc})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcc})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf})),
"[json.exception.parse_error.110] parse error at 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 6: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 7: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 8: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 9: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xa5, 0x68, 0x65})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xa5, 0x68, 0x65})),
"[json.exception.parse_error.110] parse error at 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack string: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x92, 0x01})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x92, 0x01})),
"[json.exception.parse_error.110] parse error at 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack value: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})),
"[json.exception.parse_error.110] parse error at 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack value: unexpected end of input");
CHECK(json::from_msgpack(std::vector<uint8_t>({0x87}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0x87}), true, false).is_discarded());
CHECK(json::from_msgpack(std::vector<uint8_t>({0xcc}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0xcc}), true, false).is_discarded());
@ -1216,12 +1216,12 @@ TEST_CASE("MessagePack")
{ {
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc1})), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc1})), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc1})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc1})),
"[json.exception.parse_error.112] parse error at 1: error reading MessagePack; last byte: 0xC1"); "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1");
CHECK(json::from_msgpack(std::vector<uint8_t>({0xc6}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0xc6}), true, false).is_discarded());
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc6})), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc6})), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc6})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc6})),
"[json.exception.parse_error.112] parse error at 1: error reading MessagePack; last byte: 0xC6"); "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC6");
CHECK(json::from_msgpack(std::vector<uint8_t>({0xc6}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0xc6}), true, false).is_discarded());
} }
@ -1249,7 +1249,7 @@ TEST_CASE("MessagePack")
{ {
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})),
"[json.exception.parse_error.113] parse error at 2: expected a MessagePack string; last byte: 0xFF"); "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF");
CHECK(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01}), true, false).is_discarded());
} }
@ -1266,7 +1266,7 @@ TEST_CASE("MessagePack")
{ {
CHECK_THROWS_AS(json::from_msgpack(vec), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(vec), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(vec), CHECK_THROWS_WITH(json::from_msgpack(vec),
"[json.exception.parse_error.110] parse error at 2: expected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack value: expected end of input; last byte: 0xC0");
CHECK(json::from_msgpack(vec, true, false).is_discarded()); CHECK(json::from_msgpack(vec, true, false).is_discarded());
} }
} }

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

View file

@ -1,7 +1,7 @@
/* /*
__ _____ _____ _____ __ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite) __| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.2.0 | | |__ | | | | | | version 3.3.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json |_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>. Licensed under the MIT License <http://opensource.org/licenses/MIT>.

Some files were not shown because too many files have changed in this diff Show more