Commit f63ff772 by Niels

renamed class from "JSON" to "son"

parent 4d00105e
...@@ -2,16 +2,16 @@ noinst_PROGRAMS = json_unit json_parser ...@@ -2,16 +2,16 @@ noinst_PROGRAMS = json_unit json_parser
FLAGS = -Wall -Wextra -pedantic -Weffc++ -Wcast-align -Wcast-qual -Wctor-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 FLAGS = -Wall -Wextra -pedantic -Weffc++ -Wcast-align -Wcast-qual -Wctor-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
json_unit_SOURCES = src/JSON.cc src/JSON.h test/catch.hpp test/JSON_unit.cc json_unit_SOURCES = src/json.cc src/json.h test/catch.hpp test/json_unit.cc
json_unit_CXXFLAGS = $(FLAGS) -std=c++11 json_unit_CXXFLAGS = $(FLAGS) -std=c++11
json_unit_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/test -Dprivate=public json_unit_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/test -Dprivate=public
json_parser_SOURCES = src/JSON.cc src/JSON.h benchmark/parse.cc json_parser_SOURCES = src/json.cc src/json.h benchmark/parse.cc
json_parser_CXXFLAGS = -O3 -std=c++11 -flto json_parser_CXXFLAGS = -O3 -std=c++11 -flto
json_parser_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/benchmark json_parser_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/benchmark
cppcheck: cppcheck:
cppcheck --enable=all --inconclusive --std=c++11 src/JSON.* cppcheck --enable=all --inconclusive --std=c++11 src/json.*
svn-clean: maintainer-clean svn-clean: maintainer-clean
rm -fr configure INSTALL aclocal.m4 build-aux depcomp install-sh missing test-driver rm -fr configure INSTALL aclocal.m4 build-aux depcomp install-sh missing test-driver
......
...@@ -12,9 +12,9 @@ There are myriads of [JSON](http://json.org) libraries out there, and each may e ...@@ -12,9 +12,9 @@ There are myriads of [JSON](http://json.org) libraries out there, and each may e
- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and the [reference](https://github.com/nlohmann/json/blob/master/doc/Reference.md), and you know, what I mean. - **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and the [reference](https://github.com/nlohmann/json/blob/master/doc/Reference.md), and you know, what I mean.
- **Trivial integration**. Our whole code consists of a class in just two files: A header file `JSON.h` and a source file `JSON.cc`. That's it. No library, no subproject, no dependencies. 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 class in just two files: A header file `json.h` and a source file `json.cc`. That's it. No library, no subproject, no dependencies. 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/JSON_unit.cc) 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. - **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/blob/master/test/json_unit.cc) 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.
Other aspects were not so important to us: Other aspects were not so important to us:
...@@ -29,10 +29,10 @@ Other aspects were not so important to us: ...@@ -29,10 +29,10 @@ Other aspects were not so important to us:
All you need to do is add All you need to do is add
```cpp ```cpp
#include "JSON.h" #include "json.h"
``` ```
to the files you want to use JSON objects. Furthermore, you need to compile the file `JSON.cc` and link it to your binaries. 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 use JSON objects. Furthermore, you need to compile the file `json.cc` and link it to your binaries. Do not forget to set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
## Examples ## Examples
...@@ -61,7 +61,7 @@ With the JSON class, you could write: ...@@ -61,7 +61,7 @@ With the JSON class, you could write:
```cpp ```cpp
// create an empty structure (null) // create an empty structure (null)
JSON j; json j;
// add a number that is stored as double (note the implicit conversion of j to an object) // add a number that is stored as double (note the implicit conversion of j to an object)
j["pi"] = 3.141; j["pi"] = 3.141;
...@@ -85,7 +85,7 @@ j["list"] = { 1, 0, 2 }; ...@@ -85,7 +85,7 @@ j["list"] = { 1, 0, 2 };
j["object"] = { {"currency", "USD"}, {"value", "42.99"} }; j["object"] = { {"currency", "USD"}, {"value", "42.99"} };
// instead, you could also write (which looks very similar to the JSON above) // instead, you could also write (which looks very similar to the JSON above)
JSON j2 = { json j2 = {
{"pi", 3.141}, {"pi", 3.141},
{"happy", true}, {"happy", true},
{"name", "Niels"}, {"name", "Niels"},
...@@ -109,7 +109,7 @@ You can create an object (deserialization) by appending `_json` to a string lite ...@@ -109,7 +109,7 @@ You can create an object (deserialization) by appending `_json` to a string lite
```cpp ```cpp
// create object from string literal // create object from string literal
JSON j = "{ \"pi\": 3.141, \"happy\": true }"_json; json j = "{ \"pi\": 3.141, \"happy\": true }"_json;
``` ```
You can also get a string representation (serialize): You can also get a string representation (serialize):
...@@ -125,7 +125,7 @@ You can also use streams to serialize and deserialize: ...@@ -125,7 +125,7 @@ You can also use streams to serialize and deserialize:
```cpp ```cpp
// deserialize from standard input // deserialize from standard input
JSON j; json j;
j << std::cin; j << std::cin;
// serialize to standard output // serialize to standard output
...@@ -140,13 +140,13 @@ We designed the JSON class to behave just like an STL container: ...@@ -140,13 +140,13 @@ We designed the JSON class to behave just like an STL container:
```cpp ```cpp
// create an array using push_back // create an array using push_back
JSON j; json j;
j.push_back("foo"); j.push_back("foo");
j.push_back(1); j.push_back(1);
j.push_back(true); j.push_back(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) {
std::cout << *it << '\n'; std::cout << *it << '\n';
} }
...@@ -163,14 +163,14 @@ bool foo = j.at(2); ...@@ -163,14 +163,14 @@ bool foo = j.at(2);
// other stuff // other stuff
j.size(); // 3 entries j.size(); // 3 entries
j.empty(); // false j.empty(); // false
j.type(); // JSON::value_type::array j.type(); // json::value_type::array
j.clear(); // the array is empty again j.clear(); // the array is empty again
// comparison // comparison
j == "[\"foo\", 1, true]"_json; // true j == "[\"foo\", 1, true]"_json; // true
// create an object // create an object
JSON o; json o;
o["foo"] = 23; o["foo"] = 23;
o["bar"] = false; o["bar"] = false;
o["baz"] = 3.141; o["baz"] = 3.141;
...@@ -181,7 +181,7 @@ if (o.find("foo") != o.end()) { ...@@ -181,7 +181,7 @@ if (o.find("foo") != o.end()) {
} }
// iterate the object // iterate the object
for (JSON::iterator it = o.begin(); it != o.end(); ++it) { for (json::iterator it = o.begin(); it != o.end(); ++it) {
std::cout << it.key() << ':' << it.value() << '\n'; std::cout << it.key() << ':' << it.value() << '\n';
} }
``` ```
...@@ -193,17 +193,17 @@ The type of the JSON object is determined automatically by the expression to sto ...@@ -193,17 +193,17 @@ The type of the JSON object is determined automatically by the expression to sto
```cpp ```cpp
/// strings /// strings
std::string s1 = "Hello, world!"; std::string s1 = "Hello, world!";
JSON js = s1; json js = s1;
std::string s2 = js; std::string s2 = js;
// Booleans // Booleans
bool b1 = true; bool b1 = true;
JSON jb = b1; json jb = b1;
bool b2 = jb; bool b2 = jb;
// numbers // numbers
int i = 42; int i = 42;
JSON jn = i; json jn = i;
double f = jn; double f = jn;
// etc. // etc.
......
#include "JSON.h" #include "json.h"
int main() int main()
{ {
JSON j; json j;
j << std::cin; j << std::cin;
return 0; return 0;
} }
AC_INIT([JSON], [2.0], [mail@nlohmann.me]) AC_INIT([JSON], [2.0], [mail@nlohmann.me])
AC_CONFIG_SRCDIR([src/JSON.cc]) AC_CONFIG_SRCDIR([src/json.h])
AM_INIT_AUTOMAKE([foreign subdir-objects]) AM_INIT_AUTOMAKE([foreign subdir-objects])
AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
## Nomenclature ## Nomenclature
We use the term "JSON" when we mean the [JavaScript Object Notation](http://json.org); that is, the file format. When we talk about the class implementing our library, we use "`JSON`" (typewriter font). Instances of this class are called "`JSON` values" to differentiate them from "JSON objects"; that is, unordered mappings, hashes, and whatnot. We use the term "JSON" when we mean the [JavaScript Object Notation](http://json.org); that is, the file format. When we talk about the class implementing our library, we use "`json`" (typewriter font). Instances of this class are called "`json` values" to differentiate them from "JSON objects"; that is, unordered mappings, hashes, and whatnot.
## Types and default values ## Types and default values
...@@ -11,13 +11,13 @@ This table describes how JSON values are mapped to C++ types. ...@@ -11,13 +11,13 @@ This table describes how JSON values are mapped to C++ types.
| JSON type | value_type | C++ type | type alias | default value | | JSON type | value_type | C++ type | type alias | default value |
| ----------------------- | -------------------------- | ----------------------------- | ---------------------- | -------------- | ----------------------- | -------------------------- | ----------------------------- | ---------------------- | --------------
| null | `value_type::null` | `nullptr_t` | - | `nullptr` | | null | `value_type::null` | `nullptr_t` | - | `nullptr` |
| string | `value_type::string` | `std::string` | `JSON::string_t` | `""` | | string | `value_type::string` | `std::string` | `json::string_t` | `""` |
| number (integer) | `value_type::number` | `int` | `JSON::number_t` | `0` | | number (integer) | `value_type::number` | `int` | `json::number_t` | `0` |
| number (floating point) | `value_type::number_float` | `double` | `JSON::number_float_t` | `0.0` | | number (floating point) | `value_type::number_float` | `double` | `json::number_float_t` | `0.0` |
| array | `value_type::array ` | `std::array<JSON>` | `JSON::array_t` | `{}` | | array | `value_type::array ` | `std::array<json>` | `json::array_t` | `{}` |
| object | `value_type::object` | `std::map<std::string, JSON>` | `JSON::object_t` | `{}` | | object | `value_type::object` | `std::map<std::string, json>` | `json::object_t` | `{}` |
The second column list entries of an enumeration `value_type` which can be queried by calling `type()` on a `JSON` value. The column "C++ types" list the internal type that is used to represent the respective JSON value. The "type alias" column furthermore lists type aliases that are used in the `JSON` class to allow for more flexibility. The last column list the default value; that is, the value that is set if none is passed to the constructor or that is set if `clear()` is called. The second column list entries of an enumeration `value_type` which can be queried by calling `type()` on a `json` value. The column "C++ types" list the internal type that is used to represent the respective JSON value. The "type alias" column furthermore lists type aliases that are used in the `json` class to allow for more flexibility. The last column list the default value; that is, the value that is set if none is passed to the constructor or that is set if `clear()` is called.
## Type conversions ## Type conversions
...@@ -28,21 +28,21 @@ There are only a few type conversions possible: ...@@ -28,21 +28,21 @@ There are only a few type conversions possible:
- Any value (i.e., boolean, string, number, null) but JSON objects can be translated into an array. The result is a singleton array that consists of the value before. - Any value (i.e., boolean, string, number, null) but JSON objects can be translated into an array. The result is a singleton array that consists of the value before.
- Any other conversion will throw a `std::logic_error` exception. - Any other conversion will throw a `std::logic_error` exception.
When compatible, `JSON` values **implicitly convert** to `std::string`, `int`, `double`, `JSON::array_t`, and `JSON::object_t`. Furthermore, **explicit type conversion** is possible using the `get<>()` function with the aforementioned types. When compatible, `json` values **implicitly convert** to `std::string`, `int`, `double`, `json::array_t`, and `json::object_t`. Furthermore, **explicit type conversion** is possible using the `get<>()` function with the aforementioned types.
## Initialization ## Initialization
`JSON` values can be created from many literals and variable types: `json` values can be created from many literals and variable types:
| JSON type | literal/variable types | examples | | JSON type | literal/variable types | examples |
| --------- | ---------------------- | -------- | | --------- | ---------------------- | -------- |
| none | null pointer literal, `nullptr_t` type, no value | `nullptr` | | none | null pointer literal, `nullptr_t` type, no value | `nullptr` |
| boolean | boolean literals, `bool` type, `JSON::boolean_t` type | `true`, `false` | | boolean | boolean literals, `bool` type, `json::boolean_t` type | `true`, `false` |
| string | string literal, `char*` type, `std::string` type, `std::string&&` rvalue reference, `JSON::string_t` type | `"Hello"` | | string | string literal, `char*` type, `std::string` type, `std::string&&` rvalue reference, `json::string_t` type | `"Hello"` |
| number (integer) | integer literal, `short int` type, `int` type, `JSON_number_t` type | `42` | | number (integer) | integer literal, `short int` type, `int` type, `json_number_t` type | `42` |
| number (floating point) | floating point literal, `float` type, `double` type, `JSON::number_float_t` type | `3.141529` | number (floating point) | floating point literal, `float` type, `double` type, `json::number_float_t` type | `3.141529`
| array | initializer list whose elements are `JSON` values (or can be translated into `JSON` values using the rules above), `std::vector<JSON>` type, `JSON::array_t` type, `JSON::array_t&&` rvalue reference | `{1, 2, 3, true, "foo"}` | | array | initializer list whose elements are `json` values (or can be translated into `json` values using the rules above), `std::vector<json>` type, `json::array_t` type, `json::array_t&&` rvalue reference | `{1, 2, 3, true, "foo"}` |
| object | initializer list whose elements are pairs of a string literal and a `JSON` value (or can be translated into `JSON` values using the rules above), `std::map<std::string, JSON>` type, `JSON::object_t` type, `JSON::object_t&&` rvalue reference | `{ {"key1", 42}, {"key2", false} }` | | object | initializer list whose elements are pairs of a string literal and a `json` value (or can be translated into `json` values using the rules above), `std::map<std::string, json>` type, `json::object_t` type, `json::object_t&&` rvalue reference | `{ {"key1", 42}, {"key2", false} }` |
## Number types ## Number types
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
@see https://github.com/nlohmann/json @see https://github.com/nlohmann/json
*/ */
#include "JSON.h" #include "json.h"
#include <cctype> // std::isdigit, std::isspace #include <cctype> // std::isdigit, std::isspace
#include <cstddef> // size_t #include <cstddef> // size_t
...@@ -21,19 +21,19 @@ ...@@ -21,19 +21,19 @@
// STATIC MEMBERS // // STATIC MEMBERS //
//////////////////// ////////////////////
std::mutex JSON::_token; std::mutex json::_token;
/////////////////////////////////// ///////////////////////////////////
// CONSTRUCTORS OF UNION "value" // // CONSTRUCTORS OF UNION "value" //
/////////////////////////////////// ///////////////////////////////////
JSON::value::value(array_t* _array): array(_array) {} json::value::value(array_t* _array): array(_array) {}
JSON::value::value(object_t* _object): object(_object) {} json::value::value(object_t* _object): object(_object) {}
JSON::value::value(string_t* _string): string(_string) {} json::value::value(string_t* _string): string(_string) {}
JSON::value::value(boolean_t _boolean) : boolean(_boolean) {} json::value::value(boolean_t _boolean) : boolean(_boolean) {}
JSON::value::value(number_t _number) : number(_number) {} json::value::value(number_t _number) : number(_number) {}
JSON::value::value(number_float_t _number_float) : number_float(_number_float) {} json::value::value(number_float_t _number_float) : number_float(_number_float) {}
///////////////////////////////// /////////////////////////////////
...@@ -43,11 +43,11 @@ JSON::value::value(number_float_t _number_float) : number_float(_number_float) { ...@@ -43,11 +43,11 @@ JSON::value::value(number_float_t _number_float) : number_float(_number_float) {
/*! /*!
Construct an empty JSON given the type. Construct an empty JSON given the type.
@param t the type from the @ref JSON::type enumeration. @param t the type from the @ref json::type enumeration.
@post Memory for array, object, and string are allocated. @post Memory for array, object, and string are allocated.
*/ */
JSON::JSON(const value_type t) noexcept json::json(const value_type t) noexcept
: _type(t) : _type(t)
{ {
switch (_type) switch (_type)
...@@ -92,7 +92,7 @@ JSON::JSON(const value_type t) noexcept ...@@ -92,7 +92,7 @@ JSON::JSON(const value_type t) noexcept
/*! /*!
Construct a null JSON object. Construct a null JSON object.
*/ */
JSON::JSON(std::nullptr_t) noexcept : JSON() json::json(std::nullptr_t) noexcept : json()
{} {}
/*! /*!
...@@ -100,43 +100,43 @@ Construct a string JSON object. ...@@ -100,43 +100,43 @@ Construct a string JSON object.
@param s a string to initialize the JSON object with @param s a string to initialize the JSON object with
*/ */
JSON::JSON(const std::string& s) noexcept json::json(const std::string& s) noexcept
: _type(value_type::string), _value(new string_t(s)) : _type(value_type::string), _value(new string_t(s))
{} {}
JSON::JSON(std::string&& s) noexcept json::json(std::string&& s) noexcept
: _type(value_type::string), _value(new string_t(std::move(s))) : _type(value_type::string), _value(new string_t(std::move(s)))
{} {}
JSON::JSON(const char* s) noexcept json::json(const char* s) noexcept
: _type(value_type::string), _value(new string_t(s)) : _type(value_type::string), _value(new string_t(s))
{} {}
JSON::JSON(const bool b) noexcept json::json(const bool b) noexcept
: _type(value_type::boolean), _value(b) : _type(value_type::boolean), _value(b)
{} {}
JSON::JSON(const int i) noexcept json::json(const int i) noexcept
: _type(value_type::number), _value(i) : _type(value_type::number), _value(i)
{} {}
JSON::JSON(const double f) noexcept json::json(const double f) noexcept
: _type(value_type::number_float), _value(f) : _type(value_type::number_float), _value(f)
{} {}
JSON::JSON(const array_t& a) noexcept json::json(const array_t& a) noexcept
: _type(value_type::array), _value(new array_t(a)) : _type(value_type::array), _value(new array_t(a))
{} {}
JSON::JSON(array_t&& a) noexcept json::json(array_t&& a) noexcept
: _type(value_type::array), _value(new array_t(std::move(a))) : _type(value_type::array), _value(new array_t(std::move(a)))
{} {}
JSON::JSON(const object_t& o) noexcept json::json(const object_t& o) noexcept
: _type(value_type::object), _value(new object_t(o)) : _type(value_type::object), _value(new object_t(o))
{} {}
JSON::JSON(object_t&& o) noexcept json::json(object_t&& o) noexcept
: _type(value_type::object), _value(new object_t(std::move(o))) : _type(value_type::object), _value(new object_t(std::move(o)))
{} {}
...@@ -155,7 +155,7 @@ as is to create an array. ...@@ -155,7 +155,7 @@ as is to create an array.
@bug With the described approach, we would fail to recognize an array whose @bug With the described approach, we would fail to recognize an array whose
first element is again an arrays as array. first element is again an arrays as array.
*/ */
JSON::JSON(list_init_t a) noexcept json::json(list_init_t a) noexcept
{ {
// check if each element is an array with two elements whose first element // check if each element is an array with two elements whose first element
// is a string // is a string
...@@ -176,7 +176,7 @@ JSON::JSON(list_init_t a) noexcept ...@@ -176,7 +176,7 @@ JSON::JSON(list_init_t a) noexcept
// the initializer list is a list of pairs // the initializer list is a list of pairs
_type = value_type::object; _type = value_type::object;
_value = new object_t(); _value = new object_t();
for (const JSON& element : a) for (const json& element : a)
{ {
const std::string k = element[0]; const std::string k = element[0];
_value.object->emplace(std::make_pair(std::move(k), _value.object->emplace(std::make_pair(std::move(k),
...@@ -189,7 +189,7 @@ A copy constructor for the JSON class. ...@@ -189,7 +189,7 @@ A copy constructor for the JSON class.
@param o the JSON object to copy @param o the JSON object to copy
*/ */
JSON::JSON(const JSON& o) noexcept json::json(const json& o) noexcept
: _type(o._type) : _type(o._type)
{ {
switch (_type) switch (_type)
...@@ -238,7 +238,7 @@ A move constructor for the JSON class. ...@@ -238,7 +238,7 @@ A move constructor for the JSON class.
@post The JSON object \p o is invalidated. @post The JSON object \p o is invalidated.
*/ */
JSON::JSON(JSON&& o) noexcept json::json(json&& o) noexcept
: _type(std::move(o._type)), _value(std::move(o._value)) : _type(std::move(o._type)), _value(std::move(o._value))
{ {
// invalidate payload // invalidate payload
...@@ -252,14 +252,14 @@ idiom. ...@@ -252,14 +252,14 @@ idiom.
@param o A JSON object to assign to this object. @param o A JSON object to assign to this object.
*/ */
JSON& JSON::operator=(JSON o) noexcept json& json::operator=(json o) noexcept
{ {
std::swap(_type, o._type); std::swap(_type, o._type);
std::swap(_value, o._value); std::swap(_value, o._value);
return *this; return *this;
} }
JSON::~JSON() noexcept json::~json() noexcept
{ {
switch (_type) switch (_type)
{ {
...@@ -290,22 +290,22 @@ JSON::~JSON() noexcept ...@@ -290,22 +290,22 @@ JSON::~JSON() noexcept
@param s a string representation of a JSON object @param s a string representation of a JSON object
@return a JSON object @return a JSON object
*/ */
JSON JSON::parse(const std::string& s) json json::parse(const std::string& s)
{ {
return Parser(s).parse(); return parser(s).parse();
} }
/*! /*!
@param s a string representation of a JSON object @param s a string representation of a JSON object
@return a JSON object @return a JSON object
*/ */
JSON JSON::parse(const char* s) json json::parse(const char* s)
{ {
return Parser(s).parse(); return parser(s).parse();
} }
const std::string JSON::_typename() const noexcept const std::string json::_typename() const noexcept
{ {
switch (_type) switch (_type)
{ {
...@@ -346,7 +346,7 @@ const std::string JSON::_typename() const noexcept ...@@ -346,7 +346,7 @@ const std::string JSON::_typename() const noexcept
type is not string type is not string
*/ */
template<> template<>
std::string JSON::get() const std::string json::get() const
{ {
switch (_type) switch (_type)
{ {
...@@ -362,7 +362,7 @@ std::string JSON::get() const ...@@ -362,7 +362,7 @@ std::string JSON::get() const
type is not number (int or float) type is not number (int or float)
*/ */
template<> template<>
int JSON::get() const int json::get() const
{ {
switch (_type) switch (_type)
{ {
...@@ -380,7 +380,7 @@ int JSON::get() const ...@@ -380,7 +380,7 @@ int JSON::get() const
type is not number (int or float) type is not number (int or float)
*/ */
template<> template<>
double JSON::get() const double json::get() const
{ {
switch (_type) switch (_type)
{ {
...@@ -398,7 +398,7 @@ double JSON::get() const ...@@ -398,7 +398,7 @@ double JSON::get() const
type is not boolean type is not boolean
*/ */
template<> template<>
bool JSON::get() const bool json::get() const
{ {
switch (_type) switch (_type)
{ {
...@@ -414,7 +414,7 @@ bool JSON::get() const ...@@ -414,7 +414,7 @@ bool JSON::get() const
type is an object type is an object
*/ */
template<> template<>
JSON::array_t JSON::get() const json::array_t json::get() const
{ {
if (_type == value_type::array) if (_type == value_type::array)
{ {
...@@ -435,7 +435,7 @@ JSON::array_t JSON::get() const ...@@ -435,7 +435,7 @@ JSON::array_t JSON::get() const
type is not object type is not object
*/ */
template<> template<>
JSON::object_t JSON::get() const json::object_t json::get() const
{ {
if (_type == value_type::object) if (_type == value_type::object)
{ {
...@@ -447,37 +447,37 @@ JSON::object_t JSON::get() const ...@@ -447,37 +447,37 @@ JSON::object_t JSON::get() const
} }
} }
JSON::operator const std::string() const json::operator const std::string() const
{ {
return get<std::string>(); return get<std::string>();
} }
JSON::operator int() const json::operator int() const
{ {
return get<int>(); return get<int>();
} }
JSON::operator double() const json::operator double() const
{ {
return get<double>(); return get<double>();
} }
JSON::operator bool() const json::operator bool() const
{ {
return get<bool>(); return get<bool>();
} }
JSON::operator array_t() const json::operator array_t() const
{ {
return get<array_t>(); return get<array_t>();
} }
JSON::operator object_t() const json::operator object_t() const
{ {
return get<object_t>(); return get<object_t>();
} }
const std::string JSON::toString() const noexcept const std::string json::toString() const noexcept
{ {
switch (_type) switch (_type)
{ {
...@@ -546,33 +546,33 @@ const std::string JSON::toString() const noexcept ...@@ -546,33 +546,33 @@ const std::string JSON::toString() const noexcept
// ADDING ELEMENTS TO OBJECTS AND ARRAYS // // ADDING ELEMENTS TO OBJECTS AND ARRAYS //
/////////////////////////////////////////// ///////////////////////////////////////////
JSON& JSON::operator+=(const JSON& o) json& json::operator+=(const json& o)
{ {
push_back(o); push_back(o);
return *this; return *this;
} }
JSON& JSON::operator+=(const std::string& s) json& json::operator+=(const std::string& s)
{ {
push_back(JSON(s)); push_back(json(s));
return *this; return *this;
} }
JSON& JSON::operator+=(const char* s) json& json::operator+=(const char* s)
{ {
push_back(JSON(s)); push_back(json(s));
return *this; return *this;
} }
JSON& JSON::operator+=(std::nullptr_t) json& json::operator+=(std::nullptr_t)
{ {
push_back(JSON()); push_back(json());
return *this; return *this;
} }
JSON& JSON::operator+=(bool b) json& json::operator+=(bool b)
{ {
push_back(JSON(b)); push_back(json(b));
return *this; return *this;
} }
...@@ -582,9 +582,9 @@ into a JSON and call push_back for this. ...@@ -582,9 +582,9 @@ into a JSON and call push_back for this.
@param i A number (int) to add to the array. @param i A number (int) to add to the array.
*/ */
JSON& JSON::operator+=(int i) json& json::operator+=(int i)
{ {
push_back(JSON(i)); push_back(json(i));
return *this; return *this;
} }
...@@ -594,16 +594,16 @@ number into a JSON and call push_back for this. ...@@ -594,16 +594,16 @@ number into a JSON and call push_back for this.
@param f A number (float) to add to the array. @param f A number (float) to add to the array.
*/ */
JSON& JSON::operator+=(double f) json& json::operator+=(double f)
{ {
push_back(JSON(f)); push_back(json(f));
return *this; return *this;
} }
/*! /*!
@todo comment me @todo comment me
*/ */
JSON& JSON::operator+=(const object_t::value_type& p) json& json::operator+=(const object_t::value_type& p)
{ {
return operator[](p.first) = p.second; return operator[](p.first) = p.second;
} }
...@@ -611,7 +611,7 @@ JSON& JSON::operator+=(const object_t::value_type& p) ...@@ -611,7 +611,7 @@ JSON& JSON::operator+=(const object_t::value_type& p)
/*! /*!
@todo comment me @todo comment me
*/ */
JSON& JSON::operator+=(list_init_t a) json& json::operator+=(list_init_t a)
{ {
push_back(a); push_back(a);
return *this; return *this;
...@@ -631,7 +631,7 @@ an array, the passed element is added to the array. ...@@ -631,7 +631,7 @@ an array, the passed element is added to the array.
@note Null objects are silently transformed into an array before the addition. @note Null objects are silently transformed into an array before the addition.
*/ */
void JSON::push_back(const JSON& o) void json::push_back(const json& o)
{ {
// push_back only works for null objects or arrays // push_back only works for null objects or arrays
if (not(_type == value_type::null or _type == value_type::array)) if (not(_type == value_type::null or _type == value_type::array))
...@@ -668,7 +668,7 @@ an array, the passed element is added to the array using move semantics. ...@@ -668,7 +668,7 @@ an array, the passed element is added to the array using move semantics.
@note Null objects are silently transformed into an array before the addition. @note Null objects are silently transformed into an array before the addition.
@note This function applies move semantics for the given element. @note This function applies move semantics for the given element.
*/ */
void JSON::push_back(JSON&& o) void json::push_back(json&& o)
{ {
// push_back only works for null objects or arrays // push_back only works for null objects or arrays
if (not(_type == value_type::null or _type == value_type::array)) if (not(_type == value_type::null or _type == value_type::array))
...@@ -691,24 +691,24 @@ void JSON::push_back(JSON&& o) ...@@ -691,24 +691,24 @@ void JSON::push_back(JSON&& o)
o._type = value_type::null; o._type = value_type::null;
} }
void JSON::push_back(const std::string& s) void json::push_back(const std::string& s)
{ {
push_back(JSON(s)); push_back(json(s));
} }
void JSON::push_back(const char* s) void json::push_back(const char* s)
{ {
push_back(JSON(s)); push_back(json(s));
} }
void JSON::push_back(std::nullptr_t) void json::push_back(std::nullptr_t)
{ {
push_back(JSON()); push_back(json());
} }
void JSON::push_back(bool b) void json::push_back(bool b)
{ {
push_back(JSON(b)); push_back(json(b));
} }
/*! /*!
...@@ -717,9 +717,9 @@ into a JSON and call push_back for this. ...@@ -717,9 +717,9 @@ into a JSON and call push_back for this.
@param i A number (int) to add to the array. @param i A number (int) to add to the array.
*/ */
void JSON::push_back(int i) void json::push_back(int i)
{ {
push_back(JSON(i)); push_back(json(i));
} }
/*! /*!
...@@ -728,15 +728,15 @@ number into a JSON and call push_back for this. ...@@ -728,15 +728,15 @@ number into a JSON and call push_back for this.
@param f A number (float) to add to the array. @param f A number (float) to add to the array.
*/ */
void JSON::push_back(double f) void json::push_back(double f)
{ {
push_back(JSON(f)); push_back(json(f));
} }
/*! /*!
@todo comment me @todo comment me
*/ */
void JSON::push_back(const object_t::value_type& p) void json::push_back(const object_t::value_type& p)
{ {
operator[](p.first) = p.second; operator[](p.first) = p.second;
} }
...@@ -744,7 +744,7 @@ void JSON::push_back(const object_t::value_type& p) ...@@ -744,7 +744,7 @@ void JSON::push_back(const object_t::value_type& p)
/*! /*!
@todo comment me @todo comment me
*/ */
void JSON::push_back(list_init_t a) void json::push_back(list_init_t a)
{ {
bool is_array = false; bool is_array = false;
...@@ -764,14 +764,14 @@ void JSON::push_back(list_init_t a) ...@@ -764,14 +764,14 @@ void JSON::push_back(list_init_t a)
if (is_array) if (is_array)
{ {
for (const JSON& element : a) for (const json& element : a)
{ {
push_back(element); push_back(element);
} }
} }
else else
{ {
for (const JSON& element : a) for (const json& element : a)
{ {
const object_t::value_type tmp {element[0].get<std::string>(), element[1]}; const object_t::value_type tmp {element[0].get<std::string>(), element[1]};
push_back(tmp); push_back(tmp);
...@@ -795,7 +795,7 @@ index. Bounds will not be checked. ...@@ -795,7 +795,7 @@ index. Bounds will not be checked.
@pre Object is an array. @pre Object is an array.
@exception std::domain_error if object is not an array @exception std::domain_error if object is not an array
*/ */
JSON& JSON::operator[](const int index) json& json::operator[](const int index)
{ {
// this [] operator only works for arrays // this [] operator only works for arrays
if (_type != value_type::array) if (_type != value_type::array)
...@@ -826,7 +826,7 @@ index. Bounds will not be checked. ...@@ -826,7 +826,7 @@ index. Bounds will not be checked.
@pre Object is an array. @pre Object is an array.
@exception std::domain_error if object is not an array @exception std::domain_error if object is not an array
*/ */
const JSON& JSON::operator[](const int index) const const json& json::operator[](const int index) const
{ {
// this [] operator only works for arrays // this [] operator only works for arrays
if (_type != value_type::array) if (_type != value_type::array)
...@@ -856,7 +856,7 @@ index. Bounds will be checked. ...@@ -856,7 +856,7 @@ index. Bounds will be checked.
@exception std::domain_error if object is not an array @exception std::domain_error if object is not an array
@exception std::out_of_range if index is out of range (via std::vector::at) @exception std::out_of_range if index is out of range (via std::vector::at)
*/ */
JSON& JSON::at(const int index) json& json::at(const int index)
{ {
// this function only works for arrays // this function only works for arrays
if (_type != value_type::array) if (_type != value_type::array)
...@@ -888,7 +888,7 @@ index. Bounds will be checked. ...@@ -888,7 +888,7 @@ index. Bounds will be checked.
@exception std::domain_error if object is not an array @exception std::domain_error if object is not an array
@exception std::out_of_range if index is out of range (via std::vector::at) @exception std::out_of_range if index is out of range (via std::vector::at)
*/ */
const JSON& JSON::at(const int index) const const json& json::at(const int index) const
{ {
// this function only works for arrays // this function only works for arrays
if (_type != value_type::array) if (_type != value_type::array)
...@@ -902,9 +902,9 @@ const JSON& JSON::at(const int index) const ...@@ -902,9 +902,9 @@ const JSON& JSON::at(const int index) const
} }
/*! /*!
@copydoc JSON::operator[](const char* key) @copydoc json::operator[](const char* key)
*/ */
JSON& JSON::operator[](const std::string& key) json& json::operator[](const std::string& key)
{ {
return operator[](key.c_str()); return operator[](key.c_str());
} }
...@@ -922,7 +922,7 @@ key. ...@@ -922,7 +922,7 @@ key.
@exception std::domain_error if object is not an object (or null) @exception std::domain_error if object is not an object (or null)
*/ */
JSON& JSON::operator[](const char* key) json& json::operator[](const char* key)
{ {
std::lock_guard<std::mutex> lg(_token); std::lock_guard<std::mutex> lg(_token);
...@@ -943,7 +943,7 @@ JSON& JSON::operator[](const char* key) ...@@ -943,7 +943,7 @@ JSON& JSON::operator[](const char* key)
// if the key does not exist, create it // if the key does not exist, create it
if (_value.object->find(key) == _value.object->end()) if (_value.object->find(key) == _value.object->end())
{ {
(*_value.object)[key] = JSON(); (*_value.object)[key] = json();
} }
// return reference to element from array at given index // return reference to element from array at given index
...@@ -961,7 +961,7 @@ key. ...@@ -961,7 +961,7 @@ key.
@exception std::domain_error if object is not an object @exception std::domain_error if object is not an object
@exception std::out_of_range if key is not found in object @exception std::out_of_range if key is not found in object
*/ */
const JSON& JSON::operator[](const std::string& key) const const json& json::operator[](const std::string& key) const
{ {
// this [] operator only works for objects // this [] operator only works for objects
if (_type != value_type::object) if (_type != value_type::object)
...@@ -984,9 +984,9 @@ const JSON& JSON::operator[](const std::string& key) const ...@@ -984,9 +984,9 @@ const JSON& JSON::operator[](const std::string& key) const
} }
/*! /*!
@copydoc JSON::at(const char* key) @copydoc json::at(const char* key)
*/ */
JSON& JSON::at(const std::string& key) json& json::at(const std::string& key)
{ {
return at(key.c_str()); return at(key.c_str());
} }
...@@ -1004,7 +1004,7 @@ key. ...@@ -1004,7 +1004,7 @@ key.
@exception std::domain_error if object is not an object @exception std::domain_error if object is not an object
@exception std::out_of_range if key was not found (via std::map::at) @exception std::out_of_range if key was not found (via std::map::at)
*/ */
JSON& JSON::at(const char* key) json& json::at(const char* key)
{ {
std::lock_guard<std::mutex> lg(_token); std::lock_guard<std::mutex> lg(_token);
...@@ -1020,9 +1020,9 @@ JSON& JSON::at(const char* key) ...@@ -1020,9 +1020,9 @@ JSON& JSON::at(const char* key)
} }
/*! /*!
@copydoc JSON::at(const char *key) const @copydoc json::at(const char *key) const
*/ */
const JSON& JSON::at(const std::string& key) const const json& json::at(const std::string& key) const
{ {
return at(key.c_str()); return at(key.c_str());
} }
...@@ -1038,7 +1038,7 @@ key. ...@@ -1038,7 +1038,7 @@ key.
@exception std::domain_error if object is not an object @exception std::domain_error if object is not an object
@exception std::out_of_range if key is not found (via std::map::at) @exception std::out_of_range if key is not found (via std::map::at)
*/ */
const JSON& JSON::at(const char* key) const const json& json::at(const char* key) const
{ {
// this [] operator only works for objects // this [] operator only works for objects
if (_type != value_type::object) if (_type != value_type::object)
...@@ -1061,7 +1061,7 @@ Returns the size of the JSON object. ...@@ -1061,7 +1061,7 @@ Returns the size of the JSON object.
@invariant The size is reported as 0 if and only if empty() would return true. @invariant The size is reported as 0 if and only if empty() would return true.
*/ */
size_t JSON::size() const noexcept size_t json::size() const noexcept
{ {
switch (_type) switch (_type)
{ {
...@@ -1093,7 +1093,7 @@ Returns whether a JSON object is empty. ...@@ -1093,7 +1093,7 @@ Returns whether a JSON object is empty.
@invariant Empty would report true if and only if size() would return 0. @invariant Empty would report true if and only if size() would return 0.
*/ */
bool JSON::empty() const noexcept bool json::empty() const noexcept
{ {
switch (_type) switch (_type)
{ {
...@@ -1123,7 +1123,7 @@ Removes all elements from compounds and resets values to default. ...@@ -1123,7 +1123,7 @@ Removes all elements from compounds and resets values to default.
for compounds, false for booleans, 0 for integer numbers, and 0.0 for compounds, false for booleans, 0 for integer numbers, and 0.0
for floating numbers. for floating numbers.
*/ */
void JSON::clear() noexcept void json::clear() noexcept
{ {
switch (_type) switch (_type)
{ {
...@@ -1164,22 +1164,22 @@ void JSON::clear() noexcept ...@@ -1164,22 +1164,22 @@ void JSON::clear() noexcept
} }
} }
JSON::value_type JSON::type() const noexcept json::value_type json::type() const noexcept
{ {
return _type; return _type;
} }
JSON::iterator JSON::find(const std::string& key) json::iterator json::find(const std::string& key)
{ {
return find(key.c_str()); return find(key.c_str());
} }
JSON::const_iterator JSON::find(const std::string& key) const json::const_iterator json::find(const std::string& key) const
{ {
return find(key.c_str()); return find(key.c_str());
} }
JSON::iterator JSON::find(const char* key) json::iterator json::find(const char* key)
{ {
if (_type != value_type::object) if (_type != value_type::object)
{ {
...@@ -1190,7 +1190,7 @@ JSON::iterator JSON::find(const char* key) ...@@ -1190,7 +1190,7 @@ JSON::iterator JSON::find(const char* key)
const object_t::iterator i = _value.object->find(key); const object_t::iterator i = _value.object->find(key);
if (i != _value.object->end()) if (i != _value.object->end())
{ {
JSON::iterator result(this); json::iterator result(this);
delete result._oi; delete result._oi;
result._oi = new object_t::iterator(i); result._oi = new object_t::iterator(i);
return result; return result;
...@@ -1202,7 +1202,7 @@ JSON::iterator JSON::find(const char* key) ...@@ -1202,7 +1202,7 @@ JSON::iterator JSON::find(const char* key)
} }
} }
JSON::const_iterator JSON::find(const char* key) const json::const_iterator json::find(const char* key) const
{ {
if (_type != value_type::object) if (_type != value_type::object)
{ {
...@@ -1213,7 +1213,7 @@ JSON::const_iterator JSON::find(const char* key) const ...@@ -1213,7 +1213,7 @@ JSON::const_iterator JSON::find(const char* key) const
const object_t::const_iterator i = _value.object->find(key); const object_t::const_iterator i = _value.object->find(key);
if (i != _value.object->end()) if (i != _value.object->end())
{ {
JSON::const_iterator result(this); json::const_iterator result(this);
delete result._oi; delete result._oi;
result._oi = new object_t::const_iterator(i); result._oi = new object_t::const_iterator(i);
return result; return result;
...@@ -1225,7 +1225,7 @@ JSON::const_iterator JSON::find(const char* key) const ...@@ -1225,7 +1225,7 @@ JSON::const_iterator JSON::find(const char* key) const
} }
} }
bool JSON::operator==(const JSON& o) const noexcept bool json::operator==(const json& o) const noexcept
{ {
switch (_type) switch (_type)
{ {
...@@ -1298,44 +1298,44 @@ bool JSON::operator==(const JSON& o) const noexcept ...@@ -1298,44 +1298,44 @@ bool JSON::operator==(const JSON& o) const noexcept
return false; return false;
} }
bool JSON::operator!=(const JSON& o) const noexcept bool json::operator!=(const json& o) const noexcept
{ {
return not operator==(o); return not operator==(o);
} }
JSON::iterator JSON::begin() noexcept json::iterator json::begin() noexcept
{ {
return JSON::iterator(this); return json::iterator(this);
} }
JSON::iterator JSON::end() noexcept json::iterator json::end() noexcept
{ {
return JSON::iterator(); return json::iterator();
} }
JSON::const_iterator JSON::begin() const noexcept json::const_iterator json::begin() const noexcept
{ {
return JSON::const_iterator(this); return json::const_iterator(this);
} }
JSON::const_iterator JSON::end() const noexcept json::const_iterator json::end() const noexcept
{ {
return JSON::const_iterator(); return json::const_iterator();
} }
JSON::const_iterator JSON::cbegin() const noexcept json::const_iterator json::cbegin() const noexcept
{ {
return JSON::const_iterator(this); return json::const_iterator(this);
} }
JSON::const_iterator JSON::cend() const noexcept json::const_iterator json::cend() const noexcept
{ {
return JSON::const_iterator(); return json::const_iterator();
} }
JSON::iterator::iterator(JSON* j) : _object(j) json::iterator::iterator(json* j) : _object(j)
{ {
if (_object != nullptr) if (_object != nullptr)
{ {
...@@ -1350,7 +1350,7 @@ JSON::iterator::iterator(JSON* j) : _object(j) ...@@ -1350,7 +1350,7 @@ JSON::iterator::iterator(JSON* j) : _object(j)
} }
} }
JSON::iterator::iterator(const JSON::iterator& o) : _object(o._object) json::iterator::iterator(const json::iterator& o) : _object(o._object)
{ {
if (_object != nullptr) if (_object != nullptr)
{ {
...@@ -1365,13 +1365,13 @@ JSON::iterator::iterator(const JSON::iterator& o) : _object(o._object) ...@@ -1365,13 +1365,13 @@ JSON::iterator::iterator(const JSON::iterator& o) : _object(o._object)
} }
} }
JSON::iterator::~iterator() json::iterator::~iterator()
{ {
delete _vi; delete _vi;
delete _oi; delete _oi;
} }
JSON::iterator& JSON::iterator::operator=(JSON::iterator o) json::iterator& json::iterator::operator=(json::iterator o)
{ {
std::swap(_object, o._object); std::swap(_object, o._object);
std::swap(_vi, o._vi); std::swap(_vi, o._vi);
...@@ -1379,7 +1379,7 @@ JSON::iterator& JSON::iterator::operator=(JSON::iterator o) ...@@ -1379,7 +1379,7 @@ JSON::iterator& JSON::iterator::operator=(JSON::iterator o)
return *this; return *this;
} }
bool JSON::iterator::operator==(const JSON::iterator& o) const bool json::iterator::operator==(const json::iterator& o) const
{ {
if (_object != o._object) if (_object != o._object)
{ {
...@@ -1401,12 +1401,12 @@ bool JSON::iterator::operator==(const JSON::iterator& o) const ...@@ -1401,12 +1401,12 @@ bool JSON::iterator::operator==(const JSON::iterator& o) const
return true; return true;
} }
bool JSON::iterator::operator!=(const JSON::iterator& o) const bool json::iterator::operator!=(const json::iterator& o) const
{ {
return not operator==(o); return not operator==(o);
} }
JSON::iterator& JSON::iterator::operator++() json::iterator& json::iterator::operator++()
{ {
// iterator cannot be incremented // iterator cannot be incremented
if (_object == nullptr) if (_object == nullptr)
...@@ -1440,7 +1440,7 @@ JSON::iterator& JSON::iterator::operator++() ...@@ -1440,7 +1440,7 @@ JSON::iterator& JSON::iterator::operator++()
return *this; return *this;
} }
JSON& JSON::iterator::operator*() const json& json::iterator::operator*() const
{ {
// dereferencing end() is an error // dereferencing end() is an error
if (_object == nullptr) if (_object == nullptr)
...@@ -1465,7 +1465,7 @@ JSON& JSON::iterator::operator*() const ...@@ -1465,7 +1465,7 @@ JSON& JSON::iterator::operator*() const
} }
} }
JSON* JSON::iterator::operator->() const json* json::iterator::operator->() const
{ {
// dereferencing end() is an error // dereferencing end() is an error
if (_object == nullptr) if (_object == nullptr)
...@@ -1490,7 +1490,7 @@ JSON* JSON::iterator::operator->() const ...@@ -1490,7 +1490,7 @@ JSON* JSON::iterator::operator->() const
} }
} }
std::string JSON::iterator::key() const std::string json::iterator::key() const
{ {
if (_object != nullptr and _object->_type == value_type::object) if (_object != nullptr and _object->_type == value_type::object)
{ {
...@@ -1502,7 +1502,7 @@ std::string JSON::iterator::key() const ...@@ -1502,7 +1502,7 @@ std::string JSON::iterator::key() const
} }
} }
JSON& JSON::iterator::value() const json& json::iterator::value() const
{ {
// dereferencing end() is an error // dereferencing end() is an error
if (_object == nullptr) if (_object == nullptr)
...@@ -1528,7 +1528,7 @@ JSON& JSON::iterator::value() const ...@@ -1528,7 +1528,7 @@ JSON& JSON::iterator::value() const
} }
JSON::const_iterator::const_iterator(const JSON* j) : _object(j) json::const_iterator::const_iterator(const json* j) : _object(j)
{ {
if (_object != nullptr) if (_object != nullptr)
{ {
...@@ -1543,7 +1543,7 @@ JSON::const_iterator::const_iterator(const JSON* j) : _object(j) ...@@ -1543,7 +1543,7 @@ JSON::const_iterator::const_iterator(const JSON* j) : _object(j)
} }
} }
JSON::const_iterator::const_iterator(const JSON::const_iterator& o) : _object(o._object) json::const_iterator::const_iterator(const json::const_iterator& o) : _object(o._object)
{ {
if (_object != nullptr) if (_object != nullptr)
{ {
...@@ -1558,7 +1558,7 @@ JSON::const_iterator::const_iterator(const JSON::const_iterator& o) : _object(o. ...@@ -1558,7 +1558,7 @@ JSON::const_iterator::const_iterator(const JSON::const_iterator& o) : _object(o.
} }
} }
JSON::const_iterator::const_iterator(const JSON::iterator& o) : _object(o._object) json::const_iterator::const_iterator(const json::iterator& o) : _object(o._object)
{ {
if (_object != nullptr) if (_object != nullptr)
{ {
...@@ -1573,13 +1573,13 @@ JSON::const_iterator::const_iterator(const JSON::iterator& o) : _object(o._objec ...@@ -1573,13 +1573,13 @@ JSON::const_iterator::const_iterator(const JSON::iterator& o) : _object(o._objec
} }
} }
JSON::const_iterator::~const_iterator() json::const_iterator::~const_iterator()
{ {
delete _vi; delete _vi;
delete _oi; delete _oi;
} }
JSON::const_iterator& JSON::const_iterator::operator=(JSON::const_iterator o) json::const_iterator& json::const_iterator::operator=(json::const_iterator o)
{ {
std::swap(_object, o._object); std::swap(_object, o._object);
std::swap(_vi, o._vi); std::swap(_vi, o._vi);
...@@ -1587,7 +1587,7 @@ JSON::const_iterator& JSON::const_iterator::operator=(JSON::const_iterator o) ...@@ -1587,7 +1587,7 @@ JSON::const_iterator& JSON::const_iterator::operator=(JSON::const_iterator o)
return *this; return *this;
} }
bool JSON::const_iterator::operator==(const JSON::const_iterator& o) const bool json::const_iterator::operator==(const json::const_iterator& o) const
{ {
if (_object != o._object) if (_object != o._object)
{ {
...@@ -1609,12 +1609,12 @@ bool JSON::const_iterator::operator==(const JSON::const_iterator& o) const ...@@ -1609,12 +1609,12 @@ bool JSON::const_iterator::operator==(const JSON::const_iterator& o) const
return true; return true;
} }
bool JSON::const_iterator::operator!=(const JSON::const_iterator& o) const bool json::const_iterator::operator!=(const json::const_iterator& o) const
{ {
return not operator==(o); return not operator==(o);
} }
JSON::const_iterator& JSON::const_iterator::operator++() json::const_iterator& json::const_iterator::operator++()
{ {
// iterator cannot be incremented // iterator cannot be incremented
if (_object == nullptr) if (_object == nullptr)
...@@ -1648,7 +1648,7 @@ JSON::const_iterator& JSON::const_iterator::operator++() ...@@ -1648,7 +1648,7 @@ JSON::const_iterator& JSON::const_iterator::operator++()
return *this; return *this;
} }
const JSON& JSON::const_iterator::operator*() const const json& json::const_iterator::operator*() const
{ {
// dereferencing end() is an error // dereferencing end() is an error
if (_object == nullptr) if (_object == nullptr)
...@@ -1673,7 +1673,7 @@ const JSON& JSON::const_iterator::operator*() const ...@@ -1673,7 +1673,7 @@ const JSON& JSON::const_iterator::operator*() const
} }
} }
const JSON* JSON::const_iterator::operator->() const const json* json::const_iterator::operator->() const
{ {
// dereferencing end() is an error // dereferencing end() is an error
if (_object == nullptr) if (_object == nullptr)
...@@ -1698,7 +1698,7 @@ const JSON* JSON::const_iterator::operator->() const ...@@ -1698,7 +1698,7 @@ const JSON* JSON::const_iterator::operator->() const
} }
} }
std::string JSON::const_iterator::key() const std::string json::const_iterator::key() const
{ {
if (_object != nullptr and _object->_type == value_type::object) if (_object != nullptr and _object->_type == value_type::object)
{ {
...@@ -1710,7 +1710,7 @@ std::string JSON::const_iterator::key() const ...@@ -1710,7 +1710,7 @@ std::string JSON::const_iterator::key() const
} }
} }
const JSON& JSON::const_iterator::value() const const json& json::const_iterator::value() const
{ {
// dereferencing end() is an error // dereferencing end() is an error
if (_object == nullptr) if (_object == nullptr)
...@@ -1746,7 +1746,7 @@ Initialize the JSON parser given a string \p s. ...@@ -1746,7 +1746,7 @@ Initialize the JSON parser given a string \p s.
@post \p s is copied to the buffer @ref _buffer and the first character is @post \p s is copied to the buffer @ref _buffer and the first character is
read. Whitespace is skipped. read. Whitespace is skipped.
*/ */
JSON::Parser::Parser(const char* s) json::parser::parser(const char* s)
: _buffer(s) : _buffer(s)
{ {
// read first character // read first character
...@@ -1754,9 +1754,9 @@ JSON::Parser::Parser(const char* s) ...@@ -1754,9 +1754,9 @@ JSON::Parser::Parser(const char* s)
} }
/*! /*!
@copydoc JSON::Parser::Parser(const char* s) @copydoc json::parser::parser(const char* s)
*/ */
JSON::Parser::Parser(const std::string& s) json::parser::parser(const std::string& s)
: _buffer(s) : _buffer(s)
{ {
// read first character // read first character
...@@ -1774,7 +1774,7 @@ Initialize the JSON parser given an input stream \p _is. ...@@ -1774,7 +1774,7 @@ Initialize the JSON parser given an input stream \p _is.
read. Whitespace is skipped. read. Whitespace is skipped.
*/ */
JSON::Parser::Parser(std::istream& _is) json::parser::parser(std::istream& _is)
{ {
while (_is) while (_is)
{ {
...@@ -1787,14 +1787,14 @@ JSON::Parser::Parser(std::istream& _is) ...@@ -1787,14 +1787,14 @@ JSON::Parser::Parser(std::istream& _is)
next(); next();
} }
JSON JSON::Parser::parse() json json::parser::parse()
{ {
switch (_current) switch (_current)
{ {
case ('{'): case ('{'):
{ {
// explicitly set result to object to cope with {} // explicitly set result to object to cope with {}
JSON result(value_type::object); json result(value_type::object);
next(); next();
...@@ -1825,7 +1825,7 @@ JSON JSON::Parser::parse() ...@@ -1825,7 +1825,7 @@ JSON JSON::Parser::parse()
case ('['): case ('['):
{ {
// explicitly set result to array to cope with [] // explicitly set result to array to cope with []
JSON result(value_type::array); json result(value_type::array);
next(); next();
...@@ -1847,25 +1847,25 @@ JSON JSON::Parser::parse() ...@@ -1847,25 +1847,25 @@ JSON JSON::Parser::parse()
case ('\"'): case ('\"'):
{ {
return JSON(parseString()); return json(parseString());
} }
case ('t'): case ('t'):
{ {
parseTrue(); parseTrue();
return JSON(true); return json(true);
} }
case ('f'): case ('f'):
{ {
parseFalse(); parseFalse();
return JSON(false); return json(false);
} }
case ('n'): case ('n'):
{ {
parseNull(); parseNull();
return JSON(); return json();
} }
case ('-'): case ('-'):
...@@ -1896,12 +1896,12 @@ JSON JSON::Parser::parse() ...@@ -1896,12 +1896,12 @@ JSON JSON::Parser::parse()
if (float_val == int_val) if (float_val == int_val)
{ {
// we would not lose precision -> int // we would not lose precision -> int
return JSON(int_val); return json(int_val);
} }
else else
{ {
// we would lose precision -> float // we would lose precision -> float
return JSON(float_val); return json(float_val);
} }
} }
catch (...) catch (...)
...@@ -1927,7 +1927,7 @@ true. If the end of the buffer is reached, false is returned. ...@@ -1927,7 +1927,7 @@ true. If the end of the buffer is reached, false is returned.
@post _current holds the next character @post _current holds the next character
*/ */
bool JSON::Parser::next() bool json::parser::next()
{ {
if (_pos == _buffer.size()) if (_pos == _buffer.size())
{ {
...@@ -1961,7 +1961,7 @@ the error message \p msg), and the last read token. ...@@ -1961,7 +1961,7 @@ the error message \p msg), and the last read token.
@exception std::invalid_argument whenever the function is called @exception std::invalid_argument whenever the function is called
*/ */
void JSON::Parser::error(const std::string& msg) void json::parser::error(const std::string& msg)
{ {
throw std::invalid_argument("parse error at position " + throw std::invalid_argument("parse error at position " +
std::to_string(_pos) + ": " + msg + std::to_string(_pos) + ": " + msg +
...@@ -1979,7 +1979,7 @@ Parses a string after opening quotes (\p ") where read. ...@@ -1979,7 +1979,7 @@ Parses a string after opening quotes (\p ") where read.
@post The character after the closing quote \p " is the current character @ref @post The character after the closing quote \p " is the current character @ref
_current. Whitespace is skipped. _current. Whitespace is skipped.
*/ */
std::string JSON::Parser::parseString() std::string json::parser::parseString()
{ {
// get position of closing quotes // get position of closing quotes
auto quote_pos = _buffer.find_first_of("\"", _pos); auto quote_pos = _buffer.find_first_of("\"", _pos);
...@@ -2021,7 +2021,7 @@ error is raised via @ref error. ...@@ -2021,7 +2021,7 @@ error is raised via @ref error.
@post The character after the \p "true" is the current character. Whitespace is @post The character after the \p "true" is the current character. Whitespace is
skipped. skipped.
*/ */
void JSON::Parser::parseTrue() void json::parser::parseTrue()
{ {
if (_buffer.substr(_pos, 3) != "rue") if (_buffer.substr(_pos, 3) != "rue")
{ {
...@@ -2044,7 +2044,7 @@ error is raised via @ref error. ...@@ -2044,7 +2044,7 @@ error is raised via @ref error.
@post The character after the \p "false" is the current character. Whitespace @post The character after the \p "false" is the current character. Whitespace
is skipped. is skipped.
*/ */
void JSON::Parser::parseFalse() void json::parser::parseFalse()
{ {
if (_buffer.substr(_pos, 4) != "alse") if (_buffer.substr(_pos, 4) != "alse")
{ {
...@@ -2067,7 +2067,7 @@ error is raised via @ref error. ...@@ -2067,7 +2067,7 @@ error is raised via @ref error.
@post The character after the \p "null" is the current character. Whitespace is @post The character after the \p "null" is the current character. Whitespace is
skipped. skipped.
*/ */
void JSON::Parser::parseNull() void json::parser::parseNull()
{ {
if (_buffer.substr(_pos, 3) != "ull") if (_buffer.substr(_pos, 3) != "ull")
{ {
...@@ -2090,7 +2090,7 @@ via @ref error. ...@@ -2090,7 +2090,7 @@ via @ref error.
@post The next chatacter is read. Whitespace is skipped. @post The next chatacter is read. Whitespace is skipped.
*/ */
void JSON::Parser::expect(const char c) void json::parser::expect(const char c)
{ {
if (_current != c) if (_current != c)
{ {
...@@ -2113,7 +2113,7 @@ no parse error occurred. ...@@ -2113,7 +2113,7 @@ no parse error occurred.
@param s a string representation of a JSON object @param s a string representation of a JSON object
@return a JSON object @return a JSON object
*/ */
JSON operator "" _json(const char* s, size_t) json operator "" _json(const char* s, size_t)
{ {
return JSON::parse(s); return json::parse(s);
} }
...@@ -31,12 +31,12 @@ due to alignment. ...@@ -31,12 +31,12 @@ due to alignment.
@bug Numbers are currently handled too generously. There are several formats @bug Numbers are currently handled too generously. There are several formats
that are forbidden by the standard, but are accepted by the parser. that are forbidden by the standard, but are accepted by the parser.
@todo Implement JSON::swap() @todo Implement json::swap()
@todo Implement JSON::insert(), JSON::emplace(), JSON::emplace_back, JSON::erase @todo Implement json::insert(), json::emplace(), json::emplace_back, json::erase
@todo Implement JSON::reverse_iterator, JSON::const_reverse_iterator, @todo Implement json::reverse_iterator, json::const_reverse_iterator,
JSON::rbegin(), JSON::rend(), JSON::crbegin(), JSON::crend()? json::rbegin(), json::rend(), json::crbegin(), json::crend()?
*/ */
class JSON class json
{ {
// forward declaration to friend this class // forward declaration to friend this class
public: public:
...@@ -64,9 +64,9 @@ class JSON ...@@ -64,9 +64,9 @@ class JSON
}; };
/// a type for an object /// a type for an object
using object_t = std::map<std::string, JSON>; using object_t = std::map<std::string, json>;
/// a type for an array /// a type for an array
using array_t = std::vector<JSON>; using array_t = std::vector<json>;
/// a type for a string /// a type for a string
using string_t = std::string; using string_t = std::string;
/// a type for a Boolean /// a type for a Boolean
...@@ -76,7 +76,7 @@ class JSON ...@@ -76,7 +76,7 @@ class JSON
/// a type for a floating point number /// a type for a floating point number
using number_float_t = double; using number_float_t = double;
/// a type for list initialization /// a type for list initialization
using list_init_t = std::initializer_list<JSON>; using list_init_t = std::initializer_list<json>;
/// a JSON value /// a JSON value
union value union value
...@@ -112,49 +112,49 @@ class JSON ...@@ -112,49 +112,49 @@ class JSON
public: public:
/// create an object according to given type /// create an object according to given type
JSON(const value_type) noexcept; json(const value_type) noexcept;
/// create a null object /// create a null object
JSON() = default; json() = default;
/// create a null object /// create a null object
JSON(std::nullptr_t) noexcept; json(std::nullptr_t) noexcept;
/// create a string object from a C++ string /// create a string object from a C++ string
JSON(const std::string&) noexcept; json(const std::string&) noexcept;
/// create a string object from a C++ string (move) /// create a string object from a C++ string (move)
JSON(std::string&&) noexcept; json(std::string&&) noexcept;
/// create a string object from a C string /// create a string object from a C string
JSON(const char*) noexcept; json(const char*) noexcept;
/// create a Boolean object /// create a Boolean object
JSON(const bool) noexcept; json(const bool) noexcept;
/// create a number object /// create a number object
JSON(const int) noexcept; json(const int) noexcept;
/// create a number object /// create a number object
JSON(const double) noexcept; json(const double) noexcept;
/// create an array /// create an array
JSON(const array_t&) noexcept; json(const array_t&) noexcept;
/// create an array (move) /// create an array (move)
JSON(array_t&&) noexcept; json(array_t&&) noexcept;
/// create an object /// create an object
JSON(const object_t&) noexcept; json(const object_t&) noexcept;
/// create an object (move) /// create an object (move)
JSON(object_t&&) noexcept; json(object_t&&) noexcept;
/// create from an initializer list (to an array or object) /// create from an initializer list (to an array or object)
JSON(list_init_t) noexcept; json(list_init_t) noexcept;
/// copy constructor /// copy constructor
JSON(const JSON&) noexcept; json(const json&) noexcept;
/// move constructor /// move constructor
JSON(JSON&&) noexcept; json(json&&) noexcept;
/// copy assignment /// copy assignment
JSON& operator=(JSON) noexcept; json& operator=(json) noexcept;
/// destructor /// destructor
~JSON() noexcept; ~json() noexcept;
/// create from string representation /// create from string representation
static JSON parse(const std::string&); static json parse(const std::string&);
/// create from string representation /// create from string representation
static JSON parse(const char*); static json parse(const char*);
private: private:
/// return the type as string /// return the type as string
...@@ -179,28 +179,28 @@ class JSON ...@@ -179,28 +179,28 @@ class JSON
operator object_t() const; operator object_t() const;
/// write to stream /// write to stream
friend std::ostream& operator<<(std::ostream& o, const JSON& j) friend std::ostream& operator<<(std::ostream& o, const json& j)
{ {
o << j.toString(); o << j.toString();
return o; return o;
} }
/// write to stream /// write to stream
friend std::ostream& operator>>(const JSON& j, std::ostream& o) friend std::ostream& operator>>(const json& j, std::ostream& o)
{ {
o << j.toString(); o << j.toString();
return o; return o;
} }
/// read from stream /// read from stream
friend std::istream& operator>>(std::istream& i, JSON& j) friend std::istream& operator>>(std::istream& i, json& j)
{ {
j = Parser(i).parse(); j = parser(i).parse();
return i; return i;
} }
/// read from stream /// read from stream
friend std::istream& operator<<(JSON& j, std::istream& i) friend std::istream& operator<<(json& j, std::istream& i)
{ {
j = Parser(i).parse(); j = parser(i).parse();
return i; return i;
} }
...@@ -208,29 +208,29 @@ class JSON ...@@ -208,29 +208,29 @@ class JSON
const std::string toString() const noexcept; const std::string toString() const noexcept;
/// add an object/array to an array /// add an object/array to an array
JSON& operator+=(const JSON&); json& operator+=(const json&);
/// add a string to an array /// add a string to an array
JSON& operator+=(const std::string&); json& operator+=(const std::string&);
/// add a null object to an array /// add a null object to an array
JSON& operator+=(const std::nullptr_t); json& operator+=(const std::nullptr_t);
/// add a string to an array /// add a string to an array
JSON& operator+=(const char*); json& operator+=(const char*);
/// add a Boolean to an array /// add a Boolean to an array
JSON& operator+=(bool); json& operator+=(bool);
/// add a number to an array /// add a number to an array
JSON& operator+=(int); json& operator+=(int);
/// add a number to an array /// add a number to an array
JSON& operator+=(double); json& operator+=(double);
/// add a pair to an object /// add a pair to an object
JSON& operator+=(const object_t::value_type&); json& operator+=(const object_t::value_type&);
/// add a list of elements to array or list of pairs to object /// add a list of elements to array or list of pairs to object
JSON& operator+=(list_init_t); json& operator+=(list_init_t);
/// add an object/array to an array /// add an object/array to an array
void push_back(const JSON&); void push_back(const json&);
/// add an object/array to an array (move) /// add an object/array to an array (move)
void push_back(JSON&&); void push_back(json&&);
/// add a string to an array /// add a string to an array
void push_back(const std::string&); void push_back(const std::string&);
/// add a null object to an array /// add a null object to an array
...@@ -250,28 +250,28 @@ class JSON ...@@ -250,28 +250,28 @@ class JSON
void push_back(list_init_t); void push_back(list_init_t);
/// operator to set an element in an array /// operator to set an element in an array
JSON& operator[](const int); json& operator[](const int);
/// operator to get an element in an array /// operator to get an element in an array
const JSON& operator[](const int) const; const json& operator[](const int) const;
/// operator to get an element in an array /// operator to get an element in an array
JSON& at(const int); json& at(const int);
/// operator to get an element in an array /// operator to get an element in an array
const JSON& at(const int) const; const json& at(const int) const;
/// operator to set an element in an object /// operator to set an element in an object
JSON& operator[](const std::string&); json& operator[](const std::string&);
/// operator to set an element in an object /// operator to set an element in an object
JSON& operator[](const char*); json& operator[](const char*);
/// operator to get an element in an object /// operator to get an element in an object
const JSON& operator[](const std::string&) const; const json& operator[](const std::string&) const;
/// operator to set an element in an object /// operator to set an element in an object
JSON& at(const std::string&); json& at(const std::string&);
/// operator to set an element in an object /// operator to set an element in an object
JSON& at(const char*); json& at(const char*);
/// operator to get an element in an object /// operator to get an element in an object
const JSON& at(const std::string&) const; const json& at(const std::string&) const;
/// operator to get an element in an object /// operator to get an element in an object
const JSON& at(const char*) const; const json& at(const char*) const;
/// return the number of stored values /// return the number of stored values
size_t size() const noexcept; size_t size() const noexcept;
...@@ -293,9 +293,9 @@ class JSON ...@@ -293,9 +293,9 @@ class JSON
const_iterator find(const char*) const; const_iterator find(const char*) const;
/// lexicographically compares the values /// lexicographically compares the values
bool operator==(const JSON&) const noexcept; bool operator==(const json&) const noexcept;
/// lexicographically compares the values /// lexicographically compares the values
bool operator!=(const JSON&) const noexcept; bool operator!=(const json&) const noexcept;
/// returns an iterator to the beginning (array/object) /// returns an iterator to the beginning (array/object)
iterator begin() noexcept; iterator begin() noexcept;
...@@ -325,11 +325,11 @@ class JSON ...@@ -325,11 +325,11 @@ class JSON
/// an iterator /// an iterator
class iterator class iterator
{ {
friend class JSON; friend class json;
friend class JSON::const_iterator; friend class json::const_iterator;
public: public:
iterator() = default; iterator() = default;
iterator(JSON*); iterator(json*);
iterator(const iterator&); iterator(const iterator&);
~iterator(); ~iterator();
...@@ -337,17 +337,17 @@ class JSON ...@@ -337,17 +337,17 @@ class JSON
bool operator==(const iterator&) const; bool operator==(const iterator&) const;
bool operator!=(const iterator&) const; bool operator!=(const iterator&) const;
iterator& operator++(); iterator& operator++();
JSON& operator*() const; json& operator*() const;
JSON* operator->() const; json* operator->() const;
/// getter for the key (in case of objects) /// getter for the key (in case of objects)
std::string key() const; std::string key() const;
/// getter for the value /// getter for the value
JSON& value() const; json& value() const;
private: private:
/// a JSON value /// a JSON value
JSON* _object = nullptr; json* _object = nullptr;
/// an iterator for JSON arrays /// an iterator for JSON arrays
array_t::iterator* _vi = nullptr; array_t::iterator* _vi = nullptr;
/// an iterator for JSON objects /// an iterator for JSON objects
...@@ -357,11 +357,11 @@ class JSON ...@@ -357,11 +357,11 @@ class JSON
/// a const iterator /// a const iterator
class const_iterator class const_iterator
{ {
friend class JSON; friend class json;
public: public:
const_iterator() = default; const_iterator() = default;
const_iterator(const JSON*); const_iterator(const json*);
const_iterator(const const_iterator&); const_iterator(const const_iterator&);
const_iterator(const iterator&); const_iterator(const iterator&);
~const_iterator(); ~const_iterator();
...@@ -370,17 +370,17 @@ class JSON ...@@ -370,17 +370,17 @@ class JSON
bool operator==(const const_iterator&) const; bool operator==(const const_iterator&) const;
bool operator!=(const const_iterator&) const; bool operator!=(const const_iterator&) const;
const_iterator& operator++(); const_iterator& operator++();
const JSON& operator*() const; const json& operator*() const;
const JSON* operator->() const; const json* operator->() const;
/// getter for the key (in case of objects) /// getter for the key (in case of objects)
std::string key() const; std::string key() const;
/// getter for the value /// getter for the value
const JSON& value() const; const json& value() const;
private: private:
/// a JSON value /// a JSON value
const JSON* _object = nullptr; const json* _object = nullptr;
/// an iterator for JSON arrays /// an iterator for JSON arrays
array_t::const_iterator* _vi = nullptr; array_t::const_iterator* _vi = nullptr;
/// an iterator for JSON objects /// an iterator for JSON objects
...@@ -389,25 +389,25 @@ class JSON ...@@ -389,25 +389,25 @@ class JSON
private: private:
/// a helper class to parse a JSON object /// a helper class to parse a JSON object
class Parser class parser
{ {
public: public:
/// a parser reading from a C string /// a parser reading from a C string
Parser(const char*); parser(const char*);
/// a parser reading from a C++ string /// a parser reading from a C++ string
Parser(const std::string&); parser(const std::string&);
/// a parser reading from an input stream /// a parser reading from an input stream
Parser(std::istream&); parser(std::istream&);
/// destructor of the parser /// destructor of the parser
~Parser() = default; ~parser() = default;
// no copy constructor // no copy constructor
Parser(const Parser&) = delete; parser(const parser&) = delete;
// no copy assignment // no copy assignment
Parser& operator=(Parser) = delete; parser& operator=(parser) = delete;
/// parse and return a JSON object /// parse and return a JSON object
JSON parse(); json parse();
private: private:
/// read the next character, stripping whitespace /// read the next character, stripping whitespace
...@@ -436,4 +436,4 @@ class JSON ...@@ -436,4 +436,4 @@ class JSON
}; };
/// user-defined literal operator to create JSON objects from strings /// user-defined literal operator to create JSON objects from strings
JSON operator "" _json(const char*, size_t); json operator "" _json(const char*, size_t);
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include "catch.hpp" #include "catch.hpp"
#include "JSON.h" #include "json.h"
TEST_CASE("array") TEST_CASE("array")
{ {
SECTION("Basics") SECTION("Basics")
{ {
// construction with given type // construction with given type
JSON j(JSON::value_type::array); json j(json::value_type::array);
CHECK(j.type() == JSON::value_type::array); CHECK(j.type() == json::value_type::array);
// const object // const object
const JSON j_const (j); const json j_const (j);
// string representation of default value // string representation of default value
CHECK(j.toString() == "[]"); CHECK(j.toString() == "[]");
...@@ -26,30 +26,30 @@ TEST_CASE("array") ...@@ -26,30 +26,30 @@ TEST_CASE("array")
CHECK(j.empty() == true); CHECK(j.empty() == true);
// implicit conversions // implicit conversions
CHECK_NOTHROW(JSON::array_t v = j); CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error); CHECK_THROWS_AS(json::object_t v = j, std::logic_error);
CHECK_THROWS_AS(std::string v = j, std::logic_error); CHECK_THROWS_AS(std::string v = j, std::logic_error);
CHECK_THROWS_AS(bool v = j, std::logic_error); CHECK_THROWS_AS(bool v = j, std::logic_error);
CHECK_THROWS_AS(int v = j, std::logic_error); CHECK_THROWS_AS(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error); CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions // explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>()); CHECK_NOTHROW(auto v = j.get<json::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<json::object_t>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<double>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<double>(), std::logic_error);
// transparent usage // transparent usage
auto id = [](JSON::array_t v) auto id = [](json::array_t v)
{ {
return v; return v;
}; };
CHECK(id(j) == j.get<JSON::array_t>()); CHECK(id(j) == j.get<json::array_t>());
// copy constructor // copy constructor
JSON k(j); json k(j);
CHECK(k == j); CHECK(k == j);
// copy assignment // copy assignment
...@@ -57,49 +57,49 @@ TEST_CASE("array") ...@@ -57,49 +57,49 @@ TEST_CASE("array")
CHECK(k == j); CHECK(k == j);
// move constructor // move constructor
JSON l = std::move(k); json l = std::move(k);
CHECK(l == j); CHECK(l == j);
} }
SECTION("Create from value") SECTION("Create from value")
{ {
JSON::array_t v1 = {"string", 1, 1.0, false, nullptr}; json::array_t v1 = {"string", 1, 1.0, false, nullptr};
JSON j1 = v1; json j1 = v1;
CHECK(j1.get<JSON::array_t>() == v1); CHECK(j1.get<json::array_t>() == v1);
JSON j2 = {"string", 1, 1.0, false, nullptr}; json j2 = {"string", 1, 1.0, false, nullptr};
JSON::array_t v2 = j2; json::array_t v2 = j2;
CHECK(j2.get<JSON::array_t>() == v1); CHECK(j2.get<json::array_t>() == v1);
CHECK(j2.get<JSON::array_t>() == v2); CHECK(j2.get<json::array_t>() == v2);
// special tests to make sure construction from initializer list works // special tests to make sure construction from initializer list works
// case 1: there is an element that is not an array // case 1: there is an element that is not an array
JSON j3 = { {"foo", "bar"}, 3 }; json j3 = { {"foo", "bar"}, 3 };
CHECK(j3.type() == JSON::value_type::array); CHECK(j3.type() == json::value_type::array);
// case 2: there is an element with more than two elements // case 2: there is an element with more than two elements
JSON j4 = { {"foo", "bar"}, {"one", "two", "three"} }; json j4 = { {"foo", "bar"}, {"one", "two", "three"} };
CHECK(j4.type() == JSON::value_type::array); CHECK(j4.type() == json::value_type::array);
// case 3: there is an element whose first element is not a string // case 3: there is an element whose first element is not a string
JSON j5 = { {"foo", "bar"}, {true, "baz"} }; json j5 = { {"foo", "bar"}, {true, "baz"} };
CHECK(j5.type() == JSON::value_type::array); CHECK(j5.type() == json::value_type::array);
// check if nested arrays work and are recognized as arrays // check if nested arrays work and are recognized as arrays
JSON j6 = { {{"foo", "bar"}} }; json j6 = { {{"foo", "bar"}} };
CHECK(j6.type() == JSON::value_type::array); CHECK(j6.type() == json::value_type::array);
CHECK(j6.size() == 1); CHECK(j6.size() == 1);
CHECK(j6[0].type() == JSON::value_type::object); CHECK(j6[0].type() == json::value_type::object);
// move constructor // move constructor
JSON j7(std::move(v1)); json j7(std::move(v1));
CHECK(j7 == j1); CHECK(j7 == j1);
} }
SECTION("Array operators") SECTION("Array operators")
{ {
JSON j = {0, 1, 2, 3, 4, 5, 6}; json j = {0, 1, 2, 3, 4, 5, 6};
// read // read
const int v1 = j[3]; const int v1 = j[3];
...@@ -137,15 +137,15 @@ TEST_CASE("array") ...@@ -137,15 +137,15 @@ TEST_CASE("array")
CHECK (j.size() == 21); CHECK (j.size() == 21);
// implicit transformation into an array // implicit transformation into an array
JSON empty1, empty2; json empty1, empty2;
empty1 += "foo"; empty1 += "foo";
empty2.push_back("foo"); empty2.push_back("foo");
CHECK(empty1.type() == JSON::value_type::array); CHECK(empty1.type() == json::value_type::array);
CHECK(empty2.type() == JSON::value_type::array); CHECK(empty2.type() == json::value_type::array);
CHECK(empty1 == empty2); CHECK(empty1 == empty2);
// exceptions // exceptions
JSON nonarray = 1; json nonarray = 1;
CHECK_THROWS_AS(nonarray.at(0), std::domain_error); CHECK_THROWS_AS(nonarray.at(0), std::domain_error);
CHECK_THROWS_AS(const int i = nonarray[0], std::domain_error); CHECK_THROWS_AS(const int i = nonarray[0], std::domain_error);
CHECK_NOTHROW(j[21]); CHECK_NOTHROW(j[21]);
...@@ -156,23 +156,23 @@ TEST_CASE("array") ...@@ -156,23 +156,23 @@ TEST_CASE("array")
CHECK_THROWS_AS(j.at(21) = 5, std::out_of_range); CHECK_THROWS_AS(j.at(21) = 5, std::out_of_range);
CHECK_THROWS_AS(nonarray += 2, std::runtime_error); CHECK_THROWS_AS(nonarray += 2, std::runtime_error);
const JSON nonarray_const = nonarray; const json nonarray_const = nonarray;
const JSON j_const = j; const json j_const = j;
CHECK_THROWS_AS(nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(nonarray_const.at(0), std::domain_error);
CHECK_THROWS_AS(const int i = nonarray_const[0], std::domain_error); CHECK_THROWS_AS(const int i = nonarray_const[0], std::domain_error);
CHECK_NOTHROW(j_const[21]); CHECK_NOTHROW(j_const[21]);
CHECK_THROWS_AS(const int i = j.at(21), std::out_of_range); CHECK_THROWS_AS(const int i = j.at(21), std::out_of_range);
{ {
JSON nonarray2 = JSON(1); json nonarray2 = json(1);
JSON nonarray3 = JSON(2); json nonarray3 = json(2);
JSON empty3 = JSON(); json empty3 = json();
CHECK_THROWS_AS(nonarray2.push_back(nonarray3), std::runtime_error); CHECK_THROWS_AS(nonarray2.push_back(nonarray3), std::runtime_error);
CHECK_NOTHROW(empty3.push_back(nonarray3)); CHECK_NOTHROW(empty3.push_back(nonarray3));
CHECK(empty3.type() == JSON::value_type::array); CHECK(empty3.type() == json::value_type::array);
} }
const JSON k = j; const json k = j;
CHECK_NOTHROW(k[21]); CHECK_NOTHROW(k[21]);
CHECK_THROWS_AS(const int i = k.at(21), std::out_of_range); CHECK_THROWS_AS(const int i = k.at(21), std::out_of_range);
...@@ -181,7 +181,7 @@ TEST_CASE("array") ...@@ -181,7 +181,7 @@ TEST_CASE("array")
CHECK (j.size() == 24); CHECK (j.size() == 24);
// clear() // clear()
JSON j7 = {0, 1, 2, 3, 4, 5, 6};; json j7 = {0, 1, 2, 3, 4, 5, 6};;
CHECK(j7.size() == 7); CHECK(j7.size() == 7);
j7.clear(); j7.clear();
CHECK(j7.size() == 0); CHECK(j7.size() == 0);
...@@ -190,12 +190,12 @@ TEST_CASE("array") ...@@ -190,12 +190,12 @@ TEST_CASE("array")
SECTION("Iterators") SECTION("Iterators")
{ {
std::vector<int> vec = {0, 1, 2, 3, 4, 5, 6}; std::vector<int> vec = {0, 1, 2, 3, 4, 5, 6};
JSON j1 = {0, 1, 2, 3, 4, 5, 6}; json j1 = {0, 1, 2, 3, 4, 5, 6};
const JSON j2 = {0, 1, 2, 3, 4, 5, 6}; const json j2 = {0, 1, 2, 3, 4, 5, 6};
{ {
// const_iterator // const_iterator
for (JSON::const_iterator cit = j1.begin(); cit != j1.end(); ++cit) for (json::const_iterator cit = j1.begin(); cit != j1.end(); ++cit)
{ {
int v = *cit; int v = *cit;
CHECK(v == vec[static_cast<size_t>(v)]); CHECK(v == vec[static_cast<size_t>(v)]);
...@@ -208,7 +208,7 @@ TEST_CASE("array") ...@@ -208,7 +208,7 @@ TEST_CASE("array")
} }
{ {
// const_iterator with cbegin/cend // const_iterator with cbegin/cend
for (JSON::const_iterator cit = j1.cbegin(); cit != j1.cend(); ++cit) for (json::const_iterator cit = j1.cbegin(); cit != j1.cend(); ++cit)
{ {
int v = *cit; int v = *cit;
CHECK(v == vec[static_cast<size_t>(v)]); CHECK(v == vec[static_cast<size_t>(v)]);
...@@ -231,7 +231,7 @@ TEST_CASE("array") ...@@ -231,7 +231,7 @@ TEST_CASE("array")
{ {
// iterator // iterator
for (JSON::iterator cit = j1.begin(); cit != j1.end(); ++cit) for (json::iterator cit = j1.begin(); cit != j1.end(); ++cit)
{ {
int v_old = *cit; int v_old = *cit;
*cit = cit->get<int>() * 2; *cit = cit->get<int>() * 2;
...@@ -247,7 +247,7 @@ TEST_CASE("array") ...@@ -247,7 +247,7 @@ TEST_CASE("array")
{ {
// const_iterator (on const object) // const_iterator (on const object)
for (JSON::const_iterator cit = j2.begin(); cit != j2.end(); ++cit) for (json::const_iterator cit = j2.begin(); cit != j2.end(); ++cit)
{ {
int v = *cit; int v = *cit;
CHECK(v == vec[static_cast<size_t>(v)]); CHECK(v == vec[static_cast<size_t>(v)]);
...@@ -261,7 +261,7 @@ TEST_CASE("array") ...@@ -261,7 +261,7 @@ TEST_CASE("array")
{ {
// const_iterator with cbegin/cend (on const object) // const_iterator with cbegin/cend (on const object)
for (JSON::const_iterator cit = j2.cbegin(); cit != j2.cend(); ++cit) for (json::const_iterator cit = j2.cbegin(); cit != j2.cend(); ++cit)
{ {
int v = *cit; int v = *cit;
CHECK(v == vec[static_cast<size_t>(v)]); CHECK(v == vec[static_cast<size_t>(v)]);
...@@ -286,8 +286,8 @@ TEST_CASE("array") ...@@ -286,8 +286,8 @@ TEST_CASE("array")
// edge case: This should be an array with two elements which are in // edge case: This should be an array with two elements which are in
// turn arrays with two strings. However, this is treated like the // turn arrays with two strings. However, this is treated like the
// initializer list of an object. // initializer list of an object.
JSON j_should_be_an_array = { {"foo", "bar"}, {"baz", "bat"} }; json j_should_be_an_array = { {"foo", "bar"}, {"baz", "bat"} };
CHECK(j_should_be_an_array.type() == JSON::value_type::object); CHECK(j_should_be_an_array.type() == json::value_type::object);
} }
} }
...@@ -296,11 +296,11 @@ TEST_CASE("object") ...@@ -296,11 +296,11 @@ TEST_CASE("object")
SECTION("Basics") SECTION("Basics")
{ {
// construction with given type // construction with given type
JSON j(JSON::value_type::object); json j(json::value_type::object);
CHECK(j.type() == JSON::value_type::object); CHECK(j.type() == json::value_type::object);
// const object // const object
const JSON j_const = j; const json j_const = j;
// string representation of default value // string representation of default value
CHECK(j.toString() == "{}"); CHECK(j.toString() == "{}");
...@@ -314,30 +314,30 @@ TEST_CASE("object") ...@@ -314,30 +314,30 @@ TEST_CASE("object")
CHECK(j.empty() == true); CHECK(j.empty() == true);
// implicit conversions // implicit conversions
CHECK_THROWS_AS(JSON::array_t v = j, std::logic_error); CHECK_THROWS_AS(json::array_t v = j, std::logic_error);
CHECK_NOTHROW(JSON::object_t v = j); CHECK_NOTHROW(json::object_t v = j);
CHECK_THROWS_AS(std::string v = j, std::logic_error); CHECK_THROWS_AS(std::string v = j, std::logic_error);
CHECK_THROWS_AS(bool v = j, std::logic_error); CHECK_THROWS_AS(bool v = j, std::logic_error);
CHECK_THROWS_AS(int v = j, std::logic_error); CHECK_THROWS_AS(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error); CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions // explicit conversions
CHECK_THROWS_AS(auto v = j.get<JSON::array_t>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<json::array_t>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<JSON::object_t>()); CHECK_NOTHROW(auto v = j.get<json::object_t>());
CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<double>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<double>(), std::logic_error);
// transparent usage // transparent usage
auto id = [](JSON::object_t v) auto id = [](json::object_t v)
{ {
return v; return v;
}; };
CHECK(id(j) == j.get<JSON::object_t>()); CHECK(id(j) == j.get<json::object_t>());
// copy constructor // copy constructor
JSON k(j); json k(j);
CHECK(k == j); CHECK(k == j);
// copy assignment // copy assignment
...@@ -345,34 +345,34 @@ TEST_CASE("object") ...@@ -345,34 +345,34 @@ TEST_CASE("object")
CHECK(k == j); CHECK(k == j);
// move constructor // move constructor
JSON l = std::move(k); json l = std::move(k);
CHECK(l == j); CHECK(l == j);
} }
SECTION("Create from value") SECTION("Create from value")
{ {
JSON::object_t v1 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} }; json::object_t v1 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} };
JSON j1 = v1; json j1 = v1;
CHECK(j1.get<JSON::object_t>() == v1); CHECK(j1.get<json::object_t>() == v1);
JSON j2 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} }; json j2 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} };
JSON::object_t v2 = j2; json::object_t v2 = j2;
CHECK(j2.get<JSON::object_t>() == v1); CHECK(j2.get<json::object_t>() == v1);
CHECK(j2.get<JSON::object_t>() == v2); CHECK(j2.get<json::object_t>() == v2);
// check if multiple keys are ignored // check if multiple keys are ignored
JSON j3 = { {"key", "value"}, {"key", 1} }; json j3 = { {"key", "value"}, {"key", 1} };
CHECK(j3.size() == 1); CHECK(j3.size() == 1);
// move constructor // move constructor
JSON j7(std::move(v1)); json j7(std::move(v1));
CHECK(j7 == j1); CHECK(j7 == j1);
} }
SECTION("Object operators") SECTION("Object operators")
{ {
JSON j = {{"k0", "v0"}, {"k1", nullptr}, {"k2", 42}, {"k3", 3.141}, {"k4", true}}; json j = {{"k0", "v0"}, {"k1", nullptr}, {"k2", 42}, {"k3", 3.141}, {"k4", true}};
const JSON k = j; const json k = j;
// read // read
{ {
...@@ -426,12 +426,12 @@ TEST_CASE("object") ...@@ -426,12 +426,12 @@ TEST_CASE("object")
CHECK(j.find("k0") != j.end()); CHECK(j.find("k0") != j.end());
CHECK(j.find("v0") == j.end()); CHECK(j.find("v0") == j.end());
CHECK(j.find(std::string("v0")) == j.end()); CHECK(j.find(std::string("v0")) == j.end());
JSON::const_iterator i1 = j.find("k0"); json::const_iterator i1 = j.find("k0");
JSON::iterator i2 = j.find("k0"); json::iterator i2 = j.find("k0");
CHECK(k.find("k0") != k.end()); CHECK(k.find("k0") != k.end());
CHECK(k.find("v0") == k.end()); CHECK(k.find("v0") == k.end());
CHECK(k.find(std::string("v0")) == k.end()); CHECK(k.find(std::string("v0")) == k.end());
JSON::const_iterator i22 = k.find("k0"); json::const_iterator i22 = k.find("k0");
// at // at
CHECK_THROWS_AS(j.at("foo"), std::out_of_range); CHECK_THROWS_AS(j.at("foo"), std::out_of_range);
...@@ -441,8 +441,8 @@ TEST_CASE("object") ...@@ -441,8 +441,8 @@ TEST_CASE("object")
CHECK_NOTHROW(j.at(std::string("k0"))); CHECK_NOTHROW(j.at(std::string("k0")));
CHECK_NOTHROW(k.at(std::string("k0"))); CHECK_NOTHROW(k.at(std::string("k0")));
{ {
JSON noobject = 1; json noobject = 1;
const JSON noobject_const = noobject; const json noobject_const = noobject;
CHECK_THROWS_AS(noobject.at("foo"), std::domain_error); CHECK_THROWS_AS(noobject.at("foo"), std::domain_error);
CHECK_THROWS_AS(noobject.at(std::string("foo")), std::domain_error); CHECK_THROWS_AS(noobject.at(std::string("foo")), std::domain_error);
CHECK_THROWS_AS(noobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(noobject_const.at("foo"), std::domain_error);
...@@ -453,33 +453,33 @@ TEST_CASE("object") ...@@ -453,33 +453,33 @@ TEST_CASE("object")
} }
// add pair // add pair
j.push_back(JSON::object_t::value_type {"int_key", 42}); j.push_back(json::object_t::value_type {"int_key", 42});
CHECK(j["int_key"].get<int>() == 42); CHECK(j["int_key"].get<int>() == 42);
j += JSON::object_t::value_type {"int_key2", 23}; j += json::object_t::value_type {"int_key2", 23};
CHECK(j["int_key2"].get<int>() == 23); CHECK(j["int_key2"].get<int>() == 23);
{ {
// make sure null objects are transformed // make sure null objects are transformed
JSON je; json je;
CHECK_NOTHROW(je.push_back(JSON::object_t::value_type {"int_key", 42})); CHECK_NOTHROW(je.push_back(json::object_t::value_type {"int_key", 42}));
CHECK(je["int_key"].get<int>() == 42); CHECK(je["int_key"].get<int>() == 42);
} }
{ {
// make sure null objects are transformed // make sure null objects are transformed
JSON je; json je;
CHECK_NOTHROW((je += JSON::object_t::value_type {"int_key", 42})); CHECK_NOTHROW((je += json::object_t::value_type {"int_key", 42}));
CHECK(je["int_key"].get<int>() == 42); CHECK(je["int_key"].get<int>() == 42);
} }
// add initializer list (of pairs) // add initializer list (of pairs)
{ {
JSON je; json je;
je.push_back({ {"one", 1}, {"two", false}, {"three", {1, 2, 3}} }); je.push_back({ {"one", 1}, {"two", false}, {"three", {1, 2, 3}} });
CHECK(je["one"].get<int>() == 1); CHECK(je["one"].get<int>() == 1);
CHECK(je["two"].get<bool>() == false); CHECK(je["two"].get<bool>() == false);
CHECK(je["three"].size() == 3); CHECK(je["three"].size() == 3);
} }
{ {
JSON je; json je;
je += { {"one", 1}, {"two", false}, {"three", {1, 2, 3}} }; je += { {"one", 1}, {"two", false}, {"three", {1, 2, 3}} };
CHECK(je["one"].get<int>() == 1); CHECK(je["one"].get<int>() == 1);
CHECK(je["two"].get<bool>() == false); CHECK(je["two"].get<bool>() == false);
...@@ -493,38 +493,38 @@ TEST_CASE("object") ...@@ -493,38 +493,38 @@ TEST_CASE("object")
CHECK(i2.value() == j["k0"]); CHECK(i2.value() == j["k0"]);
// key/value for uninitialzed iterator // key/value for uninitialzed iterator
JSON::const_iterator i3; json::const_iterator i3;
JSON::iterator i4; json::iterator i4;
CHECK_THROWS_AS(i3.key(), std::out_of_range); CHECK_THROWS_AS(i3.key(), std::out_of_range);
CHECK_THROWS_AS(i3.value(), std::out_of_range); CHECK_THROWS_AS(i3.value(), std::out_of_range);
CHECK_THROWS_AS(i4.key(), std::out_of_range); CHECK_THROWS_AS(i4.key(), std::out_of_range);
CHECK_THROWS_AS(i4.value(), std::out_of_range); CHECK_THROWS_AS(i4.value(), std::out_of_range);
// key/value for end-iterator // key/value for end-iterator
JSON::const_iterator i5 = j.find("v0"); json::const_iterator i5 = j.find("v0");
JSON::iterator i6 = j.find("v0"); json::iterator i6 = j.find("v0");
CHECK_THROWS_AS(i5.key(), std::out_of_range); CHECK_THROWS_AS(i5.key(), std::out_of_range);
CHECK_THROWS_AS(i5.value(), std::out_of_range); CHECK_THROWS_AS(i5.value(), std::out_of_range);
CHECK_THROWS_AS(i6.key(), std::out_of_range); CHECK_THROWS_AS(i6.key(), std::out_of_range);
CHECK_THROWS_AS(i6.value(), std::out_of_range); CHECK_THROWS_AS(i6.value(), std::out_of_range);
// implicit transformation into an object // implicit transformation into an object
JSON empty; json empty;
empty["foo"] = "bar"; empty["foo"] = "bar";
CHECK(empty.type() == JSON::value_type::object); CHECK(empty.type() == json::value_type::object);
CHECK(empty["foo"] == "bar"); CHECK(empty["foo"] == "bar");
// exceptions // exceptions
JSON nonarray = 1; json nonarray = 1;
CHECK_THROWS_AS(const int i = nonarray["v1"], std::domain_error); CHECK_THROWS_AS(const int i = nonarray["v1"], std::domain_error);
CHECK_THROWS_AS(nonarray["v1"] = 10, std::domain_error); CHECK_THROWS_AS(nonarray["v1"] = 10, std::domain_error);
{ {
const JSON c = {{"foo", "bar"}}; const json c = {{"foo", "bar"}};
CHECK_THROWS_AS(c[std::string("baz")], std::out_of_range); CHECK_THROWS_AS(c[std::string("baz")], std::out_of_range);
} }
// clear() // clear()
JSON j7 = {{"k0", 0}, {"k1", 1}, {"k2", 2}, {"k3", 3}}; json j7 = {{"k0", 0}, {"k1", 1}, {"k2", 2}, {"k3", 3}};
CHECK(j7.size() == 4); CHECK(j7.size() == 4);
j7.clear(); j7.clear();
CHECK(j7.size() == 0); CHECK(j7.size() == 0);
...@@ -532,11 +532,11 @@ TEST_CASE("object") ...@@ -532,11 +532,11 @@ TEST_CASE("object")
SECTION("Iterators") SECTION("Iterators")
{ {
JSON j1 = {{"k0", 0}, {"k1", 1}, {"k2", 2}, {"k3", 3}}; json j1 = {{"k0", 0}, {"k1", 1}, {"k2", 2}, {"k3", 3}};
const JSON j2 = {{"k0", 0}, {"k1", 1}, {"k2", 2}, {"k3", 3}}; const json j2 = {{"k0", 0}, {"k1", 1}, {"k2", 2}, {"k3", 3}};
// iterator // iterator
for (JSON::iterator it = j1.begin(); it != j1.end(); ++it) for (json::iterator it = j1.begin(); it != j1.end(); ++it)
{ {
switch (static_cast<int>(it.value())) switch (static_cast<int>(it.value()))
{ {
...@@ -556,8 +556,8 @@ TEST_CASE("object") ...@@ -556,8 +556,8 @@ TEST_CASE("object")
CHECK(false); CHECK(false);
} }
CHECK((*it).type() == JSON::value_type::number); CHECK((*it).type() == json::value_type::number);
CHECK(it->type() == JSON::value_type::number); CHECK(it->type() == json::value_type::number);
} }
// range-based for // range-based for
...@@ -567,7 +567,7 @@ TEST_CASE("object") ...@@ -567,7 +567,7 @@ TEST_CASE("object")
} }
// const_iterator // const_iterator
for (JSON::const_iterator it = j1.begin(); it != j1.end(); ++it) for (json::const_iterator it = j1.begin(); it != j1.end(); ++it)
{ {
switch (static_cast<int>(it.value())) switch (static_cast<int>(it.value()))
{ {
...@@ -587,12 +587,12 @@ TEST_CASE("object") ...@@ -587,12 +587,12 @@ TEST_CASE("object")
CHECK(false); CHECK(false);
} }
CHECK((*it).type() == JSON::value_type::number); CHECK((*it).type() == json::value_type::number);
CHECK(it->type() == JSON::value_type::number); CHECK(it->type() == json::value_type::number);
} }
// const_iterator using cbegin/cend // const_iterator using cbegin/cend
for (JSON::const_iterator it = j1.cbegin(); it != j1.cend(); ++it) for (json::const_iterator it = j1.cbegin(); it != j1.cend(); ++it)
{ {
switch (static_cast<int>(it.value())) switch (static_cast<int>(it.value()))
{ {
...@@ -612,12 +612,12 @@ TEST_CASE("object") ...@@ -612,12 +612,12 @@ TEST_CASE("object")
CHECK(false); CHECK(false);
} }
CHECK((*it).type() == JSON::value_type::number); CHECK((*it).type() == json::value_type::number);
CHECK(it->type() == JSON::value_type::number); CHECK(it->type() == json::value_type::number);
} }
// const_iterator (on const object) // const_iterator (on const object)
for (JSON::const_iterator it = j2.begin(); it != j2.end(); ++it) for (json::const_iterator it = j2.begin(); it != j2.end(); ++it)
{ {
switch (static_cast<int>(it.value())) switch (static_cast<int>(it.value()))
{ {
...@@ -637,12 +637,12 @@ TEST_CASE("object") ...@@ -637,12 +637,12 @@ TEST_CASE("object")
CHECK(false); CHECK(false);
} }
CHECK((*it).type() == JSON::value_type::number); CHECK((*it).type() == json::value_type::number);
CHECK(it->type() == JSON::value_type::number); CHECK(it->type() == json::value_type::number);
} }
// const_iterator using cbegin/cend (on const object) // const_iterator using cbegin/cend (on const object)
for (JSON::const_iterator it = j2.cbegin(); it != j2.cend(); ++it) for (json::const_iterator it = j2.cbegin(); it != j2.cend(); ++it)
{ {
switch (static_cast<int>(it.value())) switch (static_cast<int>(it.value()))
{ {
...@@ -662,8 +662,8 @@ TEST_CASE("object") ...@@ -662,8 +662,8 @@ TEST_CASE("object")
CHECK(false); CHECK(false);
} }
CHECK((*it).type() == JSON::value_type::number); CHECK((*it).type() == json::value_type::number);
CHECK(it->type() == JSON::value_type::number); CHECK(it->type() == json::value_type::number);
} }
// range-based for (on const object) // range-based for (on const object)
...@@ -679,8 +679,8 @@ TEST_CASE("null") ...@@ -679,8 +679,8 @@ TEST_CASE("null")
SECTION("Basics") SECTION("Basics")
{ {
// construction with given type // construction with given type
JSON j; json j;
CHECK(j.type() == JSON::value_type::null); CHECK(j.type() == json::value_type::null);
// string representation of default value // string representation of default value
CHECK(j.toString() == "null"); CHECK(j.toString() == "null");
...@@ -694,23 +694,23 @@ TEST_CASE("null") ...@@ -694,23 +694,23 @@ TEST_CASE("null")
CHECK(j.empty() == true); CHECK(j.empty() == true);
// implicit conversions // implicit conversions
CHECK_NOTHROW(JSON::array_t v = j); CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error); CHECK_THROWS_AS(json::object_t v = j, std::logic_error);
CHECK_THROWS_AS(std::string v = j, std::logic_error); CHECK_THROWS_AS(std::string v = j, std::logic_error);
CHECK_THROWS_AS(bool v = j, std::logic_error); CHECK_THROWS_AS(bool v = j, std::logic_error);
CHECK_THROWS_AS(int v = j, std::logic_error); CHECK_THROWS_AS(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error); CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions // explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>()); CHECK_NOTHROW(auto v = j.get<json::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<json::object_t>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<double>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<double>(), std::logic_error);
// copy constructor // copy constructor
JSON k(j); json k(j);
CHECK(k == j); CHECK(k == j);
// copy assignment // copy assignment
...@@ -718,22 +718,22 @@ TEST_CASE("null") ...@@ -718,22 +718,22 @@ TEST_CASE("null")
CHECK(k == j); CHECK(k == j);
// move constructor // move constructor
JSON l = std::move(k); json l = std::move(k);
CHECK(l == j); CHECK(l == j);
} }
SECTION("Create from value") SECTION("Create from value")
{ {
JSON j1 = nullptr; json j1 = nullptr;
CHECK(j1.type() == JSON::value_type::null); CHECK(j1.type() == json::value_type::null);
} }
SECTION("Operators") SECTION("Operators")
{ {
// clear() // clear()
JSON j1 = nullptr; json j1 = nullptr;
j1.clear(); j1.clear();
CHECK(j1 == JSON(nullptr)); CHECK(j1 == json(nullptr));
} }
} }
...@@ -742,11 +742,11 @@ TEST_CASE("string") ...@@ -742,11 +742,11 @@ TEST_CASE("string")
SECTION("Basics") SECTION("Basics")
{ {
// construction with given type // construction with given type
JSON j(JSON::value_type::string); json j(json::value_type::string);
CHECK(j.type() == JSON::value_type::string); CHECK(j.type() == json::value_type::string);
// const object // const object
const JSON j_const = j; const json j_const = j;
// iterators // iterators
CHECK(j.begin() != j.end()); CHECK(j.begin() != j.end());
...@@ -760,16 +760,16 @@ TEST_CASE("string") ...@@ -760,16 +760,16 @@ TEST_CASE("string")
CHECK(j.empty() == false); CHECK(j.empty() == false);
// implicit conversions // implicit conversions
CHECK_NOTHROW(JSON::array_t v = j); CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error); CHECK_THROWS_AS(json::object_t v = j, std::logic_error);
CHECK_NOTHROW(std::string v = j); CHECK_NOTHROW(std::string v = j);
CHECK_THROWS_AS(bool v = j, std::logic_error); CHECK_THROWS_AS(bool v = j, std::logic_error);
CHECK_THROWS_AS(int v = j, std::logic_error); CHECK_THROWS_AS(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error); CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions // explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>()); CHECK_NOTHROW(auto v = j.get<json::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<json::object_t>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<std::string>()); CHECK_NOTHROW(auto v = j.get<std::string>());
CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error);
...@@ -783,7 +783,7 @@ TEST_CASE("string") ...@@ -783,7 +783,7 @@ TEST_CASE("string")
CHECK(id(j) == j.get<std::string>()); CHECK(id(j) == j.get<std::string>());
// copy constructor // copy constructor
JSON k(j); json k(j);
CHECK(k == j); CHECK(k == j);
// copy assignment // copy assignment
...@@ -791,28 +791,28 @@ TEST_CASE("string") ...@@ -791,28 +791,28 @@ TEST_CASE("string")
CHECK(k == j); CHECK(k == j);
// move constructor // move constructor
JSON l = std::move(k); json l = std::move(k);
CHECK(l == j); CHECK(l == j);
} }
SECTION("Create from value") SECTION("Create from value")
{ {
JSON j1 = std::string("Hello, world"); json j1 = std::string("Hello, world");
std::string v1 = j1; std::string v1 = j1;
CHECK(j1.get<std::string>() == v1); CHECK(j1.get<std::string>() == v1);
JSON j2 = "Hello, world"; json j2 = "Hello, world";
CHECK(j2.get<std::string>() == "Hello, world"); CHECK(j2.get<std::string>() == "Hello, world");
std::string v3 = "Hello, world"; std::string v3 = "Hello, world";
JSON j3 = std::move(v3); json j3 = std::move(v3);
CHECK(j3.get<std::string>() == "Hello, world"); CHECK(j3.get<std::string>() == "Hello, world");
} }
SECTION("Operators") SECTION("Operators")
{ {
// clear() // clear()
JSON j1 = std::string("Hello, world"); json j1 = std::string("Hello, world");
CHECK(j1.get<std::string>() == "Hello, world"); CHECK(j1.get<std::string>() == "Hello, world");
j1.clear(); j1.clear();
CHECK(j1.get<std::string>() == ""); CHECK(j1.get<std::string>() == "");
...@@ -824,11 +824,11 @@ TEST_CASE("boolean") ...@@ -824,11 +824,11 @@ TEST_CASE("boolean")
SECTION("Basics") SECTION("Basics")
{ {
// construction with given type // construction with given type
JSON j(JSON::value_type::boolean); json j(json::value_type::boolean);
CHECK(j.type() == JSON::value_type::boolean); CHECK(j.type() == json::value_type::boolean);
// const object // const object
const JSON j_const = j; const json j_const = j;
// iterators // iterators
CHECK(j.begin() != j.end()); CHECK(j.begin() != j.end());
...@@ -842,16 +842,16 @@ TEST_CASE("boolean") ...@@ -842,16 +842,16 @@ TEST_CASE("boolean")
CHECK(j.empty() == false); CHECK(j.empty() == false);
// implicit conversions // implicit conversions
CHECK_NOTHROW(JSON::array_t v = j); CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error); CHECK_THROWS_AS(json::object_t v = j, std::logic_error);
CHECK_THROWS_AS(std::string v = j, std::logic_error); CHECK_THROWS_AS(std::string v = j, std::logic_error);
CHECK_NOTHROW(bool v = j); CHECK_NOTHROW(bool v = j);
CHECK_THROWS_AS(int v = j, std::logic_error); CHECK_THROWS_AS(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error); CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions // explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>()); CHECK_NOTHROW(auto v = j.get<json::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<json::object_t>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<bool>()); CHECK_NOTHROW(auto v = j.get<bool>());
CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error);
...@@ -865,7 +865,7 @@ TEST_CASE("boolean") ...@@ -865,7 +865,7 @@ TEST_CASE("boolean")
CHECK(id(j) == j.get<bool>()); CHECK(id(j) == j.get<bool>());
// copy constructor // copy constructor
JSON k(j); json k(j);
CHECK(k == j); CHECK(k == j);
// copy assignment // copy assignment
...@@ -873,17 +873,17 @@ TEST_CASE("boolean") ...@@ -873,17 +873,17 @@ TEST_CASE("boolean")
CHECK(k == j); CHECK(k == j);
// move constructor // move constructor
JSON l = std::move(k); json l = std::move(k);
CHECK(l == j); CHECK(l == j);
} }
SECTION("Create from value") SECTION("Create from value")
{ {
JSON j1 = true; json j1 = true;
bool v1 = j1; bool v1 = j1;
CHECK(j1.get<bool>() == v1); CHECK(j1.get<bool>() == v1);
JSON j2 = false; json j2 = false;
bool v2 = j2; bool v2 = j2;
CHECK(j2.get<bool>() == v2); CHECK(j2.get<bool>() == v2);
} }
...@@ -891,7 +891,7 @@ TEST_CASE("boolean") ...@@ -891,7 +891,7 @@ TEST_CASE("boolean")
SECTION("Operators") SECTION("Operators")
{ {
// clear() // clear()
JSON j1 = true; json j1 = true;
CHECK(j1.get<bool>() == true); CHECK(j1.get<bool>() == true);
j1.clear(); j1.clear();
CHECK(j1.get<bool>() == false); CHECK(j1.get<bool>() == false);
...@@ -903,11 +903,11 @@ TEST_CASE("number (int)") ...@@ -903,11 +903,11 @@ TEST_CASE("number (int)")
SECTION("Basics") SECTION("Basics")
{ {
// construction with given type // construction with given type
JSON j(JSON::value_type::number); json j(json::value_type::number);
CHECK(j.type() == JSON::value_type::number); CHECK(j.type() == json::value_type::number);
// const object // const object
const JSON j_const = j; const json j_const = j;
// iterators // iterators
CHECK(j.begin() != j.end()); CHECK(j.begin() != j.end());
...@@ -921,16 +921,16 @@ TEST_CASE("number (int)") ...@@ -921,16 +921,16 @@ TEST_CASE("number (int)")
CHECK(j.empty() == false); CHECK(j.empty() == false);
// implicit conversions // implicit conversions
CHECK_NOTHROW(JSON::array_t v = j); CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error); CHECK_THROWS_AS(json::object_t v = j, std::logic_error);
CHECK_THROWS_AS(std::string v = j, std::logic_error); CHECK_THROWS_AS(std::string v = j, std::logic_error);
CHECK_THROWS_AS(bool v = j, std::logic_error); CHECK_THROWS_AS(bool v = j, std::logic_error);
CHECK_NOTHROW(int v = j); CHECK_NOTHROW(int v = j);
CHECK_NOTHROW(double v = j); CHECK_NOTHROW(double v = j);
// explicit conversions // explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>()); CHECK_NOTHROW(auto v = j.get<json::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<json::object_t>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<int>()); CHECK_NOTHROW(auto v = j.get<int>());
...@@ -944,7 +944,7 @@ TEST_CASE("number (int)") ...@@ -944,7 +944,7 @@ TEST_CASE("number (int)")
CHECK(id(j) == j.get<int>()); CHECK(id(j) == j.get<int>());
// copy constructor // copy constructor
JSON k(j); json k(j);
CHECK(k == j); CHECK(k == j);
// copy assignment // copy assignment
...@@ -952,17 +952,17 @@ TEST_CASE("number (int)") ...@@ -952,17 +952,17 @@ TEST_CASE("number (int)")
CHECK(k == j); CHECK(k == j);
// move constructor // move constructor
JSON l = std::move(k); json l = std::move(k);
CHECK(l == j); CHECK(l == j);
} }
SECTION("Create from value") SECTION("Create from value")
{ {
JSON j1 = 23; json j1 = 23;
int v1 = j1; int v1 = j1;
CHECK(j1.get<int>() == v1); CHECK(j1.get<int>() == v1);
JSON j2 = 42; json j2 = 42;
int v2 = j2; int v2 = j2;
CHECK(j2.get<int>() == v2); CHECK(j2.get<int>() == v2);
} }
...@@ -970,7 +970,7 @@ TEST_CASE("number (int)") ...@@ -970,7 +970,7 @@ TEST_CASE("number (int)")
SECTION("Operators") SECTION("Operators")
{ {
// clear() // clear()
JSON j1 = 42; json j1 = 42;
CHECK(j1.get<int>() == 42); CHECK(j1.get<int>() == 42);
j1.clear(); j1.clear();
CHECK(j1.get<int>() == 0); CHECK(j1.get<int>() == 0);
...@@ -978,7 +978,7 @@ TEST_CASE("number (int)") ...@@ -978,7 +978,7 @@ TEST_CASE("number (int)")
// find() // find()
CHECK(j1.find("foo") == j1.end()); CHECK(j1.find("foo") == j1.end());
CHECK(j1.find(std::string("foo")) == j1.end()); CHECK(j1.find(std::string("foo")) == j1.end());
const JSON j2 = j1; const json j2 = j1;
CHECK(j2.find("foo") == j2.end()); CHECK(j2.find("foo") == j2.end());
CHECK(j2.find(std::string("foo")) == j2.end()); CHECK(j2.find(std::string("foo")) == j2.end());
} }
...@@ -989,11 +989,11 @@ TEST_CASE("number (float)") ...@@ -989,11 +989,11 @@ TEST_CASE("number (float)")
SECTION("Basics") SECTION("Basics")
{ {
// construction with given type // construction with given type
JSON j(JSON::value_type::number_float); json j(json::value_type::number_float);
CHECK(j.type() == JSON::value_type::number_float); CHECK(j.type() == json::value_type::number_float);
// const object // const object
const JSON j_const = j; const json j_const = j;
// iterators // iterators
CHECK(j.begin() != j.end()); CHECK(j.begin() != j.end());
...@@ -1007,16 +1007,16 @@ TEST_CASE("number (float)") ...@@ -1007,16 +1007,16 @@ TEST_CASE("number (float)")
CHECK(j.empty() == false); CHECK(j.empty() == false);
// implicit conversions // implicit conversions
CHECK_NOTHROW(JSON::array_t v = j); CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error); CHECK_THROWS_AS(json::object_t v = j, std::logic_error);
CHECK_THROWS_AS(std::string v = j, std::logic_error); CHECK_THROWS_AS(std::string v = j, std::logic_error);
CHECK_THROWS_AS(bool v = j, std::logic_error); CHECK_THROWS_AS(bool v = j, std::logic_error);
CHECK_NOTHROW(int v = j); CHECK_NOTHROW(int v = j);
CHECK_NOTHROW(double v = j); CHECK_NOTHROW(double v = j);
// explicit conversions // explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>()); CHECK_NOTHROW(auto v = j.get<json::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<json::object_t>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<std::string>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error); CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<int>()); CHECK_NOTHROW(auto v = j.get<int>());
...@@ -1030,7 +1030,7 @@ TEST_CASE("number (float)") ...@@ -1030,7 +1030,7 @@ TEST_CASE("number (float)")
CHECK(id(j) == j.get<double>()); CHECK(id(j) == j.get<double>());
// copy constructor // copy constructor
JSON k(j); json k(j);
CHECK(k == j); CHECK(k == j);
// copy assignment // copy assignment
...@@ -1038,17 +1038,17 @@ TEST_CASE("number (float)") ...@@ -1038,17 +1038,17 @@ TEST_CASE("number (float)")
CHECK(k == j); CHECK(k == j);
// move constructor // move constructor
JSON l = std::move(k); json l = std::move(k);
CHECK(l == j); CHECK(l == j);
} }
SECTION("Create from value") SECTION("Create from value")
{ {
JSON j1 = 3.1415926; json j1 = 3.1415926;
double v1 = j1; double v1 = j1;
CHECK(j1.get<double>() == v1); CHECK(j1.get<double>() == v1);
JSON j2 = 2.7182818; json j2 = 2.7182818;
double v2 = j2; double v2 = j2;
CHECK(j2.get<double>() == v2); CHECK(j2.get<double>() == v2);
} }
...@@ -1056,7 +1056,7 @@ TEST_CASE("number (float)") ...@@ -1056,7 +1056,7 @@ TEST_CASE("number (float)")
SECTION("Operators") SECTION("Operators")
{ {
// clear() // clear()
JSON j1 = 3.1415926; json j1 = 3.1415926;
CHECK(j1.get<double>() == 3.1415926); CHECK(j1.get<double>() == 3.1415926);
j1.clear(); j1.clear();
CHECK(j1.get<double>() == 0.0); CHECK(j1.get<double>() == 0.0);
...@@ -1065,37 +1065,37 @@ TEST_CASE("number (float)") ...@@ -1065,37 +1065,37 @@ TEST_CASE("number (float)")
TEST_CASE("Iterators") TEST_CASE("Iterators")
{ {
JSON j1 = {0, 1, 2, 3, 4}; json j1 = {0, 1, 2, 3, 4};
JSON j2 = {{"foo", "bar"}, {"baz", "bam"}}; json j2 = {{"foo", "bar"}, {"baz", "bam"}};
JSON j3 = true; json j3 = true;
JSON j4 = nullptr; json j4 = nullptr;
JSON j5 = 42; json j5 = 42;
JSON j6 = 23.42; json j6 = 23.42;
JSON j7 = "hello"; json j7 = "hello";
const JSON j1_const = {0, 1, 2, 3, 4}; const json j1_const = {0, 1, 2, 3, 4};
const JSON j2_const = {{"foo", "bar"}, {"baz", "bam"}}; const json j2_const = {{"foo", "bar"}, {"baz", "bam"}};
const JSON j3_const = true; const json j3_const = true;
const JSON j4_const = nullptr; const json j4_const = nullptr;
const JSON j5_const = 42; const json j5_const = 42;
const JSON j6_const = 23.42; const json j6_const = 23.42;
const JSON j7_const = "hello"; const json j7_const = "hello";
// operator * // operator *
CHECK(* j1.begin() == JSON(0)); CHECK(* j1.begin() == json(0));
CHECK(* j1_const.begin() == JSON(0)); CHECK(* j1_const.begin() == json(0));
CHECK(* j2.begin() != JSON()); CHECK(* j2.begin() != json());
CHECK(* j2_const.begin() != JSON()); CHECK(* j2_const.begin() != json());
CHECK(* j3.begin() == JSON(true)); CHECK(* j3.begin() == json(true));
CHECK(* j3_const.begin() == JSON(true)); CHECK(* j3_const.begin() == json(true));
CHECK(* j4.begin() == JSON()); CHECK(* j4.begin() == json());
CHECK(* j4_const.begin() == JSON()); CHECK(* j4_const.begin() == json());
CHECK(* j5.begin() == JSON(42)); CHECK(* j5.begin() == json(42));
CHECK(* j5_const.begin() == JSON(42)); CHECK(* j5_const.begin() == json(42));
CHECK(* j6.begin() == JSON(23.42)); CHECK(* j6.begin() == json(23.42));
CHECK(* j6_const.begin() == JSON(23.42)); CHECK(* j6_const.begin() == json(23.42));
CHECK(* j7.begin() == JSON("hello")); CHECK(* j7.begin() == json("hello"));
CHECK(* j7_const.begin() == JSON("hello")); CHECK(* j7_const.begin() == json("hello"));
CHECK_THROWS_AS(* j1.end(), std::runtime_error); CHECK_THROWS_AS(* j1.end(), std::runtime_error);
CHECK_THROWS_AS(* j1.cend(), std::runtime_error); CHECK_THROWS_AS(* j1.cend(), std::runtime_error);
...@@ -1128,35 +1128,35 @@ TEST_CASE("Iterators") ...@@ -1128,35 +1128,35 @@ TEST_CASE("Iterators")
CHECK_THROWS_AS(* j7_const.cend(), std::runtime_error); CHECK_THROWS_AS(* j7_const.cend(), std::runtime_error);
// operator -> // operator ->
CHECK(j1.begin()->type() == JSON::value_type::number); CHECK(j1.begin()->type() == json::value_type::number);
CHECK(j1.cbegin()->type() == JSON::value_type::number); CHECK(j1.cbegin()->type() == json::value_type::number);
CHECK(j2.begin()->type() == JSON::value_type::string); CHECK(j2.begin()->type() == json::value_type::string);
CHECK(j2.cbegin()->type() == JSON::value_type::string); CHECK(j2.cbegin()->type() == json::value_type::string);
CHECK(j3.begin()->type() == JSON::value_type::boolean); CHECK(j3.begin()->type() == json::value_type::boolean);
CHECK(j3.cbegin()->type() == JSON::value_type::boolean); CHECK(j3.cbegin()->type() == json::value_type::boolean);
CHECK(j4.begin()->type() == JSON::value_type::null); CHECK(j4.begin()->type() == json::value_type::null);
CHECK(j4.cbegin()->type() == JSON::value_type::null); CHECK(j4.cbegin()->type() == json::value_type::null);
CHECK(j5.begin()->type() == JSON::value_type::number); CHECK(j5.begin()->type() == json::value_type::number);
CHECK(j5.cbegin()->type() == JSON::value_type::number); CHECK(j5.cbegin()->type() == json::value_type::number);
CHECK(j6.begin()->type() == JSON::value_type::number_float); CHECK(j6.begin()->type() == json::value_type::number_float);
CHECK(j6.cbegin()->type() == JSON::value_type::number_float); CHECK(j6.cbegin()->type() == json::value_type::number_float);
CHECK(j7.begin()->type() == JSON::value_type::string); CHECK(j7.begin()->type() == json::value_type::string);
CHECK(j7.cbegin()->type() == JSON::value_type::string); CHECK(j7.cbegin()->type() == json::value_type::string);
CHECK(j1_const.begin()->type() == JSON::value_type::number); CHECK(j1_const.begin()->type() == json::value_type::number);
CHECK(j1_const.cbegin()->type() == JSON::value_type::number); CHECK(j1_const.cbegin()->type() == json::value_type::number);
CHECK(j2_const.begin()->type() == JSON::value_type::string); CHECK(j2_const.begin()->type() == json::value_type::string);
CHECK(j2_const.cbegin()->type() == JSON::value_type::string); CHECK(j2_const.cbegin()->type() == json::value_type::string);
CHECK(j3_const.begin()->type() == JSON::value_type::boolean); CHECK(j3_const.begin()->type() == json::value_type::boolean);
CHECK(j3_const.cbegin()->type() == JSON::value_type::boolean); CHECK(j3_const.cbegin()->type() == json::value_type::boolean);
CHECK(j4_const.begin()->type() == JSON::value_type::null); CHECK(j4_const.begin()->type() == json::value_type::null);
CHECK(j4_const.cbegin()->type() == JSON::value_type::null); CHECK(j4_const.cbegin()->type() == json::value_type::null);
CHECK(j5_const.begin()->type() == JSON::value_type::number); CHECK(j5_const.begin()->type() == json::value_type::number);
CHECK(j5_const.cbegin()->type() == JSON::value_type::number); CHECK(j5_const.cbegin()->type() == json::value_type::number);
CHECK(j6_const.begin()->type() == JSON::value_type::number_float); CHECK(j6_const.begin()->type() == json::value_type::number_float);
CHECK(j6_const.cbegin()->type() == JSON::value_type::number_float); CHECK(j6_const.cbegin()->type() == json::value_type::number_float);
CHECK(j7_const.begin()->type() == JSON::value_type::string); CHECK(j7_const.begin()->type() == json::value_type::string);
CHECK(j7_const.cbegin()->type() == JSON::value_type::string); CHECK(j7_const.cbegin()->type() == json::value_type::string);
CHECK_THROWS_AS(j1.end()->type(), std::runtime_error); CHECK_THROWS_AS(j1.end()->type(), std::runtime_error);
CHECK_THROWS_AS(j1.cend()->type(), std::runtime_error); CHECK_THROWS_AS(j1.cend()->type(), std::runtime_error);
...@@ -1189,35 +1189,35 @@ TEST_CASE("Iterators") ...@@ -1189,35 +1189,35 @@ TEST_CASE("Iterators")
CHECK_THROWS_AS(j7_const.cend()->type(), std::runtime_error); CHECK_THROWS_AS(j7_const.cend()->type(), std::runtime_error);
// value // value
CHECK(j1.begin().value().type() == JSON::value_type::number); CHECK(j1.begin().value().type() == json::value_type::number);
CHECK(j1.cbegin().value().type() == JSON::value_type::number); CHECK(j1.cbegin().value().type() == json::value_type::number);
CHECK(j2.begin().value().type() == JSON::value_type::string); CHECK(j2.begin().value().type() == json::value_type::string);
CHECK(j2.cbegin().value().type() == JSON::value_type::string); CHECK(j2.cbegin().value().type() == json::value_type::string);
CHECK(j3.begin().value().type() == JSON::value_type::boolean); CHECK(j3.begin().value().type() == json::value_type::boolean);
CHECK(j3.cbegin().value().type() == JSON::value_type::boolean); CHECK(j3.cbegin().value().type() == json::value_type::boolean);
CHECK(j4.begin().value().type() == JSON::value_type::null); CHECK(j4.begin().value().type() == json::value_type::null);
CHECK(j4.cbegin().value().type() == JSON::value_type::null); CHECK(j4.cbegin().value().type() == json::value_type::null);
CHECK(j5.begin().value().type() == JSON::value_type::number); CHECK(j5.begin().value().type() == json::value_type::number);
CHECK(j5.cbegin().value().type() == JSON::value_type::number); CHECK(j5.cbegin().value().type() == json::value_type::number);
CHECK(j6.begin().value().type() == JSON::value_type::number_float); CHECK(j6.begin().value().type() == json::value_type::number_float);
CHECK(j6.cbegin().value().type() == JSON::value_type::number_float); CHECK(j6.cbegin().value().type() == json::value_type::number_float);
CHECK(j7.begin().value().type() == JSON::value_type::string); CHECK(j7.begin().value().type() == json::value_type::string);
CHECK(j7.cbegin().value().type() == JSON::value_type::string); CHECK(j7.cbegin().value().type() == json::value_type::string);
CHECK(j1_const.begin().value().type() == JSON::value_type::number); CHECK(j1_const.begin().value().type() == json::value_type::number);
CHECK(j1_const.cbegin().value().type() == JSON::value_type::number); CHECK(j1_const.cbegin().value().type() == json::value_type::number);
CHECK(j2_const.begin().value().type() == JSON::value_type::string); CHECK(j2_const.begin().value().type() == json::value_type::string);
CHECK(j2_const.cbegin().value().type() == JSON::value_type::string); CHECK(j2_const.cbegin().value().type() == json::value_type::string);
CHECK(j3_const.begin().value().type() == JSON::value_type::boolean); CHECK(j3_const.begin().value().type() == json::value_type::boolean);
CHECK(j3_const.cbegin().value().type() == JSON::value_type::boolean); CHECK(j3_const.cbegin().value().type() == json::value_type::boolean);
CHECK(j4_const.begin().value().type() == JSON::value_type::null); CHECK(j4_const.begin().value().type() == json::value_type::null);
CHECK(j4_const.cbegin().value().type() == JSON::value_type::null); CHECK(j4_const.cbegin().value().type() == json::value_type::null);
CHECK(j5_const.begin().value().type() == JSON::value_type::number); CHECK(j5_const.begin().value().type() == json::value_type::number);
CHECK(j5_const.cbegin().value().type() == JSON::value_type::number); CHECK(j5_const.cbegin().value().type() == json::value_type::number);
CHECK(j6_const.begin().value().type() == JSON::value_type::number_float); CHECK(j6_const.begin().value().type() == json::value_type::number_float);
CHECK(j6_const.cbegin().value().type() == JSON::value_type::number_float); CHECK(j6_const.cbegin().value().type() == json::value_type::number_float);
CHECK(j7_const.begin().value().type() == JSON::value_type::string); CHECK(j7_const.begin().value().type() == json::value_type::string);
CHECK(j7_const.cbegin().value().type() == JSON::value_type::string); CHECK(j7_const.cbegin().value().type() == json::value_type::string);
CHECK_THROWS_AS(j1.end().value(), std::out_of_range); CHECK_THROWS_AS(j1.end().value(), std::out_of_range);
CHECK_THROWS_AS(j1.cend().value(), std::out_of_range); CHECK_THROWS_AS(j1.cend().value(), std::out_of_range);
...@@ -1350,114 +1350,114 @@ TEST_CASE("Iterators") ...@@ -1350,114 +1350,114 @@ TEST_CASE("Iterators")
// iterator copy constructors // iterator copy constructors
{ {
JSON::iterator tmp1(j1.begin()); json::iterator tmp1(j1.begin());
JSON::const_iterator tmp2(j1.cbegin()); json::const_iterator tmp2(j1.cbegin());
} }
{ {
JSON::iterator tmp1(j2.begin()); json::iterator tmp1(j2.begin());
JSON::const_iterator tmp2(j2.cbegin()); json::const_iterator tmp2(j2.cbegin());
} }
{ {
JSON::iterator tmp1(j3.begin()); json::iterator tmp1(j3.begin());
JSON::const_iterator tmp2(j3.cbegin()); json::const_iterator tmp2(j3.cbegin());
} }
{ {
JSON::iterator tmp1(j4.begin()); json::iterator tmp1(j4.begin());
JSON::const_iterator tmp2(j4.cbegin()); json::const_iterator tmp2(j4.cbegin());
} }
{ {
JSON::iterator tmp1(j5.begin()); json::iterator tmp1(j5.begin());
JSON::const_iterator tmp2(j5.cbegin()); json::const_iterator tmp2(j5.cbegin());
} }
{ {
JSON::iterator tmp1(j6.begin()); json::iterator tmp1(j6.begin());
JSON::const_iterator tmp2(j6.cbegin()); json::const_iterator tmp2(j6.cbegin());
} }
{ {
JSON::iterator tmp1(j7.begin()); json::iterator tmp1(j7.begin());
JSON::const_iterator tmp2(j7.cbegin()); json::const_iterator tmp2(j7.cbegin());
} }
{ {
JSON j_array = {0, 1, 2, 3, 4, 5}; json j_array = {0, 1, 2, 3, 4, 5};
JSON::iterator i1 = j_array.begin(); json::iterator i1 = j_array.begin();
++i1; ++i1;
JSON::iterator i2(i1); json::iterator i2(i1);
JSON::iterator i3; json::iterator i3;
i3 = i2; i3 = i2;
CHECK(i1 == i1); CHECK(i1 == i1);
JSON::const_iterator i4 = j_array.begin(); json::const_iterator i4 = j_array.begin();
++i4; ++i4;
JSON::const_iterator i5(i4); json::const_iterator i5(i4);
JSON::const_iterator i6; json::const_iterator i6;
i6 = i5; i6 = i5;
CHECK(i4 == i4); CHECK(i4 == i4);
} }
{ {
JSON j_object = {{"1", 1}, {"2", 2}, {"3", 3}}; json j_object = {{"1", 1}, {"2", 2}, {"3", 3}};
JSON::iterator i1 = j_object.begin(); json::iterator i1 = j_object.begin();
++i1; ++i1;
JSON::iterator i11 = j_object.begin(); json::iterator i11 = j_object.begin();
CHECK((i1 == i11) == false); CHECK((i1 == i11) == false);
JSON::iterator i2(i1); json::iterator i2(i1);
JSON::iterator i3; json::iterator i3;
i3 = i2; i3 = i2;
CHECK(i1 == i1); CHECK(i1 == i1);
JSON::const_iterator i4 = j_object.begin(); json::const_iterator i4 = j_object.begin();
++i4; ++i4;
JSON::iterator i41 = j_object.begin(); json::iterator i41 = j_object.begin();
CHECK((i4 == i41) == false); CHECK((i4 == i41) == false);
JSON::const_iterator i5(i4); json::const_iterator i5(i4);
JSON::const_iterator i6; json::const_iterator i6;
i6 = i5; i6 = i5;
CHECK(i4 == i4); CHECK(i4 == i4);
} }
// iterator copy assignment // iterator copy assignment
{ {
JSON::iterator i1 = j2.begin(); json::iterator i1 = j2.begin();
JSON::const_iterator i2 = j2.cbegin(); json::const_iterator i2 = j2.cbegin();
JSON::iterator i3 = i1; json::iterator i3 = i1;
JSON::const_iterator i4 = i2; json::const_iterator i4 = i2;
} }
// operator++ // operator++
{ {
JSON j; json j;
const JSON j_const = j; const json j_const = j;
{ {
JSON::iterator i = j.begin(); json::iterator i = j.begin();
++i; ++i;
CHECK(i == j.end()); CHECK(i == j.end());
++i; ++i;
CHECK(i == j.end()); CHECK(i == j.end());
} }
{ {
JSON::const_iterator i = j.begin(); json::const_iterator i = j.begin();
++i; ++i;
CHECK(i == j.end()); CHECK(i == j.end());
++i; ++i;
CHECK(i == j.end()); CHECK(i == j.end());
} }
{ {
JSON::const_iterator i = j_const.begin(); json::const_iterator i = j_const.begin();
++i; ++i;
CHECK(i == j_const.end()); CHECK(i == j_const.end());
++i; ++i;
CHECK(i == j_const.end()); CHECK(i == j_const.end());
} }
{ {
JSON::const_iterator i = j.cbegin(); json::const_iterator i = j.cbegin();
++i; ++i;
CHECK(i == j.cend()); CHECK(i == j.cend());
++i; ++i;
CHECK(i == j.cend()); CHECK(i == j.cend());
} }
{ {
JSON::const_iterator i = j_const.cbegin(); json::const_iterator i = j_const.cbegin();
++i; ++i;
CHECK(i == j_const.cend()); CHECK(i == j_const.cend());
++i; ++i;
...@@ -1468,13 +1468,13 @@ TEST_CASE("Iterators") ...@@ -1468,13 +1468,13 @@ TEST_CASE("Iterators")
TEST_CASE("Comparisons") TEST_CASE("Comparisons")
{ {
JSON j1 = {0, 1, 2, 3, 4}; json j1 = {0, 1, 2, 3, 4};
JSON j2 = {{"foo", "bar"}, {"baz", "bam"}}; json j2 = {{"foo", "bar"}, {"baz", "bam"}};
JSON j3 = true; json j3 = true;
JSON j4 = nullptr; json j4 = nullptr;
JSON j5 = 42; json j5 = 42;
JSON j6 = 23.42; json j6 = 23.42;
JSON j7 = "hello"; json j7 = "hello";
CHECK((j1 == j1) == true); CHECK((j1 == j1) == true);
CHECK((j1 == j2) == false); CHECK((j1 == j2) == false);
...@@ -1594,167 +1594,167 @@ TEST_CASE("Parser") ...@@ -1594,167 +1594,167 @@ TEST_CASE("Parser")
SECTION("null") SECTION("null")
{ {
// accept the exact values // accept the exact values
CHECK(JSON::parse("null") == JSON(nullptr)); CHECK(json::parse("null") == json(nullptr));
// ignore whitespace // ignore whitespace
CHECK(JSON::parse(" null ") == JSON(nullptr)); CHECK(json::parse(" null ") == json(nullptr));
CHECK(JSON::parse("\tnull\n") == JSON(nullptr)); CHECK(json::parse("\tnull\n") == json(nullptr));
// respect capitalization // respect capitalization
CHECK_THROWS_AS(JSON::parse("Null"), std::invalid_argument); CHECK_THROWS_AS(json::parse("Null"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("NULL"), std::invalid_argument); CHECK_THROWS_AS(json::parse("NULL"), std::invalid_argument);
// do not accept prefixes // do not accept prefixes
CHECK_THROWS_AS(JSON::parse("n"), std::invalid_argument); CHECK_THROWS_AS(json::parse("n"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("nu"), std::invalid_argument); CHECK_THROWS_AS(json::parse("nu"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("nul"), std::invalid_argument); CHECK_THROWS_AS(json::parse("nul"), std::invalid_argument);
} }
SECTION("string") SECTION("string")
{ {
// accept some values // accept some values
CHECK(JSON::parse("\"\"") == JSON("")); CHECK(json::parse("\"\"") == json(""));
CHECK(JSON::parse("\"foo\"") == JSON("foo")); CHECK(json::parse("\"foo\"") == json("foo"));
// escape characters // escape characters
CHECK_THROWS_AS(JSON::parse("\"\\\""), std::invalid_argument); CHECK_THROWS_AS(json::parse("\"\\\""), std::invalid_argument);
CHECK_NOTHROW(JSON::parse("\"\\\"\"")); CHECK_NOTHROW(json::parse("\"\\\"\""));
// quotes must be closed // quotes must be closed
CHECK_THROWS_AS(JSON::parse("\""), std::invalid_argument); CHECK_THROWS_AS(json::parse("\""), std::invalid_argument);
} }
SECTION("boolean") SECTION("boolean")
{ {
// accept the exact values // accept the exact values
CHECK(JSON::parse("true") == JSON(true)); CHECK(json::parse("true") == json(true));
CHECK(JSON::parse("false") == JSON(false)); CHECK(json::parse("false") == json(false));
// ignore whitespace // ignore whitespace
CHECK(JSON::parse(" true ") == JSON(true)); CHECK(json::parse(" true ") == json(true));
CHECK(JSON::parse("\tfalse\n") == JSON(false)); CHECK(json::parse("\tfalse\n") == json(false));
// respect capitalization // respect capitalization
CHECK_THROWS_AS(JSON::parse("True"), std::invalid_argument); CHECK_THROWS_AS(json::parse("True"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("False"), std::invalid_argument); CHECK_THROWS_AS(json::parse("False"), std::invalid_argument);
// do not accept prefixes // do not accept prefixes
CHECK_THROWS_AS(JSON::parse("t"), std::invalid_argument); CHECK_THROWS_AS(json::parse("t"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("tr"), std::invalid_argument); CHECK_THROWS_AS(json::parse("tr"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("tru"), std::invalid_argument); CHECK_THROWS_AS(json::parse("tru"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("f"), std::invalid_argument); CHECK_THROWS_AS(json::parse("f"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("fa"), std::invalid_argument); CHECK_THROWS_AS(json::parse("fa"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("fal"), std::invalid_argument); CHECK_THROWS_AS(json::parse("fal"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("fals"), std::invalid_argument); CHECK_THROWS_AS(json::parse("fals"), std::invalid_argument);
} }
SECTION("number (int)") SECTION("number (int)")
{ {
// accept the exact values // accept the exact values
CHECK(JSON::parse("0") == JSON(0)); CHECK(json::parse("0") == json(0));
CHECK(JSON::parse("-0") == JSON(0)); CHECK(json::parse("-0") == json(0));
CHECK(JSON::parse("1") == JSON(1)); CHECK(json::parse("1") == json(1));
CHECK(JSON::parse("-1") == JSON(-1)); CHECK(json::parse("-1") == json(-1));
CHECK(JSON::parse("12345678") == JSON(12345678)); CHECK(json::parse("12345678") == json(12345678));
CHECK(JSON::parse("-12345678") == JSON(-12345678)); CHECK(json::parse("-12345678") == json(-12345678));
CHECK(JSON::parse("0.0") == JSON(0)); CHECK(json::parse("0.0") == json(0));
CHECK(JSON::parse("-0.0") == JSON(0)); CHECK(json::parse("-0.0") == json(0));
CHECK(JSON::parse("1.0") == JSON(1)); CHECK(json::parse("1.0") == json(1));
CHECK(JSON::parse("-1.0") == JSON(-1)); CHECK(json::parse("-1.0") == json(-1));
CHECK(JSON::parse("12345678.0") == JSON(12345678)); CHECK(json::parse("12345678.0") == json(12345678));
CHECK(JSON::parse("-12345678.0") == JSON(-12345678)); CHECK(json::parse("-12345678.0") == json(-12345678));
CHECK(JSON::parse("17e0") == JSON(17)); CHECK(json::parse("17e0") == json(17));
CHECK(JSON::parse("17e1") == JSON(170)); CHECK(json::parse("17e1") == json(170));
CHECK(JSON::parse("17e3") == JSON(17000)); CHECK(json::parse("17e3") == json(17000));
CHECK(JSON::parse("17e+0") == JSON(17)); CHECK(json::parse("17e+0") == json(17));
CHECK(JSON::parse("17e+1") == JSON(170)); CHECK(json::parse("17e+1") == json(170));
CHECK(JSON::parse("17e+3") == JSON(17000)); CHECK(json::parse("17e+3") == json(17000));
CHECK(JSON::parse("17E0") == JSON(17)); CHECK(json::parse("17E0") == json(17));
CHECK(JSON::parse("17E1") == JSON(170)); CHECK(json::parse("17E1") == json(170));
CHECK(JSON::parse("17E3") == JSON(17000)); CHECK(json::parse("17E3") == json(17000));
CHECK(JSON::parse("17E+0") == JSON(17)); CHECK(json::parse("17E+0") == json(17));
CHECK(JSON::parse("17E+1") == JSON(170)); CHECK(json::parse("17E+1") == json(170));
CHECK(JSON::parse("17E+3") == JSON(17000)); CHECK(json::parse("17E+3") == json(17000));
CHECK(JSON::parse("10000e-0") == JSON(10000)); CHECK(json::parse("10000e-0") == json(10000));
CHECK(JSON::parse("10000e-1") == JSON(1000)); CHECK(json::parse("10000e-1") == json(1000));
CHECK(JSON::parse("10000e-4") == JSON(1)); CHECK(json::parse("10000e-4") == json(1));
CHECK(JSON::parse("10000E-0") == JSON(10000)); CHECK(json::parse("10000E-0") == json(10000));
CHECK(JSON::parse("10000E-1") == JSON(1000)); CHECK(json::parse("10000E-1") == json(1000));
CHECK(JSON::parse("10000E-4") == JSON(1)); CHECK(json::parse("10000E-4") == json(1));
CHECK(JSON::parse("17.0e0") == JSON(17)); CHECK(json::parse("17.0e0") == json(17));
CHECK(JSON::parse("17.0e1") == JSON(170)); CHECK(json::parse("17.0e1") == json(170));
CHECK(JSON::parse("17.0e3") == JSON(17000)); CHECK(json::parse("17.0e3") == json(17000));
CHECK(JSON::parse("17.0e+0") == JSON(17)); CHECK(json::parse("17.0e+0") == json(17));
CHECK(JSON::parse("17.0e+1") == JSON(170)); CHECK(json::parse("17.0e+1") == json(170));
CHECK(JSON::parse("17.0e+3") == JSON(17000)); CHECK(json::parse("17.0e+3") == json(17000));
CHECK(JSON::parse("17.0E0") == JSON(17)); CHECK(json::parse("17.0E0") == json(17));
CHECK(JSON::parse("17.0E1") == JSON(170)); CHECK(json::parse("17.0E1") == json(170));
CHECK(JSON::parse("17.0E3") == JSON(17000)); CHECK(json::parse("17.0E3") == json(17000));
CHECK(JSON::parse("17.0E+0") == JSON(17)); CHECK(json::parse("17.0E+0") == json(17));
CHECK(JSON::parse("17.0E+1") == JSON(170)); CHECK(json::parse("17.0E+1") == json(170));
CHECK(JSON::parse("17.0E+3") == JSON(17000)); CHECK(json::parse("17.0E+3") == json(17000));
CHECK(JSON::parse("10000.0e-0") == JSON(10000)); CHECK(json::parse("10000.0e-0") == json(10000));
CHECK(JSON::parse("10000.0e-1") == JSON(1000)); CHECK(json::parse("10000.0e-1") == json(1000));
CHECK(JSON::parse("10000.0e-4") == JSON(1)); CHECK(json::parse("10000.0e-4") == json(1));
CHECK(JSON::parse("10000.0E-0") == JSON(10000)); CHECK(json::parse("10000.0E-0") == json(10000));
CHECK(JSON::parse("10000.0E-1") == JSON(1000)); CHECK(json::parse("10000.0E-1") == json(1000));
CHECK(JSON::parse("10000.0E-4") == JSON(1)); CHECK(json::parse("10000.0E-4") == json(1));
// trailing zero is not allowed // trailing zero is not allowed
//CHECK_THROWS_AS(JSON::parse("01"), std::invalid_argument); //CHECK_THROWS_AS(json::parse("01"), std::invalid_argument);
// whitespace inbetween is an error // whitespace inbetween is an error
//CHECK_THROWS_AS(JSON::parse("1 0"), std::invalid_argument); //CHECK_THROWS_AS(json::parse("1 0"), std::invalid_argument);
// only one minus is allowd // only one minus is allowd
CHECK_THROWS_AS(JSON::parse("--1"), std::invalid_argument); CHECK_THROWS_AS(json::parse("--1"), std::invalid_argument);
// string representations are not allowed // string representations are not allowed
CHECK_THROWS_AS(JSON::parse("NAN"), std::invalid_argument); CHECK_THROWS_AS(json::parse("NAN"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("nan"), std::invalid_argument); CHECK_THROWS_AS(json::parse("nan"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("INF"), std::invalid_argument); CHECK_THROWS_AS(json::parse("INF"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("inf"), std::invalid_argument); CHECK_THROWS_AS(json::parse("inf"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("INFINITY"), std::invalid_argument); CHECK_THROWS_AS(json::parse("INFINITY"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("infinity"), std::invalid_argument); CHECK_THROWS_AS(json::parse("infinity"), std::invalid_argument);
} }
SECTION("number (float)") SECTION("number (float)")
{ {
// accept the exact values // accept the exact values
CHECK(JSON::parse("0.5") == JSON(0.5)); CHECK(json::parse("0.5") == json(0.5));
CHECK(JSON::parse("-0.5") == JSON(-0.5)); CHECK(json::parse("-0.5") == json(-0.5));
CHECK(JSON::parse("1.5") == JSON(1.5)); CHECK(json::parse("1.5") == json(1.5));
CHECK(JSON::parse("-1.5") == JSON(-1.5)); CHECK(json::parse("-1.5") == json(-1.5));
CHECK(JSON::parse("12345678.5") == JSON(12345678.5)); CHECK(json::parse("12345678.5") == json(12345678.5));
CHECK(JSON::parse("-12345678.5") == JSON(-12345678.5)); CHECK(json::parse("-12345678.5") == json(-12345678.5));
CHECK(JSON::parse("17.5e0") == JSON(17.5)); CHECK(json::parse("17.5e0") == json(17.5));
CHECK(JSON::parse("17.5e1") == JSON(175)); CHECK(json::parse("17.5e1") == json(175));
CHECK(JSON::parse("17.5e3") == JSON(17500)); CHECK(json::parse("17.5e3") == json(17500));
CHECK(JSON::parse("17.5e+0") == JSON(17.5)); CHECK(json::parse("17.5e+0") == json(17.5));
CHECK(JSON::parse("17.5e+1") == JSON(175)); CHECK(json::parse("17.5e+1") == json(175));
CHECK(JSON::parse("17.5e+3") == JSON(17500)); CHECK(json::parse("17.5e+3") == json(17500));
CHECK(JSON::parse("17.5E0") == JSON(17.5)); CHECK(json::parse("17.5E0") == json(17.5));
CHECK(JSON::parse("17.5E1") == JSON(175)); CHECK(json::parse("17.5E1") == json(175));
CHECK(JSON::parse("17.5E3") == JSON(17500)); CHECK(json::parse("17.5E3") == json(17500));
CHECK(JSON::parse("17.5E+0") == JSON(17.5)); CHECK(json::parse("17.5E+0") == json(17.5));
CHECK(JSON::parse("17.5E+1") == JSON(175)); CHECK(json::parse("17.5E+1") == json(175));
CHECK(JSON::parse("17.5E+3") == JSON(17500)); CHECK(json::parse("17.5E+3") == json(17500));
CHECK(JSON::parse("10000.5e-0") == JSON(10000.5)); CHECK(json::parse("10000.5e-0") == json(10000.5));
CHECK(JSON::parse("10000.5e-1") == JSON(1000.05)); CHECK(json::parse("10000.5e-1") == json(1000.05));
CHECK(JSON::parse("10000.5e-4") == JSON(1.00005)); CHECK(json::parse("10000.5e-4") == json(1.00005));
CHECK(JSON::parse("10000.5E-0") == JSON(10000.5)); CHECK(json::parse("10000.5E-0") == json(10000.5));
CHECK(JSON::parse("10000.5E-1") == JSON(1000.05)); CHECK(json::parse("10000.5E-1") == json(1000.05));
CHECK(JSON::parse("10000.5E-4") == JSON(1.00005)); CHECK(json::parse("10000.5E-4") == json(1.00005));
} }
SECTION("parse from C++ string") SECTION("parse from C++ string")
{ {
std::string s = "{ \"foo\": [1,2,true] }"; std::string s = "{ \"foo\": [1,2,true] }";
JSON j = JSON::parse(s); json j = json::parse(s);
CHECK(j["foo"].size() == 3); CHECK(j["foo"].size() == 3);
} }
...@@ -1762,7 +1762,7 @@ TEST_CASE("Parser") ...@@ -1762,7 +1762,7 @@ TEST_CASE("Parser")
{ {
std::stringstream s; std::stringstream s;
s << "{ \"foo\": [1,2,true] }"; s << "{ \"foo\": [1,2,true] }";
JSON j; json j;
j << s; j << s;
CHECK(j["foo"].size() == 3); CHECK(j["foo"].size() == 3);
} }
...@@ -1770,7 +1770,7 @@ TEST_CASE("Parser") ...@@ -1770,7 +1770,7 @@ TEST_CASE("Parser")
SECTION("user-defined string literal operator") SECTION("user-defined string literal operator")
{ {
auto j1 = "[1,2,3]"_json; auto j1 = "[1,2,3]"_json;
JSON j2 = {1, 2, 3}; json j2 = {1, 2, 3};
CHECK(j1 == j2); CHECK(j1 == j2);
auto j3 = "{\"key\": \"value\"}"_json; auto j3 = "{\"key\": \"value\"}"_json;
...@@ -1779,8 +1779,8 @@ TEST_CASE("Parser") ...@@ -1779,8 +1779,8 @@ TEST_CASE("Parser")
SECTION("Errors") SECTION("Errors")
{ {
CHECK_THROWS_AS(JSON::parse(""), std::invalid_argument); CHECK_THROWS_AS(json::parse(""), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse(std::string("")), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::string("")), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("[1,2"), std::invalid_argument); CHECK_THROWS_AS(json::parse("[1,2"), std::invalid_argument);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment