Merge branch 'release/3.1.2'
This commit is contained in:
commit
183390c10b
67 changed files with 1576 additions and 298 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,6 +10,7 @@ fuzz-testing
|
||||||
|
|
||||||
build
|
build
|
||||||
build_coverage
|
build_coverage
|
||||||
|
clang_analyze_build
|
||||||
|
|
||||||
doc/xml
|
doc/xml
|
||||||
doc/html
|
doc/html
|
||||||
|
|
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0)
|
||||||
## PROJECT
|
## PROJECT
|
||||||
## name and version
|
## name and version
|
||||||
##
|
##
|
||||||
project(nlohmann_json VERSION 3.1.1 LANGUAGES CXX)
|
project(nlohmann_json VERSION 3.1.2 LANGUAGES CXX)
|
||||||
|
|
||||||
##
|
##
|
||||||
## INCLUDE
|
## INCLUDE
|
||||||
|
|
41
ChangeLog.md
41
ChangeLog.md
|
@ -1,7 +1,46 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
|
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## [v3.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)
|
[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)
|
- Updation of child object isn't reflected in parent Object [\#968](https://github.com/nlohmann/json/issues/968)
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -258,6 +258,12 @@ fuzzing-stop:
|
||||||
cppcheck:
|
cppcheck:
|
||||||
cppcheck --enable=warning --inconclusive --force --std=c++11 $(AMALGAMATED_FILE) --error-exitcode=1
|
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
|
# maintainer targets
|
||||||
|
|
43
README.md
43
README.md
|
@ -5,7 +5,7 @@
|
||||||
[![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json)
|
[![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json)
|
||||||
[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
|
[![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&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade)
|
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&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)
|
[![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 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)
|
[![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.
|
- **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:
|
Other aspects were not so important to us:
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.
|
||||||
|
|
||||||
## Integration
|
## 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
|
```cpp
|
||||||
#include <nlohmann/json.hpp>
|
#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;
|
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
|
### Package Managers
|
||||||
|
|
||||||
|
@ -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
|
```cpp
|
||||||
// create an empty structure (null)
|
// 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
|
```cpp
|
||||||
// a way to express the empty array []
|
// 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
|
#### 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
|
```cpp
|
||||||
// create object from string literal
|
// 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.
|
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
|
```cpp
|
||||||
// parse explicitly
|
// parse explicitly
|
||||||
auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
|
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
|
```cpp
|
||||||
// explicit conversion to string
|
// 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;
|
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)
|
#### 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
|
#### 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
|
```cpp
|
||||||
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
|
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
|
||||||
|
@ -360,7 +360,7 @@ o.erase("foo");
|
||||||
|
|
||||||
### Conversion from STL containers
|
### 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
|
```cpp
|
||||||
std::vector<int> c_vector {1, 2, 3, 4};
|
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"]
|
// 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
|
```cpp
|
||||||
std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
|
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
|
### 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
|
```cpp
|
||||||
namespace ns {
|
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:
|
To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example:
|
||||||
|
|
||||||
|
@ -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:
|
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 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 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 `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.
|
Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL.
|
||||||
|
|
||||||
|
@ -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.
|
- [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.
|
- [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.
|
- [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.
|
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)
|
- [**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
|
- [**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
|
- [**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++
|
## Projects using JSON for Modern C++
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
DOXYFILE_ENCODING = UTF-8
|
DOXYFILE_ENCODING = UTF-8
|
||||||
PROJECT_NAME = "JSON for Modern C++"
|
PROJECT_NAME = "JSON for Modern C++"
|
||||||
PROJECT_NUMBER = 3.1.1
|
PROJECT_NUMBER = 3.1.2
|
||||||
PROJECT_BRIEF =
|
PROJECT_BRIEF =
|
||||||
PROJECT_LOGO =
|
PROJECT_LOGO =
|
||||||
OUTPUT_DIRECTORY = .
|
OUTPUT_DIRECTORY = .
|
||||||
|
|
BIN
doc/avatars.png
BIN
doc/avatars.png
Binary file not shown.
Before Width: | Height: | Size: 578 KiB After Width: | Height: | Size: 568 KiB |
|
@ -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>
|
|
@ -11,7 +11,7 @@
|
||||||
"version": {
|
"version": {
|
||||||
"major": 3,
|
"major": 3,
|
||||||
"minor": 1,
|
"minor": 1,
|
||||||
"patch": 1,
|
"patch": 2,
|
||||||
"string": "3.1.1"
|
"string": "3.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
@author [Niels Lohmann](http://nlohmann.me)
|
||||||
@see https://github.com/nlohmann/json to download the source code
|
@see https://github.com/nlohmann/json to download the source code
|
||||||
|
|
||||||
@version 3.1.1
|
@version 3.1.2
|
||||||
|
|
BIN
doc/json.gif
BIN
doc/json.gif
Binary file not shown.
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
@ -32,6 +32,7 @@ class lexer
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// token types for the parser
|
/// token types for the parser
|
||||||
|
@ -1130,7 +1131,7 @@ scan_number_done:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return current string value (implicitly resets the token; useful only once)
|
/// return current string value (implicitly resets the token; useful only once)
|
||||||
std::string move_string()
|
string_t&& move_string()
|
||||||
{
|
{
|
||||||
return std::move(token_buffer);
|
return std::move(token_buffer);
|
||||||
}
|
}
|
||||||
|
@ -1260,7 +1261,7 @@ scan_number_done:
|
||||||
std::vector<char> token_string {};
|
std::vector<char> token_string {};
|
||||||
|
|
||||||
/// buffer for variable-length tokens (numbers, strings)
|
/// buffer for variable-length tokens (numbers, strings)
|
||||||
std::string token_buffer {};
|
string_t token_buffer {};
|
||||||
|
|
||||||
/// a description of occurred lexer errors
|
/// a description of occurred lexer errors
|
||||||
const char* error_message = "";
|
const char* error_message = "";
|
||||||
|
|
|
@ -32,6 +32,7 @@ class parser
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using lexer_t = lexer<BasicJsonType>;
|
using lexer_t = lexer<BasicJsonType>;
|
||||||
using token_type = typename lexer_t::token_type;
|
using token_type = typename lexer_t::token_type;
|
||||||
|
|
||||||
|
@ -175,7 +176,7 @@ class parser
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse values
|
// parse values
|
||||||
std::string key;
|
string_t key;
|
||||||
BasicJsonType value;
|
BasicJsonType value;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -403,6 +404,7 @@ class parser
|
||||||
|
|
||||||
if (keep and callback and not callback(depth, parse_event_t::value, result))
|
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;
|
result.m_type = value_t::discarded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,7 +233,7 @@ struct is_compatible_complete_type
|
||||||
{
|
{
|
||||||
static constexpr bool value =
|
static constexpr bool value =
|
||||||
not std::is_base_of<std::istream, CompatibleCompleteType>::value and
|
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
|
not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and
|
||||||
has_to_json<BasicJsonType, CompatibleCompleteType>::value;
|
has_to_json<BasicJsonType, CompatibleCompleteType>::value;
|
||||||
};
|
};
|
||||||
|
|
|
@ -704,116 +704,126 @@ class binary_writer
|
||||||
oa->write_characters(vec.data(), sizeof(NumberType));
|
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,
|
void write_number_with_ubjson_prefix(const NumberType n,
|
||||||
const bool add_prefix)
|
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)
|
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>('U')); // uint8
|
||||||
{
|
|
||||||
oa->write_character(static_cast<CharType>('i')); // int8
|
|
||||||
}
|
|
||||||
write_number(static_cast<uint8_t>(n));
|
|
||||||
}
|
}
|
||||||
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>('I')); // int16
|
||||||
{
|
|
||||||
oa->write_character(static_cast<CharType>('U')); // uint8
|
|
||||||
}
|
|
||||||
write_number(static_cast<uint8_t>(n));
|
|
||||||
}
|
}
|
||||||
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>('l')); // int32
|
||||||
{
|
|
||||||
oa->write_character(static_cast<CharType>('I')); // int16
|
|
||||||
}
|
|
||||||
write_number(static_cast<int16_t>(n));
|
|
||||||
}
|
}
|
||||||
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')); // int64
|
||||||
{
|
|
||||||
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)));
|
|
||||||
}
|
}
|
||||||
|
write_number(static_cast<int64_t>(n));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
|
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
@brief determine the type prefix of container values
|
||||||
|
|
||||||
|
|
|
@ -68,11 +68,11 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
|
||||||
};
|
};
|
||||||
|
|
||||||
/// output adapter for basic_string
|
/// 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>
|
class output_string_adapter : public output_adapter_protocol<CharType>
|
||||||
{
|
{
|
||||||
public:
|
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
|
void write_character(CharType c) override
|
||||||
{
|
{
|
||||||
|
@ -85,10 +85,10 @@ class output_string_adapter : public output_adapter_protocol<CharType>
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::basic_string<CharType>& str;
|
StringType& str;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename CharType>
|
template<typename CharType, typename StringType = std::basic_string<CharType>>
|
||||||
class output_adapter
|
class output_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -98,8 +98,8 @@ class output_adapter
|
||||||
output_adapter(std::basic_ostream<CharType>& s)
|
output_adapter(std::basic_ostream<CharType>& s)
|
||||||
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
||||||
|
|
||||||
output_adapter(std::basic_string<CharType>& s)
|
output_adapter(StringType& s)
|
||||||
: oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
|
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
|
||||||
|
|
||||||
operator output_adapter_t<CharType>()
|
operator output_adapter_t<CharType>()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++
|
__| | __| | | | JSON for Modern C++
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -31,7 +31,7 @@ SOFTWARE.
|
||||||
|
|
||||||
#define NLOHMANN_JSON_VERSION_MAJOR 3
|
#define NLOHMANN_JSON_VERSION_MAJOR 3
|
||||||
#define NLOHMANN_JSON_VERSION_MINOR 1
|
#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 <algorithm> // all_of, find, for_each
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
|
@ -937,7 +937,7 @@ class basic_json
|
||||||
object = nullptr; // silence warning, see #821
|
object = nullptr; // silence warning, see #821
|
||||||
if (JSON_UNLIKELY(t == value_t::null))
|
if (JSON_UNLIKELY(t == value_t::null))
|
||||||
{
|
{
|
||||||
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.1")); // LCOV_EXCL_LINE
|
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2")); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1207,6 +1207,7 @@ class basic_json
|
||||||
- @a CompatibleType is not derived from `std::istream`,
|
- @a CompatibleType is not derived from `std::istream`,
|
||||||
- @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
|
- @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
|
||||||
constructors),
|
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.,
|
- @a CompatibleType is not a @ref basic_json nested type (e.g.,
|
||||||
@ref json_pointer, @ref iterator, etc ...)
|
@ref json_pointer, @ref iterator, etc ...)
|
||||||
- @ref @ref json_serializer<U> has a
|
- @ref @ref json_serializer<U> has a
|
||||||
|
@ -1242,6 +1243,78 @@ class basic_json
|
||||||
assert_invariant();
|
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
|
@brief create a container (array or object) from an initializer list
|
||||||
|
|
||||||
|
@ -1874,7 +1947,7 @@ class basic_json
|
||||||
const bool ensure_ascii = false) const
|
const bool ensure_ascii = false) const
|
||||||
{
|
{
|
||||||
string_t result;
|
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)
|
if (indent >= 0)
|
||||||
{
|
{
|
||||||
|
@ -2414,6 +2487,29 @@ class basic_json
|
||||||
return *this;
|
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)
|
@brief get a value (explicit)
|
||||||
|
|
||||||
|
@ -2455,7 +2551,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
|
template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
|
||||||
detail::enable_if_t <
|
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
|
detail::has_from_json<basic_json_t, ValueType>::value and
|
||||||
not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
|
not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
|
@ -2721,7 +2817,8 @@ class basic_json
|
||||||
template < typename ValueType, typename std::enable_if <
|
template < typename ValueType, typename std::enable_if <
|
||||||
not std::is_pointer<ValueType>::value and
|
not std::is_pointer<ValueType>::value and
|
||||||
not std::is_same<ValueType, detail::json_ref<basic_json>>::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
|
#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
|
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
|
||||||
#endif
|
#endif
|
||||||
|
@ -5179,7 +5276,7 @@ class basic_json
|
||||||
|
|
||||||
// passed iterators must belong to objects
|
// passed iterators must belong to objects
|
||||||
if (JSON_UNLIKELY(not first.m_object->is_object()
|
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"));
|
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++
|
__| | __| | | | JSON for Modern C++
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -31,7 +31,7 @@ SOFTWARE.
|
||||||
|
|
||||||
#define NLOHMANN_JSON_VERSION_MAJOR 3
|
#define NLOHMANN_JSON_VERSION_MAJOR 3
|
||||||
#define NLOHMANN_JSON_VERSION_MINOR 1
|
#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 <algorithm> // all_of, find, for_each
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
|
@ -466,7 +466,7 @@ struct is_compatible_complete_type
|
||||||
{
|
{
|
||||||
static constexpr bool value =
|
static constexpr bool value =
|
||||||
not std::is_base_of<std::istream, CompatibleCompleteType>::value and
|
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
|
not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and
|
||||||
has_to_json<BasicJsonType, CompatibleCompleteType>::value;
|
has_to_json<BasicJsonType, CompatibleCompleteType>::value;
|
||||||
};
|
};
|
||||||
|
@ -1871,6 +1871,7 @@ class lexer
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// token types for the parser
|
/// token types for the parser
|
||||||
|
@ -2969,7 +2970,7 @@ scan_number_done:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return current string value (implicitly resets the token; useful only once)
|
/// return current string value (implicitly resets the token; useful only once)
|
||||||
std::string move_string()
|
string_t&& move_string()
|
||||||
{
|
{
|
||||||
return std::move(token_buffer);
|
return std::move(token_buffer);
|
||||||
}
|
}
|
||||||
|
@ -3099,7 +3100,7 @@ scan_number_done:
|
||||||
std::vector<char> token_string {};
|
std::vector<char> token_string {};
|
||||||
|
|
||||||
/// buffer for variable-length tokens (numbers, strings)
|
/// buffer for variable-length tokens (numbers, strings)
|
||||||
std::string token_buffer {};
|
string_t token_buffer {};
|
||||||
|
|
||||||
/// a description of occurred lexer errors
|
/// a description of occurred lexer errors
|
||||||
const char* error_message = "";
|
const char* error_message = "";
|
||||||
|
@ -3155,6 +3156,7 @@ class parser
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using lexer_t = lexer<BasicJsonType>;
|
using lexer_t = lexer<BasicJsonType>;
|
||||||
using token_type = typename lexer_t::token_type;
|
using token_type = typename lexer_t::token_type;
|
||||||
|
|
||||||
|
@ -3298,7 +3300,7 @@ class parser
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse values
|
// parse values
|
||||||
std::string key;
|
string_t key;
|
||||||
BasicJsonType value;
|
BasicJsonType value;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -3526,6 +3528,7 @@ class parser
|
||||||
|
|
||||||
if (keep and callback and not callback(depth, parse_event_t::value, result))
|
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;
|
result.m_type = value_t::discarded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4776,11 +4779,11 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
|
||||||
};
|
};
|
||||||
|
|
||||||
/// output adapter for basic_string
|
/// 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>
|
class output_string_adapter : public output_adapter_protocol<CharType>
|
||||||
{
|
{
|
||||||
public:
|
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
|
void write_character(CharType c) override
|
||||||
{
|
{
|
||||||
|
@ -4793,10 +4796,10 @@ class output_string_adapter : public output_adapter_protocol<CharType>
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::basic_string<CharType>& str;
|
StringType& str;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename CharType>
|
template<typename CharType, typename StringType = std::basic_string<CharType>>
|
||||||
class output_adapter
|
class output_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -4806,8 +4809,8 @@ class output_adapter
|
||||||
output_adapter(std::basic_ostream<CharType>& s)
|
output_adapter(std::basic_ostream<CharType>& s)
|
||||||
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
||||||
|
|
||||||
output_adapter(std::basic_string<CharType>& s)
|
output_adapter(StringType& s)
|
||||||
: oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
|
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
|
||||||
|
|
||||||
operator output_adapter_t<CharType>()
|
operator output_adapter_t<CharType>()
|
||||||
{
|
{
|
||||||
|
@ -6909,116 +6912,126 @@ class binary_writer
|
||||||
oa->write_characters(vec.data(), sizeof(NumberType));
|
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,
|
void write_number_with_ubjson_prefix(const NumberType n,
|
||||||
const bool add_prefix)
|
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)
|
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>('U')); // uint8
|
||||||
{
|
|
||||||
oa->write_character(static_cast<CharType>('i')); // int8
|
|
||||||
}
|
|
||||||
write_number(static_cast<uint8_t>(n));
|
|
||||||
}
|
}
|
||||||
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>('I')); // int16
|
||||||
{
|
|
||||||
oa->write_character(static_cast<CharType>('U')); // uint8
|
|
||||||
}
|
|
||||||
write_number(static_cast<uint8_t>(n));
|
|
||||||
}
|
}
|
||||||
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>('l')); // int32
|
||||||
{
|
|
||||||
oa->write_character(static_cast<CharType>('I')); // int16
|
|
||||||
}
|
|
||||||
write_number(static_cast<int16_t>(n));
|
|
||||||
}
|
}
|
||||||
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')); // int64
|
||||||
{
|
|
||||||
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)));
|
|
||||||
}
|
}
|
||||||
|
write_number(static_cast<int64_t>(n));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
|
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
@brief determine the type prefix of container values
|
||||||
|
|
||||||
|
@ -10535,7 +10548,7 @@ class basic_json
|
||||||
object = nullptr; // silence warning, see #821
|
object = nullptr; // silence warning, see #821
|
||||||
if (JSON_UNLIKELY(t == value_t::null))
|
if (JSON_UNLIKELY(t == value_t::null))
|
||||||
{
|
{
|
||||||
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.1")); // LCOV_EXCL_LINE
|
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2")); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10805,6 +10818,7 @@ class basic_json
|
||||||
- @a CompatibleType is not derived from `std::istream`,
|
- @a CompatibleType is not derived from `std::istream`,
|
||||||
- @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
|
- @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
|
||||||
constructors),
|
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.,
|
- @a CompatibleType is not a @ref basic_json nested type (e.g.,
|
||||||
@ref json_pointer, @ref iterator, etc ...)
|
@ref json_pointer, @ref iterator, etc ...)
|
||||||
- @ref @ref json_serializer<U> has a
|
- @ref @ref json_serializer<U> has a
|
||||||
|
@ -10840,6 +10854,78 @@ class basic_json
|
||||||
assert_invariant();
|
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
|
@brief create a container (array or object) from an initializer list
|
||||||
|
|
||||||
|
@ -11472,7 +11558,7 @@ class basic_json
|
||||||
const bool ensure_ascii = false) const
|
const bool ensure_ascii = false) const
|
||||||
{
|
{
|
||||||
string_t result;
|
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)
|
if (indent >= 0)
|
||||||
{
|
{
|
||||||
|
@ -12012,6 +12098,29 @@ class basic_json
|
||||||
return *this;
|
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)
|
@brief get a value (explicit)
|
||||||
|
|
||||||
|
@ -12053,7 +12162,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
|
template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
|
||||||
detail::enable_if_t <
|
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
|
detail::has_from_json<basic_json_t, ValueType>::value and
|
||||||
not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
|
not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
|
@ -12319,7 +12428,8 @@ class basic_json
|
||||||
template < typename ValueType, typename std::enable_if <
|
template < typename ValueType, typename std::enable_if <
|
||||||
not std::is_pointer<ValueType>::value and
|
not std::is_pointer<ValueType>::value and
|
||||||
not std::is_same<ValueType, detail::json_ref<basic_json>>::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
|
#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
|
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
|
||||||
#endif
|
#endif
|
||||||
|
@ -14777,7 +14887,7 @@ class basic_json
|
||||||
|
|
||||||
// passed iterators must belong to objects
|
// passed iterators must belong to objects
|
||||||
if (JSON_UNLIKELY(not first.m_object->is_object()
|
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"));
|
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ foreach(file ${files})
|
||||||
|
|
||||||
target_compile_definitions(${testcase} PRIVATE CATCH_CONFIG_FAST_COMPILE)
|
target_compile_definitions(${testcase} PRIVATE CATCH_CONFIG_FAST_COMPILE)
|
||||||
target_include_directories(${testcase} PRIVATE "thirdparty/catch")
|
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_include_directories(${testcase} PRIVATE ${NLOHMANN_JSON_INCLUDE_BUILD_DIR})
|
||||||
target_link_libraries(${testcase} ${NLOHMANN_JSON_TARGET_NAME})
|
target_link_libraries(${testcase} ${NLOHMANN_JSON_TARGET_NAME})
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
|
|
||||||
# additional flags
|
# 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
|
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 \
|
SOURCES = src/unit.cpp \
|
||||||
src/unit-algorithms.cpp \
|
src/unit-algorithms.cpp \
|
||||||
src/unit-allocator.cpp \
|
src/unit-allocator.cpp \
|
||||||
|
src/unit-alt-string.cpp \
|
||||||
src/unit-capacity.cpp \
|
src/unit-capacity.cpp \
|
||||||
src/unit-cbor.cpp \
|
src/unit-cbor.cpp \
|
||||||
src/unit-class_const_iterator.cpp \
|
src/unit-class_const_iterator.cpp \
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on
|
This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
212
test/src/unit-alt-string.cpp
Normal file
212
test/src/unit-alt-string.cpp
Normal 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"})");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -42,10 +42,10 @@ TEST_CASE("version information")
|
||||||
CHECK(j["url"] == "https://github.com/nlohmann/json");
|
CHECK(j["url"] == "https://github.com/nlohmann/json");
|
||||||
CHECK(j["version"] == json(
|
CHECK(j["version"] == json(
|
||||||
{
|
{
|
||||||
{"string", "3.1.1"},
|
{"string", "3.1.2"},
|
||||||
{"major", 3},
|
{"major", 3},
|
||||||
{"minor", 1},
|
{"minor", 1},
|
||||||
{"patch", 1}
|
{"patch", 2}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
CHECK(j.find("platform") != j.end());
|
CHECK(j.find("platform") != j.end());
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -152,6 +152,10 @@ TEST_CASE("README", "[hide]")
|
||||||
j.push_back(1);
|
j.push_back(1);
|
||||||
j.push_back(true);
|
j.push_back(true);
|
||||||
|
|
||||||
|
// comparison
|
||||||
|
bool x = (j == "[\"foo\", 1, true]"_json); // true
|
||||||
|
CHECK(x == true);
|
||||||
|
|
||||||
// iterate the array
|
// iterate the array
|
||||||
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||||
{
|
{
|
||||||
|
@ -168,6 +172,7 @@ TEST_CASE("README", "[hide]")
|
||||||
const std::string tmp = j[0];
|
const std::string tmp = j[0];
|
||||||
j[1] = 42;
|
j[1] = 42;
|
||||||
bool foo = j.at(2);
|
bool foo = j.at(2);
|
||||||
|
CHECK(foo == true);
|
||||||
|
|
||||||
// other stuff
|
// other stuff
|
||||||
j.size(); // 3 entries
|
j.size(); // 3 entries
|
||||||
|
@ -175,9 +180,6 @@ TEST_CASE("README", "[hide]")
|
||||||
j.type(); // json::value_t::array
|
j.type(); // json::value_t::array
|
||||||
j.clear(); // the array is empty again
|
j.clear(); // the array is empty again
|
||||||
|
|
||||||
// comparison
|
|
||||||
bool x = (j == "[\"foo\", 1, true]"_json); // true
|
|
||||||
|
|
||||||
// create an object
|
// create an object
|
||||||
json o;
|
json o;
|
||||||
o["foo"] = 23;
|
o["foo"] = 23;
|
||||||
|
@ -257,17 +259,21 @@ TEST_CASE("README", "[hide]")
|
||||||
bool b1 = true;
|
bool b1 = true;
|
||||||
json jb = b1;
|
json jb = b1;
|
||||||
bool b2 = jb;
|
bool b2 = jb;
|
||||||
|
CHECK(b2 == true);
|
||||||
|
|
||||||
// numbers
|
// numbers
|
||||||
int i = 42;
|
int i = 42;
|
||||||
json jn = i;
|
json jn = i;
|
||||||
double f = jn;
|
double f = jn;
|
||||||
|
CHECK(f == 42);
|
||||||
|
|
||||||
// etc.
|
// etc.
|
||||||
|
|
||||||
std::string vs = js.get<std::string>();
|
std::string vs = js.get<std::string>();
|
||||||
bool vb = jb.get<bool>();
|
bool vb = jb.get<bool>();
|
||||||
|
CHECK(vb == true);
|
||||||
int vi = jn.get<int>();
|
int vi = jn.get<int>();
|
||||||
|
CHECK(vi == 42);
|
||||||
|
|
||||||
// etc.
|
// etc.
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -32,10 +32,72 @@ SOFTWARE.
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
|
#include "fifo_map.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <cstdio>
|
#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
|
namespace
|
||||||
{
|
{
|
||||||
struct nocopy
|
struct nocopy
|
||||||
|
@ -1436,4 +1498,103 @@ TEST_CASE("regression tests")
|
||||||
//CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
|
//CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
|
||||||
// "[json.exception.out_of_range.408] excessive object size: 8658170730974374167");
|
// "[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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -152,7 +152,7 @@ TEST_CASE("UBJSON")
|
||||||
numbers.push_back(-10000000);
|
numbers.push_back(-10000000);
|
||||||
numbers.push_back(-100000000);
|
numbers.push_back(-100000000);
|
||||||
numbers.push_back(-1000000000);
|
numbers.push_back(-1000000000);
|
||||||
numbers.push_back(-2147483648);
|
numbers.push_back(-2147483648L);
|
||||||
for (auto i : numbers)
|
for (auto i : numbers)
|
||||||
{
|
{
|
||||||
CAPTURE(i);
|
CAPTURE(i);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
@ -693,6 +693,83 @@ TEST_CASE("custom serializer that does adl by default", "[udt]")
|
||||||
CHECK(me == cj.get<udt::person>());
|
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
|
namespace
|
||||||
{
|
{
|
||||||
struct incomplete;
|
struct incomplete;
|
||||||
|
@ -730,6 +807,6 @@ TEST_CASE("Issue #924")
|
||||||
// Prevent get<std::vector<Evil>>() to throw
|
// Prevent get<std::vector<Evil>>() to throw
|
||||||
auto j = json::array();
|
auto j = json::array();
|
||||||
|
|
||||||
(void) j.get<Evil>();
|
CHECK_NOTHROW(j.get<Evil>());
|
||||||
(void) j.get<std::vector<Evil>>();
|
CHECK_NOTHROW(j.get<std::vector<Evil>>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
__ _____ _____ _____
|
__ _____ _____ _____
|
||||||
__| | __| | | | JSON for Modern C++ (test suite)
|
__| | __| | | | JSON for Modern C++ (test suite)
|
||||||
| | |__ | | | | | | version 3.1.1
|
| | |__ | | | | | | version 3.1.2
|
||||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
|
||||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
|
21
test/thirdparty/fifo_map/LICENSE.MIT
vendored
Normal file
21
test/thirdparty/fifo_map/LICENSE.MIT
vendored
Normal 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
530
test/thirdparty/fifo_map/fifo_map.hpp
vendored
Normal 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
|
Loading…
Reference in a new issue