diff --git a/.gitignore b/.gitignore index 35dc9b42c..086e855c0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ benchmarks/files/numbers/*.json cmake-build-debug test/test-* +/.vs diff --git a/CMakeLists.txt b/CMakeLists.txt index 230cbff88..409f5bff3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.8) ## PROJECT ## name and version ## -project(nlohmann_json VERSION 3.4.0 LANGUAGES CXX) +project(nlohmann_json VERSION 3.5.0 LANGUAGES CXX) ## ## INCLUDE @@ -60,10 +60,10 @@ if (MSVC) set(NLOHMANN_ADD_NATVIS TRUE) set(NLOHMANN_NATVIS_FILE "nlohmann_json.natvis") target_sources( - ${NLOHMANN_JSON_TARGET_NAME} - INTERFACE + ${NLOHMANN_JSON_TARGET_NAME} + INTERFACE $ - $ + $ ) endif() diff --git a/ChangeLog.md b/ChangeLog.md index 9ea088536..703a56f0b 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,84 @@ # Change Log 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\ 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 \ [\#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\ 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) [Full Changelog](https://github.com/nlohmann/json/compare/v3.3.0...v3.4.0) diff --git a/README.md b/README.md index 1154a62ea..a3f825e18 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ There are myriads of [JSON](http://json.org) libraries out there, and each may e - **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings. -- **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: @@ -79,6 +79,7 @@ You can also use the `nlohmann_json::nlohmann_json` interface target in CMake. #### External To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration: + ```cmake # CMakeLists.txt find_package(nlohmann_json 3.2.0 REQUIRED) @@ -87,11 +88,13 @@ add_library(foo ...) ... target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json) ``` + The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree. #### Embedded To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file: + ```cmake # Typically you don't care so much for a third party library's tests to be # run from your own project's code. @@ -109,7 +112,9 @@ target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json) ``` #### Supporting Both + To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following: + ``` cmake # Top level CMakeLists.txt project(FOO) @@ -135,6 +140,7 @@ else() endif() ... ``` + `thirdparty/nlohmann_json` is then a complete copy of this source tree. ### Package Managers @@ -291,19 +297,17 @@ Note the difference between serialization and assignment: // store a string in a JSON value json j_string = "this is a string"; -// retrieve the string value (implicit JSON to std::string conversion) -std::string cpp_string = j_string; -// retrieve the string value (explicit JSON to std::string conversion) -auto cpp_string2 = j_string.get(); -// retrieve the string value (alternative explicit JSON to std::string conversion) -std::string cpp_string3; -j_string.get_to(cpp_string3); +// retrieve the string value +auto cpp_string = j_string.get(); +// retrieve the string value (alternative when an variable already exists) +std::string cpp_string2; +j_string.get_to(cpp_string2); // retrieve the serialized value (explicit JSON serialization) std::string serialized_string = j_string.dump(); // output of original string -std::cout << cpp_string << " == " << cpp_string2 << " == " << cpp_string3 << " == " << j_string.get() << '\n'; +std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get() << '\n'; // output of serialized value 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). - ### 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. @@ -428,7 +431,7 @@ for (auto& element : j) { } // getter/setter -const std::string tmp = j[0]; +const auto tmp = j[0].get(); j[1] = 42; 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"; } +// 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 if (o.find("foo") != o.end()) { // there is an entry with key "foo" @@ -611,33 +624,38 @@ j_original.merge_patch(j_patch); ### 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 // strings std::string s1 = "Hello, world!"; json js = s1; -std::string s2 = js; +auto s2 = js.get(); +// NOT RECOMMENDED +std::string s3 = js; +std::string s4; +s4 = js; // Booleans bool b1 = true; json jb = b1; -bool b2 = jb; +auto b2 = jb.get(); +// NOT RECOMMENDED +bool b3 = jb; +bool b4; +b4 = jb; // numbers int i = 42; json jn = i; -double f = jn; - -// etc. -``` - -You can also explicitly ask for the value: - -```cpp -std::string vs = js.get(); -bool vb = jb.get(); -int vi = jn.get(); +auto f = jn.get(); +// NOT RECOMMENDED +double f2 = jb; +double f3; +f3 = jb; // etc. ``` @@ -695,7 +713,7 @@ std::cout << j << std::endl; // {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} // conversion: json -> person -ns::person p2 = j; +auto p2 = j.get(); // that's it assert(p == p2); @@ -727,10 +745,9 @@ Likewise, when calling `get()` or `get_to(your_type&)`, the `from_jso 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 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` **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 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();` 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. @@ -925,7 +942,7 @@ Other Important points: - When using `get()`, 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. -### 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. @@ -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: -- GCC 4.8 - 8.2 (and possibly later) -- Clang 3.4 - 6.1 (and possibly later) +- GCC 4.8 - 9.0 (and possibly later) +- Clang 3.4 - 8.0 (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++ 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. -![Contributors](https://raw.githubusercontent.com/nlohmann/json/develop/doc/avatars.png) + - [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. @@ -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. - [efp](https://github.com/efp) added line and column information to parse errors. - [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. @@ -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 - [**Catch**](https://github.com/philsquared/Catch) for the unit tests - [**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) - [**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) diff --git a/doc/Doxyfile b/doc/Doxyfile index f86b70a25..10390b76a 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "JSON for Modern C++" -PROJECT_NUMBER = 3.4.0 +PROJECT_NUMBER = 3.5.0 PROJECT_BRIEF = PROJECT_LOGO = OUTPUT_DIRECTORY = . diff --git a/doc/avatars.png b/doc/avatars.png index 876802dab..49baa70a0 100644 Binary files a/doc/avatars.png and b/doc/avatars.png differ diff --git a/doc/examples/README.link b/doc/examples/README.link index 006b7adf5..6fdefb2f1 100644 --- a/doc/examples/README.link +++ b/doc/examples/README.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/meta.output b/doc/examples/meta.output index cab02d7eb..f0e580fb9 100644 --- a/doc/examples/meta.output +++ b/doc/examples/meta.output @@ -2,7 +2,7 @@ "compiler": { "c++": "201103", "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", "name": "JSON for Modern C++", @@ -10,8 +10,8 @@ "url": "https://github.com/nlohmann/json", "version": { "major": 3, - "minor": 4, + "minor": 5, "patch": 0, - "string": "3.4.0" + "string": "3.5.0" } } diff --git a/doc/index.md b/doc/index.md index da6a97d36..1266a2733 100644 --- a/doc/index.md +++ b/doc/index.md @@ -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) @see https://github.com/nlohmann/json to download the source code -@version 3.4.0 +@version 3.5.0 diff --git a/doc/json.gif b/doc/json.gif index 5fb91d587..87eb7c191 100644 Binary files a/doc/json.gif and b/doc/json.gif differ diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index d274eadd5..ee13eb550 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -290,9 +290,9 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) template < typename BasicJsonType, typename T, std::size_t N, enable_if_t::value, + const T(&)[N]>::value, int> = 0 > -void to_json(BasicJsonType& j, const T (&arr)[N]) +void to_json(BasicJsonType& j, const T(&arr)[N]) { external_constructor::construct(j, arr); } @@ -300,21 +300,21 @@ void to_json(BasicJsonType& j, const T (&arr)[N]) template void to_json(BasicJsonType& j, const std::pair& p) { - j = {p.first, p.second}; + j = { p.first, p.second }; } // for https://github.com/nlohmann/json/pull/1134 -template::iteration_proxy_internal>::value, int> = 0> +template < typename BasicJsonType, typename T, + enable_if_t>::value, int> = 0> void to_json(BasicJsonType& j, const T& b) { - j = {{b.key(), b.value()}}; + j = { {b.key(), b.value()} }; } template void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence /*unused*/) { - j = {std::get(t)...}; + j = { std::get(t)... }; } template diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 403a4d016..2946611cf 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -241,7 +241,7 @@ class binary_reader case 0x08: // boolean { - return sax->boolean(static_cast(get())); + return sax->boolean(get() != 0); } case 0x0A: // null @@ -264,7 +264,7 @@ class binary_reader default: // anything else not supported (yet) { char cr[3]; - snprintf(cr, sizeof(cr), "%.2hhX", static_cast(element_type)); + (std::snprintf)(cr, sizeof(cr), "%.2hhX", static_cast(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))); } } @@ -300,7 +300,10 @@ class binary_reader 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))) @@ -1918,7 +1921,7 @@ class binary_reader std::string get_token_string() const { char cr[3]; - snprintf(cr, 3, "%.2hhX", static_cast(current)); + (std::snprintf)(cr, 3, "%.2hhX", static_cast(current)); return std::string{cr}; } diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index 79a19c176..91215a968 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -10,6 +10,7 @@ #include // string, char_traits #include // enable_if, is_base_of, is_pointer, is_integral, remove_pointer #include // pair, declval +#include //FILE * #include @@ -45,6 +46,27 @@ struct input_adapter_protocol /// a type to simplify interfaces using input_adapter_t = std::shared_ptr; +/*! +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::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 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 { // clear stream flags; we use underlying streambuf I/O, do not - // maintain ifstream flags - is.clear(); + // maintain ifstream flags, except eof + is.clear(is.rdstate() & std::ios::eofbit); } 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. std::char_traits::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: @@ -287,7 +315,8 @@ class input_adapter { public: // native support - + input_adapter(std::FILE* file) + : ia(std::make_shared(file)) {} /// input adapter for input stream input_adapter(std::istream& i) : ia(std::make_shared(i)) {} @@ -331,7 +360,7 @@ class input_adapter /// input adapter for iterator range with contiguous storage template::iterator_category, std::random_access_iterator_tag>::value, + std::is_same::iterator_category, std::random_access_iterator_tag>::value, int>::type = 0> input_adapter(IteratorType first, IteratorType last) { @@ -350,7 +379,7 @@ class input_adapter // assertion to check that each element is 1 byte long static_assert( - sizeof(typename std::iterator_traits::value_type) == 1, + sizeof(typename iterator_traits::value_type) == 1, "each element in the iterator range must have the size of 1 byte"); const auto len = static_cast(std::distance(first, last)); @@ -374,7 +403,7 @@ class input_adapter /// input adapter for contiguous container template::value and - std::is_base_of()))>::iterator_category>::value, + std::is_base_of()))>::iterator_category>::value, int>::type = 0> input_adapter(const ContiguousContainer& c) : input_adapter(std::begin(c), std::end(c)) {} diff --git a/include/nlohmann/detail/input/lexer.hpp b/include/nlohmann/detail/input/lexer.hpp index dd474525d..c3ecbee9e 100644 --- a/include/nlohmann/detail/input/lexer.hpp +++ b/include/nlohmann/detail/input/lexer.hpp @@ -1360,7 +1360,7 @@ scan_number_done: { // escape control characters char cs[9]; - snprintf(cs, 9, "", static_cast(c)); + (std::snprintf)(cs, 9, "", static_cast(c)); result += cs; } else diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index 6674c0645..81a5e0d76 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -17,24 +17,21 @@ namespace detail { // forward declare, to be able to friend it later on template class iteration_proxy; +template class iteration_proxy_value; /*! @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 @ref basic_json class. - @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 default-constructed, it is *uninitialized* and most methods are undefined. **The library uses assertions to detect calls on uninitialized iterators.** - @requirement The class satisfies the following concept requirements: - [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): The iterator that can be moved can be moved in both directions (i.e. incremented and decremented). - @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) */ @@ -45,6 +42,7 @@ class iter_impl friend iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; friend BasicJsonType; friend iteration_proxy; + friend iteration_proxy_value; using object_t = typename BasicJsonType::object_t; using array_t = typename BasicJsonType::array_t; @@ -611,4 +609,4 @@ class iter_impl internal_iterator::type> m_it; }; } // namespace detail -} // namespace nlohmann +} // namespace nlohmann \ No newline at end of file diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp index d4f905027..51e770469 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -3,104 +3,105 @@ #include // size_t #include // string, to_string #include // input_iterator_tag +#include // tuple_size, get, tuple_element #include +#include namespace nlohmann { namespace detail { +template 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 template class iteration_proxy { 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 typename IteratorType::reference container; @@ -110,16 +111,52 @@ template class iteration_proxy : container(cont) {} /// return iterator begin (needed for range-based for) - iteration_proxy_internal begin() noexcept + iteration_proxy_value begin() noexcept { - return iteration_proxy_internal(container.begin()); + return iteration_proxy_value(container.begin()); } /// return iterator end (needed for range-based for) - iteration_proxy_internal end() noexcept + iteration_proxy_value end() noexcept { - return iteration_proxy_internal(container.end()); + return iteration_proxy_value(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 = 0> +auto get(const nlohmann::detail::iteration_proxy_value& 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 = 0> +auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.value()) +{ + return i.value(); +} } // namespace detail } // 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 +class tuple_size<::nlohmann::detail::iteration_proxy_value> + : public std::integral_constant {}; + +template +class tuple_element> +{ + public: + using type = decltype( + get(std::declval < + ::nlohmann::detail::iteration_proxy_value> ())); +}; +} \ No newline at end of file diff --git a/include/nlohmann/detail/iterators/iterator_traits.hpp b/include/nlohmann/detail/iterators/iterator_traits.hpp new file mode 100644 index 000000000..35ea81fbe --- /dev/null +++ b/include/nlohmann/detail/iterators/iterator_traits.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include // random_access_iterator_tag + +#include +#include + +namespace nlohmann +{ +namespace detail +{ +template +struct iterator_types {}; + +template +struct iterator_types< + It, + void_t> { + 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 +struct iterator_traits +{ +}; + +template +struct iterator_traits::value>> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> { + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; +} +} diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index d901f1e00..ee04da226 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -6,6 +6,7 @@ #include // declval #include +#include #include #include #include @@ -131,10 +132,10 @@ template struct is_iterator_traits : std::false_type {}; template -struct is_iterator_traits> +struct is_iterator_traits> { private: - using traits = std::iterator_traits; + using traits = iterator_traits; public: static constexpr auto value = @@ -251,7 +252,7 @@ struct is_compatible_array_type_impl < // Therefore it is detected as a CompatibleArrayType. // The real fix would be to have an Iterable concept. not is_iterator_traits< - std::iterator_traits>::value >> + iterator_traits>::value >> { static constexpr bool value = std::is_constructible>::value and + iterator_traits>::value and (std::is_same::value or has_from_json(codepoint)); + (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", + static_cast(codepoint)); bytes += 6; } else { - std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", - static_cast(0xD7C0 + (codepoint >> 10)), - static_cast(0xDC00 + (codepoint & 0x3FF))); + (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", + static_cast(0xD7C0 + (codepoint >> 10)), + static_cast(0xDC00 + (codepoint & 0x3FF))); bytes += 12; } } @@ -416,7 +416,7 @@ class serializer case error_handler_t::strict: { 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)); } @@ -497,7 +497,7 @@ class serializer case error_handler_t::strict: { std::string sn(3, '\0'); - snprintf(&sn[0], sn.size(), "%.2X", static_cast(s.back())); + (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast(s.back())); 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::max_digits10; // 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 assert(len > 0); diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 30e698957..e6ad210fe 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -31,7 +31,7 @@ SOFTWARE. #define NLOHMANN_JSON_HPP #define NLOHMANN_JSON_VERSION_MAJOR 3 -#define NLOHMANN_JSON_VERSION_MINOR 4 +#define NLOHMANN_JSON_VERSION_MINOR 5 #define NLOHMANN_JSON_VERSION_PATCH 0 #include // all_of, find, for_each @@ -41,7 +41,7 @@ SOFTWARE. #include // hash, less #include // initializer_list #include // istream, ostream -#include // iterator_traits, random_access_iterator_tag +#include // random_access_iterator_tag #include // accumulate #include // string, stoi, to_string #include // declval, forward, move, pair, swap @@ -949,7 +949,7 @@ class basic_json object = nullptr; // silence warning, see #821 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; } @@ -4340,9 +4340,20 @@ class basic_json Range-based for loop with `items()` function: @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 @@ -4360,7 +4371,7 @@ class basic_json @complexity Constant. - @since version 3.1.0. + @since version 3.1.0, structured bindings support since 3.5.0. */ iteration_proxy items() noexcept { @@ -7851,7 +7862,7 @@ class basic_json Thereby, `Target` is the current object; that is, the patch is applied to 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. @@ -7863,15 +7874,15 @@ class basic_json @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()) { *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()) { @@ -7885,7 +7896,7 @@ class basic_json } else { - *this = patch; + *this = apply_patch; } } diff --git a/meson.build b/meson.build index f0271cc37..e6867e73d 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('nlohmann_json', 'cpp', - version : '3.4.0', + version : '3.5.0', license : 'MIT', ) @@ -11,3 +11,11 @@ nlohmann_json_dep = declare_dependency( nlohmann_json_multiple_headers = declare_dependency( 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++' +) diff --git a/nlohmann_json.natvis b/nlohmann_json.natvis index 63e3f8423..557717663 100644 --- a/nlohmann_json.natvis +++ b/nlohmann_json.natvis @@ -19,8 +19,8 @@ - - {second} @@ -28,5 +28,5 @@ second - + diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 1e7cf51e0..c9af0bed3 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -31,7 +31,7 @@ SOFTWARE. #define NLOHMANN_JSON_HPP #define NLOHMANN_JSON_VERSION_MAJOR 3 -#define NLOHMANN_JSON_VERSION_MINOR 4 +#define NLOHMANN_JSON_VERSION_MINOR 5 #define NLOHMANN_JSON_VERSION_PATCH 0 #include // all_of, find, for_each @@ -41,7 +41,7 @@ SOFTWARE. #include // hash, less #include // initializer_list #include // istream, ostream -#include // iterator_traits, random_access_iterator_tag +#include // random_access_iterator_tag #include // accumulate #include // string, stoi, to_string #include // declval, forward, move, pair, swap @@ -324,12 +324,10 @@ constexpr T static_const::value; // #include -// #include - -// #include +// #include -#include +#include // random_access_iterator_tag // #include @@ -346,6 +344,63 @@ template using void_t = typename make_void::type; } // namespace detail } // namespace nlohmann +// #include + + +namespace nlohmann +{ +namespace detail +{ +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + 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 +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::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 + +// #include + + +#include + +// #include + // http://en.cppreference.com/w/cpp/experimental/is_detected namespace nlohmann @@ -522,10 +577,10 @@ template struct is_iterator_traits : std::false_type {}; template -struct is_iterator_traits> +struct is_iterator_traits> { private: - using traits = std::iterator_traits; + using traits = iterator_traits; public: static constexpr auto value = @@ -642,7 +697,7 @@ struct is_compatible_array_type_impl < // Therefore it is detected as a CompatibleArrayType. // The real fix would be to have an Iterable concept. not is_iterator_traits< - std::iterator_traits>::value >> + iterator_traits>::value >> { static constexpr bool value = std::is_constructible>::value and + iterator_traits>::value and (std::is_same::value or has_from_json::va #include // size_t #include // string, to_string #include // input_iterator_tag +#include // tuple_size, get, tuple_element // #include +// #include + namespace nlohmann { namespace detail { +template 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 template class iteration_proxy { 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 typename IteratorType::reference container; @@ -1702,20 +1759,55 @@ template class iteration_proxy : container(cont) {} /// return iterator begin (needed for range-based for) - iteration_proxy_internal begin() noexcept + iteration_proxy_value begin() noexcept { - return iteration_proxy_internal(container.begin()); + return iteration_proxy_value(container.begin()); } /// return iterator end (needed for range-based for) - iteration_proxy_internal end() noexcept + iteration_proxy_value end() noexcept { - return iteration_proxy_internal(container.end()); + return iteration_proxy_value(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 = 0> +auto get(const nlohmann::detail::iteration_proxy_value& 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 = 0> +auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.value()) +{ + return i.value(); +} } // namespace detail } // 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 +class tuple_size<::nlohmann::detail::iteration_proxy_value> + : public std::integral_constant {}; + +template +class tuple_element> +{ + public: + using type = decltype( + get(std::declval < + ::nlohmann::detail::iteration_proxy_value> ())); +}; +} namespace nlohmann { @@ -1994,9 +2086,9 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) template < typename BasicJsonType, typename T, std::size_t N, enable_if_t::value, + const T(&)[N]>::value, int> = 0 > -void to_json(BasicJsonType& j, const T (&arr)[N]) +void to_json(BasicJsonType& j, const T(&arr)[N]) { external_constructor::construct(j, arr); } @@ -2004,21 +2096,21 @@ void to_json(BasicJsonType& j, const T (&arr)[N]) template void to_json(BasicJsonType& j, const std::pair& p) { - j = {p.first, p.second}; + j = { p.first, p.second }; } // for https://github.com/nlohmann/json/pull/1134 -template::iteration_proxy_internal>::value, int> = 0> +template < typename BasicJsonType, typename T, + enable_if_t>::value, int> = 0> void to_json(BasicJsonType& j, const T& b) { - j = {{b.key(), b.value()}}; + j = { {b.key(), b.value()} }; } template void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence /*unused*/) { - j = {std::get(t)...}; + j = { std::get(t)... }; } template @@ -2058,6 +2150,7 @@ constexpr const auto& to_json = detail::static_const::value; #include // string, char_traits #include // enable_if, is_base_of, is_pointer, is_integral, remove_pointer #include // pair, declval +#include //FILE * // #include @@ -2094,6 +2187,27 @@ struct input_adapter_protocol /// a type to simplify interfaces using input_adapter_t = std::shared_ptr; +/*! +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::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 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 { // clear stream flags; we use underlying streambuf I/O, do not - // maintain ifstream flags - is.clear(); + // maintain ifstream flags, except eof + is.clear(is.rdstate() & std::ios::eofbit); } 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. std::char_traits::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: @@ -2336,7 +2456,8 @@ class input_adapter { public: // native support - + input_adapter(std::FILE* file) + : ia(std::make_shared(file)) {} /// input adapter for input stream input_adapter(std::istream& i) : ia(std::make_shared(i)) {} @@ -2380,7 +2501,7 @@ class input_adapter /// input adapter for iterator range with contiguous storage template::iterator_category, std::random_access_iterator_tag>::value, + std::is_same::iterator_category, std::random_access_iterator_tag>::value, int>::type = 0> input_adapter(IteratorType first, IteratorType last) { @@ -2399,7 +2520,7 @@ class input_adapter // assertion to check that each element is 1 byte long static_assert( - sizeof(typename std::iterator_traits::value_type) == 1, + sizeof(typename iterator_traits::value_type) == 1, "each element in the iterator range must have the size of 1 byte"); const auto len = static_cast(std::distance(first, last)); @@ -2423,7 +2544,7 @@ class input_adapter /// input adapter for contiguous container template::value and - std::is_base_of()))>::iterator_category>::value, + std::is_base_of()))>::iterator_category>::value, int>::type = 0> input_adapter(const ContiguousContainer& c) : input_adapter(std::begin(c), std::end(c)) {} @@ -3806,7 +3927,7 @@ scan_number_done: { // escape control characters char cs[9]; - snprintf(cs, 9, "", static_cast(c)); + (std::snprintf)(cs, 9, "", static_cast(c)); result += cs; } else @@ -5486,24 +5607,21 @@ namespace detail { // forward declare, to be able to friend it later on template class iteration_proxy; +template class iteration_proxy_value; /*! @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 @ref basic_json class. - @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 default-constructed, it is *uninitialized* and most methods are undefined. **The library uses assertions to detect calls on uninitialized iterators.** - @requirement The class satisfies the following concept requirements: - [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): The iterator that can be moved can be moved in both directions (i.e. incremented and decremented). - @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) */ @@ -5514,6 +5632,7 @@ class iter_impl friend iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; friend BasicJsonType; friend iteration_proxy; + friend iteration_proxy_value; using object_t = typename BasicJsonType::object_t; using array_t = typename BasicJsonType::array_t; @@ -6080,8 +6199,7 @@ class iter_impl internal_iterator::type> m_it; }; } // namespace detail -} // namespace nlohmann - +} // namespace nlohmann // #include // #include @@ -6576,7 +6694,7 @@ class binary_reader case 0x08: // boolean { - return sax->boolean(static_cast(get())); + return sax->boolean(get() != 0); } case 0x0A: // null @@ -6599,7 +6717,7 @@ class binary_reader default: // anything else not supported (yet) { char cr[3]; - snprintf(cr, sizeof(cr), "%.2hhX", static_cast(element_type)); + (std::snprintf)(cr, sizeof(cr), "%.2hhX", static_cast(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))); } } @@ -6635,7 +6753,10 @@ class binary_reader 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))) @@ -8253,7 +8374,7 @@ class binary_reader std::string get_token_string() const { char cr[3]; - snprintf(cr, 3, "%.2hhX", static_cast(current)); + (std::snprintf)(cr, 3, "%.2hhX", static_cast(current)); return std::string{cr}; } @@ -11134,15 +11255,15 @@ class serializer { if (codepoint <= 0xFFFF) { - std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x", - static_cast(codepoint)); + (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", + static_cast(codepoint)); bytes += 6; } else { - std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", - static_cast(0xD7C0 + (codepoint >> 10)), - static_cast(0xDC00 + (codepoint & 0x3FF))); + (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", + static_cast(0xD7C0 + (codepoint >> 10)), + static_cast(0xDC00 + (codepoint & 0x3FF))); bytes += 12; } } @@ -11178,7 +11299,7 @@ class serializer case error_handler_t::strict: { 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)); } @@ -11259,7 +11380,7 @@ class serializer case error_handler_t::strict: { std::string sn(3, '\0'); - snprintf(&sn[0], sn.size(), "%.2X", static_cast(s.back())); + (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast(s.back())); 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::max_digits10; // 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 assert(len > 0); @@ -13208,7 +13329,7 @@ class basic_json object = nullptr; // silence warning, see #821 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; } @@ -16599,9 +16720,20 @@ class basic_json Range-based for loop with `items()` function: @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 @@ -16619,7 +16751,7 @@ class basic_json @complexity Constant. - @since version 3.1.0. + @since version 3.1.0, structured bindings support since 3.5.0. */ iteration_proxy items() noexcept { @@ -20110,7 +20242,7 @@ class basic_json Thereby, `Target` is the current object; that is, the patch is applied to 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. @@ -20122,15 +20254,15 @@ class basic_json @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()) { *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()) { @@ -20144,7 +20276,7 @@ class basic_json } else { - *this = patch; + *this = apply_patch; } } diff --git a/test/src/fuzzer-driver_afl.cpp b/test/src/fuzzer-driver_afl.cpp index dbefb448f..c0da9f0ef 100644 --- a/test/src/fuzzer-driver_afl.cpp +++ b/test/src/fuzzer-driver_afl.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on diff --git a/test/src/fuzzer-parse_bson.cpp b/test/src/fuzzer-parse_bson.cpp index 901fa723f..667d3da36 100644 --- a/test/src/fuzzer-parse_bson.cpp +++ b/test/src/fuzzer-parse_bson.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json This file implements a parser test suitable for fuzz testing. Given a byte diff --git a/test/src/fuzzer-parse_cbor.cpp b/test/src/fuzzer-parse_cbor.cpp index f1c86d820..eb4e6f21e 100644 --- a/test/src/fuzzer-parse_cbor.cpp +++ b/test/src/fuzzer-parse_cbor.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json This file implements a parser test suitable for fuzz testing. Given a byte diff --git a/test/src/fuzzer-parse_json.cpp b/test/src/fuzzer-parse_json.cpp index 1c3804cd4..de6b8592c 100644 --- a/test/src/fuzzer-parse_json.cpp +++ b/test/src/fuzzer-parse_json.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json This file implements a parser test suitable for fuzz testing. Given a byte diff --git a/test/src/fuzzer-parse_msgpack.cpp b/test/src/fuzzer-parse_msgpack.cpp index a1c31470a..8abcf1fb4 100644 --- a/test/src/fuzzer-parse_msgpack.cpp +++ b/test/src/fuzzer-parse_msgpack.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json This file implements a parser test suitable for fuzz testing. Given a byte diff --git a/test/src/fuzzer-parse_ubjson.cpp b/test/src/fuzzer-parse_ubjson.cpp index 704a1de05..66ba80cae 100644 --- a/test/src/fuzzer-parse_ubjson.cpp +++ b/test/src/fuzzer-parse_ubjson.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json This file implements a parser test suitable for fuzz testing. Given a byte diff --git a/test/src/unit-algorithms.cpp b/test/src/unit-algorithms.cpp index 91af7419c..547d22940 100644 --- a/test/src/unit-algorithms.cpp +++ b/test/src/unit-algorithms.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-allocator.cpp b/test/src/unit-allocator.cpp index d7779c06f..06d56d5ed 100644 --- a/test/src/unit-allocator.cpp +++ b/test/src/unit-allocator.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-alt-string.cpp b/test/src/unit-alt-string.cpp index bae19cdb8..9db580b4e 100644 --- a/test/src/unit-alt-string.cpp +++ b/test/src/unit-alt-string.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-bson.cpp b/test/src/unit-bson.cpp index 406f0800b..791e47dfd 100644 --- a/test/src/unit-bson.cpp +++ b/test/src/unit-bson.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -752,6 +752,28 @@ TEST_CASE("Incomplete BSON Input") SaxCountdown scp(0); 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") diff --git a/test/src/unit-capacity.cpp b/test/src/unit-capacity.cpp index cc2b0c0da..a23326132 100644 --- a/test/src/unit-capacity.cpp +++ b/test/src/unit-capacity.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-cbor.cpp b/test/src/unit-cbor.cpp index 0ea9812c0..db7626e1d 100644 --- a/test/src/unit-cbor.cpp +++ b/test/src/unit-cbor.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-class_const_iterator.cpp b/test/src/unit-class_const_iterator.cpp index 20c4e5400..40ce1dd5c 100644 --- a/test/src/unit-class_const_iterator.cpp +++ b/test/src/unit-class_const_iterator.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-class_iterator.cpp b/test/src/unit-class_iterator.cpp index a45659a39..b7d132e03 100644 --- a/test/src/unit-class_iterator.cpp +++ b/test/src/unit-class_iterator.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-class_lexer.cpp b/test/src/unit-class_lexer.cpp index 10798e100..a2dff5734 100644 --- a/test/src/unit-class_lexer.cpp +++ b/test/src/unit-class_lexer.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index c40dc6135..aaa39d625 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-comparison.cpp b/test/src/unit-comparison.cpp index b99aee95a..5c07a7eaf 100644 --- a/test/src/unit-comparison.cpp +++ b/test/src/unit-comparison.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-concepts.cpp b/test/src/unit-concepts.cpp index 56f8a35d1..870ef52f0 100644 --- a/test/src/unit-concepts.cpp +++ b/test/src/unit-concepts.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-constructor1.cpp b/test/src/unit-constructor1.cpp index 15fc7f82b..205daeb3f 100644 --- a/test/src/unit-constructor1.cpp +++ b/test/src/unit-constructor1.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-constructor2.cpp b/test/src/unit-constructor2.cpp index 222bec273..809b4551d 100644 --- a/test/src/unit-constructor2.cpp +++ b/test/src/unit-constructor2.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-convenience.cpp b/test/src/unit-convenience.cpp index a8037c37f..dda515f2f 100644 --- a/test/src/unit-convenience.cpp +++ b/test/src/unit-convenience.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp index fbdc53296..368cb4f56 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-deserialization.cpp b/test/src/unit-deserialization.cpp index 09896800b..29e1454e0 100644 --- a/test/src/unit-deserialization.cpp +++ b/test/src/unit-deserialization.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-element_access1.cpp b/test/src/unit-element_access1.cpp index 2903182e8..171feef49 100644 --- a/test/src/unit-element_access1.cpp +++ b/test/src/unit-element_access1.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-element_access2.cpp b/test/src/unit-element_access2.cpp index 563afcef6..52a30073d 100644 --- a/test/src/unit-element_access2.cpp +++ b/test/src/unit-element_access2.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-inspection.cpp b/test/src/unit-inspection.cpp index 5bc08fa75..a529f0982 100644 --- a/test/src/unit-inspection.cpp +++ b/test/src/unit-inspection.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-items.cpp b/test/src/unit-items.cpp index bfa3f9e48..c2f43cd45 100644 --- a/test/src/unit-items.cpp +++ b/test/src/unit-items.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -32,13 +32,20 @@ SOFTWARE. #include 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") { SECTION("object") { SECTION("value") { - json j = {{"A", 1}, {"B", 2}}; + json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (auto i : json::iterator_wrapper(j)) @@ -71,7 +78,7 @@ TEST_CASE("iterator_wrapper") SECTION("reference") { - json j = {{"A", 1}, {"B", 2}}; + json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (auto& i : json::iterator_wrapper(j)) @@ -110,12 +117,12 @@ TEST_CASE("iterator_wrapper") CHECK(counter == 3); // check if values where changed - CHECK(j == json({{"A", 11}, {"B", 22}})); + CHECK(j == json({ {"A", 11}, {"B", 22} })); } SECTION("const value") { - json j = {{"A", 1}, {"B", 2}}; + json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (const auto i : json::iterator_wrapper(j)) @@ -148,7 +155,7 @@ TEST_CASE("iterator_wrapper") SECTION("const reference") { - json j = {{"A", 1}, {"B", 2}}; + json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (const auto& i : json::iterator_wrapper(j)) @@ -184,7 +191,7 @@ TEST_CASE("iterator_wrapper") { SECTION("value") { - const json j = {{"A", 1}, {"B", 2}}; + const json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (auto i : json::iterator_wrapper(j)) @@ -217,7 +224,7 @@ TEST_CASE("iterator_wrapper") SECTION("reference") { - const json j = {{"A", 1}, {"B", 2}}; + const json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (auto& i : json::iterator_wrapper(j)) @@ -250,7 +257,7 @@ TEST_CASE("iterator_wrapper") SECTION("const value") { - const json j = {{"A", 1}, {"B", 2}}; + const json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (const auto i : json::iterator_wrapper(j)) @@ -283,7 +290,7 @@ TEST_CASE("iterator_wrapper") SECTION("const reference") { - const json j = {{"A", 1}, {"B", 2}}; + const json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (const auto& i : json::iterator_wrapper(j)) @@ -319,7 +326,7 @@ TEST_CASE("iterator_wrapper") { SECTION("value") { - json j = {"A", "B"}; + json j = { "A", "B" }; int counter = 1; for (auto i : json::iterator_wrapper(j)) @@ -352,7 +359,7 @@ TEST_CASE("iterator_wrapper") SECTION("reference") { - json j = {"A", "B"}; + json j = { "A", "B" }; int counter = 1; for (auto& i : json::iterator_wrapper(j)) @@ -391,12 +398,12 @@ TEST_CASE("iterator_wrapper") CHECK(counter == 3); // check if values where changed - CHECK(j == json({"AA", "BB"})); + CHECK(j == json({ "AA", "BB" })); } SECTION("const value") { - json j = {"A", "B"}; + json j = { "A", "B" }; int counter = 1; for (const auto i : json::iterator_wrapper(j)) @@ -429,7 +436,7 @@ TEST_CASE("iterator_wrapper") SECTION("const reference") { - json j = {"A", "B"}; + json j = { "A", "B" }; int counter = 1; for (const auto& i : json::iterator_wrapper(j)) @@ -465,7 +472,7 @@ TEST_CASE("iterator_wrapper") { SECTION("value") { - const json j = {"A", "B"}; + const json j = { "A", "B" }; int counter = 1; for (auto i : json::iterator_wrapper(j)) @@ -498,7 +505,7 @@ TEST_CASE("iterator_wrapper") SECTION("reference") { - const json j = {"A", "B"}; + const json j = { "A", "B" }; int counter = 1; for (auto& i : json::iterator_wrapper(j)) @@ -531,7 +538,7 @@ TEST_CASE("iterator_wrapper") SECTION("const value") { - const json j = {"A", "B"}; + const json j = { "A", "B" }; int counter = 1; for (const auto i : json::iterator_wrapper(j)) @@ -564,7 +571,7 @@ TEST_CASE("iterator_wrapper") SECTION("const reference") { - const json j = {"A", "B"}; + const json j = { "A", "B" }; int counter = 1; for (const auto& i : json::iterator_wrapper(j)) @@ -735,7 +742,7 @@ TEST_CASE("items()") { SECTION("value") { - json j = {{"A", 1}, {"B", 2}}; + json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (auto i : j.items()) @@ -768,7 +775,7 @@ TEST_CASE("items()") SECTION("reference") { - json j = {{"A", 1}, {"B", 2}}; + json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (auto& i : j.items()) @@ -807,12 +814,12 @@ TEST_CASE("items()") CHECK(counter == 3); // check if values where changed - CHECK(j == json({{"A", 11}, {"B", 22}})); + CHECK(j == json({ {"A", 11}, {"B", 22} })); } SECTION("const value") { - json j = {{"A", 1}, {"B", 2}}; + json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (const auto i : j.items()) @@ -845,7 +852,7 @@ TEST_CASE("items()") SECTION("const reference") { - json j = {{"A", 1}, {"B", 2}}; + json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (const auto& i : j.items()) @@ -875,13 +882,29 @@ TEST_CASE("items()") CHECK(counter == 3); } + +#ifdef JSON_HAS_CPP_17 + SECTION("structured bindings") + { + json j = { {"A", 1}, {"B", 2} }; + + std::map m; + + for (auto const&[key, value] : j.items()) + { + m.emplace(key, value); + } + + CHECK(j.get() == m); + } +#endif } SECTION("const object") { SECTION("value") { - const json j = {{"A", 1}, {"B", 2}}; + const json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (auto i : j.items()) @@ -914,7 +937,7 @@ TEST_CASE("items()") SECTION("reference") { - const json j = {{"A", 1}, {"B", 2}}; + const json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (auto& i : j.items()) @@ -947,7 +970,7 @@ TEST_CASE("items()") SECTION("const value") { - const json j = {{"A", 1}, {"B", 2}}; + const json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (const auto i : j.items()) @@ -980,7 +1003,7 @@ TEST_CASE("items()") SECTION("const reference") { - const json j = {{"A", 1}, {"B", 2}}; + const json j = { {"A", 1}, {"B", 2} }; int counter = 1; for (const auto& i : j.items()) @@ -1016,7 +1039,7 @@ TEST_CASE("items()") { SECTION("value") { - json j = {"A", "B"}; + json j = { "A", "B" }; int counter = 1; for (auto i : j.items()) @@ -1049,7 +1072,7 @@ TEST_CASE("items()") SECTION("reference") { - json j = {"A", "B"}; + json j = { "A", "B" }; int counter = 1; for (auto& i : j.items()) @@ -1088,12 +1111,12 @@ TEST_CASE("items()") CHECK(counter == 3); // check if values where changed - CHECK(j == json({"AA", "BB"})); + CHECK(j == json({ "AA", "BB" })); } SECTION("const value") { - json j = {"A", "B"}; + json j = { "A", "B" }; int counter = 1; for (const auto i : j.items()) @@ -1126,7 +1149,7 @@ TEST_CASE("items()") SECTION("const reference") { - json j = {"A", "B"}; + json j = { "A", "B" }; int counter = 1; for (const auto& i : j.items()) @@ -1162,7 +1185,7 @@ TEST_CASE("items()") { SECTION("value") { - const json j = {"A", "B"}; + const json j = { "A", "B" }; int counter = 1; for (auto i : j.items()) @@ -1195,7 +1218,7 @@ TEST_CASE("items()") SECTION("reference") { - const json j = {"A", "B"}; + const json j = { "A", "B" }; int counter = 1; for (auto& i : j.items()) @@ -1228,7 +1251,7 @@ TEST_CASE("items()") SECTION("const value") { - const json j = {"A", "B"}; + const json j = { "A", "B" }; int counter = 1; for (const auto i : j.items()) @@ -1261,7 +1284,7 @@ TEST_CASE("items()") SECTION("const reference") { - const json j = {"A", "B"}; + const json j = { "A", "B" }; int counter = 1; for (const auto& i : j.items()) diff --git a/test/src/unit-iterators1.cpp b/test/src/unit-iterators1.cpp index 716cff11f..1923cf608 100644 --- a/test/src/unit-iterators1.cpp +++ b/test/src/unit-iterators1.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp index 8ca266f94..e6536389b 100644 --- a/test/src/unit-iterators2.cpp +++ b/test/src/unit-iterators2.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-json_patch.cpp b/test/src/unit-json_patch.cpp index 605e36f1a..1b407db00 100644 --- a/test/src/unit-json_patch.cpp +++ b/test/src/unit-json_patch.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-json_pointer.cpp b/test/src/unit-json_pointer.cpp index bf1f3c85c..ac9cd71e2 100644 --- a/test/src/unit-json_pointer.cpp +++ b/test/src/unit-json_pointer.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-merge_patch.cpp b/test/src/unit-merge_patch.cpp index 9225bd80f..901d3568d 100644 --- a/test/src/unit-merge_patch.cpp +++ b/test/src/unit-merge_patch.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-meta.cpp b/test/src/unit-meta.cpp index b711a6065..46f2a9aae 100644 --- a/test/src/unit-meta.cpp +++ b/test/src/unit-meta.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -43,9 +43,9 @@ TEST_CASE("version information") CHECK(j["url"] == "https://github.com/nlohmann/json"); CHECK(j["version"] == json( { - {"string", "3.4.0"}, + {"string", "3.5.0"}, {"major", 3}, - {"minor", 4}, + {"minor", 5}, {"patch", 0} })); diff --git a/test/src/unit-modifiers.cpp b/test/src/unit-modifiers.cpp index 2f901b247..9e53deab7 100644 --- a/test/src/unit-modifiers.cpp +++ b/test/src/unit-modifiers.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-msgpack.cpp b/test/src/unit-msgpack.cpp index c082e20c5..3dfee8a4c 100644 --- a/test/src/unit-msgpack.cpp +++ b/test/src/unit-msgpack.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-noexcept.cpp b/test/src/unit-noexcept.cpp index 8857b99d3..3e1e544d7 100644 --- a/test/src/unit-noexcept.cpp +++ b/test/src/unit-noexcept.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-pointer_access.cpp b/test/src/unit-pointer_access.cpp index bc9b353d4..ab409282a 100644 --- a/test/src/unit-pointer_access.cpp +++ b/test/src/unit-pointer_access.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-readme.cpp b/test/src/unit-readme.cpp index fe2842947..280a834e5 100644 --- a/test/src/unit-readme.cpp +++ b/test/src/unit-readme.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-reference_access.cpp b/test/src/unit-reference_access.cpp index e8d20e834..bc54ef523 100644 --- a/test/src/unit-reference_access.cpp +++ b/test/src/unit-reference_access.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 5f007980c..1db43f3d2 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -1708,3 +1708,16 @@ TEST_CASE("regression tests") 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()); + } +} diff --git a/test/src/unit-serialization.cpp b/test/src/unit-serialization.cpp index 814aa18d9..51ee9b572 100644 --- a/test/src/unit-serialization.cpp +++ b/test/src/unit-serialization.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-testsuites.cpp b/test/src/unit-testsuites.cpp index 3c00fadaa..e30aeee5d 100644 --- a/test/src/unit-testsuites.cpp +++ b/test/src/unit-testsuites.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -384,6 +384,41 @@ TEST_CASE("json.org examples") json j; CHECK_NOTHROW(f >> j); } + SECTION("FILE 1.json") + { + std::unique_ptr 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 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 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 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 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") diff --git a/test/src/unit-to_chars.cpp b/test/src/unit-to_chars.cpp index 08dbd0d20..223d9c22b 100644 --- a/test/src/unit-to_chars.cpp +++ b/test/src/unit-to_chars.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-ubjson.cpp b/test/src/unit-ubjson.cpp index 20f84cd50..6760ae6ce 100644 --- a/test/src/unit-ubjson.cpp +++ b/test/src/unit-ubjson.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-udt.cpp b/test/src/unit-udt.cpp index c2b8a2d71..833a4c71d 100644 --- a/test/src/unit-udt.cpp +++ b/test/src/unit-udt.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-unicode.cpp b/test/src/unit-unicode.cpp index e3a0728b2..95d621786 100644 --- a/test/src/unit-unicode.cpp +++ b/test/src/unit-unicode.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-wstring.cpp b/test/src/unit-wstring.cpp index 540b379ff..8434b1994 100644 --- a/test/src/unit-wstring.cpp +++ b/test/src/unit-wstring.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit.cpp b/test/src/unit.cpp index b99defb02..8ea7e2e84 100644 --- a/test/src/unit.cpp +++ b/test/src/unit.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 3.4.0 +| | |__ | | | | | | version 3.5.0 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License .