Merge branch 'release/3.1.2'

This commit is contained in:
Niels Lohmann 2018-03-14 21:47:50 +01:00
commit 183390c10b
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
67 changed files with 1576 additions and 298 deletions

1
.gitignore vendored
View file

@ -10,6 +10,7 @@ fuzz-testing
build
build_coverage
clang_analyze_build
doc/xml
doc/html

View file

@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0)
## PROJECT
## name and version
##
project(nlohmann_json VERSION 3.1.1 LANGUAGES CXX)
project(nlohmann_json VERSION 3.1.2 LANGUAGES CXX)
##
## INCLUDE

View file

@ -1,7 +1,46 @@
# Change Log
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
## [v3.1.1](https://github.com/nlohmann/json/releases/tag/v3.1.1) (2018-02-12)
## [v3.1.2](https://github.com/nlohmann/json/releases/tag/v3.1.2) (2018-03-14)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.1...v3.1.2)
- STL containers are always serialized to a nested array like \[\[1,2,3\]\] [\#1013](https://github.com/nlohmann/json/issues/1013)
- The library doesn't want to insert an unordered\_map [\#1010](https://github.com/nlohmann/json/issues/1010)
- Convert Json to uint8\_t [\#1008](https://github.com/nlohmann/json/issues/1008)
- How to compare two JSON objects? [\#1007](https://github.com/nlohmann/json/issues/1007)
- Syntax checking [\#1003](https://github.com/nlohmann/json/issues/1003)
- more than one operator '=' matches these operands [\#1002](https://github.com/nlohmann/json/issues/1002)
- How to check if key existed [\#1000](https://github.com/nlohmann/json/issues/1000)
- nlohmann::json::parse exhaust memory in go binding [\#999](https://github.com/nlohmann/json/issues/999)
- Range-based iteration over a non-array object [\#998](https://github.com/nlohmann/json/issues/998)
- get\<T\> for types that are not default constructible [\#996](https://github.com/nlohmann/json/issues/996)
- Prevent Null values to appear in .dump\(\) [\#995](https://github.com/nlohmann/json/issues/995)
- number parsing [\#993](https://github.com/nlohmann/json/issues/993)
- How to create a json variable? [\#990](https://github.com/nlohmann/json/issues/990)
- C2664 \(C++/CLR\) cannot convert 'nullptr' to 'nullptr &&' [\#987](https://github.com/nlohmann/json/issues/987)
- Uniform initialization from another json object differs between gcc and clang. [\#985](https://github.com/nlohmann/json/issues/985)
- Problem with adding the lib as a submodule [\#983](https://github.com/nlohmann/json/issues/983)
- UTF-8/Unicode error [\#982](https://github.com/nlohmann/json/issues/982)
- "forcing MSVC stacktrace to show which T we're talking about." error [\#980](https://github.com/nlohmann/json/issues/980)
- reverse order of serialization [\#979](https://github.com/nlohmann/json/issues/979)
- Assigning between different json types [\#977](https://github.com/nlohmann/json/issues/977)
- Support serialisation of `unique\_ptr\<\>` and `shared\_ptr\<\>` [\#975](https://github.com/nlohmann/json/issues/975)
- Unexpected end of input \(not same as one before\) [\#974](https://github.com/nlohmann/json/issues/974)
- Segfault on direct initializing json object [\#973](https://github.com/nlohmann/json/issues/973)
- Segmentation fault on G++ when trying to assign json string literal to custom json type. [\#972](https://github.com/nlohmann/json/issues/972)
- os\_defines.h:44:19: error: missing binary operator before token "\(" [\#970](https://github.com/nlohmann/json/issues/970)
- Passing an iteration object by reference to a function [\#967](https://github.com/nlohmann/json/issues/967)
- Json and fmt::lib's format\_arg\(\) [\#964](https://github.com/nlohmann/json/issues/964)
- Feature: to\_string\(const json& j\); [\#916](https://github.com/nlohmann/json/issues/916)
- Allowing for user-defined string type in lexer/parser [\#1009](https://github.com/nlohmann/json/pull/1009) ([nlohmann](https://github.com/nlohmann))
- dump to alternative string type, as defined in basic\_json template [\#1006](https://github.com/nlohmann/json/pull/1006) ([agrianius](https://github.com/agrianius))
- Fix memory leak during parser callback [\#1001](https://github.com/nlohmann/json/pull/1001) ([nlohmann](https://github.com/nlohmann))
- fixed misprinted condition detected by PVS Studio. [\#992](https://github.com/nlohmann/json/pull/992) ([bogemic](https://github.com/bogemic))
- Fix/basic json conversion [\#986](https://github.com/nlohmann/json/pull/986) ([theodelrieu](https://github.com/theodelrieu))
- Make integration section concise [\#981](https://github.com/nlohmann/json/pull/981) ([wla80](https://github.com/wla80))
## [v3.1.1](https://github.com/nlohmann/json/releases/tag/v3.1.1) (2018-02-13)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.0...v3.1.1)
- Updation of child object isn't reflected in parent Object [\#968](https://github.com/nlohmann/json/issues/968)

View file

@ -258,6 +258,12 @@ fuzzing-stop:
cppcheck:
cppcheck --enable=warning --inconclusive --force --std=c++11 $(AMALGAMATED_FILE) --error-exitcode=1
# compile and check with Clang Static Analyzer
clang_analyze:
rm -fr clang_analyze_build
mkdir clang_analyze_build
cd clang_analyze_build ; CCC_CXX=/Users/niels/Documents/projects/llvm-clang/local/bin/clang++ /Users/niels/Documents/projects/llvm-clang/local/bin/scan-build cmake ..
/Users/niels/Documents/projects/llvm-clang/local/bin/scan-build -enable-checker alpha.core.DynamicTypeChecker,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.cplusplus.DeleteWithNonVirtualDtor,alpha.cplusplus.IteratorRange,alpha.cplusplus.MisusedMovedObject,alpha.security.ArrayBoundV2,alpha.core.Conversion --use-c++=/Users/niels/Documents/projects/llvm-clang/local/bin/clang++ --view -analyze-headers -o clang_analyze_build/report.html make -j10 -C clang_analyze_build
##########################################################################
# maintainer targets

View file

@ -5,7 +5,7 @@
[![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)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=nlohmann/json&amp;utm_campaign=Badge_Grade)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/DfWUb7e2q2USw0Q6)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/TarF5pPn9NtHQjhf)
[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
[![GitHub Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases)
@ -42,7 +42,7 @@ There are myriads of [JSON](http://json.org) libraries out there, and each may e
- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.
- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/blob/master/test/src/unit.cpp) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) that there are no memory leaks. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests agains all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
Other aspects were not so important to us:
@ -55,7 +55,7 @@ See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.
## Integration
The single required source, file `json.hpp` is in the `single_include/nlohmann` directory or [released here](https://github.com/nlohmann/json/releases). All you need to do is add
[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add
```cpp
#include <nlohmann/json.hpp>
@ -64,9 +64,9 @@ The single required source, file `json.hpp` is in the `single_include/nlohmann`
using json = nlohmann::json;
```
to the files you want to use JSON objects. That's it. Do not forget to set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`:
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.
### Package Managers
@ -82,7 +82,7 @@ If you are using [Buckaroo](https://buckaroo.pm), you can install this library's
If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can use the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json). Please see the vcpkg project for any issues regarding the packaging.
If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).
If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).
## Examples
@ -111,7 +111,7 @@ Assume you want to create the JSON object
}
```
With the JSON class, you could write:
With this library, you could write:
```cpp
// create an empty structure (null)
@ -155,7 +155,7 @@ json j2 = {
};
```
Note that in all these cases, you never need to "tell" the compiler which JSON value you want to use. If you want to be explicit or express some edge cases, the functions `json::array` and `json::object` will help:
Note that in all these cases, you never need to "tell" the compiler which JSON value type you want to use. If you want to be explicit or express some edge cases, the functions [`json::array`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa80485befaffcadaa39965494e0b4d2e.html#aa80485befaffcadaa39965494e0b4d2e) and [`json::object`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa13f7c0615867542ce80337cbcf13ada.html#aa13f7c0615867542ce80337cbcf13ada) will help:
```cpp
// a way to express the empty array []
@ -174,7 +174,7 @@ json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
#### To/from strings
You can create an object (deserialization) by appending `_json` to a string literal:
You can create a JSON value (deserialization) by appending `_json` to a string literal:
```cpp
// create object from string literal
@ -191,14 +191,14 @@ auto j2 = R"(
Note that without appending the `_json` suffix, the passed string literal is not parsed, but just used as JSON string value. That is, `json j = "{ \"happy\": true, \"pi\": 3.141 }"` would just store the string `"{ "happy": true, "pi": 3.141 }"` rather than parsing the actual object.
The above example can also be expressed explicitly using `json::parse()`:
The above example can also be expressed explicitly using [`json::parse()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa9676414f2e36383c4b181fe856aa3c0.html#aa9676414f2e36383c4b181fe856aa3c0):
```cpp
// parse explicitly
auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
```
You can also get a string representation (serialize):
You can also get a string representation of a JSON value (serialize):
```cpp
// explicit conversion to string
@ -233,7 +233,7 @@ std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::
std::cout << j_string << " == " << serialized_string << std::endl;
```
`.dump()` always returns the serialized value, and `.get<std::string>()` returns the originally stored string value.
[`.dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5adea76fedba9898d404fef8598aa663.html#a5adea76fedba9898d404fef8598aa663) always returns the serialized value, and [`.get<std::string>()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a16f9445f7629f634221a42b967cdcd43.html#a16f9445f7629f634221a42b967cdcd43) returns the originally stored string value.
#### To/from streams (e.g. files, string streams)
@ -269,7 +269,7 @@ Please note that setting the exception bit for `failbit` is inappropriate for th
#### 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<std::uint8_t>`:
You can also parse 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<std::uint8_t>`:
```cpp
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
@ -360,7 +360,7 @@ o.erase("foo");
### Conversion from STL containers
Any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON types (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends on how the elements are ordered in the respective STL container.
Any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON values (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends on how the elements are ordered in the respective STL container.
```cpp
std::vector<int> c_vector {1, 2, 3, 4};
@ -400,7 +400,7 @@ json j_umset(c_umset); // both entries for "one" are used
// maybe ["one", "two", "one", "four"]
```
Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON types (see examples above) can be used to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container.
Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON values (see examples above) can be used to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container.
```cpp
std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
@ -525,7 +525,7 @@ int vi = jn.get<int>();
### Arbitrary types conversions
Every type can be serialized in JSON, not just STL-containers and scalar types. Usually, you would do something along those lines:
Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines:
```cpp
namespace ns {
@ -629,7 +629,7 @@ struct adl_serializer {
};
```
This serializer works fine when you have control over the type's namespace. However, what about `boost::optional`, or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`...
This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`...
To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example:
@ -651,7 +651,7 @@ namespace nlohmann {
if (j.is_null()) {
opt = boost::none;
} else {
opt = j.get<T>(); // same as above, but with
opt = j.get<T>(); // same as above, but with
// adl_serializer<T>::from_json
}
}
@ -669,7 +669,7 @@ struct move_only_type {
move_only_type(int ii): i(ii) {}
move_only_type(const move_only_type&) = delete;
move_only_type(move_only_type&&) = default;
int i;
};
@ -681,7 +681,7 @@ namespace nlohmann {
static move_only_type from_json(const json& j) {
return {j.get<int>()};
}
// Here's the catch! You must provide a to_json method! Otherwise you
// will not be able to convert move_only_type to json, since you fully
// specialized adl_serializer on that type
@ -698,9 +698,9 @@ Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohma
If you write your own serializer, you'll need to do a few things:
* use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`)
* use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods
* use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL
- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`)
- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods
- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL
Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL.
@ -716,7 +716,7 @@ struct less_than_32_serializer {
// this is where the magic happens
to_json(j, value);
}
template <typename BasicJsonType>
static void from_json(const BasicJsonType& j, T& value) {
// same thing here
@ -738,7 +738,7 @@ struct bad_serializer
// if BasicJsonType::json_serializer == bad_serializer ... oops!
j = value;
}
template <typename BasicJsonType>
static void to_json(const BasicJsonType& j, T& value) {
// this calls BasicJsonType::json_serializer<T>::from_json(j, value);
@ -798,13 +798,13 @@ Please note:
- GCC 4.8 does not work because of two bugs ([55817](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55817) and [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)) in the C++11 support. Note there is a [pull request](https://github.com/nlohmann/json/pull/212) to fix some of the issues.
- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.
```
APP_STL := c++_shared
NDK_TOOLCHAIN_VERSION := clang3.6
APP_CPPFLAGS += -frtti -fexceptions
```
The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10.
- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod`) may occur. Note this is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219).
@ -833,7 +833,7 @@ The following compilers are currently used in continuous integration at [Travis]
| Clang Xcode 9.0 | Darwin Kernel Version 16.7.0 (macOS 10.12.6) | Apple LLVM version 9.0.0 (clang-900.0.37) |
| Clang Xcode 9.1 | Darwin Kernel Version 16.7.0 (macOS 10.12.6) | Apple LLVM version 9.0.0 (clang-900.0.38) |
| Clang Xcode 9.2 | Darwin Kernel Version 16.7.0 (macOS 10.12.6) | Apple LLVM version 8.1.0 (clang-900.0.39.2) |
| Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25420.1, MSVC 19.0.24215.1 |
| Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25420.1, MSVC 19.0.24215.1 |
| Visual Studio 2017 | Windows Server 2016 | Microsoft (R) Build Engine version 15.5.180.51428, MSVC 19.12.25830.2 |
## License
@ -896,7 +896,7 @@ I deeply appreciate the help of the following people.
- [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines.
- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers.
- [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file.
- [msm-](https://github.com/msm-) added support for American Fuzzy Lop.
- [msm-](https://github.com/msm-) added support for American Fuzzy Lop.
- [Annihil](https://github.com/Annihil) fixed an example in the README file.
- [Themercee](https://github.com/Themercee) noted a wrong URL in the README file.
- [Lv Zheng](https://github.com/lv-zheng) fixed a namespace issue with `int64_t` and `uint64_t`.
@ -973,6 +973,9 @@ I deeply appreciate the help of the following people.
- [Patrik Huber](https://github.com/patrikhuber) fixed links in the README file.
- [johnfb](https://github.com/johnfb) found a bug in the implementation of CBOR's indefinite length strings.
- [Paul Fultz II](https://github.com/pfultz2) added a note on the cget package manager.
- [Wilson Lin](https://github.com/wla80) made the integration section of the README more concise.
- [RalfBielig](https://github.com/ralfbielig) detected and fixed a memory leak in the parser callback.
- [agrianius](https://github.com/agrianius) allowed to dump JSON to an alternative string type
Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
@ -1002,7 +1005,7 @@ The library itself contains of a single header file licensed under the MIT licen
- [**send_to_wandbox**](https://github.com/nlohmann/json/blob/develop/doc/scripts/send_to_wandbox.py) to send code examples to [Wandbox](http://melpon.org/wandbox)
- [**Travis**](https://travis-ci.org) for [continuous integration](https://travis-ci.org/nlohmann/json) on Linux and macOS
- [**Valgrind**](http://valgrind.org) to check for correct memory management
- [**Wandbox**](http://melpon.org/wandbox) for [online examples](https://wandbox.org/permlink/DfWUb7e2q2USw0Q6)
- [**Wandbox**](http://melpon.org/wandbox) for [online examples](https://wandbox.org/permlink/TarF5pPn9NtHQjhf)
## Projects using JSON for Modern C++

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 KiB

After

Width:  |  Height:  |  Size: 568 KiB

View file

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

View file

@ -11,7 +11,7 @@
"version": {
"major": 3,
"minor": 1,
"patch": 1,
"string": "3.1.1"
"patch": 2,
"string": "3.1.2"
}
}

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

View file

@ -32,6 +32,7 @@ class lexer
using number_integer_t = typename BasicJsonType::number_integer_t;
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
using number_float_t = typename BasicJsonType::number_float_t;
using string_t = typename BasicJsonType::string_t;
public:
/// token types for the parser
@ -1130,7 +1131,7 @@ scan_number_done:
}
/// return current string value (implicitly resets the token; useful only once)
std::string move_string()
string_t&& move_string()
{
return std::move(token_buffer);
}
@ -1260,7 +1261,7 @@ scan_number_done:
std::vector<char> token_string {};
/// buffer for variable-length tokens (numbers, strings)
std::string token_buffer {};
string_t token_buffer {};
/// a description of occurred lexer errors
const char* error_message = "";

View file

@ -32,6 +32,7 @@ class parser
using number_integer_t = typename BasicJsonType::number_integer_t;
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
using number_float_t = typename BasicJsonType::number_float_t;
using string_t = typename BasicJsonType::string_t;
using lexer_t = lexer<BasicJsonType>;
using token_type = typename lexer_t::token_type;
@ -175,7 +176,7 @@ class parser
}
// parse values
std::string key;
string_t key;
BasicJsonType value;
while (true)
{
@ -403,6 +404,7 @@ class parser
if (keep and callback and not callback(depth, parse_event_t::value, result))
{
result.m_value.destroy(result.m_type);
result.m_type = value_t::discarded;
}
}

View file

@ -233,7 +233,7 @@ struct is_compatible_complete_type
{
static constexpr bool value =
not std::is_base_of<std::istream, CompatibleCompleteType>::value and
not std::is_same<BasicJsonType, CompatibleCompleteType>::value and
not is_basic_json<CompatibleCompleteType>::value and
not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and
has_to_json<BasicJsonType, CompatibleCompleteType>::value;
};

View file

@ -704,116 +704,126 @@ class binary_writer
oa->write_characters(vec.data(), sizeof(NumberType));
}
template<typename NumberType>
// UBJSON: write number (floating point)
template<typename NumberType, typename std::enable_if<
std::is_floating_point<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
{
if (std::is_floating_point<NumberType>::value)
if (add_prefix)
{
oa->write_character(static_cast<CharType>('D')); // float64
}
write_number(n);
}
// UBJSON: write number (unsigned integer)
template<typename NumberType, typename std::enable_if<
std::is_unsigned<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
{
if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('D')); // float64
oa->write_character(static_cast<CharType>('i')); // int8
}
write_number(n);
write_number(static_cast<uint8_t>(n));
}
else if (std::is_unsigned<NumberType>::value)
else if (n <= (std::numeric_limits<uint8_t>::max)())
{
if (n <= (std::numeric_limits<int8_t>::max)())
if (add_prefix)
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('i')); // int8
}
write_number(static_cast<uint8_t>(n));
oa->write_character(static_cast<CharType>('U')); // uint8
}
else if (n <= (std::numeric_limits<uint8_t>::max)())
write_number(static_cast<uint8_t>(n));
}
else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
{
if (add_prefix)
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('U')); // uint8
}
write_number(static_cast<uint8_t>(n));
oa->write_character(static_cast<CharType>('I')); // int16
}
else if (n <= (std::numeric_limits<int16_t>::max)())
write_number(static_cast<int16_t>(n));
}
else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
{
if (add_prefix)
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('I')); // int16
}
write_number(static_cast<int16_t>(n));
oa->write_character(static_cast<CharType>('l')); // int32
}
else if (n <= (std::numeric_limits<int32_t>::max)())
write_number(static_cast<int32_t>(n));
}
else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
{
if (add_prefix)
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('l')); // int32
}
write_number(static_cast<int32_t>(n));
}
else if (n <= (std::numeric_limits<int64_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('L')); // int64
}
write_number(static_cast<int64_t>(n));
}
else
{
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
oa->write_character(static_cast<CharType>('L')); // int64
}
write_number(static_cast<int64_t>(n));
}
else
{
if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('i')); // int8
}
write_number(static_cast<int8_t>(n));
}
else if ((std::numeric_limits<uint8_t>::min)() <= n and n <= (std::numeric_limits<uint8_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('U')); // uint8
}
write_number(static_cast<uint8_t>(n));
}
else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('I')); // int16
}
write_number(static_cast<int16_t>(n));
}
else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('l')); // int32
}
write_number(static_cast<int32_t>(n));
}
else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('L')); // int64
}
write_number(static_cast<int64_t>(n));
}
// LCOV_EXCL_START
else
{
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
}
// LCOV_EXCL_STOP
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
}
}
// UBJSON: write number (signed integer)
template<typename NumberType, typename std::enable_if<
std::is_signed<NumberType>::value and
not std::is_floating_point<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
{
if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('i')); // int8
}
write_number(static_cast<int8_t>(n));
}
else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('U')); // uint8
}
write_number(static_cast<uint8_t>(n));
}
else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('I')); // int16
}
write_number(static_cast<int16_t>(n));
}
else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('l')); // int32
}
write_number(static_cast<int32_t>(n));
}
else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('L')); // int64
}
write_number(static_cast<int64_t>(n));
}
// LCOV_EXCL_START
else
{
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
}
// LCOV_EXCL_STOP
}
/*!
@brief determine the type prefix of container values

View file

@ -68,11 +68,11 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
};
/// output adapter for basic_string
template<typename CharType>
template<typename CharType, typename StringType = std::basic_string<CharType>>
class output_string_adapter : public output_adapter_protocol<CharType>
{
public:
explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {}
explicit output_string_adapter(StringType& s) : str(s) {}
void write_character(CharType c) override
{
@ -85,10 +85,10 @@ class output_string_adapter : public output_adapter_protocol<CharType>
}
private:
std::basic_string<CharType>& str;
StringType& str;
};
template<typename CharType>
template<typename CharType, typename StringType = std::basic_string<CharType>>
class output_adapter
{
public:
@ -98,8 +98,8 @@ class output_adapter
output_adapter(std::basic_ostream<CharType>& s)
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
output_adapter(std::basic_string<CharType>& s)
: oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
output_adapter(StringType& s)
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
operator output_adapter_t<CharType>()
{

View file

@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++
| | |__ | | | | | | version 3.1.1
| | |__ | | | | | | version 3.1.2
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -31,7 +31,7 @@ SOFTWARE.
#define NLOHMANN_JSON_VERSION_MAJOR 3
#define NLOHMANN_JSON_VERSION_MINOR 1
#define NLOHMANN_JSON_VERSION_PATCH 1
#define NLOHMANN_JSON_VERSION_PATCH 2
#include <algorithm> // all_of, find, for_each
#include <cassert> // assert
@ -937,7 +937,7 @@ class basic_json
object = nullptr; // silence warning, see #821
if (JSON_UNLIKELY(t == value_t::null))
{
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.1")); // LCOV_EXCL_LINE
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2")); // LCOV_EXCL_LINE
}
break;
}
@ -1207,6 +1207,7 @@ class basic_json
- @a CompatibleType is not derived from `std::istream`,
- @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
constructors),
- @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
- @a CompatibleType is not a @ref basic_json nested type (e.g.,
@ref json_pointer, @ref iterator, etc ...)
- @ref @ref json_serializer<U> has a
@ -1242,6 +1243,78 @@ class basic_json
assert_invariant();
}
/*!
@brief create a JSON value from an existing one
This is a constructor for existing @ref basic_json types.
It does not hijack copy/move constructors, since the parameter has different
template arguments than the current ones.
The constructor tries to convert the internal @ref m_value of the parameter.
@tparam BasicJsonType a type such that:
- @a BasicJsonType is a @ref basic_json type.
- @a BasicJsonType has different template arguments than @ref basic_json_t.
@param[in] val the @ref basic_json value to be converted.
@complexity Usually linear in the size of the passed @a val, also
depending on the implementation of the called `to_json()`
method.
@exceptionsafety Depends on the called constructor. For types directly
supported by the library (i.e., all types for which no `to_json()` function
was provided), strong guarantee holds: if an exception is thrown, there are
no changes to any JSON value.
@since version 3.1.2
*/
template <typename BasicJsonType,
detail::enable_if_t<
detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
basic_json(const BasicJsonType& val)
{
using other_boolean_t = typename BasicJsonType::boolean_t;
using other_number_float_t = typename BasicJsonType::number_float_t;
using other_number_integer_t = typename BasicJsonType::number_integer_t;
using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
using other_string_t = typename BasicJsonType::string_t;
using other_object_t = typename BasicJsonType::object_t;
using other_array_t = typename BasicJsonType::array_t;
switch (val.type())
{
case value_t::boolean:
JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
break;
case value_t::number_float:
JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
break;
case value_t::number_integer:
JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
break;
case value_t::number_unsigned:
JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
break;
case value_t::string:
JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
break;
case value_t::object:
JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
break;
case value_t::array:
JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
break;
case value_t::null:
*this = nullptr;
break;
case value_t::discarded:
m_type = value_t::discarded;
break;
}
assert_invariant();
}
/*!
@brief create a container (array or object) from an initializer list
@ -1874,7 +1947,7 @@ class basic_json
const bool ensure_ascii = false) const
{
string_t result;
serializer s(detail::output_adapter<char>(result), indent_char);
serializer s(detail::output_adapter<char, string_t>(result), indent_char);
if (indent >= 0)
{
@ -2414,6 +2487,29 @@ class basic_json
return *this;
}
/*!
@brief get special-case overload
This overloads converts the current @ref basic_json in a different
@ref basic_json type
@tparam BasicJsonType == @ref basic_json
@return a copy of *this, converted into @tparam BasicJsonType
@complexity Depending on the implementation of the called `from_json()`
method.
@since version 3.1.2
*/
template<typename BasicJsonType, detail::enable_if_t<
not std::is_same<BasicJsonType, basic_json>::value and
detail::is_basic_json<BasicJsonType>::value, int> = 0>
BasicJsonType get() const
{
return *this;
}
/*!
@brief get a value (explicit)
@ -2455,7 +2551,7 @@ class basic_json
*/
template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
detail::enable_if_t <
not std::is_same<basic_json_t, ValueType>::value and
not detail::is_basic_json<ValueType>::value and
detail::has_from_json<basic_json_t, ValueType>::value and
not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
int> = 0>
@ -2721,7 +2817,8 @@ class basic_json
template < typename ValueType, typename std::enable_if <
not std::is_pointer<ValueType>::value and
not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
not std::is_same<ValueType, typename string_t::value_type>::value
not std::is_same<ValueType, typename string_t::value_type>::value and
not detail::is_basic_json<ValueType>::value
#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
#endif
@ -5179,7 +5276,7 @@ class basic_json
// passed iterators must belong to objects
if (JSON_UNLIKELY(not first.m_object->is_object()
or not first.m_object->is_object()))
or not last.m_object->is_object()))
{
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
}

View file

@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++
| | |__ | | | | | | version 3.1.1
| | |__ | | | | | | version 3.1.2
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -31,7 +31,7 @@ SOFTWARE.
#define NLOHMANN_JSON_VERSION_MAJOR 3
#define NLOHMANN_JSON_VERSION_MINOR 1
#define NLOHMANN_JSON_VERSION_PATCH 1
#define NLOHMANN_JSON_VERSION_PATCH 2
#include <algorithm> // all_of, find, for_each
#include <cassert> // assert
@ -466,7 +466,7 @@ struct is_compatible_complete_type
{
static constexpr bool value =
not std::is_base_of<std::istream, CompatibleCompleteType>::value and
not std::is_same<BasicJsonType, CompatibleCompleteType>::value and
not is_basic_json<CompatibleCompleteType>::value and
not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and
has_to_json<BasicJsonType, CompatibleCompleteType>::value;
};
@ -1871,6 +1871,7 @@ class lexer
using number_integer_t = typename BasicJsonType::number_integer_t;
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
using number_float_t = typename BasicJsonType::number_float_t;
using string_t = typename BasicJsonType::string_t;
public:
/// token types for the parser
@ -2969,7 +2970,7 @@ scan_number_done:
}
/// return current string value (implicitly resets the token; useful only once)
std::string move_string()
string_t&& move_string()
{
return std::move(token_buffer);
}
@ -3099,7 +3100,7 @@ scan_number_done:
std::vector<char> token_string {};
/// buffer for variable-length tokens (numbers, strings)
std::string token_buffer {};
string_t token_buffer {};
/// a description of occurred lexer errors
const char* error_message = "";
@ -3155,6 +3156,7 @@ class parser
using number_integer_t = typename BasicJsonType::number_integer_t;
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
using number_float_t = typename BasicJsonType::number_float_t;
using string_t = typename BasicJsonType::string_t;
using lexer_t = lexer<BasicJsonType>;
using token_type = typename lexer_t::token_type;
@ -3298,7 +3300,7 @@ class parser
}
// parse values
std::string key;
string_t key;
BasicJsonType value;
while (true)
{
@ -3526,6 +3528,7 @@ class parser
if (keep and callback and not callback(depth, parse_event_t::value, result))
{
result.m_value.destroy(result.m_type);
result.m_type = value_t::discarded;
}
}
@ -4776,11 +4779,11 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
};
/// output adapter for basic_string
template<typename CharType>
template<typename CharType, typename StringType = std::basic_string<CharType>>
class output_string_adapter : public output_adapter_protocol<CharType>
{
public:
explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {}
explicit output_string_adapter(StringType& s) : str(s) {}
void write_character(CharType c) override
{
@ -4793,10 +4796,10 @@ class output_string_adapter : public output_adapter_protocol<CharType>
}
private:
std::basic_string<CharType>& str;
StringType& str;
};
template<typename CharType>
template<typename CharType, typename StringType = std::basic_string<CharType>>
class output_adapter
{
public:
@ -4806,8 +4809,8 @@ class output_adapter
output_adapter(std::basic_ostream<CharType>& s)
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
output_adapter(std::basic_string<CharType>& s)
: oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
output_adapter(StringType& s)
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
operator output_adapter_t<CharType>()
{
@ -6909,116 +6912,126 @@ class binary_writer
oa->write_characters(vec.data(), sizeof(NumberType));
}
template<typename NumberType>
// UBJSON: write number (floating point)
template<typename NumberType, typename std::enable_if<
std::is_floating_point<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
{
if (std::is_floating_point<NumberType>::value)
if (add_prefix)
{
oa->write_character(static_cast<CharType>('D')); // float64
}
write_number(n);
}
// UBJSON: write number (unsigned integer)
template<typename NumberType, typename std::enable_if<
std::is_unsigned<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
{
if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('D')); // float64
oa->write_character(static_cast<CharType>('i')); // int8
}
write_number(n);
write_number(static_cast<uint8_t>(n));
}
else if (std::is_unsigned<NumberType>::value)
else if (n <= (std::numeric_limits<uint8_t>::max)())
{
if (n <= (std::numeric_limits<int8_t>::max)())
if (add_prefix)
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('i')); // int8
}
write_number(static_cast<uint8_t>(n));
oa->write_character(static_cast<CharType>('U')); // uint8
}
else if (n <= (std::numeric_limits<uint8_t>::max)())
write_number(static_cast<uint8_t>(n));
}
else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
{
if (add_prefix)
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('U')); // uint8
}
write_number(static_cast<uint8_t>(n));
oa->write_character(static_cast<CharType>('I')); // int16
}
else if (n <= (std::numeric_limits<int16_t>::max)())
write_number(static_cast<int16_t>(n));
}
else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
{
if (add_prefix)
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('I')); // int16
}
write_number(static_cast<int16_t>(n));
oa->write_character(static_cast<CharType>('l')); // int32
}
else if (n <= (std::numeric_limits<int32_t>::max)())
write_number(static_cast<int32_t>(n));
}
else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
{
if (add_prefix)
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('l')); // int32
}
write_number(static_cast<int32_t>(n));
}
else if (n <= (std::numeric_limits<int64_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('L')); // int64
}
write_number(static_cast<int64_t>(n));
}
else
{
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
oa->write_character(static_cast<CharType>('L')); // int64
}
write_number(static_cast<int64_t>(n));
}
else
{
if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('i')); // int8
}
write_number(static_cast<int8_t>(n));
}
else if ((std::numeric_limits<uint8_t>::min)() <= n and n <= (std::numeric_limits<uint8_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('U')); // uint8
}
write_number(static_cast<uint8_t>(n));
}
else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('I')); // int16
}
write_number(static_cast<int16_t>(n));
}
else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('l')); // int32
}
write_number(static_cast<int32_t>(n));
}
else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('L')); // int64
}
write_number(static_cast<int64_t>(n));
}
// LCOV_EXCL_START
else
{
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
}
// LCOV_EXCL_STOP
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
}
}
// UBJSON: write number (signed integer)
template<typename NumberType, typename std::enable_if<
std::is_signed<NumberType>::value and
not std::is_floating_point<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
{
if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('i')); // int8
}
write_number(static_cast<int8_t>(n));
}
else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('U')); // uint8
}
write_number(static_cast<uint8_t>(n));
}
else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('I')); // int16
}
write_number(static_cast<int16_t>(n));
}
else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('l')); // int32
}
write_number(static_cast<int32_t>(n));
}
else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
{
if (add_prefix)
{
oa->write_character(static_cast<CharType>('L')); // int64
}
write_number(static_cast<int64_t>(n));
}
// LCOV_EXCL_START
else
{
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
}
// LCOV_EXCL_STOP
}
/*!
@brief determine the type prefix of container values
@ -10535,7 +10548,7 @@ class basic_json
object = nullptr; // silence warning, see #821
if (JSON_UNLIKELY(t == value_t::null))
{
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.1")); // LCOV_EXCL_LINE
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2")); // LCOV_EXCL_LINE
}
break;
}
@ -10805,6 +10818,7 @@ class basic_json
- @a CompatibleType is not derived from `std::istream`,
- @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
constructors),
- @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
- @a CompatibleType is not a @ref basic_json nested type (e.g.,
@ref json_pointer, @ref iterator, etc ...)
- @ref @ref json_serializer<U> has a
@ -10840,6 +10854,78 @@ class basic_json
assert_invariant();
}
/*!
@brief create a JSON value from an existing one
This is a constructor for existing @ref basic_json types.
It does not hijack copy/move constructors, since the parameter has different
template arguments than the current ones.
The constructor tries to convert the internal @ref m_value of the parameter.
@tparam BasicJsonType a type such that:
- @a BasicJsonType is a @ref basic_json type.
- @a BasicJsonType has different template arguments than @ref basic_json_t.
@param[in] val the @ref basic_json value to be converted.
@complexity Usually linear in the size of the passed @a val, also
depending on the implementation of the called `to_json()`
method.
@exceptionsafety Depends on the called constructor. For types directly
supported by the library (i.e., all types for which no `to_json()` function
was provided), strong guarantee holds: if an exception is thrown, there are
no changes to any JSON value.
@since version 3.1.2
*/
template <typename BasicJsonType,
detail::enable_if_t<
detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
basic_json(const BasicJsonType& val)
{
using other_boolean_t = typename BasicJsonType::boolean_t;
using other_number_float_t = typename BasicJsonType::number_float_t;
using other_number_integer_t = typename BasicJsonType::number_integer_t;
using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
using other_string_t = typename BasicJsonType::string_t;
using other_object_t = typename BasicJsonType::object_t;
using other_array_t = typename BasicJsonType::array_t;
switch (val.type())
{
case value_t::boolean:
JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
break;
case value_t::number_float:
JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
break;
case value_t::number_integer:
JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
break;
case value_t::number_unsigned:
JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
break;
case value_t::string:
JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
break;
case value_t::object:
JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
break;
case value_t::array:
JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
break;
case value_t::null:
*this = nullptr;
break;
case value_t::discarded:
m_type = value_t::discarded;
break;
}
assert_invariant();
}
/*!
@brief create a container (array or object) from an initializer list
@ -11472,7 +11558,7 @@ class basic_json
const bool ensure_ascii = false) const
{
string_t result;
serializer s(detail::output_adapter<char>(result), indent_char);
serializer s(detail::output_adapter<char, string_t>(result), indent_char);
if (indent >= 0)
{
@ -12012,6 +12098,29 @@ class basic_json
return *this;
}
/*!
@brief get special-case overload
This overloads converts the current @ref basic_json in a different
@ref basic_json type
@tparam BasicJsonType == @ref basic_json
@return a copy of *this, converted into @tparam BasicJsonType
@complexity Depending on the implementation of the called `from_json()`
method.
@since version 3.1.2
*/
template<typename BasicJsonType, detail::enable_if_t<
not std::is_same<BasicJsonType, basic_json>::value and
detail::is_basic_json<BasicJsonType>::value, int> = 0>
BasicJsonType get() const
{
return *this;
}
/*!
@brief get a value (explicit)
@ -12053,7 +12162,7 @@ class basic_json
*/
template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
detail::enable_if_t <
not std::is_same<basic_json_t, ValueType>::value and
not detail::is_basic_json<ValueType>::value and
detail::has_from_json<basic_json_t, ValueType>::value and
not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
int> = 0>
@ -12319,7 +12428,8 @@ class basic_json
template < typename ValueType, typename std::enable_if <
not std::is_pointer<ValueType>::value and
not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
not std::is_same<ValueType, typename string_t::value_type>::value
not std::is_same<ValueType, typename string_t::value_type>::value and
not detail::is_basic_json<ValueType>::value
#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
#endif
@ -14777,7 +14887,7 @@ class basic_json
// passed iterators must belong to objects
if (JSON_UNLIKELY(not first.m_object->is_object()
or not first.m_object->is_object()))
or not last.m_object->is_object()))
{
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
}

