Merge branch 'release/3.5.0'

This commit is contained in:
Niels Lohmann 2018-12-22 00:01:18 +01:00
commit cebb4e052a
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
71 changed files with 882 additions and 416 deletions

1
.gitignore vendored
View file

@ -22,3 +22,4 @@ benchmarks/files/numbers/*.json
cmake-build-debug cmake-build-debug
test/test-* test/test-*
/.vs

View file

@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.8)
## PROJECT ## PROJECT
## name and version ## name and version
## ##
project(nlohmann_json VERSION 3.4.0 LANGUAGES CXX) project(nlohmann_json VERSION 3.5.0 LANGUAGES CXX)
## ##
## INCLUDE ## INCLUDE

View file

@ -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)

View file

@ -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)

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 726 KiB

After

Width:  |  Height:  |  Size: 812 KiB

View file

@ -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>

View file

@ -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"
} }
} }

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View file

@ -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>

View file

@ -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};
} }

View file

@ -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)) {}

View file

@ -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

View file

@ -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

View file

@ -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 >> ()));
};
}

View 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&;
};
}
}

View file

@ -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,

View file

@ -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);

View file

@ -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;
} }
} }

View file

@ -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++'
)

View file

@ -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;
} }
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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")

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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())

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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}
})); }));

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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());
}
}

View file

@ -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>.

View file

@ -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")

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.

View file

@ -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>.