Merge branch 'release/3.5.0'
This commit is contained in:
commit
cebb4e052a
71 changed files with 882 additions and 416 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -22,3 +22,4 @@ benchmarks/files/numbers/*.json
|
||||||
cmake-build-debug
|
cmake-build-debug
|
||||||
|
|
||||||
test/test-*
|
test/test-*
|
||||||
|
/.vs
|
||||||
|
|
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.8)
|
||||||
## PROJECT
|
## PROJECT
|
||||||
## name and version
|
## name and version
|
||||||
##
|
##
|
||||||
project(nlohmann_json VERSION 3.4.0 LANGUAGES CXX)
|
project(nlohmann_json VERSION 3.5.0 LANGUAGES CXX)
|
||||||
|
|
||||||
##
|
##
|
||||||
## INCLUDE
|
## INCLUDE
|
||||||
|
|
78
ChangeLog.md
78
ChangeLog.md
|
@ -1,6 +1,84 @@
|
||||||
# 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.5.0](https://github.com/nlohmann/json/releases/tag/v3.5.0) (2018-12-21)
|
||||||
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.4.0...v3.5.0)
|
||||||
|
|
||||||
|
- Copyconstructor inserts original into array with single element [\#1397](https://github.com/nlohmann/json/issues/1397)
|
||||||
|
- Get value without explicit typecasting [\#1395](https://github.com/nlohmann/json/issues/1395)
|
||||||
|
- Big file parsing [\#1393](https://github.com/nlohmann/json/issues/1393)
|
||||||
|
- some static analysis warning at line 11317 [\#1390](https://github.com/nlohmann/json/issues/1390)
|
||||||
|
- Adding Structured Binding Support [\#1388](https://github.com/nlohmann/json/issues/1388)
|
||||||
|
- map\<json::value\_t, string\> exhibits unexpected behavior [\#1387](https://github.com/nlohmann/json/issues/1387)
|
||||||
|
- Error Code Return [\#1386](https://github.com/nlohmann/json/issues/1386)
|
||||||
|
- using unordered\_map as object type [\#1385](https://github.com/nlohmann/json/issues/1385)
|
||||||
|
- float precision [\#1384](https://github.com/nlohmann/json/issues/1384)
|
||||||
|
- \[json.exception.type\_error.316\] invalid UTF-8 byte at index 1: 0xC3 [\#1383](https://github.com/nlohmann/json/issues/1383)
|
||||||
|
- Inconsistent Constructor \(GCC vs. Clang\) [\#1381](https://github.com/nlohmann/json/issues/1381)
|
||||||
|
- \#define or || [\#1379](https://github.com/nlohmann/json/issues/1379)
|
||||||
|
- How to iterate inside the values ? [\#1377](https://github.com/nlohmann/json/issues/1377)
|
||||||
|
- items\(\) unable to get the elements [\#1375](https://github.com/nlohmann/json/issues/1375)
|
||||||
|
- conversion json to std::map doesn't work for types \<int, double\> [\#1372](https://github.com/nlohmann/json/issues/1372)
|
||||||
|
- A minor issue in the build instructions [\#1371](https://github.com/nlohmann/json/issues/1371)
|
||||||
|
- Using this library without stream ? [\#1370](https://github.com/nlohmann/json/issues/1370)
|
||||||
|
- Writing and reading BSON data [\#1368](https://github.com/nlohmann/json/issues/1368)
|
||||||
|
- Retrieving array elements from object type iterator. [\#1367](https://github.com/nlohmann/json/issues/1367)
|
||||||
|
- json::dump\(\) silently crashes if items contain accented letters [\#1365](https://github.com/nlohmann/json/issues/1365)
|
||||||
|
- warnings in MSVC \(2015\) in 3.4.0 related to bool... [\#1364](https://github.com/nlohmann/json/issues/1364)
|
||||||
|
- Cant compile with -C++17 and beyond compiler options [\#1362](https://github.com/nlohmann/json/issues/1362)
|
||||||
|
- json to concrete type conversion through reference or pointer fails [\#1361](https://github.com/nlohmann/json/issues/1361)
|
||||||
|
- the first attributes of JSON string is misplaced [\#1360](https://github.com/nlohmann/json/issues/1360)
|
||||||
|
- Copy-construct using initializer-list converts objects to arrays [\#1359](https://github.com/nlohmann/json/issues/1359)
|
||||||
|
- About value\(key, default\_value\) and operator\[\]\(key\) [\#1358](https://github.com/nlohmann/json/issues/1358)
|
||||||
|
- Problem with printing json response object [\#1356](https://github.com/nlohmann/json/issues/1356)
|
||||||
|
- Serializing pointer segfaults [\#1355](https://github.com/nlohmann/json/issues/1355)
|
||||||
|
- Read `long long int` data as a number. [\#1354](https://github.com/nlohmann/json/issues/1354)
|
||||||
|
- eclipse oxygen in ubuntu get\<size\_t\> is ambiguous [\#1353](https://github.com/nlohmann/json/issues/1353)
|
||||||
|
- Can't build on Visual Studio 2017 v15.8.9 [\#1350](https://github.com/nlohmann/json/issues/1350)
|
||||||
|
- cannot parse from string? [\#1349](https://github.com/nlohmann/json/issues/1349)
|
||||||
|
- Error: out\_of\_range [\#1348](https://github.com/nlohmann/json/issues/1348)
|
||||||
|
- expansion pattern 'CompatibleObjectType' contains no argument packs, with CUDA 10 [\#1347](https://github.com/nlohmann/json/issues/1347)
|
||||||
|
- Unable to update a value for a nested\(multi-level\) json file [\#1344](https://github.com/nlohmann/json/issues/1344)
|
||||||
|
- Fails to compile when std::iterator\_traits is not SFINAE friendly. [\#1341](https://github.com/nlohmann/json/issues/1341)
|
||||||
|
- EOF flag not set on exhausted input streams. [\#1340](https://github.com/nlohmann/json/issues/1340)
|
||||||
|
- Shadowed Member in merge\_patch [\#1339](https://github.com/nlohmann/json/issues/1339)
|
||||||
|
- Periods/literal dots in keys? [\#1338](https://github.com/nlohmann/json/issues/1338)
|
||||||
|
- Protect macro expansion of commonly defined macros [\#1337](https://github.com/nlohmann/json/issues/1337)
|
||||||
|
- How to validate an input before parsing? [\#1336](https://github.com/nlohmann/json/issues/1336)
|
||||||
|
- Non-verifying dump\(\) alternative for debugging/logging needed [\#1335](https://github.com/nlohmann/json/issues/1335)
|
||||||
|
- Improve number-to-string conversion [\#1334](https://github.com/nlohmann/json/issues/1334)
|
||||||
|
- Json Libarary is not responding for me in c++ [\#1332](https://github.com/nlohmann/json/issues/1332)
|
||||||
|
- Question - how to find an object in an array [\#1331](https://github.com/nlohmann/json/issues/1331)
|
||||||
|
- Nesting additional data in json object [\#1328](https://github.com/nlohmann/json/issues/1328)
|
||||||
|
- can to\_json\(\) be defined inside a class? [\#1324](https://github.com/nlohmann/json/issues/1324)
|
||||||
|
- CodeBlocks IDE can't find `json.hpp` header [\#1318](https://github.com/nlohmann/json/issues/1318)
|
||||||
|
- Change json\_pointer to provide an iterator begin/end/etc, don't use vectors, and also enable string\_view [\#1312](https://github.com/nlohmann/json/issues/1312)
|
||||||
|
- Xcode - adding it to library [\#1300](https://github.com/nlohmann/json/issues/1300)
|
||||||
|
- unicode: accept char16\_t, char32\_t sequences [\#1298](https://github.com/nlohmann/json/issues/1298)
|
||||||
|
- unicode: char16\_t\* is compiler error, but char16\_t\[\] is accepted [\#1297](https://github.com/nlohmann/json/issues/1297)
|
||||||
|
- Dockerfile Project Help Needed [\#1296](https://github.com/nlohmann/json/issues/1296)
|
||||||
|
- Comparisons between large unsigned and negative signed integers [\#1295](https://github.com/nlohmann/json/issues/1295)
|
||||||
|
- CMake alias to `nlohmann::json` [\#1291](https://github.com/nlohmann/json/issues/1291)
|
||||||
|
- Release zips without tests [\#1285](https://github.com/nlohmann/json/issues/1285)
|
||||||
|
- Suggestion to improve value\(\) accessors with respect to move semantics [\#1275](https://github.com/nlohmann/json/issues/1275)
|
||||||
|
- separate object\_t::key\_type from basic\_json::key\_type, and use an allocator which returns object\_t::key\_type [\#1274](https://github.com/nlohmann/json/issues/1274)
|
||||||
|
- Is there a nice way to associate external values with json elements? [\#1256](https://github.com/nlohmann/json/issues/1256)
|
||||||
|
- Delete by json\_pointer [\#1248](https://github.com/nlohmann/json/issues/1248)
|
||||||
|
- Expose lexer, as a StAX parser [\#1219](https://github.com/nlohmann/json/issues/1219)
|
||||||
|
- Subclassing json\(\) & error on recursive load [\#1201](https://github.com/nlohmann/json/issues/1201)
|
||||||
|
- Check value for existence by json\_pointer [\#1194](https://github.com/nlohmann/json/issues/1194)
|
||||||
|
|
||||||
|
- Feature/add file input adapter [\#1392](https://github.com/nlohmann/json/pull/1392) ([dumarjo](https://github.com/dumarjo))
|
||||||
|
- Added Support for Structured Bindings [\#1391](https://github.com/nlohmann/json/pull/1391) ([pratikpc](https://github.com/pratikpc))
|
||||||
|
- Link to issue \#958 broken [\#1382](https://github.com/nlohmann/json/pull/1382) ([kjpus](https://github.com/kjpus))
|
||||||
|
- readme: fix typo [\#1380](https://github.com/nlohmann/json/pull/1380) ([manu-chroma](https://github.com/manu-chroma))
|
||||||
|
- recommend using explicit from JSON conversions [\#1363](https://github.com/nlohmann/json/pull/1363) ([theodelrieu](https://github.com/theodelrieu))
|
||||||
|
- Fix merge\_patch shadow warning [\#1346](https://github.com/nlohmann/json/pull/1346) ([ax3l](https://github.com/ax3l))
|
||||||
|
- Allow installation via Meson [\#1345](https://github.com/nlohmann/json/pull/1345) ([mpoquet](https://github.com/mpoquet))
|
||||||
|
- Set eofbit on exhausted input stream. [\#1343](https://github.com/nlohmann/json/pull/1343) ([mefyl](https://github.com/mefyl))
|
||||||
|
- Add a SFINAE friendly iterator\_traits and use that instead. [\#1342](https://github.com/nlohmann/json/pull/1342) ([davedissian](https://github.com/davedissian))
|
||||||
|
- Fix EOL Whitespaces & CMake Spelling [\#1329](https://github.com/nlohmann/json/pull/1329) ([ax3l](https://github.com/ax3l))
|
||||||
|
|
||||||
## [v3.4.0](https://github.com/nlohmann/json/releases/tag/v3.4.0) (2018-10-30)
|
## [v3.4.0](https://github.com/nlohmann/json/releases/tag/v3.4.0) (2018-10-30)
|
||||||
[Full Changelog](https://github.com/nlohmann/json/compare/v3.3.0...v3.4.0)
|
[Full Changelog](https://github.com/nlohmann/json/compare/v3.3.0...v3.4.0)
|
||||||
|
|
||||||
|
|
92
README.md
92
README.md
|
@ -46,7 +46,7 @@ There are myriads of [JSON](http://json.org) libraries out there, and each may e
|
||||||
|
|
||||||
- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.
|
- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.
|
||||||
|
|
||||||
- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests agains all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
|
- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
|
||||||
|
|
||||||
Other aspects were not so important to us:
|
Other aspects were not so important to us:
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ You can also use the `nlohmann_json::nlohmann_json` interface target in CMake.
|
||||||
#### External
|
#### 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:
|
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
|
```cmake
|
||||||
# CMakeLists.txt
|
# CMakeLists.txt
|
||||||
find_package(nlohmann_json 3.2.0 REQUIRED)
|
find_package(nlohmann_json 3.2.0 REQUIRED)
|
||||||
|
@ -87,11 +88,13 @@ add_library(foo ...)
|
||||||
...
|
...
|
||||||
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
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.
|
The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.
|
||||||
|
|
||||||
#### Embedded
|
#### 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:
|
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
|
```cmake
|
||||||
# Typically you don't care so much for a third party library's tests to be
|
# Typically you don't care so much for a third party library's tests to be
|
||||||
# run from your own project's code.
|
# run from your own project's code.
|
||||||
|
@ -109,7 +112,9 @@ target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Supporting Both
|
#### 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:
|
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
|
``` cmake
|
||||||
# Top level CMakeLists.txt
|
# Top level CMakeLists.txt
|
||||||
project(FOO)
|
project(FOO)
|
||||||
|
@ -135,6 +140,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
`thirdparty/nlohmann_json` is then a complete copy of this source tree.
|
`thirdparty/nlohmann_json` is then a complete copy of this source tree.
|
||||||
|
|
||||||
### Package Managers
|
### Package Managers
|
||||||
|
@ -291,19 +297,17 @@ Note the difference between serialization and assignment:
|
||||||
// store a string in a JSON value
|
// store a string in a JSON value
|
||||||
json j_string = "this is a string";
|
json j_string = "this is a string";
|
||||||
|
|
||||||
// retrieve the string value (implicit JSON to std::string conversion)
|
// retrieve the string value
|
||||||
std::string cpp_string = j_string;
|
auto cpp_string = j_string.get<std::string>();
|
||||||
// retrieve the string value (explicit JSON to std::string conversion)
|
// retrieve the string value (alternative when an variable already exists)
|
||||||
auto cpp_string2 = j_string.get<std::string>();
|
std::string cpp_string2;
|
||||||
// retrieve the string value (alternative explicit JSON to std::string conversion)
|
j_string.get_to(cpp_string2);
|
||||||
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 << " == " << cpp_string3 << " == " << j_string.get<std::string>() << '\n';
|
std::cout << cpp_string << " == " << cpp_string2 << " == " << 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;
|
||||||
```
|
```
|
||||||
|
@ -402,7 +406,6 @@ To implement your own SAX handler, proceed as follows:
|
||||||
|
|
||||||
Note the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return a `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file [`json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp).
|
Note the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return a `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file [`json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp).
|
||||||
|
|
||||||
|
|
||||||
### STL-like access
|
### STL-like access
|
||||||
|
|
||||||
We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) requirement.
|
We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) requirement.
|
||||||
|
@ -428,7 +431,7 @@ for (auto& element : j) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getter/setter
|
// getter/setter
|
||||||
const std::string tmp = j[0];
|
const auto tmp = j[0].get<std::string>();
|
||||||
j[1] = 42;
|
j[1] = 42;
|
||||||
bool foo = j.at(2);
|
bool foo = j.at(2);
|
||||||
|
|
||||||
|
@ -463,6 +466,16 @@ for (json::iterator it = o.begin(); it != o.end(); ++it) {
|
||||||
std::cout << it.key() << " : " << it.value() << "\n";
|
std::cout << it.key() << " : " << it.value() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the same code as range for
|
||||||
|
for (auto& el : o.items()) {
|
||||||
|
std::cout << el.key() << " : " << el.value() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// even easier with structured bindings (C++17)
|
||||||
|
for (auto& [key, value] : o.items()) {
|
||||||
|
std::cout << key << " : " << value << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
// find an entry
|
// find an entry
|
||||||
if (o.find("foo") != o.end()) {
|
if (o.find("foo") != o.end()) {
|
||||||
// there is an entry with key "foo"
|
// there is an entry with key "foo"
|
||||||
|
@ -611,33 +624,38 @@ j_original.merge_patch(j_patch);
|
||||||
|
|
||||||
### Implicit conversions
|
### Implicit conversions
|
||||||
|
|
||||||
The type of the JSON object is determined automatically by the expression to store. Likewise, the stored value is implicitly converted.
|
Supported types can be implicitly converted to JSON values.
|
||||||
|
|
||||||
|
It is recommended to **NOT USE** implicit conversions **FROM** a JSON value.
|
||||||
|
You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958).
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// strings
|
// strings
|
||||||
std::string s1 = "Hello, world!";
|
std::string s1 = "Hello, world!";
|
||||||
json js = s1;
|
json js = s1;
|
||||||
std::string s2 = js;
|
auto s2 = js.get<std::string>();
|
||||||
|
// NOT RECOMMENDED
|
||||||
|
std::string s3 = js;
|
||||||
|
std::string s4;
|
||||||
|
s4 = js;
|
||||||
|
|
||||||
// Booleans
|
// Booleans
|
||||||
bool b1 = true;
|
bool b1 = true;
|
||||||
json jb = b1;
|
json jb = b1;
|
||||||
bool b2 = jb;
|
auto b2 = jb.get<bool>();
|
||||||
|
// NOT RECOMMENDED
|
||||||
|
bool b3 = jb;
|
||||||
|
bool b4;
|
||||||
|
b4 = jb;
|
||||||
|
|
||||||
// numbers
|
// numbers
|
||||||
int i = 42;
|
int i = 42;
|
||||||
json jn = i;
|
json jn = i;
|
||||||
double f = jn;
|
auto f = jn.get<double>();
|
||||||
|
// NOT RECOMMENDED
|
||||||
// etc.
|
double f2 = jb;
|
||||||
```
|
double f3;
|
||||||
|
f3 = jb;
|
||||||
You can also explicitly ask for the value:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
std::string vs = js.get<std::string>();
|
|
||||||
bool vb = jb.get<bool>();
|
|
||||||
int vi = jn.get<int>();
|
|
||||||
|
|
||||||
// etc.
|
// etc.
|
||||||
```
|
```
|
||||||
|
@ -695,7 +713,7 @@ std::cout << j << std::endl;
|
||||||
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
|
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
|
||||||
|
|
||||||
// conversion: json -> person
|
// conversion: json -> person
|
||||||
ns::person p2 = j;
|
auto p2 = j.get<ns::person>();
|
||||||
|
|
||||||
// that's it
|
// that's it
|
||||||
assert(p == p2);
|
assert(p == p2);
|
||||||
|
@ -727,10 +745,9 @@ Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_jso
|
||||||
Some important things:
|
Some important things:
|
||||||
|
|
||||||
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
||||||
* 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 these 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)>();` 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.
|
||||||
|
|
||||||
|
|
||||||
|
@ -925,7 +942,7 @@ Other Important points:
|
||||||
- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.
|
- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.
|
||||||
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
|
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
|
||||||
|
|
||||||
### Binary formats (BSON, CBOR, MessagePack, and UBJSON
|
### Binary formats (BSON, CBOR, MessagePack, and UBJSON)
|
||||||
|
|
||||||
Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [BSON](http://bsonspec.org) (Binary JSON), [CBOR](http://cbor.io) (Concise Binary Object Representation), [MessagePack](http://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors.
|
Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [BSON](http://bsonspec.org) (Binary JSON), [CBOR](http://cbor.io) (Concise Binary Object Representation), [MessagePack](http://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors.
|
||||||
|
|
||||||
|
@ -971,8 +988,8 @@ 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.8 - 8.2 (and possibly later)
|
- GCC 4.8 - 9.0 (and possibly later)
|
||||||
- Clang 3.4 - 6.1 (and possibly later)
|
- Clang 3.4 - 8.0 (and possibly later)
|
||||||
- Intel C++ Compiler 17.0.2 (and possibly later)
|
- Intel C++ Compiler 17.0.2 (and possibly later)
|
||||||
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
|
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
|
||||||
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
|
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
|
||||||
|
@ -1063,7 +1080,7 @@ Only if your request would contain confidential information, please [send me an
|
||||||
|
|
||||||
I deeply appreciate the help of the following people.
|
I deeply appreciate the help of the following people.
|
||||||
|
|
||||||
![Contributors](https://raw.githubusercontent.com/nlohmann/json/develop/doc/avatars.png)
|
<img src="https://raw.githubusercontent.com/nlohmann/json/develop/doc/avatars.png" align="right">
|
||||||
|
|
||||||
- [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization.
|
- [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization.
|
||||||
- [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes.
|
- [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes.
|
||||||
|
@ -1200,6 +1217,15 @@ I deeply appreciate the help of the following people.
|
||||||
- [Dan Gendreau](https://github.com/dgendreau) implemented the `NLOHMANN_JSON_SERIALIZE_ENUM` macro to quickly define a enum/JSON mapping.
|
- [Dan Gendreau](https://github.com/dgendreau) implemented the `NLOHMANN_JSON_SERIALIZE_ENUM` macro to quickly define a enum/JSON mapping.
|
||||||
- [efp](https://github.com/efp) added line and column information to parse errors.
|
- [efp](https://github.com/efp) added line and column information to parse errors.
|
||||||
- [julian-becker](https://github.com/julian-becker) added BSON support.
|
- [julian-becker](https://github.com/julian-becker) added BSON support.
|
||||||
|
- [Pratik Chowdhury](https://github.com/pratikpc) added support for structured bindings.
|
||||||
|
- [David Avedissian](https://github.com/davedissian) added support for Clang 5.0.1 (PS4 version).
|
||||||
|
- [Jonathan Dumaresq](https://github.com/dumarjo) implemented an input adapter to read from `FILE*`.
|
||||||
|
- [kjpus](https://github.com/kjpus) fixed a link in the documentation.
|
||||||
|
- [Manvendra Singh](https://github.com/manu-chroma) fixed a typo in the documentation.
|
||||||
|
- [ziggurat29](https://github.com/ziggurat29) fixed an MSVC warning.
|
||||||
|
- [Sylvain Corlay](https://github.com/SylvainCorlay) added code to avoid an issue with MSVC.
|
||||||
|
- [mefyl](https://github.com/mefyl) fixed a bug when JSON was parsed from an input stream.
|
||||||
|
- [Millian Poquet](https://github.com/mpoquet) allowed to install the library via Meson.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
@ -1214,7 +1240,7 @@ The library itself consists of a single header file licensed under the MIT licen
|
||||||
- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code identation
|
- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code identation
|
||||||
- [**Catch**](https://github.com/philsquared/Catch) for the unit tests
|
- [**Catch**](https://github.com/philsquared/Catch) for the unit tests
|
||||||
- [**Clang**](http://clang.llvm.org) for compilation with code sanitizers
|
- [**Clang**](http://clang.llvm.org) for compilation with code sanitizers
|
||||||
- [**Cmake**](https://cmake.org) for build automation
|
- [**CMake**](https://cmake.org) for build automation
|
||||||
- [**Codacity**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json)
|
- [**Codacity**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json)
|
||||||
- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json)
|
- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json)
|
||||||
- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json)
|
- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json)
|
||||||
|
|
|
@ -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.4.0
|
PROJECT_NUMBER = 3.5.0
|
||||||
PROJECT_BRIEF =
|
PROJECT_BRIEF =
|
||||||
PROJECT_LOGO =
|
PROJECT_LOGO =
|
||||||
OUTPUT_DIRECTORY = .
|
OUTPUT_DIRECTORY = .
|
||||||
|
|
BIN
doc/avatars.png
BIN
doc/avatars.png
Binary file not shown.
Before Width: | Height: | Size: 726 KiB After Width: | Height: | Size: 812 KiB |
|
@ -1 +1 @@
|
||||||
<a target="_blank" href="https://wandbox.org/permlink/f7QirmxXKiKAsPts"><b>online</b></a>
|
<a target="_blank" href="https://wandbox.org/permlink/jhAlfAa9ZPKTp8JK"><b>online</b></a>
|
|
@ -2,7 +2,7 @@
|
||||||
"compiler": {
|
"compiler": {
|
||||||
"c++": "201103",
|
"c++": "201103",
|
||||||
"family": "clang",
|
"family": "clang",
|
||||||
"version": "10.0.0 (clang-1000.10.43.1)"
|
"version": "10.0.0 (clang-1000.11.45.5)"
|
||||||
},
|
},
|
||||||
"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": 4,
|
"minor": 5,
|
||||||
"patch": 0,
|
"patch": 0,
|
||||||
"string": "3.4.0"
|
"string": "3.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.4.0
|
@version 3.5.0
|
||||||
|
|
BIN
doc/json.gif
BIN
doc/json.gif
Binary file not shown.
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.6 MiB |
|
@ -290,9 +290,9 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
||||||
template <
|
template <
|
||||||
typename BasicJsonType, typename T, std::size_t N,
|
typename BasicJsonType, typename T, std::size_t N,
|
||||||
enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
|
enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
|
||||||
const T (&)[N]>::value,
|
const T(&)[N]>::value,
|
||||||
int> = 0 >
|
int> = 0 >
|
||||||
void to_json(BasicJsonType& j, const T (&arr)[N])
|
void to_json(BasicJsonType& j, const T(&arr)[N])
|
||||||
{
|
{
|
||||||
external_constructor<value_t::array>::construct(j, arr);
|
external_constructor<value_t::array>::construct(j, arr);
|
||||||
}
|
}
|
||||||
|
@ -300,21 +300,21 @@ void to_json(BasicJsonType& j, const T (&arr)[N])
|
||||||
template<typename BasicJsonType, typename... Args>
|
template<typename BasicJsonType, typename... Args>
|
||||||
void to_json(BasicJsonType& j, const std::pair<Args...>& p)
|
void to_json(BasicJsonType& j, const std::pair<Args...>& p)
|
||||||
{
|
{
|
||||||
j = {p.first, p.second};
|
j = { p.first, p.second };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
|
||||||
void to_json(BasicJsonType& j, const T& b)
|
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...> /*unused*/)
|
void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
|
||||||
{
|
{
|
||||||
j = {std::get<Idx>(t)...};
|
j = { std::get<Idx>(t)... };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename... Args>
|
template<typename BasicJsonType, typename... Args>
|
||||||
|
|
|
@ -241,7 +241,7 @@ class binary_reader
|
||||||
|
|
||||||
case 0x08: // boolean
|
case 0x08: // boolean
|
||||||
{
|
{
|
||||||
return sax->boolean(static_cast<bool>(get()));
|
return sax->boolean(get() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x0A: // null
|
case 0x0A: // null
|
||||||
|
@ -264,7 +264,7 @@ class binary_reader
|
||||||
default: // anything else not supported (yet)
|
default: // anything else not supported (yet)
|
||||||
{
|
{
|
||||||
char cr[3];
|
char cr[3];
|
||||||
snprintf(cr, sizeof(cr), "%.2hhX", static_cast<unsigned char>(element_type));
|
(std::snprintf)(cr, sizeof(cr), "%.2hhX", static_cast<unsigned char>(element_type));
|
||||||
return sax->parse_error(element_type_parse_position, std::string(cr), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr)));
|
return sax->parse_error(element_type_parse_position, std::string(cr), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,10 @@ class binary_reader
|
||||||
|
|
||||||
if (not is_array)
|
if (not is_array)
|
||||||
{
|
{
|
||||||
sax->key(key);
|
if (not sax->key(key))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
|
if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
|
||||||
|
@ -1918,7 +1921,7 @@ class binary_reader
|
||||||
std::string get_token_string() const
|
std::string get_token_string() const
|
||||||
{
|
{
|
||||||
char cr[3];
|
char cr[3];
|
||||||
snprintf(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
|
(std::snprintf)(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
|
||||||
return std::string{cr};
|
return std::string{cr};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <string> // string, char_traits
|
#include <string> // string, char_traits
|
||||||
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
|
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
|
||||||
#include <utility> // pair, declval
|
#include <utility> // pair, declval
|
||||||
|
#include <cstdio> //FILE *
|
||||||
|
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
|
@ -45,6 +46,27 @@ struct input_adapter_protocol
|
||||||
/// a type to simplify interfaces
|
/// a type to simplify interfaces
|
||||||
using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
|
using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Input adapter for stdio file access. This adapter read only 1 byte and do not use any
|
||||||
|
buffer. This adapter is a very low level adapter.
|
||||||
|
*/
|
||||||
|
class file_input_adapter : public input_adapter_protocol
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit file_input_adapter(std::FILE* f) noexcept
|
||||||
|
: m_file(f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::char_traits<char>::int_type get_character() noexcept override
|
||||||
|
{
|
||||||
|
return std::fgetc(m_file);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
/// the file pointer to read from
|
||||||
|
std::FILE* m_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
|
Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
|
||||||
beginning of input. Does not support changing the underlying std::streambuf
|
beginning of input. Does not support changing the underlying std::streambuf
|
||||||
|
@ -60,8 +82,8 @@ class input_stream_adapter : public input_adapter_protocol
|
||||||
~input_stream_adapter() override
|
~input_stream_adapter() override
|
||||||
{
|
{
|
||||||
// clear stream flags; we use underlying streambuf I/O, do not
|
// clear stream flags; we use underlying streambuf I/O, do not
|
||||||
// maintain ifstream flags
|
// maintain ifstream flags, except eof
|
||||||
is.clear();
|
is.clear(is.rdstate() & std::ios::eofbit);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit input_stream_adapter(std::istream& i)
|
explicit input_stream_adapter(std::istream& i)
|
||||||
|
@ -79,7 +101,13 @@ class input_stream_adapter : public input_adapter_protocol
|
||||||
// end up as the same value, eg. 0xFFFFFFFF.
|
// end up as the same value, eg. 0xFFFFFFFF.
|
||||||
std::char_traits<char>::int_type get_character() override
|
std::char_traits<char>::int_type get_character() override
|
||||||
{
|
{
|
||||||
return sb.sbumpc();
|
auto res = sb.sbumpc();
|
||||||
|
// set eof manually, as we don't use the istream interface.
|
||||||
|
if (res == EOF)
|
||||||
|
{
|
||||||
|
is.clear(is.rdstate() | std::ios::eofbit);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -287,7 +315,8 @@ class input_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// native support
|
// native support
|
||||||
|
input_adapter(std::FILE* file)
|
||||||
|
: ia(std::make_shared<file_input_adapter>(file)) {}
|
||||||
/// input adapter for input stream
|
/// input adapter for input stream
|
||||||
input_adapter(std::istream& i)
|
input_adapter(std::istream& i)
|
||||||
: ia(std::make_shared<input_stream_adapter>(i)) {}
|
: ia(std::make_shared<input_stream_adapter>(i)) {}
|
||||||
|
@ -331,7 +360,7 @@ class input_adapter
|
||||||
/// input adapter for iterator range with contiguous storage
|
/// input adapter for iterator range with contiguous storage
|
||||||
template<class IteratorType,
|
template<class IteratorType,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
|
std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
input_adapter(IteratorType first, IteratorType last)
|
input_adapter(IteratorType first, IteratorType last)
|
||||||
{
|
{
|
||||||
|
@ -350,7 +379,7 @@ class input_adapter
|
||||||
|
|
||||||
// assertion to check that each element is 1 byte long
|
// assertion to check that each element is 1 byte long
|
||||||
static_assert(
|
static_assert(
|
||||||
sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
|
sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
|
||||||
"each element in the iterator range must have the size of 1 byte");
|
"each element in the iterator range must have the size of 1 byte");
|
||||||
|
|
||||||
const auto len = static_cast<size_t>(std::distance(first, last));
|
const auto len = static_cast<size_t>(std::distance(first, last));
|
||||||
|
@ -374,7 +403,7 @@ class input_adapter
|
||||||
/// input adapter for contiguous container
|
/// input adapter for contiguous container
|
||||||
template<class ContiguousContainer, typename
|
template<class ContiguousContainer, typename
|
||||||
std::enable_if<not std::is_pointer<ContiguousContainer>::value and
|
std::enable_if<not std::is_pointer<ContiguousContainer>::value and
|
||||||
std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
|
std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
input_adapter(const ContiguousContainer& c)
|
input_adapter(const ContiguousContainer& c)
|
||||||
: input_adapter(std::begin(c), std::end(c)) {}
|
: input_adapter(std::begin(c), std::end(c)) {}
|
||||||
|
|
|
@ -1360,7 +1360,7 @@ scan_number_done:
|
||||||
{
|
{
|
||||||
// escape control characters
|
// escape control characters
|
||||||
char cs[9];
|
char cs[9];
|
||||||
snprintf(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
|
(std::snprintf)(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
|
||||||
result += cs;
|
result += cs;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -17,24 +17,21 @@ namespace detail
|
||||||
{
|
{
|
||||||
// forward declare, to be able to friend it later on
|
// forward declare, to be able to friend it later on
|
||||||
template<typename IteratorType> class iteration_proxy;
|
template<typename IteratorType> class iteration_proxy;
|
||||||
|
template<typename IteratorType> class iteration_proxy_value;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief a template for a bidirectional iterator for the @ref basic_json class
|
@brief a template for a bidirectional iterator for the @ref basic_json class
|
||||||
|
|
||||||
This class implements a both iterators (iterator and const_iterator) for the
|
This class implements a both iterators (iterator and const_iterator) for the
|
||||||
@ref basic_json class.
|
@ref basic_json class.
|
||||||
|
|
||||||
@note An iterator is called *initialized* when a pointer to a JSON value has
|
@note An iterator is called *initialized* when a pointer to a JSON value has
|
||||||
been set (e.g., by a constructor or a copy assignment). If the iterator is
|
been set (e.g., by a constructor or a copy assignment). If the iterator is
|
||||||
default-constructed, it is *uninitialized* and most methods are undefined.
|
default-constructed, it is *uninitialized* and most methods are undefined.
|
||||||
**The library uses assertions to detect calls on uninitialized iterators.**
|
**The library uses assertions to detect calls on uninitialized iterators.**
|
||||||
|
|
||||||
@requirement The class satisfies the following concept requirements:
|
@requirement The class satisfies the following concept requirements:
|
||||||
-
|
-
|
||||||
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
||||||
The iterator that can be moved can be moved in both directions (i.e.
|
The iterator that can be moved can be moved in both directions (i.e.
|
||||||
incremented and decremented).
|
incremented and decremented).
|
||||||
|
|
||||||
@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
|
@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
|
||||||
iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
|
iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +42,7 @@ class iter_impl
|
||||||
friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
|
friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
|
||||||
friend BasicJsonType;
|
friend BasicJsonType;
|
||||||
friend iteration_proxy<iter_impl>;
|
friend iteration_proxy<iter_impl>;
|
||||||
|
friend iteration_proxy_value<iter_impl>;
|
||||||
|
|
||||||
using object_t = typename BasicJsonType::object_t;
|
using object_t = typename BasicJsonType::object_t;
|
||||||
using array_t = typename BasicJsonType::array_t;
|
using array_t = typename BasicJsonType::array_t;
|
||||||
|
@ -611,4 +609,4 @@ class iter_impl
|
||||||
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
|
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
|
@ -3,104 +3,105 @@
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <string> // string, to_string
|
#include <string> // string, to_string
|
||||||
#include <iterator> // input_iterator_tag
|
#include <iterator> // input_iterator_tag
|
||||||
|
#include <tuple> // tuple_size, get, tuple_element
|
||||||
|
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
|
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
template <typename IteratorType> class iteration_proxy_value
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using value_type = iteration_proxy_value;
|
||||||
|
using pointer = value_type * ;
|
||||||
|
using reference = value_type & ;
|
||||||
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// the iterator
|
||||||
|
IteratorType anchor;
|
||||||
|
/// an index for arrays (used to create key names)
|
||||||
|
std::size_t array_index = 0;
|
||||||
|
/// last stringified array index
|
||||||
|
mutable std::size_t array_index_last = 0;
|
||||||
|
/// a string representation of the array index
|
||||||
|
mutable std::string array_index_str = "0";
|
||||||
|
/// an empty string (to return a reference for primitive values)
|
||||||
|
const std::string empty_str = "";
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
|
||||||
|
|
||||||
|
/// dereference operator (needed for range-based for)
|
||||||
|
iteration_proxy_value& operator*()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// increment operator (needed for range-based for)
|
||||||
|
iteration_proxy_value& operator++()
|
||||||
|
{
|
||||||
|
++anchor;
|
||||||
|
++array_index;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// equality operator (needed for InputIterator)
|
||||||
|
bool operator==(const iteration_proxy_value& o) const noexcept
|
||||||
|
{
|
||||||
|
return anchor == o.anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// inequality operator (needed for range-based for)
|
||||||
|
bool operator!=(const iteration_proxy_value& o) const noexcept
|
||||||
|
{
|
||||||
|
return anchor != o.anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return key of the iterator
|
||||||
|
const std::string& key() const
|
||||||
|
{
|
||||||
|
assert(anchor.m_object != nullptr);
|
||||||
|
|
||||||
|
switch (anchor.m_object->type())
|
||||||
|
{
|
||||||
|
// use integer array index as key
|
||||||
|
case value_t::array:
|
||||||
|
{
|
||||||
|
if (array_index != array_index_last)
|
||||||
|
{
|
||||||
|
array_index_str = std::to_string(array_index);
|
||||||
|
array_index_last = array_index;
|
||||||
|
}
|
||||||
|
return array_index_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use key from the object
|
||||||
|
case value_t::object:
|
||||||
|
return anchor.key();
|
||||||
|
|
||||||
|
// use an empty key for all primitive types
|
||||||
|
default:
|
||||||
|
return empty_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return value of the iterator
|
||||||
|
typename IteratorType::reference value() const
|
||||||
|
{
|
||||||
|
return anchor.value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// proxy class for the items() function
|
/// proxy class for the items() function
|
||||||
template<typename IteratorType> class iteration_proxy
|
template<typename IteratorType> class iteration_proxy
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/// helper class for iteration
|
|
||||||
class iteration_proxy_internal
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using difference_type = std::ptrdiff_t;
|
|
||||||
using value_type = iteration_proxy_internal;
|
|
||||||
using pointer = iteration_proxy_internal*;
|
|
||||||
using reference = iteration_proxy_internal&;
|
|
||||||
using iterator_category = std::input_iterator_tag;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// the iterator
|
|
||||||
IteratorType anchor;
|
|
||||||
/// an index for arrays (used to create key names)
|
|
||||||
std::size_t array_index = 0;
|
|
||||||
/// last stringified array index
|
|
||||||
mutable std::size_t array_index_last = 0;
|
|
||||||
/// a string representation of the array index
|
|
||||||
mutable std::string array_index_str = "0";
|
|
||||||
/// an empty string (to return a reference for primitive values)
|
|
||||||
const std::string empty_str = "";
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
|
|
||||||
|
|
||||||
/// dereference operator (needed for range-based for)
|
|
||||||
iteration_proxy_internal& operator*()
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// increment operator (needed for range-based for)
|
|
||||||
iteration_proxy_internal& operator++()
|
|
||||||
{
|
|
||||||
++anchor;
|
|
||||||
++array_index;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// equality operator (needed for InputIterator)
|
|
||||||
bool operator==(const iteration_proxy_internal& o) const noexcept
|
|
||||||
{
|
|
||||||
return anchor == o.anchor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// inequality operator (needed for range-based for)
|
|
||||||
bool operator!=(const iteration_proxy_internal& o) const noexcept
|
|
||||||
{
|
|
||||||
return anchor != o.anchor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return key of the iterator
|
|
||||||
const std::string& key() const
|
|
||||||
{
|
|
||||||
assert(anchor.m_object != nullptr);
|
|
||||||
|
|
||||||
switch (anchor.m_object->type())
|
|
||||||
{
|
|
||||||
// use integer array index as key
|
|
||||||
case value_t::array:
|
|
||||||
{
|
|
||||||
if (array_index != array_index_last)
|
|
||||||
{
|
|
||||||
array_index_str = std::to_string(array_index);
|
|
||||||
array_index_last = array_index;
|
|
||||||
}
|
|
||||||
return array_index_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// use key from the object
|
|
||||||
case value_t::object:
|
|
||||||
return anchor.key();
|
|
||||||
|
|
||||||
// use an empty key for all primitive types
|
|
||||||
default:
|
|
||||||
return empty_str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return value of the iterator
|
|
||||||
typename IteratorType::reference value() const
|
|
||||||
{
|
|
||||||
return anchor.value();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// the container to iterate
|
/// the container to iterate
|
||||||
typename IteratorType::reference container;
|
typename IteratorType::reference container;
|
||||||
|
|
||||||
|
@ -110,16 +111,52 @@ template<typename IteratorType> class iteration_proxy
|
||||||
: container(cont) {}
|
: container(cont) {}
|
||||||
|
|
||||||
/// return iterator begin (needed for range-based for)
|
/// return iterator begin (needed for range-based for)
|
||||||
iteration_proxy_internal begin() noexcept
|
iteration_proxy_value<IteratorType> begin() noexcept
|
||||||
{
|
{
|
||||||
return iteration_proxy_internal(container.begin());
|
return iteration_proxy_value<IteratorType>(container.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return iterator end (needed for range-based for)
|
/// return iterator end (needed for range-based for)
|
||||||
iteration_proxy_internal end() noexcept
|
iteration_proxy_value<IteratorType> end() noexcept
|
||||||
{
|
{
|
||||||
return iteration_proxy_internal(container.end());
|
return iteration_proxy_value<IteratorType>(container.end());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Structured Bindings Support
|
||||||
|
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
|
||||||
|
// And see https://github.com/nlohmann/json/pull/1391
|
||||||
|
template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
|
||||||
|
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
|
||||||
|
{
|
||||||
|
return i.key();
|
||||||
|
}
|
||||||
|
// Structured Bindings Support
|
||||||
|
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
|
||||||
|
// And see https://github.com/nlohmann/json/pull/1391
|
||||||
|
template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
|
||||||
|
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
|
||||||
|
{
|
||||||
|
return i.value();
|
||||||
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
||||||
|
// The Addition to the STD Namespace is required to add
|
||||||
|
// Structured Bindings Support to the iteration_proxy_value class
|
||||||
|
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
|
||||||
|
// And see https://github.com/nlohmann/json/pull/1391
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <typename IteratorType>
|
||||||
|
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
|
||||||
|
: public std::integral_constant<std::size_t, 2> {};
|
||||||
|
|
||||||
|
template <std::size_t N, typename IteratorType>
|
||||||
|
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using type = decltype(
|
||||||
|
get<N>(std::declval <
|
||||||
|
::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
|
||||||
|
};
|
||||||
|
}
|
49
include/nlohmann/detail/iterators/iterator_traits.hpp
Normal file
49
include/nlohmann/detail/iterators/iterator_traits.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iterator> // random_access_iterator_tag
|
||||||
|
|
||||||
|
#include <nlohmann/detail/meta/void_t.hpp>
|
||||||
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename It, typename = void>
|
||||||
|
struct iterator_types {};
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
struct iterator_types<
|
||||||
|
It,
|
||||||
|
void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
|
||||||
|
typename It::reference, typename It::iterator_category>> {
|
||||||
|
using difference_type = typename It::difference_type;
|
||||||
|
using value_type = typename It::value_type;
|
||||||
|
using pointer = typename It::pointer;
|
||||||
|
using reference = typename It::reference;
|
||||||
|
using iterator_category = typename It::iterator_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is required as some compilers implement std::iterator_traits in a way that
|
||||||
|
// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct iterator_traits
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct iterator_traits<T, enable_if_t<!std::is_pointer<T>::value>>
|
||||||
|
: iterator_types<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>> {
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
using value_type = T;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
using pointer = T*;
|
||||||
|
using reference = T&;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
#include <utility> // declval
|
#include <utility> // declval
|
||||||
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
#include <nlohmann/detail/iterators/iterator_traits.hpp>
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
#include <nlohmann/detail/meta/detected.hpp>
|
#include <nlohmann/detail/meta/detected.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
@ -131,10 +132,10 @@ template <typename T, typename = void>
|
||||||
struct is_iterator_traits : std::false_type {};
|
struct is_iterator_traits : std::false_type {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_iterator_traits<std::iterator_traits<T>>
|
struct is_iterator_traits<iterator_traits<T>>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using traits = std::iterator_traits<T>;
|
using traits = iterator_traits<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr auto value =
|
static constexpr auto value =
|
||||||
|
@ -251,7 +252,7 @@ struct is_compatible_array_type_impl <
|
||||||
// Therefore it is detected as a CompatibleArrayType.
|
// Therefore it is detected as a CompatibleArrayType.
|
||||||
// The real fix would be to have an Iterable concept.
|
// The real fix would be to have an Iterable concept.
|
||||||
not is_iterator_traits<
|
not is_iterator_traits<
|
||||||
std::iterator_traits<CompatibleArrayType>>::value >>
|
iterator_traits<CompatibleArrayType>>::value >>
|
||||||
{
|
{
|
||||||
static constexpr bool value =
|
static constexpr bool value =
|
||||||
std::is_constructible<BasicJsonType,
|
std::is_constructible<BasicJsonType,
|
||||||
|
@ -288,7 +289,7 @@ struct is_constructible_array_type_impl <
|
||||||
// Therefore it is detected as a ConstructibleArrayType.
|
// Therefore it is detected as a ConstructibleArrayType.
|
||||||
// The real fix would be to have an Iterable concept.
|
// The real fix would be to have an Iterable concept.
|
||||||
not is_iterator_traits <
|
not is_iterator_traits <
|
||||||
std::iterator_traits<ConstructibleArrayType >>::value and
|
iterator_traits<ConstructibleArrayType >>::value and
|
||||||
|
|
||||||
(std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
|
(std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
|
||||||
has_from_json<BasicJsonType,
|
has_from_json<BasicJsonType,
|
||||||
|
|
|
@ -372,15 +372,15 @@ class serializer
|
||||||
{
|
{
|
||||||
if (codepoint <= 0xFFFF)
|
if (codepoint <= 0xFFFF)
|
||||||
{
|
{
|
||||||
std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x",
|
(std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
|
||||||
static_cast<uint16_t>(codepoint));
|
static_cast<uint16_t>(codepoint));
|
||||||
bytes += 6;
|
bytes += 6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
|
(std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
|
||||||
static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
|
static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
|
||||||
static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
|
static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
|
||||||
bytes += 12;
|
bytes += 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,7 @@ class serializer
|
||||||
case error_handler_t::strict:
|
case error_handler_t::strict:
|
||||||
{
|
{
|
||||||
std::string sn(3, '\0');
|
std::string sn(3, '\0');
|
||||||
snprintf(&sn[0], sn.size(), "%.2X", byte);
|
(std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
|
||||||
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
|
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,7 +497,7 @@ class serializer
|
||||||
case error_handler_t::strict:
|
case error_handler_t::strict:
|
||||||
{
|
{
|
||||||
std::string sn(3, '\0');
|
std::string sn(3, '\0');
|
||||||
snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
|
(std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
|
||||||
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
|
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +616,7 @@ class serializer
|
||||||
static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
|
static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
|
||||||
|
|
||||||
// the actual conversion
|
// the actual conversion
|
||||||
std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
|
std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
|
||||||
|
|
||||||
// negative value indicates an error
|
// negative value indicates an error
|
||||||
assert(len > 0);
|
assert(len > 0);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++
|
__| | __| | | | JSON for Modern C++
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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 4
|
#define NLOHMANN_JSON_VERSION_MINOR 5
|
||||||
#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
|
||||||
|
@ -41,7 +41,7 @@ SOFTWARE.
|
||||||
#include <functional> // hash, less
|
#include <functional> // hash, less
|
||||||
#include <initializer_list> // initializer_list
|
#include <initializer_list> // initializer_list
|
||||||
#include <iosfwd> // istream, ostream
|
#include <iosfwd> // istream, ostream
|
||||||
#include <iterator> // iterator_traits, random_access_iterator_tag
|
#include <iterator> // random_access_iterator_tag
|
||||||
#include <numeric> // accumulate
|
#include <numeric> // accumulate
|
||||||
#include <string> // string, stoi, to_string
|
#include <string> // string, stoi, to_string
|
||||||
#include <utility> // declval, forward, move, pair, swap
|
#include <utility> // declval, forward, move, pair, swap
|
||||||
|
@ -949,7 +949,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.4.0")); // LCOV_EXCL_LINE
|
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.5.0")); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4340,9 +4340,20 @@ class basic_json
|
||||||
Range-based for loop with `items()` function:
|
Range-based for loop with `items()` function:
|
||||||
|
|
||||||
@code{cpp}
|
@code{cpp}
|
||||||
for (auto it : j_object.items())
|
for (auto& el : j_object.items())
|
||||||
{
|
{
|
||||||
std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
|
std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The `items()` function also allows to use
|
||||||
|
[structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
|
||||||
|
(C++17):
|
||||||
|
|
||||||
|
@code{cpp}
|
||||||
|
for (auto& [key, val] : j_object.items())
|
||||||
|
{
|
||||||
|
std::cout << "key: " << key << ", value:" << val << '\n';
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
@ -4360,7 +4371,7 @@ class basic_json
|
||||||
|
|
||||||
@complexity Constant.
|
@complexity Constant.
|
||||||
|
|
||||||
@since version 3.1.0.
|
@since version 3.1.0, structured bindings support since 3.5.0.
|
||||||
*/
|
*/
|
||||||
iteration_proxy<iterator> items() noexcept
|
iteration_proxy<iterator> items() noexcept
|
||||||
{
|
{
|
||||||
|
@ -7851,7 +7862,7 @@ class basic_json
|
||||||
Thereby, `Target` is the current object; that is, the patch is applied to
|
Thereby, `Target` is the current object; that is, the patch is applied to
|
||||||
the current value.
|
the current value.
|
||||||
|
|
||||||
@param[in] patch the patch to apply
|
@param[in] apply_patch the patch to apply
|
||||||
|
|
||||||
@complexity Linear in the lengths of @a patch.
|
@complexity Linear in the lengths of @a patch.
|
||||||
|
|
||||||
|
@ -7863,15 +7874,15 @@ class basic_json
|
||||||
|
|
||||||
@since version 3.0.0
|
@since version 3.0.0
|
||||||
*/
|
*/
|
||||||
void merge_patch(const basic_json& patch)
|
void merge_patch(const basic_json& apply_patch)
|
||||||
{
|
{
|
||||||
if (patch.is_object())
|
if (apply_patch.is_object())
|
||||||
{
|
{
|
||||||
if (not is_object())
|
if (not is_object())
|
||||||
{
|
{
|
||||||
*this = object();
|
*this = object();
|
||||||
}
|
}
|
||||||
for (auto it = patch.begin(); it != patch.end(); ++it)
|
for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it.value().is_null())
|
if (it.value().is_null())
|
||||||
{
|
{
|
||||||
|
@ -7885,7 +7896,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*this = patch;
|
*this = apply_patch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
meson.build
10
meson.build
|
@ -1,6 +1,6 @@
|
||||||
project('nlohmann_json',
|
project('nlohmann_json',
|
||||||
'cpp',
|
'cpp',
|
||||||
version : '3.4.0',
|
version : '3.5.0',
|
||||||
license : 'MIT',
|
license : 'MIT',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,3 +11,11 @@ nlohmann_json_dep = declare_dependency(
|
||||||
nlohmann_json_multiple_headers = declare_dependency(
|
nlohmann_json_multiple_headers = declare_dependency(
|
||||||
include_directories: include_directories('include')
|
include_directories: include_directories('include')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann')
|
||||||
|
|
||||||
|
pkgc = import('pkgconfig')
|
||||||
|
pkgc.generate(name: 'nlohmann_json',
|
||||||
|
version: meson.project_version(),
|
||||||
|
description: 'JSON for Modern C++'
|
||||||
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++
|
__| | __| | | | JSON for Modern C++
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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 4
|
#define NLOHMANN_JSON_VERSION_MINOR 5
|
||||||
#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
|
||||||
|
@ -41,7 +41,7 @@ SOFTWARE.
|
||||||
#include <functional> // hash, less
|
#include <functional> // hash, less
|
||||||
#include <initializer_list> // initializer_list
|
#include <initializer_list> // initializer_list
|
||||||
#include <iosfwd> // istream, ostream
|
#include <iosfwd> // istream, ostream
|
||||||
#include <iterator> // iterator_traits, random_access_iterator_tag
|
#include <iterator> // random_access_iterator_tag
|
||||||
#include <numeric> // accumulate
|
#include <numeric> // accumulate
|
||||||
#include <string> // string, stoi, to_string
|
#include <string> // string, stoi, to_string
|
||||||
#include <utility> // declval, forward, move, pair, swap
|
#include <utility> // declval, forward, move, pair, swap
|
||||||
|
@ -324,12 +324,10 @@ constexpr T static_const<T>::value;
|
||||||
|
|
||||||
// #include <nlohmann/json_fwd.hpp>
|
// #include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta/detected.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
#include <type_traits>
|
#include <iterator> // random_access_iterator_tag
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta/void_t.hpp>
|
// #include <nlohmann/detail/meta/void_t.hpp>
|
||||||
|
|
||||||
|
@ -346,6 +344,63 @@ template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename It, typename = void>
|
||||||
|
struct iterator_types {};
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
struct iterator_types <
|
||||||
|
It,
|
||||||
|
void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
|
||||||
|
typename It::reference, typename It::iterator_category >>
|
||||||
|
{
|
||||||
|
using difference_type = typename It::difference_type;
|
||||||
|
using value_type = typename It::value_type;
|
||||||
|
using pointer = typename It::pointer;
|
||||||
|
using reference = typename It::reference;
|
||||||
|
using iterator_category = typename It::iterator_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is required as some compilers implement std::iterator_traits in a way that
|
||||||
|
// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct iterator_traits
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
|
||||||
|
: iterator_types<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
|
||||||
|
{
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
using value_type = T;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
using pointer = T*;
|
||||||
|
using reference = T&;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/detected.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/void_t.hpp>
|
||||||
|
|
||||||
|
|
||||||
// http://en.cppreference.com/w/cpp/experimental/is_detected
|
// http://en.cppreference.com/w/cpp/experimental/is_detected
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
|
@ -522,10 +577,10 @@ template <typename T, typename = void>
|
||||||
struct is_iterator_traits : std::false_type {};
|
struct is_iterator_traits : std::false_type {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_iterator_traits<std::iterator_traits<T>>
|
struct is_iterator_traits<iterator_traits<T>>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using traits = std::iterator_traits<T>;
|
using traits = iterator_traits<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr auto value =
|
static constexpr auto value =
|
||||||
|
@ -642,7 +697,7 @@ struct is_compatible_array_type_impl <
|
||||||
// Therefore it is detected as a CompatibleArrayType.
|
// Therefore it is detected as a CompatibleArrayType.
|
||||||
// The real fix would be to have an Iterable concept.
|
// The real fix would be to have an Iterable concept.
|
||||||
not is_iterator_traits<
|
not is_iterator_traits<
|
||||||
std::iterator_traits<CompatibleArrayType>>::value >>
|
iterator_traits<CompatibleArrayType>>::value >>
|
||||||
{
|
{
|
||||||
static constexpr bool value =
|
static constexpr bool value =
|
||||||
std::is_constructible<BasicJsonType,
|
std::is_constructible<BasicJsonType,
|
||||||
|
@ -679,7 +734,7 @@ struct is_constructible_array_type_impl <
|
||||||
// Therefore it is detected as a ConstructibleArrayType.
|
// Therefore it is detected as a ConstructibleArrayType.
|
||||||
// The real fix would be to have an Iterable concept.
|
// The real fix would be to have an Iterable concept.
|
||||||
not is_iterator_traits <
|
not is_iterator_traits <
|
||||||
std::iterator_traits<ConstructibleArrayType >>::value and
|
iterator_traits<ConstructibleArrayType >>::value and
|
||||||
|
|
||||||
(std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
|
(std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
|
||||||
has_from_json<BasicJsonType,
|
has_from_json<BasicJsonType,
|
||||||
|
@ -1594,105 +1649,107 @@ constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::va
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <string> // string, to_string
|
#include <string> // string, to_string
|
||||||
#include <iterator> // input_iterator_tag
|
#include <iterator> // input_iterator_tag
|
||||||
|
#include <tuple> // tuple_size, get, tuple_element
|
||||||
|
|
||||||
// #include <nlohmann/detail/value_t.hpp>
|
// #include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
template <typename IteratorType> class iteration_proxy_value
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using value_type = iteration_proxy_value;
|
||||||
|
using pointer = value_type * ;
|
||||||
|
using reference = value_type & ;
|
||||||
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// the iterator
|
||||||
|
IteratorType anchor;
|
||||||
|
/// an index for arrays (used to create key names)
|
||||||
|
std::size_t array_index = 0;
|
||||||
|
/// last stringified array index
|
||||||
|
mutable std::size_t array_index_last = 0;
|
||||||
|
/// a string representation of the array index
|
||||||
|
mutable std::string array_index_str = "0";
|
||||||
|
/// an empty string (to return a reference for primitive values)
|
||||||
|
const std::string empty_str = "";
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
|
||||||
|
|
||||||
|
/// dereference operator (needed for range-based for)
|
||||||
|
iteration_proxy_value& operator*()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// increment operator (needed for range-based for)
|
||||||
|
iteration_proxy_value& operator++()
|
||||||
|
{
|
||||||
|
++anchor;
|
||||||
|
++array_index;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// equality operator (needed for InputIterator)
|
||||||
|
bool operator==(const iteration_proxy_value& o) const noexcept
|
||||||
|
{
|
||||||
|
return anchor == o.anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// inequality operator (needed for range-based for)
|
||||||
|
bool operator!=(const iteration_proxy_value& o) const noexcept
|
||||||
|
{
|
||||||
|
return anchor != o.anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return key of the iterator
|
||||||
|
const std::string& key() const
|
||||||
|
{
|
||||||
|
assert(anchor.m_object != nullptr);
|
||||||
|
|
||||||
|
switch (anchor.m_object->type())
|
||||||
|
{
|
||||||
|
// use integer array index as key
|
||||||
|
case value_t::array:
|
||||||
|
{
|
||||||
|
if (array_index != array_index_last)
|
||||||
|
{
|
||||||
|
array_index_str = std::to_string(array_index);
|
||||||
|
array_index_last = array_index;
|
||||||
|
}
|
||||||
|
return array_index_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use key from the object
|
||||||
|
case value_t::object:
|
||||||
|
return anchor.key();
|
||||||
|
|
||||||
|
// use an empty key for all primitive types
|
||||||
|
default:
|
||||||
|
return empty_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return value of the iterator
|
||||||
|
typename IteratorType::reference value() const
|
||||||
|
{
|
||||||
|
return anchor.value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// proxy class for the items() function
|
/// proxy class for the items() function
|
||||||
template<typename IteratorType> class iteration_proxy
|
template<typename IteratorType> class iteration_proxy
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/// helper class for iteration
|
|
||||||
class iteration_proxy_internal
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using difference_type = std::ptrdiff_t;
|
|
||||||
using value_type = iteration_proxy_internal;
|
|
||||||
using pointer = iteration_proxy_internal*;
|
|
||||||
using reference = iteration_proxy_internal&;
|
|
||||||
using iterator_category = std::input_iterator_tag;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// the iterator
|
|
||||||
IteratorType anchor;
|
|
||||||
/// an index for arrays (used to create key names)
|
|
||||||
std::size_t array_index = 0;
|
|
||||||
/// last stringified array index
|
|
||||||
mutable std::size_t array_index_last = 0;
|
|
||||||
/// a string representation of the array index
|
|
||||||
mutable std::string array_index_str = "0";
|
|
||||||
/// an empty string (to return a reference for primitive values)
|
|
||||||
const std::string empty_str = "";
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
|
|
||||||
|
|
||||||
/// dereference operator (needed for range-based for)
|
|
||||||
iteration_proxy_internal& operator*()
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// increment operator (needed for range-based for)
|
|
||||||
iteration_proxy_internal& operator++()
|
|
||||||
{
|
|
||||||
++anchor;
|
|
||||||
++array_index;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// equality operator (needed for InputIterator)
|
|
||||||
bool operator==(const iteration_proxy_internal& o) const noexcept
|
|
||||||
{
|
|
||||||
return anchor == o.anchor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// inequality operator (needed for range-based for)
|
|
||||||
bool operator!=(const iteration_proxy_internal& o) const noexcept
|
|
||||||
{
|
|
||||||
return anchor != o.anchor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return key of the iterator
|
|
||||||
const std::string& key() const
|
|
||||||
{
|
|
||||||
assert(anchor.m_object != nullptr);
|
|
||||||
|
|
||||||
switch (anchor.m_object->type())
|
|
||||||
{
|
|
||||||
// use integer array index as key
|
|
||||||
case value_t::array:
|
|
||||||
{
|
|
||||||
if (array_index != array_index_last)
|
|
||||||
{
|
|
||||||
array_index_str = std::to_string(array_index);
|
|
||||||
array_index_last = array_index;
|
|
||||||
}
|
|
||||||
return array_index_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// use key from the object
|
|
||||||
case value_t::object:
|
|
||||||
return anchor.key();
|
|
||||||
|
|
||||||
// use an empty key for all primitive types
|
|
||||||
default:
|
|
||||||
return empty_str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return value of the iterator
|
|
||||||
typename IteratorType::reference value() const
|
|
||||||
{
|
|
||||||
return anchor.value();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// the container to iterate
|
/// the container to iterate
|
||||||
typename IteratorType::reference container;
|
typename IteratorType::reference container;
|
||||||
|
|
||||||
|
@ -1702,20 +1759,55 @@ template<typename IteratorType> class iteration_proxy
|
||||||
: container(cont) {}
|
: container(cont) {}
|
||||||
|
|
||||||
/// return iterator begin (needed for range-based for)
|
/// return iterator begin (needed for range-based for)
|
||||||
iteration_proxy_internal begin() noexcept
|
iteration_proxy_value<IteratorType> begin() noexcept
|
||||||
{
|
{
|
||||||
return iteration_proxy_internal(container.begin());
|
return iteration_proxy_value<IteratorType>(container.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return iterator end (needed for range-based for)
|
/// return iterator end (needed for range-based for)
|
||||||
iteration_proxy_internal end() noexcept
|
iteration_proxy_value<IteratorType> end() noexcept
|
||||||
{
|
{
|
||||||
return iteration_proxy_internal(container.end());
|
return iteration_proxy_value<IteratorType>(container.end());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Structured Bindings Support
|
||||||
|
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
|
||||||
|
// And see https://github.com/nlohmann/json/pull/1391
|
||||||
|
template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
|
||||||
|
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
|
||||||
|
{
|
||||||
|
return i.key();
|
||||||
|
}
|
||||||
|
// Structured Bindings Support
|
||||||
|
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
|
||||||
|
// And see https://github.com/nlohmann/json/pull/1391
|
||||||
|
template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
|
||||||
|
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
|
||||||
|
{
|
||||||
|
return i.value();
|
||||||
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
||||||
|
// The Addition to the STD Namespace is required to add
|
||||||
|
// Structured Bindings Support to the iteration_proxy_value class
|
||||||
|
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
|
||||||
|
// And see https://github.com/nlohmann/json/pull/1391
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <typename IteratorType>
|
||||||
|
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
|
||||||
|
: public std::integral_constant<std::size_t, 2> {};
|
||||||
|
|
||||||
|
template <std::size_t N, typename IteratorType>
|
||||||
|
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using type = decltype(
|
||||||
|
get<N>(std::declval <
|
||||||
|
::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
{
|
{
|
||||||
|
@ -1994,9 +2086,9 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
||||||
template <
|
template <
|
||||||
typename BasicJsonType, typename T, std::size_t N,
|
typename BasicJsonType, typename T, std::size_t N,
|
||||||
enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
|
enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
|
||||||
const T (&)[N]>::value,
|
const T(&)[N]>::value,
|
||||||
int> = 0 >
|
int> = 0 >
|
||||||
void to_json(BasicJsonType& j, const T (&arr)[N])
|
void to_json(BasicJsonType& j, const T(&arr)[N])
|
||||||
{
|
{
|
||||||
external_constructor<value_t::array>::construct(j, arr);
|
external_constructor<value_t::array>::construct(j, arr);
|
||||||
}
|
}
|
||||||
|
@ -2004,21 +2096,21 @@ void to_json(BasicJsonType& j, const T (&arr)[N])
|
||||||
template<typename BasicJsonType, typename... Args>
|
template<typename BasicJsonType, typename... Args>
|
||||||
void to_json(BasicJsonType& j, const std::pair<Args...>& p)
|
void to_json(BasicJsonType& j, const std::pair<Args...>& p)
|
||||||
{
|
{
|
||||||
j = {p.first, p.second};
|
j = { p.first, p.second };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
|
||||||
void to_json(BasicJsonType& j, const T& b)
|
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...> /*unused*/)
|
void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
|
||||||
{
|
{
|
||||||
j = {std::get<Idx>(t)...};
|
j = { std::get<Idx>(t)... };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename... Args>
|
template<typename BasicJsonType, typename... Args>
|
||||||
|
@ -2058,6 +2150,7 @@ constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
|
||||||
#include <string> // string, char_traits
|
#include <string> // string, char_traits
|
||||||
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
|
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
|
||||||
#include <utility> // pair, declval
|
#include <utility> // pair, declval
|
||||||
|
#include <cstdio> //FILE *
|
||||||
|
|
||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
|
@ -2094,6 +2187,27 @@ struct input_adapter_protocol
|
||||||
/// a type to simplify interfaces
|
/// a type to simplify interfaces
|
||||||
using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
|
using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Input adapter for stdio file access. This adapter read only 1 byte and do not use any
|
||||||
|
buffer. This adapter is a very low level adapter.
|
||||||
|
*/
|
||||||
|
class file_input_adapter : public input_adapter_protocol
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit file_input_adapter(std::FILE* f) noexcept
|
||||||
|
: m_file(f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::char_traits<char>::int_type get_character() noexcept override
|
||||||
|
{
|
||||||
|
return std::fgetc(m_file);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
/// the file pointer to read from
|
||||||
|
std::FILE* m_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
|
Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
|
||||||
beginning of input. Does not support changing the underlying std::streambuf
|
beginning of input. Does not support changing the underlying std::streambuf
|
||||||
|
@ -2109,8 +2223,8 @@ class input_stream_adapter : public input_adapter_protocol
|
||||||
~input_stream_adapter() override
|
~input_stream_adapter() override
|
||||||
{
|
{
|
||||||
// clear stream flags; we use underlying streambuf I/O, do not
|
// clear stream flags; we use underlying streambuf I/O, do not
|
||||||
// maintain ifstream flags
|
// maintain ifstream flags, except eof
|
||||||
is.clear();
|
is.clear(is.rdstate() & std::ios::eofbit);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit input_stream_adapter(std::istream& i)
|
explicit input_stream_adapter(std::istream& i)
|
||||||
|
@ -2128,7 +2242,13 @@ class input_stream_adapter : public input_adapter_protocol
|
||||||
// end up as the same value, eg. 0xFFFFFFFF.
|
// end up as the same value, eg. 0xFFFFFFFF.
|
||||||
std::char_traits<char>::int_type get_character() override
|
std::char_traits<char>::int_type get_character() override
|
||||||
{
|
{
|
||||||
return sb.sbumpc();
|
auto res = sb.sbumpc();
|
||||||
|
// set eof manually, as we don't use the istream interface.
|
||||||
|
if (res == EOF)
|
||||||
|
{
|
||||||
|
is.clear(is.rdstate() | std::ios::eofbit);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -2336,7 +2456,8 @@ class input_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// native support
|
// native support
|
||||||
|
input_adapter(std::FILE* file)
|
||||||
|
: ia(std::make_shared<file_input_adapter>(file)) {}
|
||||||
/// input adapter for input stream
|
/// input adapter for input stream
|
||||||
input_adapter(std::istream& i)
|
input_adapter(std::istream& i)
|
||||||
: ia(std::make_shared<input_stream_adapter>(i)) {}
|
: ia(std::make_shared<input_stream_adapter>(i)) {}
|
||||||
|
@ -2380,7 +2501,7 @@ class input_adapter
|
||||||
/// input adapter for iterator range with contiguous storage
|
/// input adapter for iterator range with contiguous storage
|
||||||
template<class IteratorType,
|
template<class IteratorType,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
|
std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
input_adapter(IteratorType first, IteratorType last)
|
input_adapter(IteratorType first, IteratorType last)
|
||||||
{
|
{
|
||||||
|
@ -2399,7 +2520,7 @@ class input_adapter
|
||||||
|
|
||||||
// assertion to check that each element is 1 byte long
|
// assertion to check that each element is 1 byte long
|
||||||
static_assert(
|
static_assert(
|
||||||
sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
|
sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
|
||||||
"each element in the iterator range must have the size of 1 byte");
|
"each element in the iterator range must have the size of 1 byte");
|
||||||
|
|
||||||
const auto len = static_cast<size_t>(std::distance(first, last));
|
const auto len = static_cast<size_t>(std::distance(first, last));
|
||||||
|
@ -2423,7 +2544,7 @@ class input_adapter
|
||||||
/// input adapter for contiguous container
|
/// input adapter for contiguous container
|
||||||
template<class ContiguousContainer, typename
|
template<class ContiguousContainer, typename
|
||||||
std::enable_if<not std::is_pointer<ContiguousContainer>::value and
|
std::enable_if<not std::is_pointer<ContiguousContainer>::value and
|
||||||
std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
|
std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
input_adapter(const ContiguousContainer& c)
|
input_adapter(const ContiguousContainer& c)
|
||||||
: input_adapter(std::begin(c), std::end(c)) {}
|
: input_adapter(std::begin(c), std::end(c)) {}
|
||||||
|
@ -3806,7 +3927,7 @@ scan_number_done:
|
||||||
{
|
{
|
||||||
// escape control characters
|
// escape control characters
|
||||||
char cs[9];
|
char cs[9];
|
||||||
snprintf(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
|
(std::snprintf)(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
|
||||||
result += cs;
|
result += cs;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5486,24 +5607,21 @@ namespace detail
|
||||||
{
|
{
|
||||||
// forward declare, to be able to friend it later on
|
// forward declare, to be able to friend it later on
|
||||||
template<typename IteratorType> class iteration_proxy;
|
template<typename IteratorType> class iteration_proxy;
|
||||||
|
template<typename IteratorType> class iteration_proxy_value;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief a template for a bidirectional iterator for the @ref basic_json class
|
@brief a template for a bidirectional iterator for the @ref basic_json class
|
||||||
|
|
||||||
This class implements a both iterators (iterator and const_iterator) for the
|
This class implements a both iterators (iterator and const_iterator) for the
|
||||||
@ref basic_json class.
|
@ref basic_json class.
|
||||||
|
|
||||||
@note An iterator is called *initialized* when a pointer to a JSON value has
|
@note An iterator is called *initialized* when a pointer to a JSON value has
|
||||||
been set (e.g., by a constructor or a copy assignment). If the iterator is
|
been set (e.g., by a constructor or a copy assignment). If the iterator is
|
||||||
default-constructed, it is *uninitialized* and most methods are undefined.
|
default-constructed, it is *uninitialized* and most methods are undefined.
|
||||||
**The library uses assertions to detect calls on uninitialized iterators.**
|
**The library uses assertions to detect calls on uninitialized iterators.**
|
||||||
|
|
||||||
@requirement The class satisfies the following concept requirements:
|
@requirement The class satisfies the following concept requirements:
|
||||||
-
|
-
|
||||||
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
||||||
The iterator that can be moved can be moved in both directions (i.e.
|
The iterator that can be moved can be moved in both directions (i.e.
|
||||||
incremented and decremented).
|
incremented and decremented).
|
||||||
|
|
||||||
@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
|
@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
|
||||||
iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
|
iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
|
||||||
*/
|
*/
|
||||||
|
@ -5514,6 +5632,7 @@ class iter_impl
|
||||||
friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
|
friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
|
||||||
friend BasicJsonType;
|
friend BasicJsonType;
|
||||||
friend iteration_proxy<iter_impl>;
|
friend iteration_proxy<iter_impl>;
|
||||||
|
friend iteration_proxy_value<iter_impl>;
|
||||||
|
|
||||||
using object_t = typename BasicJsonType::object_t;
|
using object_t = typename BasicJsonType::object_t;
|
||||||
using array_t = typename BasicJsonType::array_t;
|
using array_t = typename BasicJsonType::array_t;
|
||||||
|
@ -6080,8 +6199,7 @@ class iter_impl
|
||||||
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
|
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
||||||
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
|
// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
|
||||||
|
@ -6576,7 +6694,7 @@ class binary_reader
|
||||||
|
|
||||||
case 0x08: // boolean
|
case 0x08: // boolean
|
||||||
{
|
{
|
||||||
return sax->boolean(static_cast<bool>(get()));
|
return sax->boolean(get() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x0A: // null
|
case 0x0A: // null
|
||||||
|
@ -6599,7 +6717,7 @@ class binary_reader
|
||||||
default: // anything else not supported (yet)
|
default: // anything else not supported (yet)
|
||||||
{
|
{
|
||||||
char cr[3];
|
char cr[3];
|
||||||
snprintf(cr, sizeof(cr), "%.2hhX", static_cast<unsigned char>(element_type));
|
(std::snprintf)(cr, sizeof(cr), "%.2hhX", static_cast<unsigned char>(element_type));
|
||||||
return sax->parse_error(element_type_parse_position, std::string(cr), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr)));
|
return sax->parse_error(element_type_parse_position, std::string(cr), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6635,7 +6753,10 @@ class binary_reader
|
||||||
|
|
||||||
if (not is_array)
|
if (not is_array)
|
||||||
{
|
{
|
||||||
sax->key(key);
|
if (not sax->key(key))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
|
if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
|
||||||
|
@ -8253,7 +8374,7 @@ class binary_reader
|
||||||
std::string get_token_string() const
|
std::string get_token_string() const
|
||||||
{
|
{
|
||||||
char cr[3];
|
char cr[3];
|
||||||
snprintf(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
|
(std::snprintf)(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
|
||||||
return std::string{cr};
|
return std::string{cr};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11134,15 +11255,15 @@ class serializer
|
||||||
{
|
{
|
||||||
if (codepoint <= 0xFFFF)
|
if (codepoint <= 0xFFFF)
|
||||||
{
|
{
|
||||||
std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x",
|
(std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
|
||||||
static_cast<uint16_t>(codepoint));
|
static_cast<uint16_t>(codepoint));
|
||||||
bytes += 6;
|
bytes += 6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
|
(std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
|
||||||
static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
|
static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
|
||||||
static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
|
static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
|
||||||
bytes += 12;
|
bytes += 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11178,7 +11299,7 @@ class serializer
|
||||||
case error_handler_t::strict:
|
case error_handler_t::strict:
|
||||||
{
|
{
|
||||||
std::string sn(3, '\0');
|
std::string sn(3, '\0');
|
||||||
snprintf(&sn[0], sn.size(), "%.2X", byte);
|
(std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
|
||||||
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
|
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11259,7 +11380,7 @@ class serializer
|
||||||
case error_handler_t::strict:
|
case error_handler_t::strict:
|
||||||
{
|
{
|
||||||
std::string sn(3, '\0');
|
std::string sn(3, '\0');
|
||||||
snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
|
(std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
|
||||||
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
|
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11378,7 +11499,7 @@ class serializer
|
||||||
static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
|
static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
|
||||||
|
|
||||||
// the actual conversion
|
// the actual conversion
|
||||||
std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
|
std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
|
||||||
|
|
||||||
// negative value indicates an error
|
// negative value indicates an error
|
||||||
assert(len > 0);
|
assert(len > 0);
|
||||||
|
@ -13208,7 +13329,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.4.0")); // LCOV_EXCL_LINE
|
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.5.0")); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -16599,9 +16720,20 @@ class basic_json
|
||||||
Range-based for loop with `items()` function:
|
Range-based for loop with `items()` function:
|
||||||
|
|
||||||
@code{cpp}
|
@code{cpp}
|
||||||
for (auto it : j_object.items())
|
for (auto& el : j_object.items())
|
||||||
{
|
{
|
||||||
std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
|
std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The `items()` function also allows to use
|
||||||
|
[structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
|
||||||
|
(C++17):
|
||||||
|
|
||||||
|
@code{cpp}
|
||||||
|
for (auto& [key, val] : j_object.items())
|
||||||
|
{
|
||||||
|
std::cout << "key: " << key << ", value:" << val << '\n';
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
@ -16619,7 +16751,7 @@ class basic_json
|
||||||
|
|
||||||
@complexity Constant.
|
@complexity Constant.
|
||||||
|
|
||||||
@since version 3.1.0.
|
@since version 3.1.0, structured bindings support since 3.5.0.
|
||||||
*/
|
*/
|
||||||
iteration_proxy<iterator> items() noexcept
|
iteration_proxy<iterator> items() noexcept
|
||||||
{
|
{
|
||||||
|
@ -20110,7 +20242,7 @@ class basic_json
|
||||||
Thereby, `Target` is the current object; that is, the patch is applied to
|
Thereby, `Target` is the current object; that is, the patch is applied to
|
||||||
the current value.
|
the current value.
|
||||||
|
|
||||||
@param[in] patch the patch to apply
|
@param[in] apply_patch the patch to apply
|
||||||
|
|
||||||
@complexity Linear in the lengths of @a patch.
|
@complexity Linear in the lengths of @a patch.
|
||||||
|
|
||||||
|
@ -20122,15 +20254,15 @@ class basic_json
|
||||||
|
|
||||||
@since version 3.0.0
|
@since version 3.0.0
|
||||||
*/
|
*/
|
||||||
void merge_patch(const basic_json& patch)
|
void merge_patch(const basic_json& apply_patch)
|
||||||
{
|
{
|
||||||
if (patch.is_object())
|
if (apply_patch.is_object())
|
||||||
{
|
{
|
||||||
if (not is_object())
|
if (not is_object())
|
||||||
{
|
{
|
||||||
*this = object();
|
*this = object();
|
||||||
}
|
}
|
||||||
for (auto it = patch.begin(); it != patch.end(); ++it)
|
for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it.value().is_null())
|
if (it.value().is_null())
|
||||||
{
|
{
|
||||||
|
@ -20144,7 +20276,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*this = patch;
|
*this = apply_patch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
@ -752,6 +752,28 @@ TEST_CASE("Incomplete BSON Input")
|
||||||
SaxCountdown scp(0);
|
SaxCountdown scp(0);
|
||||||
CHECK(not json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
|
CHECK(not json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("Improve coverage")
|
||||||
|
{
|
||||||
|
SECTION("key")
|
||||||
|
{
|
||||||
|
json j = {{"key", "value"}};
|
||||||
|
auto bson_vec = json::to_bson(j);
|
||||||
|
SaxCountdown scp(2);
|
||||||
|
CHECK(not json::sax_parse(bson_vec, &scp, json::input_format_t::bson));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array")
|
||||||
|
{
|
||||||
|
json j =
|
||||||
|
{
|
||||||
|
{ "entry", json::array() }
|
||||||
|
};
|
||||||
|
auto bson_vec = json::to_bson(j);
|
||||||
|
SaxCountdown scp(2);
|
||||||
|
CHECK(not json::sax_parse(bson_vec, &scp, json::input_format_t::bson));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Unsupported BSON input")
|
TEST_CASE("Unsupported BSON input")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
@ -32,13 +32,20 @@ SOFTWARE.
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
|
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
||||||
|
#define JSON_HAS_CPP_17
|
||||||
|
#define JSON_HAS_CPP_14
|
||||||
|
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
|
||||||
|
#define JSON_HAS_CPP_14
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_CASE("iterator_wrapper")
|
TEST_CASE("iterator_wrapper")
|
||||||
{
|
{
|
||||||
SECTION("object")
|
SECTION("object")
|
||||||
{
|
{
|
||||||
SECTION("value")
|
SECTION("value")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : json::iterator_wrapper(j))
|
for (auto i : json::iterator_wrapper(j))
|
||||||
|
@ -71,7 +78,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("reference")
|
SECTION("reference")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto& i : json::iterator_wrapper(j))
|
for (auto& i : json::iterator_wrapper(j))
|
||||||
|
@ -110,12 +117,12 @@ TEST_CASE("iterator_wrapper")
|
||||||
CHECK(counter == 3);
|
CHECK(counter == 3);
|
||||||
|
|
||||||
// check if values where changed
|
// check if values where changed
|
||||||
CHECK(j == json({{"A", 11}, {"B", 22}}));
|
CHECK(j == json({ {"A", 11}, {"B", 22} }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("const value")
|
SECTION("const value")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto i : json::iterator_wrapper(j))
|
for (const auto i : json::iterator_wrapper(j))
|
||||||
|
@ -148,7 +155,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("const reference")
|
SECTION("const reference")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto& i : json::iterator_wrapper(j))
|
for (const auto& i : json::iterator_wrapper(j))
|
||||||
|
@ -184,7 +191,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
{
|
{
|
||||||
SECTION("value")
|
SECTION("value")
|
||||||
{
|
{
|
||||||
const json j = {{"A", 1}, {"B", 2}};
|
const json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : json::iterator_wrapper(j))
|
for (auto i : json::iterator_wrapper(j))
|
||||||
|
@ -217,7 +224,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("reference")
|
SECTION("reference")
|
||||||
{
|
{
|
||||||
const json j = {{"A", 1}, {"B", 2}};
|
const json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto& i : json::iterator_wrapper(j))
|
for (auto& i : json::iterator_wrapper(j))
|
||||||
|
@ -250,7 +257,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("const value")
|
SECTION("const value")
|
||||||
{
|
{
|
||||||
const json j = {{"A", 1}, {"B", 2}};
|
const json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto i : json::iterator_wrapper(j))
|
for (const auto i : json::iterator_wrapper(j))
|
||||||
|
@ -283,7 +290,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("const reference")
|
SECTION("const reference")
|
||||||
{
|
{
|
||||||
const json j = {{"A", 1}, {"B", 2}};
|
const json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto& i : json::iterator_wrapper(j))
|
for (const auto& i : json::iterator_wrapper(j))
|
||||||
|
@ -319,7 +326,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
{
|
{
|
||||||
SECTION("value")
|
SECTION("value")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : json::iterator_wrapper(j))
|
for (auto i : json::iterator_wrapper(j))
|
||||||
|
@ -352,7 +359,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("reference")
|
SECTION("reference")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto& i : json::iterator_wrapper(j))
|
for (auto& i : json::iterator_wrapper(j))
|
||||||
|
@ -391,12 +398,12 @@ TEST_CASE("iterator_wrapper")
|
||||||
CHECK(counter == 3);
|
CHECK(counter == 3);
|
||||||
|
|
||||||
// check if values where changed
|
// check if values where changed
|
||||||
CHECK(j == json({"AA", "BB"}));
|
CHECK(j == json({ "AA", "BB" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("const value")
|
SECTION("const value")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto i : json::iterator_wrapper(j))
|
for (const auto i : json::iterator_wrapper(j))
|
||||||
|
@ -429,7 +436,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("const reference")
|
SECTION("const reference")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto& i : json::iterator_wrapper(j))
|
for (const auto& i : json::iterator_wrapper(j))
|
||||||
|
@ -465,7 +472,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
{
|
{
|
||||||
SECTION("value")
|
SECTION("value")
|
||||||
{
|
{
|
||||||
const json j = {"A", "B"};
|
const json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : json::iterator_wrapper(j))
|
for (auto i : json::iterator_wrapper(j))
|
||||||
|
@ -498,7 +505,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("reference")
|
SECTION("reference")
|
||||||
{
|
{
|
||||||
const json j = {"A", "B"};
|
const json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto& i : json::iterator_wrapper(j))
|
for (auto& i : json::iterator_wrapper(j))
|
||||||
|
@ -531,7 +538,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("const value")
|
SECTION("const value")
|
||||||
{
|
{
|
||||||
const json j = {"A", "B"};
|
const json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto i : json::iterator_wrapper(j))
|
for (const auto i : json::iterator_wrapper(j))
|
||||||
|
@ -564,7 +571,7 @@ TEST_CASE("iterator_wrapper")
|
||||||
|
|
||||||
SECTION("const reference")
|
SECTION("const reference")
|
||||||
{
|
{
|
||||||
const json j = {"A", "B"};
|
const json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto& i : json::iterator_wrapper(j))
|
for (const auto& i : json::iterator_wrapper(j))
|
||||||
|
@ -735,7 +742,7 @@ TEST_CASE("items()")
|
||||||
{
|
{
|
||||||
SECTION("value")
|
SECTION("value")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : j.items())
|
for (auto i : j.items())
|
||||||
|
@ -768,7 +775,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("reference")
|
SECTION("reference")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto& i : j.items())
|
for (auto& i : j.items())
|
||||||
|
@ -807,12 +814,12 @@ TEST_CASE("items()")
|
||||||
CHECK(counter == 3);
|
CHECK(counter == 3);
|
||||||
|
|
||||||
// check if values where changed
|
// check if values where changed
|
||||||
CHECK(j == json({{"A", 11}, {"B", 22}}));
|
CHECK(j == json({ {"A", 11}, {"B", 22} }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("const value")
|
SECTION("const value")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto i : j.items())
|
for (const auto i : j.items())
|
||||||
|
@ -845,7 +852,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("const reference")
|
SECTION("const reference")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto& i : j.items())
|
for (const auto& i : j.items())
|
||||||
|
@ -875,13 +882,29 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
CHECK(counter == 3);
|
CHECK(counter == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef JSON_HAS_CPP_17
|
||||||
|
SECTION("structured bindings")
|
||||||
|
{
|
||||||
|
json j = { {"A", 1}, {"B", 2} };
|
||||||
|
|
||||||
|
std::map<std::string, int> m;
|
||||||
|
|
||||||
|
for (auto const&[key, value] : j.items())
|
||||||
|
{
|
||||||
|
m.emplace(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(j.get<decltype(m)>() == m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("const object")
|
SECTION("const object")
|
||||||
{
|
{
|
||||||
SECTION("value")
|
SECTION("value")
|
||||||
{
|
{
|
||||||
const json j = {{"A", 1}, {"B", 2}};
|
const json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : j.items())
|
for (auto i : j.items())
|
||||||
|
@ -914,7 +937,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("reference")
|
SECTION("reference")
|
||||||
{
|
{
|
||||||
const json j = {{"A", 1}, {"B", 2}};
|
const json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto& i : j.items())
|
for (auto& i : j.items())
|
||||||
|
@ -947,7 +970,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("const value")
|
SECTION("const value")
|
||||||
{
|
{
|
||||||
const json j = {{"A", 1}, {"B", 2}};
|
const json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto i : j.items())
|
for (const auto i : j.items())
|
||||||
|
@ -980,7 +1003,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("const reference")
|
SECTION("const reference")
|
||||||
{
|
{
|
||||||
const json j = {{"A", 1}, {"B", 2}};
|
const json j = { {"A", 1}, {"B", 2} };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto& i : j.items())
|
for (const auto& i : j.items())
|
||||||
|
@ -1016,7 +1039,7 @@ TEST_CASE("items()")
|
||||||
{
|
{
|
||||||
SECTION("value")
|
SECTION("value")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : j.items())
|
for (auto i : j.items())
|
||||||
|
@ -1049,7 +1072,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("reference")
|
SECTION("reference")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto& i : j.items())
|
for (auto& i : j.items())
|
||||||
|
@ -1088,12 +1111,12 @@ TEST_CASE("items()")
|
||||||
CHECK(counter == 3);
|
CHECK(counter == 3);
|
||||||
|
|
||||||
// check if values where changed
|
// check if values where changed
|
||||||
CHECK(j == json({"AA", "BB"}));
|
CHECK(j == json({ "AA", "BB" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("const value")
|
SECTION("const value")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto i : j.items())
|
for (const auto i : j.items())
|
||||||
|
@ -1126,7 +1149,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("const reference")
|
SECTION("const reference")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto& i : j.items())
|
for (const auto& i : j.items())
|
||||||
|
@ -1162,7 +1185,7 @@ TEST_CASE("items()")
|
||||||
{
|
{
|
||||||
SECTION("value")
|
SECTION("value")
|
||||||
{
|
{
|
||||||
const json j = {"A", "B"};
|
const json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : j.items())
|
for (auto i : j.items())
|
||||||
|
@ -1195,7 +1218,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("reference")
|
SECTION("reference")
|
||||||
{
|
{
|
||||||
const json j = {"A", "B"};
|
const json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto& i : j.items())
|
for (auto& i : j.items())
|
||||||
|
@ -1228,7 +1251,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("const value")
|
SECTION("const value")
|
||||||
{
|
{
|
||||||
const json j = {"A", "B"};
|
const json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto i : j.items())
|
for (const auto i : j.items())
|
||||||
|
@ -1261,7 +1284,7 @@ TEST_CASE("items()")
|
||||||
|
|
||||||
SECTION("const reference")
|
SECTION("const reference")
|
||||||
{
|
{
|
||||||
const json j = {"A", "B"};
|
const json j = { "A", "B" };
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (const auto& i : j.items())
|
for (const auto& i : j.items())
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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.4.0"},
|
{"string", "3.5.0"},
|
||||||
{"major", 3},
|
{"major", 3},
|
||||||
{"minor", 4},
|
{"minor", 5},
|
||||||
{"patch", 0}
|
{"patch", 0}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
@ -1708,3 +1708,16 @@ TEST_CASE("regression tests")
|
||||||
CHECK(expected == data);
|
CHECK(expected == data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("regression tests, exceptions dependent", "[!throws]")
|
||||||
|
{
|
||||||
|
SECTION("issue #1340 - eof not set on exhausted input stream")
|
||||||
|
{
|
||||||
|
std::stringstream s("{}{}");
|
||||||
|
json j;
|
||||||
|
s >> j;
|
||||||
|
s >> j;
|
||||||
|
CHECK_THROWS_AS(s >> j, json::parse_error const&);
|
||||||
|
CHECK(s.eof());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
@ -384,6 +384,41 @@ TEST_CASE("json.org examples")
|
||||||
json j;
|
json j;
|
||||||
CHECK_NOTHROW(f >> j);
|
CHECK_NOTHROW(f >> j);
|
||||||
}
|
}
|
||||||
|
SECTION("FILE 1.json")
|
||||||
|
{
|
||||||
|
std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen("test/data/json.org/1.json", "r"), &std::fclose);
|
||||||
|
json j;
|
||||||
|
CHECK_NOTHROW(j.parse(f.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("FILE 2.json")
|
||||||
|
{
|
||||||
|
std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen("test/data/json.org/2.json", "r"), &std::fclose);
|
||||||
|
json j;
|
||||||
|
CHECK_NOTHROW(j.parse(f.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("FILE 3.json")
|
||||||
|
{
|
||||||
|
std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen("test/data/json.org/3.json", "r"), &std::fclose);
|
||||||
|
json j;
|
||||||
|
CHECK_NOTHROW(j.parse(f.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("FILE 4.json")
|
||||||
|
{
|
||||||
|
std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen("test/data/json.org/4.json", "r"), &std::fclose);
|
||||||
|
json j;
|
||||||
|
CHECK_NOTHROW(j.parse(f.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("FILE 5.json")
|
||||||
|
{
|
||||||
|
std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen("test/data/json.org/5.json", "r"), &std::fclose);
|
||||||
|
json j;
|
||||||
|
CHECK_NOTHROW(j.parse(f.get()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("RFC 7159 examples")
|
TEST_CASE("RFC 7159 examples")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.4.0
|
| | |__ | | | | | | version 3.5.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>.
|
||||||
|
|
Loading…
Reference in a new issue