View file

@ -104,6 +104,7 @@ foreach(file ${files})
target_compile_definitions(${testcase} PRIVATE CATCH_CONFIG_FAST_COMPILE)
target_include_directories(${testcase} PRIVATE "thirdparty/catch")
target_include_directories(${testcase} PRIVATE "thirdparty/fifo_map")
target_include_directories(${testcase} PRIVATE ${NLOHMANN_JSON_INCLUDE_BUILD_DIR})
target_link_libraries(${testcase} ${NLOHMANN_JSON_TARGET_NAME})

View file

@ -4,11 +4,12 @@
# additional flags
CXXFLAGS += -std=c++11 -Wall -Wextra -pedantic -Wcast-align -Wcast-qual -Wno-ctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch -Wundef -Wno-unused -Wnon-virtual-dtor -Wreorder -Wdeprecated -Wno-float-equal
CPPFLAGS += -I ../single_include -I . -I thirdparty/catch -DCATCH_CONFIG_FAST_COMPILE
CPPFLAGS += -I ../single_include -I . -I thirdparty/catch -I thirdparty/fifo_map -DCATCH_CONFIG_FAST_COMPILE
SOURCES = src/unit.cpp \
src/unit-algorithms.cpp \
src/unit-allocator.cpp \
src/unit-alt-string.cpp \
src/unit-capacity.cpp \
src/unit-cbor.cpp \
src/unit-class_const_iterator.cpp \

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,212 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.1.2
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
Copyright (c) 2018 Vitaliy Manushkin <agri@akamo.info>.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "catch.hpp"
#include <nlohmann/json.hpp>
#include <string>
#include <utility>
/*
* This is virtually a string class.
* It covers std::string under the hood.
*/
class alt_string
{
public:
using value_type = std::string::value_type;
alt_string(const char* str): str_impl(str) {}
alt_string(const char* str, std::size_t count): str_impl(str, count) {}
alt_string(size_t count, char chr): str_impl(count, chr) {}
alt_string() = default;
template <typename...TParams>
alt_string& append(TParams&& ...params)
{
str_impl.append(std::forward<TParams>(params)...);
return *this;
}
void push_back(char c)
{
str_impl.push_back(c);
}
template <typename op_type>
bool operator==(op_type&& op) const
{
return str_impl == op;
}
template <typename op_type>
bool operator!=(op_type&& op) const
{
return str_impl != op;
}
std::size_t size() const noexcept
{
return str_impl.size();
}
void resize (std::size_t n)
{
str_impl.resize(n);
}
void resize (std::size_t n, char c)
{
str_impl.resize(n, c);
}
template <typename op_type>
bool operator<(op_type&& op) const
{
return str_impl < op;
}
bool operator<(const alt_string& op) const
{
return str_impl < op.str_impl;
}
const char* c_str() const
{
return str_impl.c_str();
}
char& operator[](std::size_t index)
{
return str_impl[index];
}
const char& operator[](std::size_t index) const
{
return str_impl[index];
}
char& back()
{
return str_impl.back();
}
const char& back() const
{
return str_impl.back();
}
void clear()
{
str_impl.clear();
}
const value_type* data()
{
return str_impl.data();
}
private:
std::string str_impl;
};
using alt_json = nlohmann::basic_json <
std::map,
std::vector,
alt_string,
bool,
std::int64_t,
std::uint64_t,
double,
std::allocator,
nlohmann::adl_serializer >;
TEST_CASE("alternative string type")
{
SECTION("dump")
{
{
alt_json doc;
doc["pi"] = 3.141;
alt_string dump = doc.dump();
CHECK(dump == R"({"pi":3.141})");
}
{
alt_json doc;
doc["happy"] = true;
alt_string dump = doc.dump();
CHECK(dump == R"({"happy":true})");
}
{
alt_json doc;
doc["name"] = "I'm Batman";
alt_string dump = doc.dump();
CHECK(dump == R"({"name":"I'm Batman"})");
}
{
alt_json doc;
doc["nothing"] = nullptr;
alt_string dump = doc.dump();
CHECK(dump == R"({"nothing":null})");
}
{
alt_json doc;
doc["answer"]["everything"] = 42;
alt_string dump = doc.dump();
CHECK(dump == R"({"answer":{"everything":42}})");
}
{
alt_json doc;
doc["list"] = { 1, 0, 2 };
alt_string dump = doc.dump();
CHECK(dump == R"({"list":[1,0,2]})");
}
{
alt_json doc;
doc["list"] = { 1, 0, 2 };
alt_string dump = doc.dump();
CHECK(dump == R"({"list":[1,0,2]})");
}
}
SECTION("parse")
{
auto doc = alt_json::parse("{\"foo\": \"bar\"}");
alt_string dump = doc.dump();
CHECK(dump == R"({"foo":"bar"})");
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.1.1
| | |__ | | | | | | version 3.1.2
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -152,6 +152,10 @@ TEST_CASE("README", "[hide]")
j.push_back(1);
j.push_back(true);
// comparison
bool x = (j == "[\"foo\", 1, true]"_json); // true
CHECK(x == true);
// iterate the array
for (json::iterator it = j.begin(); it != j.end(); ++it)
{
@ -168,6 +172,7 @@ TEST_CASE("README", "[hide]")
const std::string tmp = j[0];
j[1] = 42;
bool foo = j.at(2);
CHECK(foo == true);
// other stuff
j.size(); // 3 entries
@ -175,9 +180,6 @@ TEST_CASE("README", "[hide]")
j.type(); // json::value_t::array
j.clear(); // the array is empty again
// comparison
bool x = (j == "[\"foo\", 1, true]"_json); // true
// create an object
json o;
o["foo"] = 23;
@ -257,17 +259,21 @@ TEST_CASE("README", "[hide]")
bool b1 = true;
json jb = b1;
bool b2 = jb;
CHECK(b2 == true);
// numbers
int i = 42;
json jn = i;
double f = jn;
CHECK(f == 42);
// etc.
std::string vs = js.get<std::string>();
bool vb = jb.get<bool>();
CHECK(vb == true);
int vi = jn.get<int>();
CHECK(vi == 42);
// etc.
}

View file

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

View file

@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.1.1
| | |__ | | | | | | version 3.1.2
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -32,10 +32,72 @@ SOFTWARE.
#include <nlohmann/json.hpp>
using nlohmann::json;
#include "fifo_map.hpp"
#include <fstream>
#include <list>
#include <cstdio>
/////////////////////////////////////////////////////////////////////
// for #972
/////////////////////////////////////////////////////////////////////
template<class K, class V, class dummy_compare, class A>
using my_workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
using my_json = nlohmann::basic_json<my_workaround_fifo_map>;
/////////////////////////////////////////////////////////////////////
// for #977
/////////////////////////////////////////////////////////////////////
namespace ns
{
struct foo
{
int x;
};
template <typename, typename SFINAE = void>
struct foo_serializer;
template<typename T>
struct foo_serializer<T, typename std::enable_if<std::is_same<foo, T>::value>::type>
{
template <typename BasicJsonType>
static void to_json(BasicJsonType& j, const T& value)
{
j = BasicJsonType{{"x", value.x}};
}
template <typename BasicJsonType>
static void from_json(const BasicJsonType& j, T& value) // !!!
{
nlohmann::from_json(j.at("x"), value.x);
}
};
template<typename T>
struct foo_serializer < T, typename std::enable_if < !std::is_same<foo, T>::value >::type >
{
template <typename BasicJsonType>
static void to_json(BasicJsonType& j, const T& value) noexcept
{
::nlohmann::to_json(j, value);
}
template <typename BasicJsonType>
static void from_json(const BasicJsonType& j, T& value) //!!!
{
::nlohmann::from_json(j, value);
}
};
}
using foo_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t,
std::uint64_t, double, std::allocator, ns::foo_serializer>;
/////////////////////////////////////////////////////////////////////
// for #805
/////////////////////////////////////////////////////////////////////
namespace
{
struct nocopy
@ -1436,4 +1498,103 @@ TEST_CASE("regression tests")
//CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
// "[json.exception.out_of_range.408] excessive object size: 8658170730974374167");
}
SECTION("issue #972 - Segmentation fault on G++ when trying to assign json string literal to custom json type")
{
my_json foo = R"([1, 2, 3])"_json;
}
SECTION("issue #977 - Assigning between different json types")
{
foo_json lj = ns::foo{3};
ns::foo ff = lj;
CHECK(lj.is_object());
CHECK(lj.size() == 1);
CHECK(lj["x"] == 3);
CHECK(ff.x == 3);
nlohmann::json nj = lj; // This line works as expected
}
SECTION("issue #1001 - Fix memory leak during parser callback")
{
auto geojsonExample = R"(
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
"properties": {"prop0": "value0"}
},
{ "type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
]
},
"properties": {
"prop0": "value0",
"prop1": 0.0
}
},
{ "type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
[100.0, 1.0], [100.0, 0.0] ]
]
},
"properties": {
"prop0": "value0",
"prop1": {"this": "that"}
}
}
]
})";
json::parser_callback_t cb = [&](int, json::parse_event_t event, json & parsed)
{
// skip uninteresting events
if (event == json::parse_event_t::value and !parsed.is_primitive())
{
return false;
}
switch (event)
{
case json::parse_event_t::key:
{
return true;
}
case json::parse_event_t::value:
{
return false;
}
case json::parse_event_t::object_start:
{
return true;
}
case json::parse_event_t::object_end:
{
return false;
}
case json::parse_event_t::array_start:
{
return true;
}
case json::parse_event_t::array_end:
{
return false;
}
default:
{
return true;
}
}
};
auto j = json::parse(geojsonExample, cb, true);
CHECK(j == json());
}
}

