diff --git a/.gitignore b/.gitignore index c7e847c4..bd8c8699 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,7 @@ doc/html me.nlohmann.json.docset benchmarks/files/numbers/*.json + +.idea +cmake-build-debug + diff --git a/.travis.yml b/.travis.yml index 1325e43e..d9896384 100644 --- a/.travis.yml +++ b/.travis.yml @@ -84,50 +84,41 @@ matrix: # Coverity (only for branch coverity_scan) - os: linux - compiler: gcc + compiler: clang before_install: echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['g++-5', 'valgrind'] + packages: ['valgrind'] coverity_scan: project: name: "nlohmann/json" description: "Build submitted via Travis CI" notification_email: niels.lohmann@gmail.com - build_command_prepend: "make clean ; sudo cp $(which g++-5) $(which g++)" + build_command_prepend: "make clean" build_command: "make" branch_pattern: coverity_scan env: - - COMPILER=g++-5 + - LLVM_VERSION=3.6.0 - SPECIAL=coverity # OSX / Clang - - os: osx - osx_image: beta-xcode6.1 - - - os: osx - osx_image: beta-xcode6.2 - - - os: osx - osx_image: beta-xcode6.3 - - os: osx osx_image: xcode6.4 - - os: osx - osx_image: xcode7.1 - - - os: osx - osx_image: xcode7.2 - - os: osx osx_image: xcode7.3 - os: osx osx_image: xcode8 + - os: osx + osx_image: xcode8.1 + + - os: osx + osx_image: xcode8.2 + # Linux / GCC - os: linux diff --git a/CMakeLists.txt b/CMakeLists.txt index 703c9048..efda6e92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0) # define the project -project(nlohmann_json VERSION 2.0.7 LANGUAGES CXX) +project(nlohmann_json VERSION 2.0.8 LANGUAGES CXX) enable_testing() diff --git a/ChangeLog.md b/ChangeLog.md index 37ef06a9..287420c6 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,24 +1,69 @@ # Change Log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [v2.0.8](https://github.com/nlohmann/json/releases/tag/v2.0.8) (2016-12-02) +[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.7...v2.0.8) + +- Reading from file [\#374](https://github.com/nlohmann/json/issues/374) +- Compiler warnings? [\#372](https://github.com/nlohmann/json/issues/372) +- docs: how to release a json object in memory? [\#371](https://github.com/nlohmann/json/issues/371) +- crash in dump [\#370](https://github.com/nlohmann/json/issues/370) +- Conversion operators not considered [\#369](https://github.com/nlohmann/json/issues/369) +- Coverity issue \(FORWARD\_NULL\) in lexer\(std::istream& s\) [\#368](https://github.com/nlohmann/json/issues/368) +- json::parse on failed stream gets stuck [\#366](https://github.com/nlohmann/json/issues/366) +- Performance improvements [\#365](https://github.com/nlohmann/json/issues/365) +- 'to\_string' is not a member of 'std' [\#364](https://github.com/nlohmann/json/issues/364) +- Optional comment support. [\#363](https://github.com/nlohmann/json/issues/363) +- Loss of precision when serializing \ [\#360](https://github.com/nlohmann/json/issues/360) +- Crash in dump\(\) from a static object [\#359](https://github.com/nlohmann/json/issues/359) +- json::parse\(...\) vs json j; j.parse\(...\) [\#357](https://github.com/nlohmann/json/issues/357) +- Hi, is there any method to dump json to string with the insert order rather than alphabets [\#356](https://github.com/nlohmann/json/issues/356) +- Provide an example of reading from an json with only a key that has an array of strings. [\#354](https://github.com/nlohmann/json/issues/354) +- Request: access with default value. [\#353](https://github.com/nlohmann/json/issues/353) +- {} and \[\] causes parser error. [\#352](https://github.com/nlohmann/json/issues/352) +- Reading a JSON file into a JSON object [\#351](https://github.com/nlohmann/json/issues/351) +- Request: 'emplace\_back' [\#349](https://github.com/nlohmann/json/issues/349) +- Is it possible to stream data through the json parser without storing everything in memory? [\#347](https://github.com/nlohmann/json/issues/347) +- pure virtual conversion operator [\#346](https://github.com/nlohmann/json/issues/346) +- Floating point precision lost [\#345](https://github.com/nlohmann/json/issues/345) +- unit-conversions SIGSEGV on armv7hl [\#303](https://github.com/nlohmann/json/issues/303) +- Coverity scan fails [\#299](https://github.com/nlohmann/json/issues/299) +- Using QString as string type [\#274](https://github.com/nlohmann/json/issues/274) + ## [v2.0.7](https://github.com/nlohmann/json/releases/tag/v2.0.7) (2016-11-02) [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.6...v2.0.7) -- ""-operators ignore the length parameter [\#340](https://github.com/nlohmann/json/issues/340) - +- JSON5 [\#348](https://github.com/nlohmann/json/issues/348) - Check "Parsing JSON is a Minefield" [\#344](https://github.com/nlohmann/json/issues/344) +- Allow hex numbers [\#342](https://github.com/nlohmann/json/issues/342) +- Convert strings to numbers [\#341](https://github.com/nlohmann/json/issues/341) +- ""-operators ignore the length parameter [\#340](https://github.com/nlohmann/json/issues/340) +- JSON into std::tuple [\#339](https://github.com/nlohmann/json/issues/339) +- JSON into vector [\#335](https://github.com/nlohmann/json/issues/335) +- Installing with Homebrew on Mac Errors \(El Capitan\) [\#331](https://github.com/nlohmann/json/issues/331) +- g++ make check results in error [\#312](https://github.com/nlohmann/json/issues/312) +- Cannot convert from 'json' to 'char' [\#276](https://github.com/nlohmann/json/issues/276) +- Please add a Pretty-Print option for arrays to stay always in one line [\#229](https://github.com/nlohmann/json/issues/229) +- Conversion to STL map\\> gives error [\#220](https://github.com/nlohmann/json/issues/220) +- std::unorderd\_map cannot be used as ObjectType [\#164](https://github.com/nlohmann/json/issues/164) - fix minor grammar/style issue in README.md [\#336](https://github.com/nlohmann/json/pull/336) ([seeekr](https://github.com/seeekr)) ## [v2.0.6](https://github.com/nlohmann/json/releases/tag/v2.0.6) (2016-10-15) [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.5...v2.0.6) +- How to handle json files? [\#333](https://github.com/nlohmann/json/issues/333) +- This file requires compiler and library support .... [\#332](https://github.com/nlohmann/json/issues/332) +- Segmentation fault on saving json to file [\#326](https://github.com/nlohmann/json/issues/326) +- parse error - unexpected \ with 2.0.5 [\#325](https://github.com/nlohmann/json/issues/325) - Add nested object capability to pointers [\#323](https://github.com/nlohmann/json/issues/323) -- make has\_mapped\_type struct friendly [\#324](https://github.com/nlohmann/json/pull/324) ([vpetrigo](https://github.com/vpetrigo)) - - Fix usage examples' comments for std::multiset [\#322](https://github.com/nlohmann/json/issues/322) - json\_unit runs forever when executed in build directory [\#319](https://github.com/nlohmann/json/issues/319) +- Visual studio 2015 update3 true != TRUE [\#317](https://github.com/nlohmann/json/issues/317) +- releasing single header file in compressed format [\#316](https://github.com/nlohmann/json/issues/316) +- json object from std::ifstream [\#315](https://github.com/nlohmann/json/issues/315) +- make has\_mapped\_type struct friendly [\#324](https://github.com/nlohmann/json/pull/324) ([vpetrigo](https://github.com/vpetrigo)) - Fix usage examples' comments for std::multiset [\#321](https://github.com/nlohmann/json/pull/321) ([vasild](https://github.com/vasild)) - Include dir relocation [\#318](https://github.com/nlohmann/json/pull/318) ([ChristophJud](https://github.com/ChristophJud)) - trivial documentation fix [\#313](https://github.com/nlohmann/json/pull/313) ([5tefan](https://github.com/5tefan)) @@ -26,33 +71,44 @@ All notable changes to this project will be documented in this file. This projec ## [v2.0.5](https://github.com/nlohmann/json/releases/tag/v2.0.5) (2016-09-14) [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.4...v2.0.5) +- \[feature request\]: schema validator and comments [\#311](https://github.com/nlohmann/json/issues/311) - make json\_benchmarks no longer working in 2.0.4 [\#310](https://github.com/nlohmann/json/issues/310) +- Segmentation fault \(core dumped\) [\#309](https://github.com/nlohmann/json/issues/309) +- No matching member function for call to 'get\_impl' [\#308](https://github.com/nlohmann/json/issues/308) ## [v2.0.4](https://github.com/nlohmann/json/releases/tag/v2.0.4) (2016-09-11) [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.3...v2.0.4) - Parsing fails without space at end of file [\#306](https://github.com/nlohmann/json/issues/306) - +- json schema validator [\#305](https://github.com/nlohmann/json/issues/305) - Unused variable warning [\#304](https://github.com/nlohmann/json/issues/304) ## [v2.0.3](https://github.com/nlohmann/json/releases/tag/v2.0.3) (2016-08-31) [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.2...v2.0.3) -- Support for iterator-range parsing [\#290](https://github.com/nlohmann/json/issues/290) - - warning C4706: assignment within conditional expression [\#295](https://github.com/nlohmann/json/issues/295) +- Strip comments / Minify [\#294](https://github.com/nlohmann/json/issues/294) +- Q: Is it possible to build json tree from already UTF8 encoded values? [\#293](https://github.com/nlohmann/json/issues/293) +- Equality operator results in array when assigned object [\#292](https://github.com/nlohmann/json/issues/292) +- Support for integers not from the range \[-\(2\*\*53\)+1, \(2\*\*53\)-1\] in parser [\#291](https://github.com/nlohmann/json/issues/291) +- Support for iterator-range parsing [\#290](https://github.com/nlohmann/json/issues/290) - Horribly inconsistent behavior between const/non-const reference in operator \[\] \(\) [\#289](https://github.com/nlohmann/json/issues/289) +- Silently get numbers into smaller types [\#288](https://github.com/nlohmann/json/issues/288) +- Incorrect parsing of large int64\_t numbers [\#287](https://github.com/nlohmann/json/issues/287) +- \[question\]: macro to disable floating point support [\#284](https://github.com/nlohmann/json/issues/284) - unit-constructor1.cpp: Fix floating point truncation warning [\#300](https://github.com/nlohmann/json/pull/300) ([t-b](https://github.com/t-b)) ## [v2.0.2](https://github.com/nlohmann/json/releases/tag/v2.0.2) (2016-07-31) [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.1...v2.0.2) +- can function dump\(\) return string in the order I push in the json object ? [\#286](https://github.com/nlohmann/json/issues/286) +- Error on the Mac: Undefined symbols for architecture x86\_64 [\#285](https://github.com/nlohmann/json/issues/285) - value\(\) does not work with \_json\_pointer types [\#283](https://github.com/nlohmann/json/issues/283) -- Easy serialization of classes [\#280](https://github.com/nlohmann/json/issues/280) - - Build error for std::int64 [\#282](https://github.com/nlohmann/json/issues/282) - +- strings can't be accessed after dump\(\)-\>parse\(\) - type is lost [\#281](https://github.com/nlohmann/json/issues/281) +- Easy serialization of classes [\#280](https://github.com/nlohmann/json/issues/280) +- recursive data structures [\#277](https://github.com/nlohmann/json/issues/277) - hexify\(\) function emits conversion warning [\#270](https://github.com/nlohmann/json/issues/270) - let the makefile choose the correct sed [\#279](https://github.com/nlohmann/json/pull/279) ([murinicanor](https://github.com/murinicanor)) @@ -61,6 +117,7 @@ All notable changes to this project will be documented in this file. This projec ## [v2.0.1](https://github.com/nlohmann/json/releases/tag/v2.0.1) (2016-06-28) [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...v2.0.1) +- Compilation error. [\#273](https://github.com/nlohmann/json/issues/273) - dump\(\) performance degradation in v2 [\#272](https://github.com/nlohmann/json/issues/272) - fixed a tiny typo [\#271](https://github.com/nlohmann/json/pull/271) ([thelostt](https://github.com/thelostt)) @@ -68,43 +125,61 @@ All notable changes to this project will be documented in this file. This projec ## [v2.0.0](https://github.com/nlohmann/json/releases/tag/v2.0.0) (2016-06-23) [Full Changelog](https://github.com/nlohmann/json/compare/v1.1.0...v2.0.0) -- concatenate objects [\#252](https://github.com/nlohmann/json/issues/252) -- Unit test fails when doing a CMake out-of-tree build [\#241](https://github.com/nlohmann/json/issues/241) -- Additional integration options [\#237](https://github.com/nlohmann/json/issues/237) -- Can't use basic\_json::iterator as a base iterator for std::move\_iterator [\#233](https://github.com/nlohmann/json/issues/233) -- Provide a FAQ [\#163](https://github.com/nlohmann/json/issues/163) -- Create PULL\_REQUEST\_TEMPLATE.md [\#213](https://github.com/nlohmann/json/pull/213) ([whackashoe](https://github.com/whackashoe)) -- fixed noexcept; added constexpr [\#208](https://github.com/nlohmann/json/pull/208) ([nlohmann](https://github.com/nlohmann)) -- Add support for afl-fuzz testing [\#207](https://github.com/nlohmann/json/pull/207) ([mykter](https://github.com/mykter)) -- Issue \#178 - Extending support to full uint64\_t/int64\_t range and unsigned type \(updated\) [\#193](https://github.com/nlohmann/json/pull/193) ([twelsby](https://github.com/twelsby)) - - json::diff generates incorrect patch when removing multiple array elements. [\#269](https://github.com/nlohmann/json/issues/269) +- Docs - What does Json\[key\] return? [\#267](https://github.com/nlohmann/json/issues/267) +- Compiler Errors With JSON.hpp [\#265](https://github.com/nlohmann/json/issues/265) +- Throw exception instead of crashing my app [\#264](https://github.com/nlohmann/json/issues/264) +- Ambiguous push\_back and operator+= overloads [\#263](https://github.com/nlohmann/json/issues/263) +- Preseving order of items in json [\#262](https://github.com/nlohmann/json/issues/262) +- '\' char problem in strings [\#261](https://github.com/nlohmann/json/issues/261) +- VS2015 compile fail [\#260](https://github.com/nlohmann/json/issues/260) - -Wconversion warning [\#259](https://github.com/nlohmann/json/issues/259) - Maybe a bug [\#258](https://github.com/nlohmann/json/issues/258) +- Few tests failed on Visual C++ 2015 [\#257](https://github.com/nlohmann/json/issues/257) +- Access keys when iteration with new for loop C++11 [\#256](https://github.com/nlohmann/json/issues/256) +- multiline text values [\#255](https://github.com/nlohmann/json/issues/255) +- Error when using json in g++ [\#254](https://github.com/nlohmann/json/issues/254) +- is the release 2.0? [\#253](https://github.com/nlohmann/json/issues/253) +- concatenate objects [\#252](https://github.com/nlohmann/json/issues/252) +- Encoding [\#251](https://github.com/nlohmann/json/issues/251) +- Unable to build example for constructing json object with stringstreams [\#250](https://github.com/nlohmann/json/issues/250) +- Hexadecimal support [\#249](https://github.com/nlohmann/json/issues/249) +- Update long-term goals [\#246](https://github.com/nlohmann/json/issues/246) +- Contribution To This Json Project [\#245](https://github.com/nlohmann/json/issues/245) +- Trouble using parser with initial dictionary [\#243](https://github.com/nlohmann/json/issues/243) +- Unit test fails when doing a CMake out-of-tree build [\#241](https://github.com/nlohmann/json/issues/241) - -Wconversion warnings [\#239](https://github.com/nlohmann/json/issues/239) +- Additional integration options [\#237](https://github.com/nlohmann/json/issues/237) +- .get\\(\) works for non spaced string but returns as array for spaced/longer strings [\#236](https://github.com/nlohmann/json/issues/236) - ambiguous overload for 'push\_back' and 'operator+=' [\#235](https://github.com/nlohmann/json/issues/235) +- Can't use basic\_json::iterator as a base iterator for std::move\_iterator [\#233](https://github.com/nlohmann/json/issues/233) +- json object's creation can freezes execution [\#231](https://github.com/nlohmann/json/issues/231) - Incorrect dumping of parsed numbers with exponents, but without decimal places [\#230](https://github.com/nlohmann/json/issues/230) - double values are serialized with commas as decimal points [\#228](https://github.com/nlohmann/json/issues/228) - Move semantics with std::initializer\_list [\#225](https://github.com/nlohmann/json/issues/225) +- replace emplace [\#224](https://github.com/nlohmann/json/issues/224) - abort during getline in yyfill [\#223](https://github.com/nlohmann/json/issues/223) +- free\(\): invalid pointer error in GCC 5.2.1 [\#221](https://github.com/nlohmann/json/issues/221) +- Error compile Android NDK error: 'strtof' is not a member of 'std' [\#219](https://github.com/nlohmann/json/issues/219) - Wrong link in the README.md [\#217](https://github.com/nlohmann/json/issues/217) +- Wide character strings not supported [\#216](https://github.com/nlohmann/json/issues/216) +- Memory allocations using range-based for loops [\#214](https://github.com/nlohmann/json/issues/214) +- would you like to support gcc 4.8.1? [\#211](https://github.com/nlohmann/json/issues/211) +- Reading concatenated json's from an istream [\#210](https://github.com/nlohmann/json/issues/210) +- Conflicting typedef of ssize\_t on Windows 32 bit when using Boost.Python [\#204](https://github.com/nlohmann/json/issues/204) +- Inconsistency between operator\[\] and push\_back [\#203](https://github.com/nlohmann/json/issues/203) - Small bugs in json.hpp \(get\_number\) and unit.cpp \(non-standard integer type test\) [\#199](https://github.com/nlohmann/json/issues/199) - GCC/clang floating point parsing bug in strtod\(\) [\#195](https://github.com/nlohmann/json/issues/195) +- What is within scope? [\#192](https://github.com/nlohmann/json/issues/192) - Bugs in miloyip/nativejson-benchmark: roundtrips [\#187](https://github.com/nlohmann/json/issues/187) - Floating point exceptions [\#181](https://github.com/nlohmann/json/issues/181) -- In basic\_json::basic\_json\(const CompatibleArrayType& val\), the requirement of CompatibleArrayType is not strict enough. [\#174](https://github.com/nlohmann/json/issues/174) -- Implicit assignment to std::string fails [\#144](https://github.com/nlohmann/json/issues/144) -- Fix Issue \#265 [\#266](https://github.com/nlohmann/json/pull/266) ([06needhamt](https://github.com/06needhamt)) -- Issue \#195 - update Travis to Trusty due to gcc/clang strtod\(\) bug [\#196](https://github.com/nlohmann/json/pull/196) ([twelsby](https://github.com/twelsby)) - -- Compiler Errors With JSON.hpp [\#265](https://github.com/nlohmann/json/issues/265) -- VS2015 compile fail [\#260](https://github.com/nlohmann/json/issues/260) -- Error when using json in g++ [\#254](https://github.com/nlohmann/json/issues/254) -- Update long-term goals [\#246](https://github.com/nlohmann/json/issues/246) -- Error compile Android NDK error: 'strtof' is not a member of 'std' [\#219](https://github.com/nlohmann/json/issues/219) -- Conflicting typedef of ssize\_t on Windows 32 bit when using Boost.Python [\#204](https://github.com/nlohmann/json/issues/204) - Integer conversion to unsigned [\#178](https://github.com/nlohmann/json/issues/178) +- map string string fails to compile [\#176](https://github.com/nlohmann/json/issues/176) +- In basic\_json::basic\_json\(const CompatibleArrayType& val\), the requirement of CompatibleArrayType is not strict enough. [\#174](https://github.com/nlohmann/json/issues/174) +- Provide a FAQ [\#163](https://github.com/nlohmann/json/issues/163) +- Implicit assignment to std::string fails [\#144](https://github.com/nlohmann/json/issues/144) +- Fix Issue \#265 [\#266](https://github.com/nlohmann/json/pull/266) ([06needhamt](https://github.com/06needhamt)) - Define CMake/CTest tests [\#247](https://github.com/nlohmann/json/pull/247) ([robertmrk](https://github.com/robertmrk)) - Out of tree builds and a few other miscellaneous CMake cleanups. [\#242](https://github.com/nlohmann/json/pull/242) ([ChrisKitching](https://github.com/ChrisKitching)) - Implement additional integration options [\#238](https://github.com/nlohmann/json/pull/238) ([robertmrk](https://github.com/robertmrk)) @@ -113,72 +188,81 @@ All notable changes to this project will be documented in this file. This projec - Use namespace std for int64\_t and uint64\_t [\#226](https://github.com/nlohmann/json/pull/226) ([lv-zheng](https://github.com/lv-zheng)) - Added missing cerrno header to fix ERANGE compile error on android [\#222](https://github.com/nlohmann/json/pull/222) ([Teemperor](https://github.com/Teemperor)) - Corrected readme [\#218](https://github.com/nlohmann/json/pull/218) ([Annihil](https://github.com/Annihil)) +- Create PULL\_REQUEST\_TEMPLATE.md [\#213](https://github.com/nlohmann/json/pull/213) ([whackashoe](https://github.com/whackashoe)) +- fixed noexcept; added constexpr [\#208](https://github.com/nlohmann/json/pull/208) ([nlohmann](https://github.com/nlohmann)) +- Add support for afl-fuzz testing [\#207](https://github.com/nlohmann/json/pull/207) ([mykter](https://github.com/mykter)) - replaced ssize\_t occurrences with auto \(addresses \#204\) [\#205](https://github.com/nlohmann/json/pull/205) ([nlohmann](https://github.com/nlohmann)) - Fixed issue \#199 - Small bugs in json.hpp \(get\_number\) and unit.cpp \(non-standard integer type test\) [\#200](https://github.com/nlohmann/json/pull/200) ([twelsby](https://github.com/twelsby)) - Fix broken link [\#197](https://github.com/nlohmann/json/pull/197) ([vog](https://github.com/vog)) +- Issue \#195 - update Travis to Trusty due to gcc/clang strtod\(\) bug [\#196](https://github.com/nlohmann/json/pull/196) ([twelsby](https://github.com/twelsby)) +- Issue \#178 - Extending support to full uint64\_t/int64\_t range and unsigned type \(updated\) [\#193](https://github.com/nlohmann/json/pull/193) ([twelsby](https://github.com/twelsby)) ## [v1.1.0](https://github.com/nlohmann/json/releases/tag/v1.1.0) (2016-01-24) [Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0...v1.1.0) -- JSON performance benchmark comparision [\#177](https://github.com/nlohmann/json/issues/177) -- Since re2c is often ignored in pull requests, it may make sense to make a contributing.md file [\#175](https://github.com/nlohmann/json/issues/175) -- Add assertions [\#168](https://github.com/nlohmann/json/issues/168) -- range based for loop for objects [\#83](https://github.com/nlohmann/json/issues/83) -- Implementation of get\_ref\(\) [\#184](https://github.com/nlohmann/json/pull/184) ([dariomt](https://github.com/dariomt)) - - Small error in pull \#185 [\#194](https://github.com/nlohmann/json/issues/194) - Bugs in miloyip/nativejson-benchmark: floating-point parsing [\#186](https://github.com/nlohmann/json/issues/186) -- Cannot index by key of type static constexpr const char\* [\#171](https://github.com/nlohmann/json/issues/171) -- Fixed Issue \#171 - added two extra template overloads of operator\[\] for T\* arguments [\#189](https://github.com/nlohmann/json/pull/189) ([twelsby](https://github.com/twelsby)) -- Fixed issue \#167 - removed operator ValueType\(\) condition for VS2015 [\#188](https://github.com/nlohmann/json/pull/188) ([twelsby](https://github.com/twelsby)) - - Floating point equality [\#185](https://github.com/nlohmann/json/issues/185) - Unused variables in catch [\#180](https://github.com/nlohmann/json/issues/180) - Typo in documentation [\#179](https://github.com/nlohmann/json/issues/179) +- JSON performance benchmark comparision [\#177](https://github.com/nlohmann/json/issues/177) +- Since re2c is often ignored in pull requests, it may make sense to make a contributing.md file [\#175](https://github.com/nlohmann/json/issues/175) +- Question about exceptions [\#173](https://github.com/nlohmann/json/issues/173) - Android? [\#172](https://github.com/nlohmann/json/issues/172) +- Cannot index by key of type static constexpr const char\* [\#171](https://github.com/nlohmann/json/issues/171) +- Add assertions [\#168](https://github.com/nlohmann/json/issues/168) - MSVC 2015 build fails when attempting to compare object\_t [\#167](https://github.com/nlohmann/json/issues/167) - Member detector is not portable [\#166](https://github.com/nlohmann/json/issues/166) - Unnecessary const\_cast [\#162](https://github.com/nlohmann/json/issues/162) +- Question about get\_ref\(\) [\#128](https://github.com/nlohmann/json/issues/128) +- range based for loop for objects [\#83](https://github.com/nlohmann/json/issues/83) - Consider submitting this to the Boost Library Incubator [\#66](https://github.com/nlohmann/json/issues/66) - Fixed Issue \#186 - add strto\(f|d|ld\) overload wrappers, "-0.0" special case and FP trailing zero [\#191](https://github.com/nlohmann/json/pull/191) ([twelsby](https://github.com/twelsby)) - Issue \#185 - remove approx\(\) and use \#pragma to kill warnings [\#190](https://github.com/nlohmann/json/pull/190) ([twelsby](https://github.com/twelsby)) +- Fixed Issue \#171 - added two extra template overloads of operator\[\] for T\* arguments [\#189](https://github.com/nlohmann/json/pull/189) ([twelsby](https://github.com/twelsby)) +- Fixed issue \#167 - removed operator ValueType\(\) condition for VS2015 [\#188](https://github.com/nlohmann/json/pull/188) ([twelsby](https://github.com/twelsby)) +- Implementation of get\_ref\(\) [\#184](https://github.com/nlohmann/json/pull/184) ([dariomt](https://github.com/dariomt)) - Fixed some typos in CONTRIBUTING.md [\#182](https://github.com/nlohmann/json/pull/182) ([nibroc](https://github.com/nibroc)) ## [v1.0.0](https://github.com/nlohmann/json/releases/tag/v1.0.0) (2015-12-27) [Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0-rc1...v1.0.0) - add key name to exception [\#160](https://github.com/nlohmann/json/issues/160) -- prevent json.hpp from emitting compiler warnings [\#154](https://github.com/nlohmann/json/issues/154) -- json::parse\(string\) does not check utf8 bom [\#152](https://github.com/nlohmann/json/issues/152) -- unsigned 64bit values output as signed [\#151](https://github.com/nlohmann/json/issues/151) -- overload of at\(\) with default value [\#133](https://github.com/nlohmann/json/issues/133) -- Memory leak in face of exceptions [\#118](https://github.com/nlohmann/json/issues/118) -- Find and Count for arrays [\#117](https://github.com/nlohmann/json/issues/117) -- dynamically constructing an arbitrarily nested object [\#114](https://github.com/nlohmann/json/issues/114) -- object field accessors [\#103](https://github.com/nlohmann/json/issues/103) -- v8pp and json [\#95](https://github.com/nlohmann/json/issues/95) -- Wishlist [\#65](https://github.com/nlohmann/json/issues/65) -- Windows/Visual Studio \(through 2013\) is unsupported [\#62](https://github.com/nlohmann/json/issues/62) - -- Bug in basic\_json::operator\[\] const overload [\#135](https://github.com/nlohmann/json/issues/135) -- wrong enable\_if for const pointer \(instead of pointer-to-const\) [\#134](https://github.com/nlohmann/json/issues/134) -- Visual Studio 14 Debug assertion failed [\#125](https://github.com/nlohmann/json/issues/125) -- Compile error with g++ 4.9.3 cygwin 64-bit [\#112](https://github.com/nlohmann/json/issues/112) -- error: unterminated raw string [\#109](https://github.com/nlohmann/json/issues/109) -- \[clang-3.6.2\] string/sstream with number to json issue [\#107](https://github.com/nlohmann/json/issues/107) - - Getting member discarding qualifyer [\#159](https://github.com/nlohmann/json/issues/159) - basic\_json::iterator::value\(\) output includes quotes while basic\_json::iterator::key\(\) doesn't [\#158](https://github.com/nlohmann/json/issues/158) - Indexing `const basic\_json\<\>` with `const basic\_string\` [\#157](https://github.com/nlohmann/json/issues/157) - token\_type\_name\(token\_type t\): not all control paths return a value [\#156](https://github.com/nlohmann/json/issues/156) +- prevent json.hpp from emitting compiler warnings [\#154](https://github.com/nlohmann/json/issues/154) +- json::parse\(string\) does not check utf8 bom [\#152](https://github.com/nlohmann/json/issues/152) +- unsigned 64bit values output as signed [\#151](https://github.com/nlohmann/json/issues/151) +- Wish feature: json5 [\#150](https://github.com/nlohmann/json/issues/150) - Unable to compile on MSVC 2015 with SDL checking enabled: This function or variable may be unsafe. [\#149](https://github.com/nlohmann/json/issues/149) +- "Json Object" type does not keep object order [\#148](https://github.com/nlohmann/json/issues/148) - dump\(\) convert strings encoded by utf-8 to shift-jis on windows 10. [\#147](https://github.com/nlohmann/json/issues/147) - Unable to get field names in a json object [\#145](https://github.com/nlohmann/json/issues/145) +- Question: Is the use of incomplete type correct? [\#138](https://github.com/nlohmann/json/issues/138) - json.hpp:5746:32: error: 'to\_string' is not a member of 'std' [\#136](https://github.com/nlohmann/json/issues/136) +- Bug in basic\_json::operator\[\] const overload [\#135](https://github.com/nlohmann/json/issues/135) +- wrong enable\_if for const pointer \(instead of pointer-to-const\) [\#134](https://github.com/nlohmann/json/issues/134) +- overload of at\(\) with default value [\#133](https://github.com/nlohmann/json/issues/133) +- Splitting source [\#132](https://github.com/nlohmann/json/issues/132) +- Question about get\_ptr\(\) [\#127](https://github.com/nlohmann/json/issues/127) +- Visual Studio 14 Debug assertion failed [\#125](https://github.com/nlohmann/json/issues/125) +- Memory leak in face of exceptions [\#118](https://github.com/nlohmann/json/issues/118) +- Find and Count for arrays [\#117](https://github.com/nlohmann/json/issues/117) +- dynamically constructing an arbitrarily nested object [\#114](https://github.com/nlohmann/json/issues/114) - Returning any data type [\#113](https://github.com/nlohmann/json/issues/113) +- Compile error with g++ 4.9.3 cygwin 64-bit [\#112](https://github.com/nlohmann/json/issues/112) +- insert json array issue with gcc4.8.2 [\#110](https://github.com/nlohmann/json/issues/110) +- error: unterminated raw string [\#109](https://github.com/nlohmann/json/issues/109) - vector\ copy constructor really weird [\#108](https://github.com/nlohmann/json/issues/108) +- \[clang-3.6.2\] string/sstream with number to json issue [\#107](https://github.com/nlohmann/json/issues/107) - maintaining order of keys during iteration [\#106](https://github.com/nlohmann/json/issues/106) +- object field accessors [\#103](https://github.com/nlohmann/json/issues/103) +- v8pp and json [\#95](https://github.com/nlohmann/json/issues/95) +- Wishlist [\#65](https://github.com/nlohmann/json/issues/65) +- Windows/Visual Studio \(through 2013\) is unsupported [\#62](https://github.com/nlohmann/json/issues/62) - Replace sprintf with hex function, this fixes \#149 [\#153](https://github.com/nlohmann/json/pull/153) ([whackashoe](https://github.com/whackashoe)) - Fix character skipping after a surrogate pair [\#146](https://github.com/nlohmann/json/pull/146) ([robertmrk](https://github.com/robertmrk)) @@ -194,65 +278,71 @@ All notable changes to this project will be documented in this file. This projec - Use the right variable name in doc string [\#115](https://github.com/nlohmann/json/pull/115) ([whoshuu](https://github.com/whoshuu)) ## [v1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1) (2015-07-26) +- Finish documenting the public interface in Doxygen [\#102](https://github.com/nlohmann/json/issues/102) +- Binary string causes numbers to be dumped as hex [\#101](https://github.com/nlohmann/json/issues/101) +- failed to iterator json object with reverse\_iterator [\#100](https://github.com/nlohmann/json/issues/100) +- 'noexcept' : unknown override specifier [\#99](https://github.com/nlohmann/json/issues/99) +- json float parsing problem [\#98](https://github.com/nlohmann/json/issues/98) - Adjust wording to JSON RFC [\#97](https://github.com/nlohmann/json/issues/97) +- 17 MB / 90 MB repo size!? [\#96](https://github.com/nlohmann/json/issues/96) +- static analysis warnings [\#94](https://github.com/nlohmann/json/issues/94) +- reverse\_iterator operator inheritance problem [\#93](https://github.com/nlohmann/json/issues/93) +- init error [\#92](https://github.com/nlohmann/json/issues/92) - access by \(const\) reference [\#91](https://github.com/nlohmann/json/issues/91) - is\_integer and is\_float tests [\#90](https://github.com/nlohmann/json/issues/90) +- Nonstandard integer type [\#89](https://github.com/nlohmann/json/issues/89) +- static library build [\#84](https://github.com/nlohmann/json/issues/84) +- lexer::get\_number return NAN [\#82](https://github.com/nlohmann/json/issues/82) - MinGW have no std::to\_string [\#80](https://github.com/nlohmann/json/issues/80) +- Incorrect behaviour of basic\_json::count method [\#78](https://github.com/nlohmann/json/issues/78) +- Invoking is\_array\(\) function creates "null" value [\#77](https://github.com/nlohmann/json/issues/77) +- dump\(\) / parse\(\) not idempotent [\#76](https://github.com/nlohmann/json/issues/76) +- Handle infinity and NaN cases [\#70](https://github.com/nlohmann/json/issues/70) +- errors in g++-4.8.1 [\#68](https://github.com/nlohmann/json/issues/68) +- Keys when iterating over objects [\#67](https://github.com/nlohmann/json/issues/67) +- Compilation results in tons of warnings [\#64](https://github.com/nlohmann/json/issues/64) +- Complete brief documentation [\#61](https://github.com/nlohmann/json/issues/61) +- Double quotation mark is not parsed correctly [\#60](https://github.com/nlohmann/json/issues/60) +- Get coverage back to 100% [\#58](https://github.com/nlohmann/json/issues/58) - erase elements using iterators [\#57](https://github.com/nlohmann/json/issues/57) - Removing item from array [\#56](https://github.com/nlohmann/json/issues/56) - Serialize/Deserialize like PHP? [\#55](https://github.com/nlohmann/json/issues/55) +- Numbers as keys [\#54](https://github.com/nlohmann/json/issues/54) +- Why are elements alphabetized on key while iterating? [\#53](https://github.com/nlohmann/json/issues/53) - Document erase, count, and iterators key and value [\#52](https://github.com/nlohmann/json/issues/52) +- Do not use std::to\_string [\#51](https://github.com/nlohmann/json/issues/51) - Supported compilers [\#50](https://github.com/nlohmann/json/issues/50) +- Confused about iterating through json objects [\#49](https://github.com/nlohmann/json/issues/49) - Use non-member begin/end [\#48](https://github.com/nlohmann/json/issues/48) - Erase key [\#47](https://github.com/nlohmann/json/issues/47) - Key iterator [\#46](https://github.com/nlohmann/json/issues/46) - Add count member function [\#45](https://github.com/nlohmann/json/issues/45) -- Printing attribute names [\#39](https://github.com/nlohmann/json/issues/39) -- Avoid using spaces when encoding without pretty print [\#31](https://github.com/nlohmann/json/issues/31) -- Cannot encode long numbers [\#30](https://github.com/nlohmann/json/issues/30) -- Creating an empty array [\#27](https://github.com/nlohmann/json/issues/27) -- Custom allocator support [\#25](https://github.com/nlohmann/json/issues/25) -- create a header-only version [\#16](https://github.com/nlohmann/json/issues/16) -- Add to\_string overload for indentation [\#13](https://github.com/nlohmann/json/issues/13) -- move code into namespace [\#9](https://github.com/nlohmann/json/issues/9) -- free functions for explicit objects and arrays in initializer lists [\#8](https://github.com/nlohmann/json/issues/8) -- Test case coverage [\#2](https://github.com/nlohmann/json/issues/2) -- Parse streams incrementally. [\#40](https://github.com/nlohmann/json/pull/40) ([aburgh](https://github.com/aburgh)) - -- Binary string causes numbers to be dumped as hex [\#101](https://github.com/nlohmann/json/issues/101) -- failed to iterator json object with reverse\_iterator [\#100](https://github.com/nlohmann/json/issues/100) -- static analysis warnings [\#94](https://github.com/nlohmann/json/issues/94) -- reverse\_iterator operator inheritance problem [\#93](https://github.com/nlohmann/json/issues/93) -- Nonstandard integer type [\#89](https://github.com/nlohmann/json/issues/89) -- lexer::get\_number return NAN [\#82](https://github.com/nlohmann/json/issues/82) -- Handle infinity and NaN cases [\#70](https://github.com/nlohmann/json/issues/70) -- errors in g++-4.8.1 [\#68](https://github.com/nlohmann/json/issues/68) -- Double quotation mark is not parsed correctly [\#60](https://github.com/nlohmann/json/issues/60) -- Do not use std::to\_string [\#51](https://github.com/nlohmann/json/issues/51) -- Confused about iterating through json objects [\#49](https://github.com/nlohmann/json/issues/49) - Problem getting vector \(array\) of strings [\#44](https://github.com/nlohmann/json/issues/44) - Compilation error due to assuming that private=public [\#43](https://github.com/nlohmann/json/issues/43) - Use of deprecated implicit copy constructor [\#42](https://github.com/nlohmann/json/issues/42) +- Printing attribute names [\#39](https://github.com/nlohmann/json/issues/39) - dumping a small number\_float just outputs 0.000000 [\#37](https://github.com/nlohmann/json/issues/37) +- find is error [\#32](https://github.com/nlohmann/json/issues/32) - Avoid using spaces when encoding without pretty print [\#31](https://github.com/nlohmann/json/issues/31) - Cannot encode long numbers [\#30](https://github.com/nlohmann/json/issues/30) - segmentation fault when iterating over empty arrays/objects [\#28](https://github.com/nlohmann/json/issues/28) +- Creating an empty array [\#27](https://github.com/nlohmann/json/issues/27) +- Custom allocator support [\#25](https://github.com/nlohmann/json/issues/25) +- make the type of the used string container customizable [\#20](https://github.com/nlohmann/json/issues/20) - Improper parsing of JSON string "\\" [\#17](https://github.com/nlohmann/json/issues/17) +- create a header-only version [\#16](https://github.com/nlohmann/json/issues/16) - Don't return "const values" [\#15](https://github.com/nlohmann/json/issues/15) +- Add to\_string overload for indentation [\#13](https://github.com/nlohmann/json/issues/13) - string parser does not recognize uncompliant strings [\#12](https://github.com/nlohmann/json/issues/12) -- free functions for explicit objects and arrays in initializer lists [\#8](https://github.com/nlohmann/json/issues/8) -- Runtime error in Travis job [\#1](https://github.com/nlohmann/json/issues/1) -- Fix compilation of json\_unit with GCC 5 [\#59](https://github.com/nlohmann/json/pull/59) ([dkopecek](https://github.com/dkopecek)) - -- Finish documenting the public interface in Doxygen [\#102](https://github.com/nlohmann/json/issues/102) -- 'noexcept' : unknown override specifier [\#99](https://github.com/nlohmann/json/issues/99) -- Keys when iterating over objects [\#67](https://github.com/nlohmann/json/issues/67) -- Complete brief documentation [\#61](https://github.com/nlohmann/json/issues/61) -- Get coverage back to 100% [\#58](https://github.com/nlohmann/json/issues/58) - possible double-free in find function [\#11](https://github.com/nlohmann/json/issues/11) - UTF-8 encoding/deconding/testing [\#10](https://github.com/nlohmann/json/issues/10) +- move code into namespace [\#9](https://github.com/nlohmann/json/issues/9) +- free functions for explicit objects and arrays in initializer lists [\#8](https://github.com/nlohmann/json/issues/8) +- unique\_ptr for ownership [\#7](https://github.com/nlohmann/json/issues/7) - Add unit tests [\#4](https://github.com/nlohmann/json/issues/4) - Drop C++98 support [\#3](https://github.com/nlohmann/json/issues/3) +- Test case coverage [\#2](https://github.com/nlohmann/json/issues/2) +- Runtime error in Travis job [\#1](https://github.com/nlohmann/json/issues/1) - Keyword 'inline' is useless when member functions are defined in headers [\#87](https://github.com/nlohmann/json/pull/87) ([ahamez](https://github.com/ahamez)) - Remove useless typename [\#86](https://github.com/nlohmann/json/pull/86) ([ahamez](https://github.com/ahamez)) @@ -262,6 +352,8 @@ All notable changes to this project will be documented in this file. This projec - support enum [\#71](https://github.com/nlohmann/json/pull/71) ([likebeta](https://github.com/likebeta)) - Fix performance regression introduced with the parsing callback feature. [\#69](https://github.com/nlohmann/json/pull/69) ([aburgh](https://github.com/aburgh)) - Improve the implementations of the comparission-operators [\#63](https://github.com/nlohmann/json/pull/63) ([Florianjw](https://github.com/Florianjw)) +- Fix compilation of json\_unit with GCC 5 [\#59](https://github.com/nlohmann/json/pull/59) ([dkopecek](https://github.com/dkopecek)) +- Parse streams incrementally. [\#40](https://github.com/nlohmann/json/pull/40) ([aburgh](https://github.com/aburgh)) - Feature/small float serialization [\#38](https://github.com/nlohmann/json/pull/38) ([jrandall](https://github.com/jrandall)) - template version with re2c scanner [\#36](https://github.com/nlohmann/json/pull/36) ([nlohmann](https://github.com/nlohmann)) - more descriptive documentation in example [\#33](https://github.com/nlohmann/json/pull/33) ([luxe](https://github.com/luxe)) diff --git a/LICENSE.MIT b/LICENSE.MIT index e2ac4891..79145efa 100644 --- a/LICENSE.MIT +++ b/LICENSE.MIT @@ -1,4 +1,4 @@ -The library is licensed under the MIT License +JSON for Modern C++ is licensed under the MIT License : Copyright (c) 2013-2016 Niels Lohmann diff --git a/Makefile b/Makefile index 4c66fbfb..3fd6d54b 100644 --- a/Makefile +++ b/Makefile @@ -95,7 +95,7 @@ pretty: # benchmarks json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/cxxopts.hpp src/json.hpp cd benchmarks/files/numbers ; python generate.py - $(CXX) -std=c++11 $(CXXFLAGS) -DNDEBUG -O3 -flto -I src -I benchmarks $< $(LDFLAGS) -o $@ + $(CXX) -std=c++11 -pthread $(CXXFLAGS) -DNDEBUG -O3 -flto -I src -I benchmarks $< $(LDFLAGS) -o $@ ./json_benchmarks diff --git a/README.md b/README.md index 4bcbe97f..0305ea07 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build Status](https://travis-ci.org/nlohmann/json.svg?branch=master)](https://travis-ci.org/nlohmann/json) [![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json) [![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json) [![Try online](https://img.shields.io/badge/try-online-blue.svg)](http://melpon.org/wandbox/permlink/fsf5FqYe6GoX68W6) [![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT) @@ -24,7 +25,7 @@ Other aspects were not so important to us: - **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. -- **Speed**. We currently implement the parser as naive [recursive descent parser](http://en.wikipedia.org/wiki/Recursive_descent_parser) with hand coded string handling. It is fast enough, but a [LALR-parser](http://en.wikipedia.org/wiki/LALR_parser) may be even faster (but would consist of more files which makes the integration harder). +- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set. See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information. @@ -129,6 +130,8 @@ json array_not_object = { json::array({"currency", "USD"}), json::array({"value" ### Serialization / Deserialization +#### To/from strings + You can create an object (deserialization) by appending `_json` to a string literal: ```cpp @@ -162,6 +165,8 @@ std::cout << j.dump(4) << std::endl; // } ``` +#### To/from streams (e.g. files, string streams) + You can also use streams to serialize and deserialize: ```cpp @@ -176,10 +181,37 @@ std::cout << j; std::cout << std::setw(4) << j << std::endl; ``` -These operators work for any subclasses of `std::istream` or `std::ostream`. +These operators work for any subclasses of `std::istream` or `std::ostream`. Here is the same example with files: + +```cpp +// read a JSON file +std::ifstream i("file.json"); +json j; +i >> j; + +// write prettified JSON to another file +std::ofstream o("pretty.json"); +o << std::setw(4) << j << std::endl; +``` Please note that setting the exception bit for `failbit` is inappropriate for this use case. It will result in program termination due to the `noexcept` specifier in use. +#### Read from iterator range + +You can also read JSON from an iterator range; that is, from any container accessible by iterators whose content is stored as contiguous byte sequence, for instance a `std::vector`: + +```cpp +std::vector v = {'t', 'r', 'u', 'e'}; +json j = json::parse(v.begin(), v.end()); +``` + +You may leave the iterators for the range [begin, end): + +```cpp +std::vector v = {'t', 'r', 'u', 'e'}; +json j = json::parse(v); +``` + ### STL-like access @@ -192,6 +224,9 @@ j.push_back("foo"); j.push_back(1); j.push_back(true); +// also use emplace_back +j.emplace_back(1.78); + // iterate the array for (json::iterator it = j.begin(); it != j.end(); ++it) { std::cout << *it << '\n'; @@ -230,6 +265,9 @@ o["foo"] = 23; o["bar"] = false; o["baz"] = 3.141; +// also use emplace +o.emplace("weather", "sunny"); + // special iterator member functions for objects for (json::iterator it = o.begin(); it != o.end(); ++it) { std::cout << it.key() << " : " << it.value() << "\n"; @@ -423,14 +461,11 @@ The following compilers are currently used in continuous integration at [Travis] | Clang 3.7.1 | Ubuntu 14.04.4 LTS | clang version 3.7.1 (tags/RELEASE_371/final) | | Clang 3.8.0 | Ubuntu 14.04.4 LTS | clang version 3.8.0 (tags/RELEASE_380/final) | | Clang 3.8.1 | Ubuntu 14.04.4 LTS | clang version 3.8.1 (tags/RELEASE_381/final) | -| Clang Xcode 6.1 | Darwin Kernel Version 13.4.0 (OSX 10.9.5) | Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn) | -| Clang Xcode 6.2 | Darwin Kernel Version 13.4.0 (OSX 10.9.5) | Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) | -| Clang Xcode 6.3 | Darwin Kernel Version 14.3.0 (OSX 10.10.3) | Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn) | | Clang Xcode 6.4 | Darwin Kernel Version 14.3.0 (OSX 10.10.3) | Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) | -| Clang Xcode 7.1 | Darwin Kernel Version 14.5.0 (OSX 10.10.5) | Apple LLVM version 7.0.0 (clang-700.1.76) | -| Clang Xcode 7.2 | Darwin Kernel Version 15.0.0 (OSX 10.10.5) | Apple LLVM version 7.0.2 (clang-700.1.81) | | Clang Xcode 7.3 | Darwin Kernel Version 15.0.0 (OSX 10.10.5) | Apple LLVM version 7.3.0 (clang-703.0.29) | -| Clang Xcode 8.0 | Darwin Kernel Version 15.6.0 (OSX 10.11.6) | Apple LLVM version 8.0.0 (clang-800.0.38) | +| Clang Xcode 8.0 | Darwin Kernel Version 15.6.0 | Apple LLVM version 8.0.0 (clang-800.0.38) | +| Clang Xcode 8.1 | Darwin Kernel Version 16.1.0 (macOS 10.12.1) | Apple LLVM version 8.0.0 (clang-800.0.42.1) | +| Clang Xcode 8.2 | Darwin Kernel Version 16.1.0 (macOS 10.12.1) | Apple LLVM version 8.0.0 (clang-800.0.42.1) | | Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25123.0 | @@ -499,6 +534,9 @@ I deeply appreciate the help of the following people. - [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion. - [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable. - [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file. +- [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function. +- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](http://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser and improved the benchmarking code. +- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan. Thanks a lot for helping out! @@ -522,7 +560,7 @@ To compile and run the tests, you need to execute $ make check =============================================================================== -All tests passed (8905491 assertions in 36 test cases) +All tests passed (8905518 assertions in 36 test cases) ``` Alternatively, you can use [CMake](https://cmake.org) and run diff --git a/benchmarks/benchmarks.cpp b/benchmarks/benchmarks.cpp index ec6b462c..745123c9 100644 --- a/benchmarks/benchmarks.cpp +++ b/benchmarks/benchmarks.cpp @@ -1,107 +1,118 @@ #define BENCHPRESS_CONFIG_MAIN #include +#include #include #include +#include +#include -BENCHMARK("parse jeopardy.json", [](benchpress::context* ctx) +using json = nlohmann::json; + +struct StartUp { - for (size_t i = 0; i < ctx->num_iterations(); ++i) + StartUp() { - std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json"); - nlohmann::json j; - j << input_file; +#ifndef __llvm__ + // pin thread to a single CPU + cpu_set_t cpuset; + pthread_t thread; + thread = pthread_self(); + CPU_ZERO(&cpuset); + CPU_SET(std::thread::hardware_concurrency() - 1, &cpuset); + pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset); +#endif } -}) +}; +StartUp startup; -BENCHMARK("parse canada.json", [](benchpress::context* ctx) +enum class EMode { input, output_no_indent, output_with_indent }; + +static void bench(benchpress::context& ctx, + const std::string& in_path, + const EMode mode) { - for (size_t i = 0; i < ctx->num_iterations(); ++i) + // using string streams for benchmarking to factor-out cold-cache disk + // access. + std::stringstream istr; { - std::ifstream input_file("benchmarks/files/nativejson-benchmark/canada.json"); - nlohmann::json j; - j << input_file; - } -}) + // read file into string stream + std::ifstream input_file(in_path); + istr << input_file.rdbuf(); + input_file.close(); -BENCHMARK("parse citm_catalog.json", [](benchpress::context* ctx) -{ - for (size_t i = 0; i < ctx->num_iterations(); ++i) - { - std::ifstream input_file("benchmarks/files/nativejson-benchmark/citm_catalog.json"); - nlohmann::json j; - j << input_file; - } -}) - -BENCHMARK("parse twitter.json", [](benchpress::context* ctx) -{ - for (size_t i = 0; i < ctx->num_iterations(); ++i) - { - std::ifstream input_file("benchmarks/files/nativejson-benchmark/twitter.json"); - nlohmann::json j; - j << input_file; - } -}) - -BENCHMARK("parse numbers/floats.json", [](benchpress::context* ctx) -{ - for (size_t i = 0; i < ctx->num_iterations(); ++i) - { - std::ifstream input_file("benchmarks/files/numbers/floats.json"); - nlohmann::json j; - j << input_file; - } -}) - -BENCHMARK("parse numbers/signed_ints.json", [](benchpress::context* ctx) -{ - for (size_t i = 0; i < ctx->num_iterations(); ++i) - { - std::ifstream input_file("benchmarks/files/numbers/signed_ints.json"); - nlohmann::json j; - j << input_file; - } -}) - -BENCHMARK("parse numbers/unsigned_ints.json", [](benchpress::context* ctx) -{ - for (size_t i = 0; i < ctx->num_iterations(); ++i) - { - std::ifstream input_file("benchmarks/files/numbers/unsigned_ints.json"); - nlohmann::json j; - j << input_file; - } -}) - -BENCHMARK("dump jeopardy.json", [](benchpress::context* ctx) -{ - std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json"); - nlohmann::json j; - j << input_file; - std::ofstream output_file("jeopardy.dump.json"); - - ctx->reset_timer(); - for (size_t i = 0; i < ctx->num_iterations(); ++i) - { - output_file << j; + // read the stream once + json j; + j << istr; + // clear flags and rewind + istr.clear(); + istr.seekg(0); } - std::remove("jeopardy.dump.json"); -}) - -BENCHMARK("dump jeopardy.json with indent", [](benchpress::context* ctx) -{ - std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json"); - nlohmann::json j; - j << input_file; - std::ofstream output_file("jeopardy.dump.json"); - - ctx->reset_timer(); - for (size_t i = 0; i < ctx->num_iterations(); ++i) + switch (mode) { - output_file << std::setw(4) << j; - } + // benchmarking input + case EMode::input: + { + ctx.reset_timer(); - std::remove("jeopardy.dump.json"); -}) + for (size_t i = 0; i < ctx.num_iterations(); ++i) + { + // clear flags and rewind + istr.clear(); + istr.seekg(0); + json j; + j << istr; + } + + break; + } + + // benchmarking output + case EMode::output_no_indent: + case EMode::output_with_indent: + { + // create JSON value from input + json j; + j << istr; + std::stringstream ostr; + + ctx.reset_timer(); + for (size_t i = 0; i < ctx.num_iterations(); ++i) + { + if (mode == EMode::output_no_indent) + { + ostr << j; + } + else + { + ostr << std::setw(4) << j; + } + + // reset data + ostr.str(std::string()); + } + + break; + } + } +} + +#define BENCHMARK_I(mode, title, in_path) \ + BENCHMARK((title), [](benchpress::context* ctx) \ + { \ + bench(*ctx, (in_path), (mode)); \ + }) + +BENCHMARK_I(EMode::input, "parse jeopardy.json", "benchmarks/files/jeopardy/jeopardy.json"); +BENCHMARK_I(EMode::input, "parse canada.json", "benchmarks/files/nativejson-benchmark/canada.json"); +BENCHMARK_I(EMode::input, "parse citm_catalog.json", "benchmarks/files/nativejson-benchmark/citm_catalog.json"); +BENCHMARK_I(EMode::input, "parse twitter.json", "benchmarks/files/nativejson-benchmark/twitter.json"); +BENCHMARK_I(EMode::input, "parse numbers/floats.json", "benchmarks/files/numbers/floats.json"); +BENCHMARK_I(EMode::input, "parse numbers/signed_ints.json", "benchmarks/files/numbers/signed_ints.json"); +BENCHMARK_I(EMode::input, "parse numbers/unsigned_ints.json", "benchmarks/files/numbers/unsigned_ints.json"); + +BENCHMARK_I(EMode::output_no_indent, "dump jeopardy.json", "benchmarks/files/jeopardy/jeopardy.json"); +BENCHMARK_I(EMode::output_with_indent, "dump jeopardy.json with indent", "benchmarks/files/jeopardy/jeopardy.json"); +BENCHMARK_I(EMode::output_no_indent, "dump numbers/floats.json", "benchmarks/files/numbers/floats.json"); +BENCHMARK_I(EMode::output_no_indent, "dump numbers/signed_ints.json", "benchmarks/files/numbers/signed_ints.json"); diff --git a/doc/Doxyfile b/doc/Doxyfile index 3201df52..625f9c11 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "JSON for Modern C++" -PROJECT_NUMBER = 2.0.7 +PROJECT_NUMBER = 2.0.8 PROJECT_BRIEF = PROJECT_LOGO = OUTPUT_DIRECTORY = . diff --git a/doc/examples/README.link b/doc/examples/README.link index 19e256b5..48a66aa0 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/emplace.cpp b/doc/examples/emplace.cpp new file mode 100644 index 00000000..c3b3c3e3 --- /dev/null +++ b/doc/examples/emplace.cpp @@ -0,0 +1,30 @@ +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values + auto res1 = object.emplace("three", 3); + null.emplace("A", "a"); + null.emplace("B", "b"); + + // the following call will not add an object, because there is already + // a value stored at key "B" + auto res2 = null.emplace("B", "c"); + + // print values + std::cout << object << '\n'; + std::cout << *res1.first << " " << std::boolalpha << res1.second << '\n'; + + std::cout << null << '\n'; + std::cout << *res2.first << " " << std::boolalpha << res2.second << '\n'; +} diff --git a/doc/examples/emplace.link b/doc/examples/emplace.link new file mode 100644 index 00000000..a9366c32 --- /dev/null +++ b/doc/examples/emplace.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/emplace.output b/doc/examples/emplace.output new file mode 100644 index 00000000..83d6f773 --- /dev/null +++ b/doc/examples/emplace.output @@ -0,0 +1,6 @@ +{"one":1,"two":2} +null +{"one":1,"three":3,"two":2} +3 true +{"A":"a","B":"b"} +"b" false diff --git a/doc/examples/emplace_back.cpp b/doc/examples/emplace_back.cpp new file mode 100644 index 00000000..4e9ec89a --- /dev/null +++ b/doc/examples/emplace_back.cpp @@ -0,0 +1,23 @@ +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json array = {1, 2, 3, 4, 5}; + json null; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; + + // add values + array.emplace_back(6); + null.emplace_back("first"); + null.emplace_back(3, "second"); + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; +} diff --git a/doc/examples/emplace_back.link b/doc/examples/emplace_back.link new file mode 100644 index 00000000..4363e4c7 --- /dev/null +++ b/doc/examples/emplace_back.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/emplace_back.output b/doc/examples/emplace_back.output new file mode 100644 index 00000000..bdd80d82 --- /dev/null +++ b/doc/examples/emplace_back.output @@ -0,0 +1,4 @@ +[1,2,3,4,5] +null +[1,2,3,4,5,6] +["first",["second","second","second"]] diff --git a/doc/index.md b/doc/index.md index fcb5b432..0b608eb5 100644 --- a/doc/index.md +++ b/doc/index.md @@ -197,7 +197,7 @@ The container functions known from STL have been extended to support the differe @link nlohmann::basic_json::max_size `max_size` @endlink (returns `0`) - modifiers + modifiers `clear` @link nlohmann::basic_json::clear `clear` @endlink @link nlohmann::basic_json::clear `clear` @endlink @@ -233,6 +233,15 @@ The container functions known from STL have been extended to support the differe throws `std::domain_error` @link nlohmann::basic_json::push_back(const typename object_t::value_type & val) `push_back` @endlink (creates object)
@link nlohmann::basic_json::push_back(const nlohmann::basic_json &) `push_back` @endlink (creates array) + + `emplace` / `emplace_back` + @link nlohmann::basic_json::emplace() `emplace` @endlink + @link nlohmann::basic_json::emplace_back() `emplace_back` @endlink + throws `std::domain_error` + throws `std::domain_error` + throws `std::domain_error` + @link nlohmann::basic_json::emplace() `emplace` @endlink (creates object)
@link nlohmann::basic_json::emplace_back() `emplace_back` @endlink (creates array) + `swap` @link nlohmann::basic_json::swap `swap` @endlink @@ -268,4 +277,4 @@ The container functions known from STL have been extended to support the differe @author [Niels Lohmann](http://nlohmann.me) @see https://github.com/nlohmann/json to download the source code -@version 2.0.7 +@version 2.0.8 diff --git a/doc/json.gif b/doc/json.gif index 02ffdc89..a5f11878 100644 Binary files a/doc/json.gif and b/doc/json.gif differ diff --git a/src/json.hpp b/src/json.hpp index a302bb02..6fed0a12 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -45,7 +45,7 @@ SOFTWARE. #include // istream, ostream #include // advance, begin, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator #include // numeric_limits -#include // locale, numpunct +#include // locale #include // map #include // addressof, allocator, allocator_traits, unique_ptr #include // accumulate @@ -122,26 +122,6 @@ struct has_mapped_type std::is_integral()))>::value; }; -/*! -@brief helper class to create locales with decimal point - -This struct is used a default locale during the JSON serialization. JSON -requires the decimal point to be `.`, so this function overloads the -`do_decimal_point()` function to return `.`. This function is called by -float-to-string conversions to retrieve the decimal separator between integer -and fractional parts. - -@sa https://github.com/nlohmann/json/issues/51#issuecomment-86869315 -@since version 2.0.0 -*/ -struct DecimalSeparator : std::numpunct -{ - char do_decimal_point() const - { - return '.'; - } -}; - } /*! @@ -2201,8 +2181,7 @@ class basic_json { std::stringstream ss; // fix locale problems - const static std::locale loc(std::locale(), new DecimalSeparator); - ss.imbue(loc); + ss.imbue(std::locale::classic()); // 6, 15 or 16 digits of precision allows round-trip IEEE 754 // string->float->string, string->double->string or string->long @@ -5053,6 +5032,102 @@ class basic_json return *this; } + /*! + @brief add an object to an array + + Creates a JSON value from the passed parameters @a args to the end of the + JSON value. If the function is called on a JSON null value, an empty array + is created before appending the value created from @a args. + + @param[in] args arguments to forward to a constructor of @ref basic_json + @tparam Args compatible types to create a @ref basic_json object + + @throw std::domain_error when called on a type other than JSON array or + null; example: `"cannot use emplace_back() with number"` + + @complexity Amortized constant. + + @liveexample{The example shows how `push_back()` can be used to add + elements to a JSON array. Note how the `null` value was silently converted + to a JSON array.,emplace_back} + + @since version 2.0.8 + */ + template + void emplace_back(Args&& ... args) + { + // emplace_back only works for null objects or arrays + if (not(is_null() or is_array())) + { + throw std::domain_error("cannot use emplace_back() with " + type_name()); + } + + // transform null object into an array + if (is_null()) + { + m_type = value_t::array; + m_value = value_t::array; + assert_invariant(); + } + + // add element to array (perfect forwarding) + m_value.array->emplace_back(std::forward(args)...); + } + + /*! + @brief add an object to an object if key does not exist + + Inserts a new element into a JSON object constructed in-place with the given + @a args if there is no element with the key in the container. If the + function is called on a JSON null value, an empty object is created before + appending the value created from @a args. + + @param[in] args arguments to forward to a constructor of @ref basic_json + @tparam Args compatible types to create a @ref basic_json object + + @return a pair consisting of an iterator to the inserted element, or the + already-existing element if no insertion happened, and a bool + denoting whether the insertion took place. + + @throw std::domain_error when called on a type other than JSON object or + null; example: `"cannot use emplace() with number"` + + @complexity Logarithmic in the size of the container, O(log(`size()`)). + + @liveexample{The example shows how `emplace()` can be used to add elements + to a JSON object. Note how the `null` value was silently converted to a + JSON object. Further note how no value is added if there was already one + value stored with the same key.,emplace} + + @since version 2.0.8 + */ + template + std::pair emplace(Args&& ... args) + { + // emplace only works for null objects or arrays + if (not(is_null() or is_object())) + { + throw std::domain_error("cannot use emplace() with " + type_name()); + } + + // transform null object into an object + if (is_null()) + { + m_type = value_t::object; + m_value = value_t::object; + assert_invariant(); + } + + // add element to array (perfect forwarding) + auto res = m_value.object->emplace(std::forward(args)...); + // create result iterator and set iterator to the result of emplace + auto it = begin(); + it.m_it.object_iterator = res.first; + + // return pair of iterator and boolean + return {it, res.second}; + } + /*! @brief inserts element @@ -5829,7 +5904,7 @@ class basic_json o.width(0); // fix locale problems - const auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator)); + const auto old_locale = o.imbue(std::locale::classic()); // set precision // 6, 15 or 16 digits of precision allows round-trip IEEE 754 @@ -7618,6 +7693,12 @@ class basic_json explicit lexer(std::istream& s) : m_stream(&s), m_line_buffer() { + // immediately abort if stream is erroneous + if (s.fail()) + { + throw std::invalid_argument("stream error: " + std::string(strerror(errno))); + } + // fill buffer fill_line_buffer(); @@ -8740,8 +8821,22 @@ basic_json_parser_66: */ void fill_line_buffer(size_t n = 0) { + // if line buffer is used, m_content points to its data + assert(m_line_buffer.empty() + or m_content == reinterpret_cast(m_line_buffer.data())); + + // if line buffer is used, m_limit is set past the end of its data + assert(m_line_buffer.empty() + or m_limit == m_content + m_line_buffer.size()); + + // pointer relationships + assert(m_content <= m_start); + assert(m_start <= m_cursor); + assert(m_cursor <= m_limit); + assert(m_marker == nullptr or m_marker <= m_limit); + // number of processed characters (p) - const auto offset_start = m_start - m_content; + const size_t num_processed_chars = static_cast(m_start - m_content); // offset for m_marker wrt. to m_start const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start; // number of unprocessed characters (u) @@ -8750,35 +8845,34 @@ basic_json_parser_66: // no stream is used or end of file is reached if (m_stream == nullptr or m_stream->eof()) { - // skip this part if we are already using the line buffer - if (m_start != reinterpret_cast(m_line_buffer.data())) - { - // copy unprocessed characters to line buffer - m_line_buffer.clear(); - for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor) - { - m_line_buffer.append(1, static_cast(*m_cursor)); - } - } + // m_start may or may not be pointing into m_line_buffer at + // this point. We trust the standand library to do the right + // thing. See http://stackoverflow.com/q/28142011/266378 + m_line_buffer.assign(m_start, m_limit); // append n characters to make sure that there is sufficient // space between m_cursor and m_limit m_line_buffer.append(1, '\x00'); - m_line_buffer.append(n - 1, '\x01'); + if (n > 0) + { + m_line_buffer.append(n - 1, '\x01'); + } } else { // delete processed characters from line buffer - m_line_buffer.erase(0, static_cast(offset_start)); + m_line_buffer.erase(0, num_processed_chars); // read next line from input stream - std::string line; - std::getline(*m_stream, line, '\n'); + m_line_buffer_tmp.clear(); + std::getline(*m_stream, m_line_buffer_tmp, '\n'); + // add line with newline symbol to the line buffer - m_line_buffer += line + "\n"; + m_line_buffer += m_line_buffer_tmp; + m_line_buffer.push_back('\n'); } // set pointers - m_content = reinterpret_cast(m_line_buffer.c_str()); + m_content = reinterpret_cast(m_line_buffer.data()); assert(m_content != nullptr); m_start = m_content; m_marker = m_start + offset_marker; @@ -8861,9 +8955,20 @@ basic_json_parser_66: // iterate the result between the quotes for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i) { - // process escaped characters - if (*i == '\\') + // find next escape character + auto e = std::find(i, m_cursor - 1, '\\'); + if (e != i) { + // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705 + for (auto k = i; k < e; k++) + { + result.push_back(static_cast(*k)); + } + i = e - 1; // -1 because of ++i + } + else + { + // processing escaped character // read next character ++i; @@ -8950,12 +9055,6 @@ basic_json_parser_66: } } } - else - { - // all other characters are just copied to the end of the - // string - result.append(1, static_cast(*i)); - } } return result; @@ -9139,6 +9238,8 @@ basic_json_parser_66: std::istream* m_stream = nullptr; /// line buffer buffer for m_stream string_t m_line_buffer {}; + /// used for filling m_line_buffer + string_t m_line_buffer_tmp {}; /// the buffer pointer const lexer_char_t* m_content = nullptr; /// pointer to the beginning of the current symbol diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index b829889d..c6a99b89 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -45,7 +45,7 @@ SOFTWARE. #include // istream, ostream #include // advance, begin, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator #include // numeric_limits -#include // locale, numpunct +#include // locale #include // map #include // addressof, allocator, allocator_traits, unique_ptr #include // accumulate @@ -122,26 +122,6 @@ struct has_mapped_type std::is_integral()))>::value; }; -/*! -@brief helper class to create locales with decimal point - -This struct is used a default locale during the JSON serialization. JSON -requires the decimal point to be `.`, so this function overloads the -`do_decimal_point()` function to return `.`. This function is called by -float-to-string conversions to retrieve the decimal separator between integer -and fractional parts. - -@sa https://github.com/nlohmann/json/issues/51#issuecomment-86869315 -@since version 2.0.0 -*/ -struct DecimalSeparator : std::numpunct -{ - char do_decimal_point() const - { - return '.'; - } -}; - } /*! @@ -2201,8 +2181,7 @@ class basic_json { std::stringstream ss; // fix locale problems - const static std::locale loc(std::locale(), new DecimalSeparator); - ss.imbue(loc); + ss.imbue(std::locale::classic()); // 6, 15 or 16 digits of precision allows round-trip IEEE 754 // string->float->string, string->double->string or string->long @@ -5053,6 +5032,102 @@ class basic_json return *this; } + /*! + @brief add an object to an array + + Creates a JSON value from the passed parameters @a args to the end of the + JSON value. If the function is called on a JSON null value, an empty array + is created before appending the value created from @a args. + + @param[in] args arguments to forward to a constructor of @ref basic_json + @tparam Args compatible types to create a @ref basic_json object + + @throw std::domain_error when called on a type other than JSON array or + null; example: `"cannot use emplace_back() with number"` + + @complexity Amortized constant. + + @liveexample{The example shows how `push_back()` can be used to add + elements to a JSON array. Note how the `null` value was silently converted + to a JSON array.,emplace_back} + + @since version 2.0.8 + */ + template + void emplace_back(Args&& ... args) + { + // emplace_back only works for null objects or arrays + if (not(is_null() or is_array())) + { + throw std::domain_error("cannot use emplace_back() with " + type_name()); + } + + // transform null object into an array + if (is_null()) + { + m_type = value_t::array; + m_value = value_t::array; + assert_invariant(); + } + + // add element to array (perfect forwarding) + m_value.array->emplace_back(std::forward(args)...); + } + + /*! + @brief add an object to an object if key does not exist + + Inserts a new element into a JSON object constructed in-place with the given + @a args if there is no element with the key in the container. If the + function is called on a JSON null value, an empty object is created before + appending the value created from @a args. + + @param[in] args arguments to forward to a constructor of @ref basic_json + @tparam Args compatible types to create a @ref basic_json object + + @return a pair consisting of an iterator to the inserted element, or the + already-existing element if no insertion happened, and a bool + denoting whether the insertion took place. + + @throw std::domain_error when called on a type other than JSON object or + null; example: `"cannot use emplace() with number"` + + @complexity Logarithmic in the size of the container, O(log(`size()`)). + + @liveexample{The example shows how `emplace()` can be used to add elements + to a JSON object. Note how the `null` value was silently converted to a + JSON object. Further note how no value is added if there was already one + value stored with the same key.,emplace} + + @since version 2.0.8 + */ + template + std::pair emplace(Args&& ... args) + { + // emplace only works for null objects or arrays + if (not(is_null() or is_object())) + { + throw std::domain_error("cannot use emplace() with " + type_name()); + } + + // transform null object into an object + if (is_null()) + { + m_type = value_t::object; + m_value = value_t::object; + assert_invariant(); + } + + // add element to array (perfect forwarding) + auto res = m_value.object->emplace(std::forward(args)...); + // create result iterator and set iterator to the result of emplace + auto it = begin(); + it.m_it.object_iterator = res.first; + + // return pair of iterator and boolean + return {it, res.second}; + } + /*! @brief inserts element @@ -5829,7 +5904,7 @@ class basic_json o.width(0); // fix locale problems - const auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator)); + const auto old_locale = o.imbue(std::locale::classic()); // set precision // 6, 15 or 16 digits of precision allows round-trip IEEE 754 @@ -7618,6 +7693,12 @@ class basic_json explicit lexer(std::istream& s) : m_stream(&s), m_line_buffer() { + // immediately abort if stream is erroneous + if (s.fail()) + { + throw std::invalid_argument("stream error: " + std::string(strerror(errno))); + } + // fill buffer fill_line_buffer(); @@ -7889,8 +7970,22 @@ class basic_json */ void fill_line_buffer(size_t n = 0) { + // if line buffer is used, m_content points to its data + assert(m_line_buffer.empty() + or m_content == reinterpret_cast(m_line_buffer.data())); + + // if line buffer is used, m_limit is set past the end of its data + assert(m_line_buffer.empty() + or m_limit == m_content + m_line_buffer.size()); + + // pointer relationships + assert(m_content <= m_start); + assert(m_start <= m_cursor); + assert(m_cursor <= m_limit); + assert(m_marker == nullptr or m_marker <= m_limit); + // number of processed characters (p) - const auto offset_start = m_start - m_content; + const size_t num_processed_chars = static_cast(m_start - m_content); // offset for m_marker wrt. to m_start const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start; // number of unprocessed characters (u) @@ -7899,35 +7994,34 @@ class basic_json // no stream is used or end of file is reached if (m_stream == nullptr or m_stream->eof()) { - // skip this part if we are already using the line buffer - if (m_start != reinterpret_cast(m_line_buffer.data())) - { - // copy unprocessed characters to line buffer - m_line_buffer.clear(); - for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor) - { - m_line_buffer.append(1, static_cast(*m_cursor)); - } - } + // m_start may or may not be pointing into m_line_buffer at + // this point. We trust the standand library to do the right + // thing. See http://stackoverflow.com/q/28142011/266378 + m_line_buffer.assign(m_start, m_limit); // append n characters to make sure that there is sufficient // space between m_cursor and m_limit m_line_buffer.append(1, '\x00'); - m_line_buffer.append(n - 1, '\x01'); + if (n > 0) + { + m_line_buffer.append(n - 1, '\x01'); + } } else { // delete processed characters from line buffer - m_line_buffer.erase(0, static_cast(offset_start)); + m_line_buffer.erase(0, num_processed_chars); // read next line from input stream - std::string line; - std::getline(*m_stream, line, '\n'); + m_line_buffer_tmp.clear(); + std::getline(*m_stream, m_line_buffer_tmp, '\n'); + // add line with newline symbol to the line buffer - m_line_buffer += line + "\n"; + m_line_buffer += m_line_buffer_tmp; + m_line_buffer.push_back('\n'); } // set pointers - m_content = reinterpret_cast(m_line_buffer.c_str()); + m_content = reinterpret_cast(m_line_buffer.data()); assert(m_content != nullptr); m_start = m_content; m_marker = m_start + offset_marker; @@ -8010,9 +8104,20 @@ class basic_json // iterate the result between the quotes for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i) { - // process escaped characters - if (*i == '\\') + // find next escape character + auto e = std::find(i, m_cursor - 1, '\\'); + if (e != i) { + // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705 + for (auto k = i; k < e; k++) + { + result.push_back(static_cast(*k)); + } + i = e - 1; // -1 because of ++i + } + else + { + // processing escaped character // read next character ++i; @@ -8099,12 +8204,6 @@ class basic_json } } } - else - { - // all other characters are just copied to the end of the - // string - result.append(1, static_cast(*i)); - } } return result; @@ -8288,6 +8387,8 @@ class basic_json std::istream* m_stream = nullptr; /// line buffer buffer for m_stream string_t m_line_buffer {}; + /// used for filling m_line_buffer + string_t m_line_buffer_tmp {}; /// the buffer pointer const lexer_char_t* m_content = nullptr; /// pointer to the beginning of the current symbol diff --git a/test/src/catch.hpp b/test/src/catch.hpp index 879fc5b1..2e6fe8d3 100644 --- a/test/src/catch.hpp +++ b/test/src/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v1.5.6 - * Generated: 2016-06-09 19:20:41.460328 + * Catch v1.5.8 + * Generated: 2016-10-26 12:07:30.938259 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. @@ -3223,10 +3223,11 @@ namespace Catch { bool matches( TestCaseInfo const& testCase ) const { // All patterns in a filter must match for the filter to be a match - for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) + for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { if( !(*it)->matches( testCase ) ) return false; - return true; + } + return true; } }; @@ -4719,8 +4720,11 @@ namespace Catch { std::string line; while( std::getline( f, line ) ) { line = trim(line); - if( !line.empty() && !startsWith( line, "#" ) ) - addTestOrTags( config, "\"" + line + "\"," ); + if( !line.empty() && !startsWith( line, "#" ) ) { + if( !startsWith( line, "\"" ) ) + line = "\"" + line + "\""; + addTestOrTags( config, line + "," ); + } } } @@ -5368,7 +5372,10 @@ namespace Catch { ++it ) { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); - Catch::cout() << testCaseInfo.name << std::endl; + if( startsWith( testCaseInfo.name, "#" ) ) + Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl; + else + Catch::cout() << testCaseInfo.name << std::endl; } return matchedTests; } @@ -6454,7 +6461,7 @@ namespace Catch { namespace Catch { struct RandomNumberGenerator { - typedef int result_type; + typedef std::ptrdiff_t result_type; result_type operator()( result_type n ) const { return std::rand() % n; } @@ -7571,7 +7578,7 @@ namespace Catch { return os; } - Version libraryVersion( 1, 5, 6, "", 0 ); + Version libraryVersion( 1, 5, 8, "", 0 ); } @@ -7802,8 +7809,11 @@ namespace Catch { bool contains( std::string const& s, std::string const& infix ) { return s.find( infix ) != std::string::npos; } + char toLowerCh(char c) { + return static_cast( ::tolower( c ) ); + } void toLowerInPlace( std::string& s ) { - std::transform( s.begin(), s.end(), s.begin(), ::tolower ); + std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); } std::string toLower( std::string const& s ) { std::string lc = s; @@ -8951,9 +8961,10 @@ namespace Catch { break; default: - // Escape control chars - based on contribution by @espenalb in PR #465 + // Escape control chars - based on contribution by @espenalb in PR #465 and + // by @mrpi PR #588 if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) - os << "&#x" << std::uppercase << std::hex << static_cast( c ); + os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast( c ) << ';'; else os << c; } @@ -9008,13 +9019,20 @@ namespace Catch { : m_tagIsOpen( false ), m_needsNewline( false ), m_os( &Catch::cout() ) - {} + { + // We encode control characters, which requires + // XML 1.1 + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + *m_os << "\n"; + } XmlWriter( std::ostream& os ) : m_tagIsOpen( false ), m_needsNewline( false ), m_os( &os ) - {} + { + *m_os << "\n"; + } ~XmlWriter() { while( !m_tags.empty() ) @@ -9181,7 +9199,7 @@ namespace Catch { virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { StreamingReporterBase::testCaseStarting(testInfo); - m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) ); + m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name ); if ( m_config->showDurations() == ShowDurations::Always ) m_testCaseTimer.start(); @@ -9243,7 +9261,7 @@ namespace Catch { .writeText( assertionResult.getMessage() ); break; case ResultWas::FatalErrorCondition: - m_xml.scopedElement( "Fatal Error Condition" ) + m_xml.scopedElement( "FatalErrorCondition" ) .writeAttribute( "filename", assertionResult.getSourceInfo().file ) .writeAttribute( "line", assertionResult.getSourceInfo().line ) .writeText( assertionResult.getMessage() ); diff --git a/test/src/fuzz.cpp b/test/src/fuzz.cpp index e614b238..880dc1ca 100644 --- a/test/src/fuzz.cpp +++ b/test/src/fuzz.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Run "make fuzz_testing" and follow the instructions. diff --git a/test/src/unit-algorithms.cpp b/test/src/unit-algorithms.cpp index 83612c37..5197f803 100644 --- a/test/src/unit-algorithms.cpp +++ b/test/src/unit-algorithms.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 c2487ccf..f6cecc87 100644 --- a/test/src/unit-allocator.cpp +++ b/test/src/unit-allocator.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-capacity.cpp b/test/src/unit-capacity.cpp index 19137407..97c19cf2 100644 --- a/test/src/unit-capacity.cpp +++ b/test/src/unit-capacity.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 9504dff5..2ef62441 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 428baf50..3d82fce4 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 c5999e35..22a04b05 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 c9d5fcd9..dad6b1ed 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 eb1cf627..582146a1 100644 --- a/test/src/unit-comparison.cpp +++ b/test/src/unit-comparison.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 d9a74029..002ccdfb 100644 --- a/test/src/unit-concepts.cpp +++ b/test/src/unit-concepts.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 45b7aebe..6804a3a9 100644 --- a/test/src/unit-constructor1.cpp +++ b/test/src/unit-constructor1.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 671e4ad6..1edad6ae 100644 --- a/test/src/unit-constructor2.cpp +++ b/test/src/unit-constructor2.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 e797e5e1..8791caf2 100644 --- a/test/src/unit-convenience.cpp +++ b/test/src/unit-convenience.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 b02431be..1c49a93b 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 8c820ce7..969a7753 100644 --- a/test/src/unit-deserialization.cpp +++ b/test/src/unit-deserialization.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 09e5f479..d3b9ed4e 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 1b825339..ed1348f8 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 8a2eb039..d373c103 100644 --- a/test/src/unit-inspection.cpp +++ b/test/src/unit-inspection.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-iterator_wrapper.cpp b/test/src/unit-iterator_wrapper.cpp index d4434393..af1fa08e 100644 --- a/test/src/unit-iterator_wrapper.cpp +++ b/test/src/unit-iterator_wrapper.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-iterators1.cpp b/test/src/unit-iterators1.cpp index f4d1aad7..d51c4541 100644 --- a/test/src/unit-iterators1.cpp +++ b/test/src/unit-iterators1.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 27d8fbb8..f231c8ec 100644 --- a/test/src/unit-iterators2.cpp +++ b/test/src/unit-iterators2.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 79070135..9a40ce79 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 1b1e3485..35558d27 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit-modifiers.cpp b/test/src/unit-modifiers.cpp index fd7fed56..08a6dd34 100644 --- a/test/src/unit-modifiers.cpp +++ b/test/src/unit-modifiers.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -258,6 +258,103 @@ TEST_CASE("modifiers") } } + SECTION("emplace_back()") + { + SECTION("to array") + { + SECTION("null") + { + json j; + j.emplace_back(1); + j.emplace_back(2); + CHECK(j.type() == json::value_t::array); + CHECK(j == json({1, 2})); + } + + SECTION("array") + { + json j = {1, 2, 3}; + j.emplace_back("Hello"); + CHECK(j.type() == json::value_t::array); + CHECK(j == json({1, 2, 3, "Hello"})); + } + + SECTION("multiple values") + { + json j; + j.emplace_back(3, "foo"); + CHECK(j.type() == json::value_t::array); + CHECK(j == json({{"foo", "foo", "foo"}})); + } + } + + SECTION("other type") + { + json j = 1; + CHECK_THROWS_AS(j.emplace_back("Hello"), std::domain_error); + CHECK_THROWS_WITH(j.emplace_back("Hello"), "cannot use emplace_back() with number"); + } + } + + SECTION("emplace()") + { + SECTION("to object") + { + SECTION("null") + { + // start with a null value + json j; + + // add a new key + auto res1 = j.emplace("foo", "bar"); + CHECK(res1.second == true); + CHECK(*res1.first == "bar"); + + // the null value is changed to an object + CHECK(j.type() == json::value_t::object); + + // add a new key + auto res2 = j.emplace("baz", "bam"); + CHECK(res2.second == true); + CHECK(*res2.first == "bam"); + + // we try to insert at given key - no change + auto res3 = j.emplace("baz", "bad"); + CHECK(res3.second == false); + CHECK(*res3.first == "bam"); + + // the final object + CHECK(j == json({{"baz", "bam"}, {"foo", "bar"}})); + } + + SECTION("object") + { + // start with an object + json j = {{"foo", "bar"}}; + + // add a new key + auto res1 = j.emplace("baz", "bam"); + CHECK(res1.second == true); + CHECK(*res1.first == "bam"); + + // add an existing key + auto res2 = j.emplace("foo", "bad"); + CHECK(res2.second == false); + CHECK(*res2.first == "bar"); + + // check final object + CHECK(j == json({{"baz", "bam"}, {"foo", "bar"}})); + } + } + + SECTION("other type") + { + json j = 1; + CHECK_THROWS_AS(j.emplace("foo", "bar"), std::domain_error); + CHECK_THROWS_WITH(j.emplace("foo", "bar"), "cannot use emplace() with number"); + } + } + SECTION("operator+=") { SECTION("to array") diff --git a/test/src/unit-pointer_access.cpp b/test/src/unit-pointer_access.cpp index 8948360c..5d5eb163 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 a5078e90..07f36363 100644 --- a/test/src/unit-readme.cpp +++ b/test/src/unit-readme.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 b7e1b90a..a036d2f8 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 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 661edc25..e04513ca 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -495,4 +495,25 @@ TEST_CASE("regression tests") json j = json::parse("22e2222"); CHECK(j == json()); } + + SECTION("issue #366 - json::parse on failed stream gets stuck") + { + std::ifstream f("file_not_found.json"); + CHECK_THROWS_AS(json::parse(f), std::invalid_argument); + } + + SECTION("issue #367 - calling stream at EOF") + { + std::stringstream ss; + json j; + ss << "123"; + CHECK_NOTHROW(j << ss); + + // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893: + // ss is not at EOF; this yielded an error before the fix + // (threw basic_string::append). No, it should just throw + // a parse error because of the EOF. + CHECK_THROWS_AS(j << ss, std::invalid_argument); + CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input"); + } } diff --git a/test/src/unit-serialization.cpp b/test/src/unit-serialization.cpp index cc8dcec0..0c800382 100644 --- a/test/src/unit-serialization.cpp +++ b/test/src/unit-serialization.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 15fee1f5..c41c4788 100644 --- a/test/src/unit-testsuites.cpp +++ b/test/src/unit-testsuites.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| 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 19da6497..0e49757b 100644 --- a/test/src/unit-unicode.cpp +++ b/test/src/unit-unicode.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . diff --git a/test/src/unit.cpp b/test/src/unit.cpp index 6ad7d8e1..7b93c387 100644 --- a/test/src/unit.cpp +++ b/test/src/unit.cpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.0.7 +| | |__ | | | | | | version 2.0.8 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License .