View file

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

View file

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

View file

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

View file

@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.1.1
| | |__ | | | | | | version 3.1.2
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -152,7 +152,7 @@ TEST_CASE("UBJSON")
numbers.push_back(-10000000);
numbers.push_back(-100000000);
numbers.push_back(-1000000000);
numbers.push_back(-2147483648);
numbers.push_back(-2147483648L);
for (auto i : numbers)
{
CAPTURE(i);

View file

@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.1.1
| | |__ | | | | | | version 3.1.2
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@ -693,6 +693,83 @@ TEST_CASE("custom serializer that does adl by default", "[udt]")
CHECK(me == cj.get<udt::person>());
}
TEST_CASE("different basic_json types conversions")
{
using json = nlohmann::json;
SECTION("null")
{
json j;
custom_json cj = j;
CHECK(cj == nullptr);
}
SECTION("boolean")
{
json j = true;
custom_json cj = j;
CHECK(cj == true);
}
SECTION("discarded")
{
json j(json::value_t::discarded);
custom_json cj;
CHECK_NOTHROW(cj = j);
CHECK(cj.type() == custom_json::value_t::discarded);
}
SECTION("array")
{
json j = {1, 2, 3};
custom_json cj = j;
CHECK((cj == std::vector<int> {1, 2, 3}));
}
SECTION("integer")
{
json j = 42;
custom_json cj = j;
CHECK(cj == 42);
}
SECTION("float")
{
json j = 42.0;
custom_json cj = j;
CHECK(cj == 42.0);
}
SECTION("unsigned")
{
json j = 42u;
custom_json cj = j;
CHECK(cj == 42u);
}
SECTION("string")
{
json j = "forty-two";
custom_json cj = j;
CHECK(cj == "forty-two");
}
SECTION("object")
{
json j = {{"forty", "two"}};
custom_json cj = j;
auto m = j.get<std::map<std::string, std::string>>();
CHECK(cj == m);
}
SECTION("get<custom_json>")
{
json j = 42;
custom_json cj = j.get<custom_json>();
CHECK(cj == 42);
}
}
namespace
{
struct incomplete;
@ -730,6 +807,6 @@ TEST_CASE("Issue #924")
// Prevent get<std::vector<Evil>>() to throw
auto j = json::array();
(void) j.get<Evil>();
(void) j.get<std::vector<Evil>>();
CHECK_NOTHROW(j.get<Evil>());
CHECK_NOTHROW(j.get<std::vector<Evil>>());
}

View file

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

View file

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

21
test/thirdparty/fifo_map/LICENSE.MIT vendored Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2015-2017 Niels Lohmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

530
test/thirdparty/fifo_map/fifo_map.hpp vendored Normal file
View file

@ -0,0 +1,530 @@
/*
The code is licensed under the MIT License <http://opensource.org/licenses/MIT>:
Copyright (c) 2015-2017 Niels Lohmann.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef NLOHMANN_FIFO_MAP_HPP
#define NLOHMANN_FIFO_MAP_HPP
#include <algorithm>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>
/*!
@brief namespace for Niels Lohmann
@see https://github.com/nlohmann
*/
namespace nlohmann
{
template<class Key>
class fifo_map_compare
{
public:
/// constructor given a pointer to a key storage
fifo_map_compare(std::unordered_map<Key, std::size_t>* k) : keys(k) {}
/*!
This function compares two keys with respect to the order in which they
were added to the container. For this, the mapping keys is used.
*/
bool operator()(const Key& lhs, const Key& rhs) const
{
// look up timestamps for both keys
const auto timestamp_lhs = keys->find(lhs);
const auto timestamp_rhs = keys->find(rhs);
if (timestamp_lhs == keys->end())
{
// timestamp for lhs not found - cannot be smaller than for rhs
return false;
}
if (timestamp_rhs == keys->end())
{
// timestamp for rhs not found - timestamp for lhs is smaller
return true;
}
// compare timestamps
return timestamp_lhs->second < timestamp_rhs->second;
}
void add_key(const Key& key)
{
keys->insert({key, timestamp++});
}
void remove_key(const Key& key)
{
keys->erase(key);
}
private:
/// pointer to a mapping from keys to insertion timestamps
std::unordered_map<Key, std::size_t>* keys = nullptr;
/// the next valid insertion timestamp
size_t timestamp = 1;
};
template <
class Key,
class T,
class Compare = fifo_map_compare<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>
> class fifo_map
{
public:
using key_type = Key;
using mapped_type = T;
using value_type = std::pair<const Key, T>;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using key_compare = Compare;
using allocator_type = Allocator;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = typename std::allocator_traits<Allocator>::pointer;
using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
using internal_map_type = std::map<Key, T, Compare, Allocator>;
using iterator = typename internal_map_type::iterator;
using const_iterator = typename internal_map_type::const_iterator;
using reverse_iterator = typename internal_map_type::reverse_iterator;
using const_reverse_iterator = typename internal_map_type::const_reverse_iterator;
public:
/// default constructor
fifo_map() : m_keys(), m_compare(&m_keys), m_map(m_compare) {}
/// copy constructor
fifo_map(const fifo_map &f) : m_keys(f.m_keys), m_compare(&m_keys), m_map(f.m_map.begin(), f.m_map.end(), m_compare) {}
/// constructor for a range of elements
template<class InputIterator>
fifo_map(InputIterator first, InputIterator last)
: m_keys(), m_compare(&m_keys), m_map(m_compare)
{
for (auto it = first; it != last; ++it)
{
insert(*it);
}
}
/// constructor for a list of elements
fifo_map(std::initializer_list<value_type> init) : fifo_map()
{
for (auto x : init)
{
insert(x);
}
}
/*
* Element access
*/
/// access specified element with bounds checking
T& at(const Key& key)
{
return m_map.at(key);
}
/// access specified element with bounds checking
const T& at(const Key& key) const
{
return m_map.at(key);
}
/// access specified element
T& operator[](const Key& key)
{
m_compare.add_key(key);
return m_map[key];
}
/// access specified element
T& operator[](Key&& key)
{
m_compare.add_key(key);
return m_map[key];
}
/*
* Iterators
*/
/// returns an iterator to the beginning
iterator begin() noexcept
{
return m_map.begin();
}
/// returns an iterator to the end
iterator end() noexcept
{
return m_map.end();
}
/// returns an iterator to the beginning
const_iterator begin() const noexcept
{
return m_map.begin();
}
/// returns an iterator to the end
const_iterator end() const noexcept
{
return m_map.end();
}
/// returns an iterator to the beginning
const_iterator cbegin() const noexcept
{
return m_map.cbegin();
}
/// returns an iterator to the end
const_iterator cend() const noexcept
{
return m_map.cend();
}
/// returns a reverse iterator to the beginning
reverse_iterator rbegin() noexcept
{
return m_map.rbegin();
}
/// returns a reverse iterator to the end
reverse_iterator rend() noexcept
{
return m_map.rend();
}
/// returns a reverse iterator to the beginning
const_reverse_iterator rbegin() const noexcept
{
return m_map.rbegin();
}
/// returns a reverse iterator to the end
const_reverse_iterator rend() const noexcept
{
return m_map.rend();
}
/// returns a reverse iterator to the beginning
const_reverse_iterator crbegin() const noexcept
{
return m_map.crbegin();
}
/// returns a reverse iterator to the end
const_reverse_iterator crend() const noexcept
{
return m_map.crend();
}
/*
* Capacity
*/
/// checks whether the container is empty
bool empty() const noexcept
{
return m_map.empty();
}
/// returns the number of elements
size_type size() const noexcept
{
return m_map.size();
}
/// returns the maximum possible number of elements
size_type max_size() const noexcept
{
return m_map.max_size();
}
/*
* Modifiers
*/
/// clears the contents
void clear() noexcept
{
m_map.clear();
m_keys.clear();
}
/// insert value
std::pair<iterator, bool> insert(const value_type& value)
{
m_compare.add_key(value.first);
return m_map.insert(value);
}
/// insert value
template<class P>
std::pair<iterator, bool> insert( P&& value )
{
m_compare.add_key(value.first);
return m_map.insert(value);
}
/// insert value with hint
iterator insert(const_iterator hint, const value_type& value)
{
m_compare.add_key(value.first);
return m_map.insert(hint, value);
}
/// insert value with hint
iterator insert(const_iterator hint, value_type&& value)
{
m_compare.add_key(value.first);
return m_map.insert(hint, value);
}
/// insert value range
template<class InputIt>
void insert(InputIt first, InputIt last)
{
for (const_iterator it = first; it != last; ++it)
{
m_compare.add_key(it->first);
}
m_map.insert(first, last);
}
/// insert value list
void insert(std::initializer_list<value_type> ilist)
{
for (auto value : ilist)
{
m_compare.add_key(value.first);
}
m_map.insert(ilist);
}
/// constructs element in-place
template<class... Args>
std::pair<iterator, bool> emplace(Args&& ... args)
{
typename fifo_map::value_type value(std::forward<Args>(args)...);
m_compare.add_key(value.first);
return m_map.emplace(std::move(value));
}
/// constructs element in-place with hint
template<class... Args>
iterator emplace_hint(const_iterator hint, Args&& ... args)
{
typename fifo_map::value_type value(std::forward<Args>(args)...);
m_compare.add_key(value.first);
return m_map.emplace_hint(hint, std::move(value));
}
/// remove element at position
iterator erase(const_iterator pos)
{
m_compare.remove_key(pos->first);
return m_map.erase(pos);
}
/// remove elements in range
iterator erase(const_iterator first, const_iterator last)
{
for (const_iterator it = first; it != last; ++it)
{
m_compare.remove_key(it->first);
}
return m_map.erase(first, last);
}
/// remove elements with key
size_type erase(const key_type& key)
{
size_type res = m_map.erase(key);
if (res > 0)
{
m_compare.remove_key(key);
}
return res;
}
/// swaps the contents
void swap(fifo_map& other)
{
std::swap(m_map, other.m_map);
std::swap(m_compare, other.m_compare);
std::swap(m_keys, other.m_keys);
}
/*
* Lookup
*/
/// returns the number of elements matching specific key
size_type count(const Key& key) const
{
return m_map.count(key);
}
/// finds element with specific key
iterator find(const Key& key)
{
return m_map.find(key);
}
/// finds element with specific key
const_iterator find(const Key& key) const
{
return m_map.find(key);
}
/// returns range of elements matching a specific key
std::pair<iterator, iterator> equal_range(const Key& key)
{
return m_map.equal_range(key);
}
/// returns range of elements matching a specific key
std::pair<const_iterator, const_iterator> equal_range(const Key& key) const
{
return m_map.equal_range(key);
}
/// returns an iterator to the first element not less than the given key
iterator lower_bound(const Key& key)
{
return m_map.lower_bound(key);
}
/// returns an iterator to the first element not less than the given key
const_iterator lower_bound(const Key& key) const
{
return m_map.lower_bound(key);
}
/// returns an iterator to the first element greater than the given key
iterator upper_bound(const Key& key)
{
return m_map.upper_bound(key);
}
/// returns an iterator to the first element greater than the given key
const_iterator upper_bound(const Key& key) const
{
return m_map.upper_bound(key);
}
/*
* Observers
*/
/// returns the function that compares keys
key_compare key_comp() const
{
return m_compare;
}
/*
* Non-member functions
*/
friend bool operator==(const fifo_map& lhs, const fifo_map& rhs)
{
return lhs.m_map == rhs.m_map;
}
friend bool operator!=(const fifo_map& lhs, const fifo_map& rhs)
{
return lhs.m_map != rhs.m_map;
}
friend bool operator<(const fifo_map& lhs, const fifo_map& rhs)
{
return lhs.m_map < rhs.m_map;
}
friend bool operator<=(const fifo_map& lhs, const fifo_map& rhs)
{
return lhs.m_map <= rhs.m_map;
}
friend bool operator>(const fifo_map& lhs, const fifo_map& rhs)
{
return lhs.m_map > rhs.m_map;
}
friend bool operator>=(const fifo_map& lhs, const fifo_map& rhs)
{
return lhs.m_map >= rhs.m_map;
}
private:
/// the keys
std::unordered_map<Key, std::size_t> m_keys;
/// the comparison object
Compare m_compare;
/// the internal data structure
internal_map_type m_map;
};
}
// specialization of std::swap
namespace std
{
template <class Key, class T, class Compare, class Allocator>
inline void swap(nlohmann::fifo_map<Key, T, Compare, Allocator>& m1,
nlohmann::fifo_map<Key, T, Compare, Allocator>& m2)
{
m1.swap(m2);
}
}
#endif