Commit f63ff772 authored by Niels's avatar Niels

renamed class from "JSON" to "son"

parent 4d00105e
......@@ -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
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_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_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/benchmark
cppcheck:
cppcheck --enable=all --inconclusive --std=c++11 src/JSON.*
cppcheck --enable=all --inconclusive --std=c++11 src/json.*
svn-clean: maintainer-clean
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
- **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:
......@@ -29,10 +29,10 @@ Other aspects were not so important to us:
All you need to do is add
```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
......@@ -61,7 +61,7 @@ With the JSON class, you could write:
```cpp
// 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)
j["pi"] = 3.141;
......@@ -85,7 +85,7 @@ j["list"] = { 1, 0, 2 };
j["object"] = { {"currency", "USD"}, {"value", "42.99"} };
// instead, you could also write (which looks very similar to the JSON above)
JSON j2 = {
json j2 = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
......@@ -109,7 +109,7 @@ You can create an object (deserialization) by appending `_json` to a string lite
```cpp
// 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):
......@@ -125,7 +125,7 @@ You can also use streams to serialize and deserialize:
```cpp
// deserialize from standard input
JSON j;
json j;
j << std::cin;
// serialize to standard output
......@@ -140,13 +140,13 @@ We designed the JSON class to behave just like an STL container:
```cpp
// create an array using push_back
JSON j;
json j;
j.push_back("foo");
j.push_back(1);
j.push_back(true);
// 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';
}
......@@ -163,14 +163,14 @@ bool foo = j.at(2);
// other stuff
j.size(); // 3 entries
j.empty(); // false
j.type(); // JSON::value_type::array
j.type(); // json::value_type::array
j.clear(); // the array is empty again
// comparison
j == "[\"foo\", 1, true]"_json; // true
// create an object
JSON o;
json o;
o["foo"] = 23;
o["bar"] = false;
o["baz"] = 3.141;
......@@ -181,7 +181,7 @@ if (o.find("foo") != o.end()) {
}
// 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';
}
```
......@@ -193,17 +193,17 @@ The type of the JSON object is determined automatically by the expression to sto
```cpp
/// strings
std::string s1 = "Hello, world!";
JSON js = s1;
json js = s1;
std::string s2 = js;
// Booleans
bool b1 = true;
JSON jb = b1;
json jb = b1;
bool b2 = jb;
// numbers
int i = 42;
JSON jn = i;
json jn = i;
double f = jn;
// etc.
......
#include "JSON.h"
#include "json.h"
int main()
{
JSON j;
json j;
j << std::cin;
return 0;
}
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_SILENT_RULES([yes])
......
......@@ -2,7 +2,7 @@
## 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
......@@ -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 |
| ----------------------- | -------------------------- | ----------------------------- | ---------------------- | --------------
| null | `value_type::null` | `nullptr_t` | - | `nullptr` |
| string | `value_type::string` | `std::string` | `JSON::string_t` | `""` |
| number (integer) | `value_type::number` | `int` | `JSON::number_t` | `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` | `{}` |
| object | `value_type::object` | `std::map<std::string, JSON>` | `JSON::object_t` | `{}` |
| string | `value_type::string` | `std::string` | `json::string_t` | `""` |
| number (integer) | `value_type::number` | `int` | `json::number_t` | `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` | `{}` |
| 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
......@@ -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 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
`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 |
| --------- | ---------------------- | -------- |
| none | null pointer literal, `nullptr_t` type, no value | `nullptr` |
| 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"` |
| 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`
| 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} }` |
| 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"` |
| 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`
| 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} }` |
## Number types
......
......@@ -9,7 +9,7 @@
@see https://github.com/nlohmann/json
*/
#include "JSON.h"
#include "json.h"
#include <cctype> // std::isdigit, std::isspace
#include <cstddef> // size_t
......@@ -21,19 +21,19 @@
// STATIC MEMBERS //
////////////////////
std::mutex JSON::_token;
std::mutex json::_token;
///////////////////////////////////
// CONSTRUCTORS OF UNION "value" //
///////////////////////////////////
JSON::value::value(array_t* _array): array(_array) {}
JSON::value::value(object_t* _object): object(_object) {}
JSON::value::value(string_t* _string): string(_string) {}
JSON::value::value(boolean_t _boolean) : boolean(_boolean) {}
JSON::value::value(number_t _number) : number(_number) {}
JSON::value::value(number_float_t _number_float) : number_float(_number_float) {}
json::value::value(array_t* _array): array(_array) {}
json::value::value(object_t* _object): object(_object) {}
json::value::value(string_t* _string): string(_string) {}
json::value::value(boolean_t _boolean) : boolean(_boolean) {}
json::value::value(number_t _number) : number(_number) {}
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.
@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.
*/
JSON::JSON(const value_type t) noexcept
json::json(const value_type t) noexcept
: _type(t)
{
switch (_type)
......@@ -92,7 +92,7 @@ JSON::JSON(const value_type t) noexcept
/*!
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.
@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))
{}
JSON::JSON(std::string&& s) noexcept
json::json(std::string&& s) noexcept
: _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))
{}
JSON::JSON(const bool b) noexcept
json::json(const bool b) noexcept
: _type(value_type::boolean), _value(b)
{}
JSON::JSON(const int i) noexcept
json::json(const int i) noexcept
: _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)
{}
JSON::JSON(const array_t& a) noexcept
json::json(const array_t& a) noexcept
: _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)))
{}
JSON::JSON(const object_t& o) noexcept
json::json(const object_t& o) noexcept
: _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)))
{}
......@@ -155,7 +155,7 @@ as is to create an array.
@bug With the described approach, we would fail to recognize an array whose
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
// is a string
......@@ -176,7 +176,7 @@ JSON::JSON(list_init_t a) noexcept
// the initializer list is a list of pairs
_type = value_type::object;
_value = new object_t();
for (const JSON& element : a)
for (const json& element : a)
{
const std::string k = element[0];
_value.object->emplace(std::make_pair(std::move(k),
......@@ -189,7 +189,7 @@ A copy constructor for the JSON class.
@param o the JSON object to copy
*/
JSON::JSON(const JSON& o) noexcept
json::json(const json& o) noexcept
: _type(o._type)
{
switch (_type)
......@@ -238,7 +238,7 @@ A move constructor for the JSON class.
@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))
{
// invalidate payload
......@@ -252,14 +252,14 @@ idiom.
@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(_value, o._value);
return *this;
}
JSON::~JSON() noexcept
json::~json() noexcept
{
switch (_type)
{
......@@ -290,22 +290,22 @@ JSON::~JSON() noexcept
@param s a string representation of 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
@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)
{
......@@ -346,7 +346,7 @@ const std::string JSON::_typename() const noexcept
type is not string
*/
template<>
std::string JSON::get() const
std::string json::get() const
{
switch (_type)
{
......@@ -362,7 +362,7 @@ std::string JSON::get() const
type is not number (int or float)
*/
template<>
int JSON::get() const
int json::get() const
{
switch (_type)
{
......@@ -380,7 +380,7 @@ int JSON::get() const
type is not number (int or float)
*/
template<>
double JSON::get() const
double json::get() const
{
switch (_type)
{
......@@ -398,7 +398,7 @@ double JSON::get() const
type is not boolean
*/
template<>
bool JSON::get() const
bool json::get() const
{
switch (_type)
{
......@@ -414,7 +414,7 @@ bool JSON::get() const
type is an object
*/
template<>
JSON::array_t JSON::get() const
json::array_t json::get() const
{
if (_type == value_type::array)
{
......@@ -435,7 +435,7 @@ JSON::array_t JSON::get() const
type is not object
*/
template<>
JSON::object_t JSON::get() const
json::object_t json::get() const
{
if (_type == value_type::object)
{
......@@ -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>();
}
JSON::operator int() const
json::operator int() const
{
return get<int>();
}
JSON::operator double() const
json::operator double() const
{
return get<double>();
}
JSON::operator bool() const
json::operator bool() const
{
return get<bool>();
}
JSON::operator array_t() const
json::operator array_t() const
{
return get<array_t>();
}
JSON::operator object_t() const
json::operator object_t() const
{
return get<object_t>();
}
const std::string JSON::toString() const noexcept
const std::string json::toString() const noexcept
{
switch (_type)
{
......@@ -546,33 +546,33 @@ const std::string JSON::toString() const noexcept
// ADDING ELEMENTS TO OBJECTS AND ARRAYS //
///////////////////////////////////////////
JSON& JSON::operator+=(const JSON& o)
json& json::operator+=(const json& o)
{
push_back(o);
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;
}
JSON& JSON::operator+=(const char* s)
json& json::operator+=(const char* s)
{
push_back(JSON(s));
push_back(json(s));
return *this;
}
JSON& JSON::operator+=(std::nullptr_t)
json& json::operator+=(std::nullptr_t)
{
push_back(JSON());
push_back(json());
return *this;
}
JSON& JSON::operator+=(bool b)
json& json::operator+=(bool b)
{
push_back(JSON(b));
push_back(json(b));
return *this;
}
......@@ -582,9 +582,9 @@ into a JSON and call push_back for this.
@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;
}
......@@ -594,16 +594,16 @@ number into a JSON and call push_back for this.
@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;
}
/*!
@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;
}
......@@ -611,7 +611,7 @@ JSON& JSON::operator+=(const object_t::value_type& p)
/*!
@todo comment me
*/
JSON& JSON::operator+=(list_init_t a)
json& json::operator+=(list_init_t a)
{
push_back(a);
return *this;
......@@ -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.
*/
void JSON::push_back(const JSON& o)
void json::push_back(const json& o)
{
// push_back only works for null objects or arrays
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.
@note Null objects are silently transformed into an array before the addition.
@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
if (not(_type == value_type::null or _type == value_type::array))
......@@ -691,24 +691,24 @@ void JSON::push_back(JSON&& o)
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.
@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.
@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
*/
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;
}
......@@ -744,7 +744,7 @@ void JSON::push_back(const object_t::value_type& p)
/*!
@todo comment me
*/
void JSON::push_back(list_init_t a)
void json::push_back(list_init_t a)
{
bool is_array = false;
......@@ -764,14 +764,14 @@ void JSON::push_back(list_init_t a)
if (is_array)
{
for (const JSON& element : a)
for (const json& element : a)
{
push_back(element);
}
}
else
{
for (const JSON& element : a)
for (const json& element : a)
{
const object_t::value_type tmp {element[0].get<std::string>(), element[1]};
push_back(tmp);
......@@ -795,7 +795,7 @@ index. Bounds will not be checked.
@pre Object is 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
if (_type != value_type::array)
......@@ -826,7 +826,7 @@ index. Bounds will not be checked.
@pre Object is 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
if (_type != value_type::array)
......@@ -856,7 +856,7 @@ index. Bounds will be checked.
@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)
*/
JSON& JSON::at(const int index)
json& json::at(const int index)
{
// this function only works for arrays
if (_type != value_type::array)
......@@ -888,7 +888,7 @@ index. Bounds will be checked.
@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)
*/
const JSON& JSON::at(const int index) const
const json& json::at(const int index) const
{
// this function only works for arrays
if (_type != value_type::array)
......@@ -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());
}
......@@ -922,7 +922,7 @@ key.
@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);
......@@ -943,7 +943,7 @@ JSON& JSON::operator[](const char* key)
// if the key does not exist, create it
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
......@@ -961,7 +961,7 @@ key.
@exception std::domain_error if object is not an 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
if (_type != value_type::object)
......@@ -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());
}
......@@ -1004,7 +1004,7 @@ key.
@exception std::domain_error if object is not an object
@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);
......@@ -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());
}
......@@ -1038,7 +1038,7 @@ key.
@exception std::domain_error if object is not an object
@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
if (_type != value_type::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.
*/
size_t JSON::size() const noexcept
size_t json::size() const noexcept
{
switch (_type)
{
......@@ -1093,7 +1093,7 @@ Returns whether a JSON object is empty.
@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)
{
......@@ -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 floating numbers.
*/
void JSON::clear() noexcept
void json::clear() noexcept
{
switch (_type)
{
......@@ -1164,22 +1164,22 @@ void JSON::clear() noexcept
}
}
JSON::value_type JSON::type() const noexcept
json::value_type json::type() const noexcept
{
return _type;
}
JSON::iterator JSON::find(const std::string& key)
json::iterator json::find(const std::string& key)
{
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());
}
JSON::iterator JSON::find(const char* key)
json::iterator json::find(const char* key)
{
if (_type != value_type::object)
{
......@@ -1190,7 +1190,7 @@ JSON::iterator JSON::find(const char* key)
const object_t::iterator i = _value.object->find(key);
if (i != _value.object->end())
{
JSON::iterator result(this);
json::iterator result(this);
delete result._oi;
result._oi = new object_t::iterator(i);
return result;
......@@ -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)
{
......@@ -1213,7 +1213,7 @@ JSON::const_iterator JSON::find(const char* key) const
const object_t::const_iterator i = _value.object->find(key);
if (i != _value.object->end())
{
JSON::const_iterator result(this);
json::const_iterator result(this);
delete result._oi;
result._oi = new object_t::const_iterator(i);
return result;
......@@ -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)
{
......@@ -1298,44 +1298,44 @@ bool JSON::operator==(const JSON& o) const noexcept
return false;
}
bool JSON::operator!=(const JSON& o) const noexcept
bool json::operator!=(const json& o) const noexcept
{
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)
{
......@@ -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)
{
......@@ -1365,13 +1365,13 @@ JSON::iterator::iterator(const JSON::iterator& o) : _object(o._object)
}
}
JSON::iterator::~iterator()
json::iterator::~iterator()
{
delete _vi;
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(_vi, o._vi);
......@@ -1379,7 +1379,7 @@ JSON::iterator& JSON::iterator::operator=(JSON::iterator o)
return *this;
}
bool JSON::iterator::operator==(const JSON::iterator& o) const
bool json::iterator::operator==(const json::iterator& o) const
{
if (_object != o._object)
{
......@@ -1401,12 +1401,12 @@ bool JSON::iterator::operator==(const JSON::iterator& o) const
return true;
}
bool JSON::iterator::operator!=(const JSON::iterator& o) const
bool json::iterator::operator!=(const json::iterator& o) const
{
return not operator==(o);
}
JSON::iterator& JSON::iterator::operator++()
json::iterator& json::iterator::operator++()
{
// iterator cannot be incremented
if (_object == nullptr)
......@@ -1440,7 +1440,7 @@ JSON::iterator& JSON::iterator::operator++()
return *this;
}
JSON& JSON::iterator::operator*() const
json& json::iterator::operator*() const
{
// dereferencing end() is an error
if (_object == nullptr)
......@@ -1465,7 +1465,7 @@ JSON& JSON::iterator::operator*() const
}
}
JSON* JSON::iterator::operator->() const
json* json::iterator::operator->() const
{
// dereferencing end() is an error
if (_object == nullptr)
......@@ -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)
{
......@@ -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
if (_object == nullptr)
......@@ -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)
{
......@@ -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)
{
......@@ -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)
{
......@@ -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 _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(_vi, o._vi);
......@@ -1587,7 +1587,7 @@ JSON::const_iterator& JSON::const_iterator::operator=(JSON::const_iterator o)
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)
{
......@@ -1609,12 +1609,12 @@ bool JSON::const_iterator::operator==(const JSON::const_iterator& o) const
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);
}
JSON::const_iterator& JSON::const_iterator::operator++()
json::const_iterator& json::const_iterator::operator++()
{
// iterator cannot be incremented
if (_object == nullptr)
......@@ -1648,7 +1648,7 @@ JSON::const_iterator& JSON::const_iterator::operator++()
return *this;
}
const JSON& JSON::const_iterator::operator*() const
const json& json::const_iterator::operator*() const
{
// dereferencing end() is an error
if (_object == nullptr)
......@@ -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
if (_object == nullptr)
......@@ -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)
{
......@@ -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
if (_object == nullptr)
......@@ -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
read. Whitespace is skipped.
*/
JSON::Parser::Parser(const char* s)
json::parser::parser(const char* s)
: _buffer(s)
{
// read first character
......@@ -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)
{
// read first character
......@@ -1774,7 +1774,7 @@ Initialize the JSON parser given an input stream \p _is.
read. Whitespace is skipped.
*/
JSON::Parser::Parser(std::istream& _is)
json::parser::parser(std::istream& _is)
{
while (_is)
{
......@@ -1787,14 +1787,14 @@ JSON::Parser::Parser(std::istream& _is)
next();
}
JSON JSON::Parser::parse()
json json::parser::parse()
{
switch (_current)
{
case ('{'):
{
// explicitly set result to object to cope with {}
JSON result(value_type::object);
json result(value_type::object);
next();
......@@ -1825,7 +1825,7 @@ JSON JSON::Parser::parse()
case ('['):
{
// explicitly set result to array to cope with []
JSON result(value_type::array);
json result(value_type::array);
next();
......@@ -1847,25 +1847,25 @@ JSON JSON::Parser::parse()
case ('\"'):
{
return JSON(parseString());
return json(parseString());
}
case ('t'):
{
parseTrue();
return JSON(true);
return json(true);
}
case ('f'):
{
parseFalse();
return JSON(false);
return json(false);
}
case ('n'):
{
parseNull();
return JSON();
return json();
}
case ('-'):
......@@ -1896,12 +1896,12 @@ JSON JSON::Parser::parse()
if (float_val == int_val)
{
// we would not lose precision -> int
return JSON(int_val);
return json(int_val);
}
else
{
// we would lose precision -> float
return JSON(float_val);
return json(float_val);
}
}
catch (...)
......@@ -1927,7 +1927,7 @@ true. If the end of the buffer is reached, false is returned.
@post _current holds the next character
*/
bool JSON::Parser::next()
bool json::parser::next()
{
if (_pos == _buffer.size())
{
......@@ -1961,7 +1961,7 @@ the error message \p msg), and the last read token.
@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 " +
std::to_string(_pos) + ": " + msg +
......@@ -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
_current. Whitespace is skipped.
*/
std::string JSON::Parser::parseString()
std::string json::parser::parseString()
{
// get position of closing quotes
auto quote_pos = _buffer.find_first_of("\"", _pos);
......@@ -2021,7 +2021,7 @@ error is raised via @ref error.
@post The character after the \p "true" is the current character. Whitespace is
skipped.
*/
void JSON::Parser::parseTrue()
void json::parser::parseTrue()
{
if (_buffer.substr(_pos, 3) != "rue")
{
......@@ -2044,7 +2044,7 @@ error is raised via @ref error.
@post The character after the \p "false" is the current character. Whitespace
is skipped.
*/
void JSON::Parser::parseFalse()
void json::parser::parseFalse()
{
if (_buffer.substr(_pos, 4) != "alse")
{
......@@ -2067,7 +2067,7 @@ error is raised via @ref error.
@post The character after the \p "null" is the current character. Whitespace is
skipped.
*/
void JSON::Parser::parseNull()
void json::parser::parseNull()
{
if (_buffer.substr(_pos, 3) != "ull")
{
......@@ -2090,7 +2090,7 @@ via @ref error.
@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)
{
......@@ -2113,7 +2113,7 @@ no parse error occurred.
@param s a string representation of 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.
@bug Numbers are currently handled too generously. There are several formats
that are forbidden by the standard, but are accepted by the parser.
@todo Implement JSON::swap()
@todo Implement JSON::insert(), JSON::emplace(), JSON::emplace_back, JSON::erase
@todo Implement JSON::reverse_iterator, JSON::const_reverse_iterator,
JSON::rbegin(), JSON::rend(), JSON::crbegin(), JSON::crend()?
@todo Implement json::swap()
@todo Implement json::insert(), json::emplace(), json::emplace_back, json::erase
@todo Implement json::reverse_iterator, json::const_reverse_iterator,
json::rbegin(), json::rend(), json::crbegin(), json::crend()?
*/
class JSON
class json
{
// forward declaration to friend this class
public:
......@@ -64,9 +64,9 @@ class JSON
};
/// 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
using array_t = std::vector<JSON>;
using array_t = std::vector<json>;
/// a type for a string
using string_t = std::string;
/// a type for a Boolean
......@@ -76,7 +76,7 @@ class JSON
/// a type for a floating point number
using number_float_t = double;
/// a type for list initialization
using list_init_t = std::initializer_list<JSON>;
using list_init_t = std::initializer_list<json>;
/// a JSON value
union value
......@@ -112,49 +112,49 @@ class JSON
public:
/// create an object according to given type
JSON(const value_type) noexcept;
json(const value_type) noexcept;
/// create a null object
JSON() = default;
json() = default;
/// create a null object
JSON(std::nullptr_t) noexcept;
json(std::nullptr_t) noexcept;
/// 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)
JSON(std::string&&) noexcept;
json(std::string&&) noexcept;
/// create a string object from a C string
JSON(const char*) noexcept;
json(const char*) noexcept;
/// create a Boolean object
JSON(const bool) noexcept;
json(const bool) noexcept;
/// create a number object
JSON(const int) noexcept;
json(const int) noexcept;
/// create a number object
JSON(const double) noexcept;
json(const double) noexcept;
/// create an array
JSON(const array_t&) noexcept;
json(const array_t&) noexcept;
/// create an array (move)
JSON(array_t&&) noexcept;
json(array_t&&) noexcept;
/// create an object
JSON(const object_t&) noexcept;
json(const object_t&) noexcept;
/// create an object (move)
JSON(object_t&&) noexcept;
json(object_t&&) noexcept;
/// create from an initializer list (to an array or object)
JSON(list_init_t) noexcept;
json(list_init_t) noexcept;
/// copy constructor
JSON(const JSON&) noexcept;
json(const json&) noexcept;
/// move constructor
JSON(JSON&&) noexcept;
json(json&&) noexcept;
/// copy assignment
JSON& operator=(JSON) noexcept;
json& operator=(json) noexcept;
/// destructor
~JSON() noexcept;
~json() noexcept;
/// create from string representation
static JSON parse(const std::string&);
static json parse(const std::string&);
/// create from string representation
static JSON parse(const char*);
static json parse(const char*);
private:
/// return the type as string
......@@ -179,28 +179,28 @@ class JSON
operator object_t() const;
/// 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();
return o;
}
/// 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();
return o;
}
/// 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;
}
/// 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;
}
......@@ -208,29 +208,29 @@ class JSON
const std::string toString() const noexcept;
/// add an object/array to an array
JSON& operator+=(const JSON&);
json& operator+=(const json&);
/// add a string to an array
JSON& operator+=(const std::string&);
json& operator+=(const std::string&);
/// 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
JSON& operator+=(const char*);
json& operator+=(const char*);
/// add a Boolean to an array
JSON& operator+=(bool);
json& operator+=(bool);
/// add a number to an array
JSON& operator+=(int);
json& operator+=(int);
/// add a number to an array
JSON& operator+=(double);
json& operator+=(double);
/// 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
JSON& operator+=(list_init_t);
json& operator+=(list_init_t);
/// 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)
void push_back(JSON&&);
void push_back(json&&);
/// add a string to an array
void push_back(const std::string&);
/// add a null object to an array
......@@ -250,28 +250,28 @@ class JSON
void push_back(list_init_t);
/// operator to set an element in an array
JSON& operator[](const int);
json& operator[](const int);
/// 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
JSON& at(const int);
json& at(const int);
/// 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
JSON& operator[](const std::string&);
json& operator[](const std::string&);
/// operator to set an element in an object
JSON& operator[](const char*);
json& operator[](const char*);
/// 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
JSON& at(const std::string&);
json& at(const std::string&);
/// operator to set an element in an object
JSON& at(const char*);
json& at(const char*);
/// 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
const JSON& at(const char*) const;
const json& at(const char*) const;
/// return the number of stored values
size_t size() const noexcept;
......@@ -293,9 +293,9 @@ class JSON
const_iterator find(const char*) const;
/// lexicographically compares the values
bool operator==(const JSON&) const noexcept;
bool operator==(const json&) const noexcept;
/// lexicographically compares the values
bool operator!=(const JSON&) const noexcept;
bool operator!=(const json&) const noexcept;
/// returns an iterator to the beginning (array/object)
iterator begin() noexcept;
......@@ -325,11 +325,11 @@ class JSON
/// an iterator
class iterator
{
friend class JSON;
friend class JSON::const_iterator;
friend class json;
friend class json::const_iterator;
public:
iterator() = default;
iterator(JSON*);
iterator(json*);
iterator(const iterator&);
~iterator();
......@@ -337,17 +337,17 @@ class JSON
bool operator==(const iterator&) const;
bool operator!=(const iterator&) const;
iterator& operator++();
JSON& operator*() const;
JSON* operator->() const;
json& operator*() const;
json* operator->() const;
/// getter for the key (in case of objects)
std::string key() const;
/// getter for the value
JSON& value() const;
json& value() const;
private:
/// a JSON value
JSON* _object = nullptr;
json* _object = nullptr;
/// an iterator for JSON arrays
array_t::iterator* _vi = nullptr;
/// an iterator for JSON objects
......@@ -357,11 +357,11 @@ class JSON
/// a const iterator
class const_iterator
{
friend class JSON;
friend class json;
public:
const_iterator() = default;
const_iterator(const JSON*);
const_iterator(const json*);
const_iterator(const const_iterator&);
const_iterator(const iterator&);
~const_iterator();
......@@ -370,17 +370,17 @@ class JSON
bool operator==(const const_iterator&) const;
bool operator!=(const const_iterator&) const;
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)
std::string key() const;
/// getter for the value
const JSON& value() const;
const json& value() const;
private:
/// a JSON value
const JSON* _object = nullptr;
const json* _object = nullptr;
/// an iterator for JSON arrays
array_t::const_iterator* _vi = nullptr;
/// an iterator for JSON objects
......@@ -389,25 +389,25 @@ class JSON
private:
/// a helper class to parse a JSON object
class Parser
class parser
{
public:
/// a parser reading from a C string
Parser(const char*);
parser(const char*);
/// a parser reading from a C++ string
Parser(const std::string&);
parser(const std::string&);
/// a parser reading from an input stream
Parser(std::istream&);
parser(std::istream&);
/// destructor of the parser
~Parser() = default;
~parser() = default;
// no copy constructor
Parser(const Parser&) = delete;
parser(const parser&) = delete;
// no copy assignment
Parser& operator=(Parser) = delete;
parser& operator=(parser) = delete;
/// parse and return a JSON object
JSON parse();
json parse();
private:
/// read the next character, stripping whitespace
......@@ -436,4 +436,4 @@ class JSON
};
/// 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
#include "catch.hpp"
#include "JSON.h"
#include "json.h"
TEST_CASE("array")
{
SECTION("Basics")
{
// construction with given type
JSON j(JSON::value_type::array);
CHECK(j.type() == JSON::value_type::array);
json j(json::value_type::array);
CHECK(j.type() == json::value_type::array);
// const object
const JSON j_const (j);
const json j_const (j);
// string representation of default value
CHECK(j.toString() == "[]");
......@@ -26,30 +26,30 @@ TEST_CASE("array")
CHECK(j.empty() == true);
// implicit conversions
CHECK_NOTHROW(JSON::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error);
CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(json::object_t 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(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error);
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<std::string>(), 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<double>(), std::logic_error);
// transparent usage
auto id = [](JSON::array_t v)
auto id = [](json::array_t v)
{
return v;
};
CHECK(id(j) == j.get<JSON::array_t>());
CHECK(id(j) == j.get<json::array_t>());
// copy constructor
JSON k(j);
json k(j);
CHECK(k == j);
// copy assignment
......@@ -57,49 +57,49 @@ TEST_CASE("array")
CHECK(k == j);
// move constructor
JSON l = std::move(k);
json l = std::move(k);
CHECK(l == j);
}
SECTION("Create from value")
{
JSON::array_t v1 = {"string", 1, 1.0, false, nullptr};
JSON j1 = v1;
CHECK(j1.get<JSON::array_t>() == v1);
json::array_t v1 = {"string", 1, 1.0, false, nullptr};
json j1 = v1;
CHECK(j1.get<json::array_t>() == v1);
JSON j2 = {"string", 1, 1.0, false, nullptr};
JSON::array_t v2 = j2;
CHECK(j2.get<JSON::array_t>() == v1);
CHECK(j2.get<JSON::array_t>() == v2);
json j2 = {"string", 1, 1.0, false, nullptr};
json::array_t v2 = j2;
CHECK(j2.get<json::array_t>() == v1);
CHECK(j2.get<json::array_t>() == v2);
// special tests to make sure construction from initializer list works
// case 1: there is an element that is not an array
JSON j3 = { {"foo", "bar"}, 3 };
CHECK(j3.type() == JSON::value_type::array);
json j3 = { {"foo", "bar"}, 3 };
CHECK(j3.type() == json::value_type::array);
// case 2: there is an element with more than two elements
JSON j4 = { {"foo", "bar"}, {"one", "two", "three"} };
CHECK(j4.type() == JSON::value_type::array);
json j4 = { {"foo", "bar"}, {"one", "two", "three"} };
CHECK(j4.type() == json::value_type::array);
// case 3: there is an element whose first element is not a string
JSON j5 = { {"foo", "bar"}, {true, "baz"} };
CHECK(j5.type() == JSON::value_type::array);
json j5 = { {"foo", "bar"}, {true, "baz"} };
CHECK(j5.type() == json::value_type::array);
// check if nested arrays work and are recognized as arrays
JSON j6 = { {{"foo", "bar"}} };
CHECK(j6.type() == JSON::value_type::array);
json j6 = { {{"foo", "bar"}} };
CHECK(j6.type() == json::value_type::array);
CHECK(j6.size() == 1);
CHECK(j6[0].type() == JSON::value_type::object);
CHECK(j6[0].type() == json::value_type::object);
// move constructor
JSON j7(std::move(v1));
json j7(std::move(v1));
CHECK(j7 == j1);
}
SECTION("Array operators")
{
JSON j = {0, 1, 2, 3, 4, 5, 6};
json j = {0, 1, 2, 3, 4, 5, 6};
// read
const int v1 = j[3];
......@@ -137,15 +137,15 @@ TEST_CASE("array")
CHECK (j.size() == 21);
// implicit transformation into an array
JSON empty1, empty2;
json empty1, empty2;
empty1 += "foo";
empty2.push_back("foo");
CHECK(empty1.type() == JSON::value_type::array);
CHECK(empty2.type() == JSON::value_type::array);
CHECK(empty1.type() == json::value_type::array);
CHECK(empty2.type() == json::value_type::array);
CHECK(empty1 == empty2);
// exceptions
JSON nonarray = 1;
json nonarray = 1;
CHECK_THROWS_AS(nonarray.at(0), std::domain_error);
CHECK_THROWS_AS(const int i = nonarray[0], std::domain_error);
CHECK_NOTHROW(j[21]);
......@@ -156,23 +156,23 @@ TEST_CASE("array")
CHECK_THROWS_AS(j.at(21) = 5, std::out_of_range);
CHECK_THROWS_AS(nonarray += 2, std::runtime_error);
const JSON nonarray_const = nonarray;
const JSON j_const = j;
const json nonarray_const = nonarray;
const json j_const = j;
CHECK_THROWS_AS(nonarray_const.at(0), std::domain_error);
CHECK_THROWS_AS(const int i = nonarray_const[0], std::domain_error);
CHECK_NOTHROW(j_const[21]);
CHECK_THROWS_AS(const int i = j.at(21), std::out_of_range);
{
JSON nonarray2 = JSON(1);
JSON nonarray3 = JSON(2);
JSON empty3 = JSON();
json nonarray2 = json(1);
json nonarray3 = json(2);
json empty3 = json();
CHECK_THROWS_AS(nonarray2.push_back(nonarray3), std::runtime_error);
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_THROWS_AS(const int i = k.at(21), std::out_of_range);
......@@ -181,7 +181,7 @@ TEST_CASE("array")
CHECK (j.size() == 24);
// clear()
JSON j7 = {0, 1, 2, 3, 4, 5, 6};;
json j7 = {0, 1, 2, 3, 4, 5, 6};;
CHECK(j7.size() == 7);
j7.clear();
CHECK(j7.size() == 0);
......@@ -190,12 +190,12 @@ TEST_CASE("array")
SECTION("Iterators")
{
std::vector<int> vec = {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};
json j1 = {0, 1, 2, 3, 4, 5, 6};
const json j2 = {0, 1, 2, 3, 4, 5, 6};
{
// 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;
CHECK(v == vec[static_cast<size_t>(v)]);
......@@ -208,7 +208,7 @@ TEST_CASE("array")
}
{
// 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;
CHECK(v == vec[static_cast<size_t>(v)]);
......@@ -231,7 +231,7 @@ TEST_CASE("array")
{
// 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;
*cit = cit->get<int>() * 2;
......@@ -247,7 +247,7 @@ TEST_CASE("array")
{
// 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;
CHECK(v == vec[static_cast<size_t>(v)]);
......@@ -261,7 +261,7 @@ TEST_CASE("array")
{
// 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;
CHECK(v == vec[static_cast<size_t>(v)]);
......@@ -286,8 +286,8 @@ TEST_CASE("array")
// edge case: This should be an array with two elements which are in
// turn arrays with two strings. However, this is treated like the
// initializer list of an object.
JSON j_should_be_an_array = { {"foo", "bar"}, {"baz", "bat"} };
CHECK(j_should_be_an_array.type() == JSON::value_type::object);
json j_should_be_an_array = { {"foo", "bar"}, {"baz", "bat"} };
CHECK(j_should_be_an_array.type() == json::value_type::object);
}
}
......@@ -296,11 +296,11 @@ TEST_CASE("object")
SECTION("Basics")
{
// construction with given type
JSON j(JSON::value_type::object);
CHECK(j.type() == JSON::value_type::object);
json j(json::value_type::object);
CHECK(j.type() == json::value_type::object);
// const object
const JSON j_const = j;
const json j_const = j;
// string representation of default value
CHECK(j.toString() == "{}");
......@@ -314,30 +314,30 @@ TEST_CASE("object")
CHECK(j.empty() == true);
// implicit conversions
CHECK_THROWS_AS(JSON::array_t v = j, std::logic_error);
CHECK_NOTHROW(JSON::object_t v = j);
CHECK_THROWS_AS(json::array_t v = j, std::logic_error);
CHECK_NOTHROW(json::object_t v = j);
CHECK_THROWS_AS(std::string 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(double v = j, std::logic_error);
// explicit conversions
CHECK_THROWS_AS(auto v = j.get<JSON::array_t>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<JSON::object_t>());
CHECK_THROWS_AS(auto v = j.get<json::array_t>(), std::logic_error);
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<bool>(), 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);
// transparent usage
auto id = [](JSON::object_t v)
auto id = [](json::object_t v)
{
return v;
};
CHECK(id(j) == j.get<JSON::object_t>());
CHECK(id(j) == j.get<json::object_t>());
// copy constructor
JSON k(j);
json k(j);
CHECK(k == j);
// copy assignment
......@@ -345,34 +345,34 @@ TEST_CASE("object")
CHECK(k == j);
// move constructor
JSON l = std::move(k);
json l = std::move(k);
CHECK(l == j);
}
SECTION("Create from value")
{
JSON::object_t v1 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} };
JSON j1 = v1;
CHECK(j1.get<JSON::object_t>() == v1);
json::object_t v1 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} };
json j1 = v1;
CHECK(j1.get<json::object_t>() == v1);
JSON j2 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} };
JSON::object_t v2 = j2;
CHECK(j2.get<JSON::object_t>() == v1);
CHECK(j2.get<JSON::object_t>() == v2);
json j2 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} };
json::object_t v2 = j2;
CHECK(j2.get<json::object_t>() == v1);
CHECK(j2.get<json::object_t>() == v2);
// check if multiple keys are ignored
JSON j3 = { {"key", "value"}, {"key", 1} };
json j3 = { {"key", "value"}, {"key", 1} };
CHECK(j3.size() == 1);
// move constructor
JSON j7(std::move(v1));
json j7(std::move(v1));
CHECK(j7 == j1);
}
SECTION("Object operators")
{
JSON j = {{"k0", "v0"}, {"k1", nullptr}, {"k2", 42}, {"k3", 3.141}, {"k4", true}};
const JSON k = j;
json j = {{"k0", "v0"}, {"k1", nullptr}, {"k2", 42}, {"k3", 3.141}, {"k4", true}};
const json k = j;
// read
{
......@@ -426,12 +426,12 @@ TEST_CASE("object")
CHECK(j.find("k0") != j.end());
CHECK(j.find("v0") == j.end());
CHECK(j.find(std::string("v0")) == j.end());
JSON::const_iterator i1 = j.find("k0");
JSON::iterator i2 = j.find("k0");
json::const_iterator i1 = j.find("k0");
json::iterator i2 = j.find("k0");
CHECK(k.find("k0") != k.end());
CHECK(k.find("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
CHECK_THROWS_AS(j.at("foo"), std::out_of_range);
......@@ -441,8 +441,8 @@ TEST_CASE("object")
CHECK_NOTHROW(j.at(std::string("k0")));
CHECK_NOTHROW(k.at(std::string("k0")));
{
JSON noobject = 1;
const JSON noobject_const = noobject;
json noobject = 1;
const json noobject_const = noobject;
CHECK_THROWS_AS(noobject.at("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);
......@@ -453,33 +453,33 @@ TEST_CASE("object")
}
// 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);
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);
{
// make sure null objects are transformed
JSON je;
CHECK_NOTHROW(je.push_back(JSON::object_t::value_type {"int_key", 42}));
json je;
CHECK_NOTHROW(je.push_back(json::object_t::value_type {"int_key", 42}));
CHECK(je["int_key"].get<int>() == 42);
}
{
// make sure null objects are transformed
JSON je;
CHECK_NOTHROW((je += JSON::object_t::value_type {"int_key", 42}));
json je;
CHECK_NOTHROW((je += json::object_t::value_type {"int_key", 42}));
CHECK(je["int_key"].get<int>() == 42);
}
// add initializer list (of pairs)
{
JSON je;
json je;
je.push_back({ {"one", 1}, {"two", false}, {"three", {1, 2, 3}} });
CHECK(je["one"].get<int>() == 1);
CHECK(je["two"].get<bool>() == false);
CHECK(je["three"].size() == 3);
}
{
JSON je;
json je;
je += { {"one", 1}, {"two", false}, {"three", {1, 2, 3}} };
CHECK(je["one"].get<int>() == 1);
CHECK(je["two"].get<bool>() == false);
......@@ -493,38 +493,38 @@ TEST_CASE("object")
CHECK(i2.value() == j["k0"]);
// key/value for uninitialzed iterator
JSON::const_iterator i3;
JSON::iterator i4;
json::const_iterator i3;
json::iterator i4;
CHECK_THROWS_AS(i3.key(), 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.value(), std::out_of_range);
// key/value for end-iterator
JSON::const_iterator i5 = j.find("v0");
JSON::iterator i6 = j.find("v0");
json::const_iterator i5 = j.find("v0");
json::iterator i6 = j.find("v0");
CHECK_THROWS_AS(i5.key(), 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.value(), std::out_of_range);
// implicit transformation into an object
JSON empty;
json empty;
empty["foo"] = "bar";
CHECK(empty.type() == JSON::value_type::object);
CHECK(empty.type() == json::value_type::object);
CHECK(empty["foo"] == "bar");
// exceptions
JSON nonarray = 1;
json nonarray = 1;
CHECK_THROWS_AS(const int i = nonarray["v1"], 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);
}
// 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);
j7.clear();
CHECK(j7.size() == 0);
......@@ -532,11 +532,11 @@ TEST_CASE("object")
SECTION("Iterators")
{
JSON j1 = {{"k0", 0}, {"k1", 1}, {"k2", 2}, {"k3", 3}};
const JSON j2 = {{"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}};
// 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()))
{
......@@ -556,8 +556,8 @@ TEST_CASE("object")
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
......@@ -567,7 +567,7 @@ TEST_CASE("object")
}
// 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()))
{
......@@ -587,12 +587,12 @@ TEST_CASE("object")
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
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()))
{
......@@ -612,12 +612,12 @@ TEST_CASE("object")
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)
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()))
{
......@@ -637,12 +637,12 @@ TEST_CASE("object")
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)
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()))
{
......@@ -662,8 +662,8 @@ TEST_CASE("object")
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)
......@@ -679,8 +679,8 @@ TEST_CASE("null")
SECTION("Basics")
{
// construction with given type
JSON j;
CHECK(j.type() == JSON::value_type::null);
json j;
CHECK(j.type() == json::value_type::null);
// string representation of default value
CHECK(j.toString() == "null");
......@@ -694,23 +694,23 @@ TEST_CASE("null")
CHECK(j.empty() == true);
// implicit conversions
CHECK_NOTHROW(JSON::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error);
CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(json::object_t 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(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error);
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<std::string>(), 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<double>(), std::logic_error);
// copy constructor
JSON k(j);
json k(j);
CHECK(k == j);
// copy assignment
......@@ -718,22 +718,22 @@ TEST_CASE("null")
CHECK(k == j);
// move constructor
JSON l = std::move(k);
json l = std::move(k);
CHECK(l == j);
}
SECTION("Create from value")
{
JSON j1 = nullptr;
CHECK(j1.type() == JSON::value_type::null);
json j1 = nullptr;
CHECK(j1.type() == json::value_type::null);
}
SECTION("Operators")
{
// clear()
JSON j1 = nullptr;
json j1 = nullptr;
j1.clear();
CHECK(j1 == JSON(nullptr));
CHECK(j1 == json(nullptr));
}
}
......@@ -742,11 +742,11 @@ TEST_CASE("string")
SECTION("Basics")
{
// construction with given type
JSON j(JSON::value_type::string);
CHECK(j.type() == JSON::value_type::string);
json j(json::value_type::string);
CHECK(j.type() == json::value_type::string);
// const object
const JSON j_const = j;
const json j_const = j;
// iterators
CHECK(j.begin() != j.end());
......@@ -760,16 +760,16 @@ TEST_CASE("string")
CHECK(j.empty() == false);
// implicit conversions
CHECK_NOTHROW(JSON::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error);
CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(json::object_t v = j, std::logic_error);
CHECK_NOTHROW(std::string v = j);
CHECK_THROWS_AS(bool v = j, std::logic_error);
CHECK_THROWS_AS(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<json::array_t>());
CHECK_THROWS_AS(auto v = j.get<json::object_t>(), std::logic_error);
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<int>(), std::logic_error);
......@@ -783,7 +783,7 @@ TEST_CASE("string")
CHECK(id(j) == j.get<std::string>());
// copy constructor
JSON k(j);
json k(j);
CHECK(k == j);
// copy assignment
......@@ -791,28 +791,28 @@ TEST_CASE("string")
CHECK(k == j);
// move constructor
JSON l = std::move(k);
json l = std::move(k);
CHECK(l == j);
}
SECTION("Create from value")
{
JSON j1 = std::string("Hello, world");
json j1 = std::string("Hello, world");
std::string v1 = j1;
CHECK(j1.get<std::string>() == v1);
JSON j2 = "Hello, world";
json j2 = "Hello, world";
CHECK(j2.get<std::string>() == "Hello, world");
std::string v3 = "Hello, world";
JSON j3 = std::move(v3);
json j3 = std::move(v3);
CHECK(j3.get<std::string>() == "Hello, world");
}
SECTION("Operators")
{
// clear()
JSON j1 = std::string("Hello, world");
json j1 = std::string("Hello, world");
CHECK(j1.get<std::string>() == "Hello, world");
j1.clear();
CHECK(j1.get<std::string>() == "");
......@@ -824,11 +824,11 @@ TEST_CASE("boolean")
SECTION("Basics")
{
// construction with given type
JSON j(JSON::value_type::boolean);
CHECK(j.type() == JSON::value_type::boolean);
json j(json::value_type::boolean);
CHECK(j.type() == json::value_type::boolean);
// const object
const JSON j_const = j;
const json j_const = j;
// iterators
CHECK(j.begin() != j.end());
......@@ -842,16 +842,16 @@ TEST_CASE("boolean")
CHECK(j.empty() == false);
// implicit conversions
CHECK_NOTHROW(JSON::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error);
CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(json::object_t v = j, std::logic_error);
CHECK_THROWS_AS(std::string v = j, std::logic_error);
CHECK_NOTHROW(bool v = j);
CHECK_THROWS_AS(int v = j, std::logic_error);
CHECK_THROWS_AS(double v = j, std::logic_error);
// explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error);
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<std::string>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<bool>());
CHECK_THROWS_AS(auto v = j.get<int>(), std::logic_error);
......@@ -865,7 +865,7 @@ TEST_CASE("boolean")
CHECK(id(j) == j.get<bool>());
// copy constructor
JSON k(j);
json k(j);
CHECK(k == j);
// copy assignment
......@@ -873,17 +873,17 @@ TEST_CASE("boolean")
CHECK(k == j);
// move constructor
JSON l = std::move(k);
json l = std::move(k);
CHECK(l == j);
}
SECTION("Create from value")
{
JSON j1 = true;
json j1 = true;
bool v1 = j1;
CHECK(j1.get<bool>() == v1);
JSON j2 = false;
json j2 = false;
bool v2 = j2;
CHECK(j2.get<bool>() == v2);
}
......@@ -891,7 +891,7 @@ TEST_CASE("boolean")
SECTION("Operators")
{
// clear()
JSON j1 = true;
json j1 = true;
CHECK(j1.get<bool>() == true);
j1.clear();
CHECK(j1.get<bool>() == false);
......@@ -903,11 +903,11 @@ TEST_CASE("number (int)")
SECTION("Basics")
{
// construction with given type
JSON j(JSON::value_type::number);
CHECK(j.type() == JSON::value_type::number);
json j(json::value_type::number);
CHECK(j.type() == json::value_type::number);
// const object
const JSON j_const = j;
const json j_const = j;
// iterators
CHECK(j.begin() != j.end());
......@@ -921,16 +921,16 @@ TEST_CASE("number (int)")
CHECK(j.empty() == false);
// implicit conversions
CHECK_NOTHROW(JSON::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error);
CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(json::object_t 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_NOTHROW(int v = j);
CHECK_NOTHROW(double v = j);
// explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error);
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<std::string>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<int>());
......@@ -944,7 +944,7 @@ TEST_CASE("number (int)")
CHECK(id(j) == j.get<int>());
// copy constructor
JSON k(j);
json k(j);
CHECK(k == j);
// copy assignment
......@@ -952,17 +952,17 @@ TEST_CASE("number (int)")
CHECK(k == j);
// move constructor
JSON l = std::move(k);
json l = std::move(k);
CHECK(l == j);
}
SECTION("Create from value")
{
JSON j1 = 23;
json j1 = 23;
int v1 = j1;
CHECK(j1.get<int>() == v1);
JSON j2 = 42;
json j2 = 42;
int v2 = j2;
CHECK(j2.get<int>() == v2);
}
......@@ -970,7 +970,7 @@ TEST_CASE("number (int)")
SECTION("Operators")
{
// clear()
JSON j1 = 42;
json j1 = 42;
CHECK(j1.get<int>() == 42);
j1.clear();
CHECK(j1.get<int>() == 0);
......@@ -978,7 +978,7 @@ TEST_CASE("number (int)")
// find()
CHECK(j1.find("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(std::string("foo")) == j2.end());
}
......@@ -989,11 +989,11 @@ TEST_CASE("number (float)")
SECTION("Basics")
{
// construction with given type
JSON j(JSON::value_type::number_float);
CHECK(j.type() == JSON::value_type::number_float);
json j(json::value_type::number_float);
CHECK(j.type() == json::value_type::number_float);
// const object
const JSON j_const = j;
const json j_const = j;
// iterators
CHECK(j.begin() != j.end());
......@@ -1007,16 +1007,16 @@ TEST_CASE("number (float)")
CHECK(j.empty() == false);
// implicit conversions
CHECK_NOTHROW(JSON::array_t v = j);
CHECK_THROWS_AS(JSON::object_t v = j, std::logic_error);
CHECK_NOTHROW(json::array_t v = j);
CHECK_THROWS_AS(json::object_t 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_NOTHROW(int v = j);
CHECK_NOTHROW(double v = j);
// explicit conversions
CHECK_NOTHROW(auto v = j.get<JSON::array_t>());
CHECK_THROWS_AS(auto v = j.get<JSON::object_t>(), std::logic_error);
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<std::string>(), std::logic_error);
CHECK_THROWS_AS(auto v = j.get<bool>(), std::logic_error);
CHECK_NOTHROW(auto v = j.get<int>());
......@@ -1030,7 +1030,7 @@ TEST_CASE("number (float)")
CHECK(id(j) == j.get<double>());
// copy constructor
JSON k(j);
json k(j);
CHECK(k == j);
// copy assignment
......@@ -1038,17 +1038,17 @@ TEST_CASE("number (float)")
CHECK(k == j);
// move constructor
JSON l = std::move(k);
json l = std::move(k);
CHECK(l == j);
}
SECTION("Create from value")
{
JSON j1 = 3.1415926;
json j1 = 3.1415926;
double v1 = j1;
CHECK(j1.get<double>() == v1);
JSON j2 = 2.7182818;
json j2 = 2.7182818;
double v2 = j2;
CHECK(j2.get<double>() == v2);
}
......@@ -1056,7 +1056,7 @@ TEST_CASE("number (float)")
SECTION("Operators")
{
// clear()
JSON j1 = 3.1415926;
json j1 = 3.1415926;
CHECK(j1.get<double>() == 3.1415926);
j1.clear();
CHECK(j1.get<double>() == 0.0);
......@@ -1065,37 +1065,37 @@ TEST_CASE("number (float)")
TEST_CASE("Iterators")
{
JSON j1 = {0, 1, 2, 3, 4};
JSON j2 = {{"foo", "bar"}, {"baz", "bam"}};
JSON j3 = true;
JSON j4 = nullptr;
JSON j5 = 42;
JSON j6 = 23.42;
JSON j7 = "hello";
const JSON j1_const = {0, 1, 2, 3, 4};
const JSON j2_const = {{"foo", "bar"}, {"baz", "bam"}};
const JSON j3_const = true;
const JSON j4_const = nullptr;
const JSON j5_const = 42;
const JSON j6_const = 23.42;
const JSON j7_const = "hello";
json j1 = {0, 1, 2, 3, 4};
json j2 = {{"foo", "bar"}, {"baz", "bam"}};
json j3 = true;
json j4 = nullptr;
json j5 = 42;
json j6 = 23.42;
json j7 = "hello";
const json j1_const = {0, 1, 2, 3, 4};
const json j2_const = {{"foo", "bar"}, {"baz", "bam"}};
const json j3_const = true;
const json j4_const = nullptr;
const json j5_const = 42;
const json j6_const = 23.42;
const json j7_const = "hello";
// operator *
CHECK(* j1.begin() == JSON(0));
CHECK(* j1_const.begin() == JSON(0));
CHECK(* j2.begin() != JSON());
CHECK(* j2_const.begin() != JSON());
CHECK(* j3.begin() == JSON(true));
CHECK(* j3_const.begin() == JSON(true));
CHECK(* j4.begin() == JSON());
CHECK(* j4_const.begin() == JSON());
CHECK(* j5.begin() == JSON(42));
CHECK(* j5_const.begin() == JSON(42));
CHECK(* j6.begin() == JSON(23.42));
CHECK(* j6_const.begin() == JSON(23.42));
CHECK(* j7.begin() == JSON("hello"));
CHECK(* j7_const.begin() == JSON("hello"));
CHECK(* j1.begin() == json(0));
CHECK(* j1_const.begin() == json(0));
CHECK(* j2.begin() != json());
CHECK(* j2_const.begin() != json());
CHECK(* j3.begin() == json(true));
CHECK(* j3_const.begin() == json(true));
CHECK(* j4.begin() == json());
CHECK(* j4_const.begin() == json());
CHECK(* j5.begin() == json(42));
CHECK(* j5_const.begin() == json(42));
CHECK(* j6.begin() == json(23.42));
CHECK(* j6_const.begin() == json(23.42));
CHECK(* j7.begin() == json("hello"));
CHECK(* j7_const.begin() == json("hello"));
CHECK_THROWS_AS(* j1.end(), std::runtime_error);
CHECK_THROWS_AS(* j1.cend(), std::runtime_error);
......@@ -1128,35 +1128,35 @@ TEST_CASE("Iterators")
CHECK_THROWS_AS(* j7_const.cend(), std::runtime_error);
// operator ->
CHECK(j1.begin()->type() == JSON::value_type::number);
CHECK(j1.cbegin()->type() == JSON::value_type::number);
CHECK(j2.begin()->type() == JSON::value_type::string);
CHECK(j2.cbegin()->type() == JSON::value_type::string);
CHECK(j3.begin()->type() == JSON::value_type::boolean);
CHECK(j3.cbegin()->type() == JSON::value_type::boolean);
CHECK(j4.begin()->type() == JSON::value_type::null);
CHECK(j4.cbegin()->type() == JSON::value_type::null);
CHECK(j5.begin()->type() == JSON::value_type::number);
CHECK(j5.cbegin()->type() == JSON::value_type::number);
CHECK(j6.begin()->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.cbegin()->type() == JSON::value_type::string);
CHECK(j1_const.begin()->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.cbegin()->type() == JSON::value_type::string);
CHECK(j3_const.begin()->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.cbegin()->type() == JSON::value_type::null);
CHECK(j5_const.begin()->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.cbegin()->type() == JSON::value_type::number_float);
CHECK(j7_const.begin()->type() == JSON::value_type::string);
CHECK(j7_const.cbegin()->type() == JSON::value_type::string);
CHECK(j1.begin()->type() == json::value_type::number);
CHECK(j1.cbegin()->type() == json::value_type::number);
CHECK(j2.begin()->type() == json::value_type::string);
CHECK(j2.cbegin()->type() == json::value_type::string);
CHECK(j3.begin()->type() == json::value_type::boolean);
CHECK(j3.cbegin()->type() == json::value_type::boolean);
CHECK(j4.begin()->type() == json::value_type::null);
CHECK(j4.cbegin()->type() == json::value_type::null);
CHECK(j5.begin()->type() == json::value_type::number);
CHECK(j5.cbegin()->type() == json::value_type::number);
CHECK(j6.begin()->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.cbegin()->type() == json::value_type::string);
CHECK(j1_const.begin()->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.cbegin()->type() == json::value_type::string);
CHECK(j3_const.begin()->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.cbegin()->type() == json::value_type::null);
CHECK(j5_const.begin()->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.cbegin()->type() == json::value_type::number_float);
CHECK(j7_const.begin()->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.cend()->type(), std::runtime_error);
......@@ -1189,35 +1189,35 @@ TEST_CASE("Iterators")
CHECK_THROWS_AS(j7_const.cend()->type(), std::runtime_error);
// value
CHECK(j1.begin().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.cbegin().value().type() == JSON::value_type::string);
CHECK(j3.begin().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.cbegin().value().type() == JSON::value_type::null);
CHECK(j5.begin().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.cbegin().value().type() == JSON::value_type::number_float);
CHECK(j7.begin().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.cbegin().value().type() == JSON::value_type::number);
CHECK(j2_const.begin().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.cbegin().value().type() == JSON::value_type::boolean);
CHECK(j4_const.begin().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.cbegin().value().type() == JSON::value_type::number);
CHECK(j6_const.begin().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.cbegin().value().type() == JSON::value_type::string);
CHECK(j1.begin().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.cbegin().value().type() == json::value_type::string);
CHECK(j3.begin().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.cbegin().value().type() == json::value_type::null);
CHECK(j5.begin().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.cbegin().value().type() == json::value_type::number_float);
CHECK(j7.begin().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.cbegin().value().type() == json::value_type::number);
CHECK(j2_const.begin().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.cbegin().value().type() == json::value_type::boolean);
CHECK(j4_const.begin().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.cbegin().value().type() == json::value_type::number);
CHECK(j6_const.begin().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.cbegin().value().type() == json::value_type::string);
CHECK_THROWS_AS(j1.end().value(), std::out_of_range);
CHECK_THROWS_AS(j1.cend().value(), std::out_of_range);
......@@ -1350,114 +1350,114 @@ TEST_CASE("Iterators")
// iterator copy constructors
{
JSON::iterator tmp1(j1.begin());
JSON::const_iterator tmp2(j1.cbegin());
json::iterator tmp1(j1.begin());
json::const_iterator tmp2(j1.cbegin());
}
{
JSON::iterator tmp1(j2.begin());
JSON::const_iterator tmp2(j2.cbegin());
json::iterator tmp1(j2.begin());
json::const_iterator tmp2(j2.cbegin());
}
{
JSON::iterator tmp1(j3.begin());
JSON::const_iterator tmp2(j3.cbegin());
json::iterator tmp1(j3.begin());
json::const_iterator tmp2(j3.cbegin());
}
{
JSON::iterator tmp1(j4.begin());
JSON::const_iterator tmp2(j4.cbegin());
json::iterator tmp1(j4.begin());
json::const_iterator tmp2(j4.cbegin());
}
{
JSON::iterator tmp1(j5.begin());
JSON::const_iterator tmp2(j5.cbegin());
json::iterator tmp1(j5.begin());
json::const_iterator tmp2(j5.cbegin());
}
{
JSON::iterator tmp1(j6.begin());
JSON::const_iterator tmp2(j6.cbegin());
json::iterator tmp1(j6.begin());
json::const_iterator tmp2(j6.cbegin());
}
{
JSON::iterator tmp1(j7.begin());
JSON::const_iterator tmp2(j7.cbegin());
json::iterator tmp1(j7.begin());
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;
JSON::iterator i2(i1);
JSON::iterator i3;
json::iterator i2(i1);
json::iterator i3;
i3 = i2;
CHECK(i1 == i1);
JSON::const_iterator i4 = j_array.begin();
json::const_iterator i4 = j_array.begin();
++i4;
JSON::const_iterator i5(i4);
JSON::const_iterator i6;
json::const_iterator i5(i4);
json::const_iterator i6;
i6 = i5;
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;
JSON::iterator i11 = j_object.begin();
json::iterator i11 = j_object.begin();
CHECK((i1 == i11) == false);
JSON::iterator i2(i1);
JSON::iterator i3;
json::iterator i2(i1);
json::iterator i3;
i3 = i2;
CHECK(i1 == i1);
JSON::const_iterator i4 = j_object.begin();
json::const_iterator i4 = j_object.begin();
++i4;
JSON::iterator i41 = j_object.begin();
json::iterator i41 = j_object.begin();
CHECK((i4 == i41) == false);
JSON::const_iterator i5(i4);
JSON::const_iterator i6;
json::const_iterator i5(i4);
json::const_iterator i6;
i6 = i5;
CHECK(i4 == i4);
}
// iterator copy assignment
{
JSON::iterator i1 = j2.begin();
JSON::const_iterator i2 = j2.cbegin();
JSON::iterator i3 = i1;
JSON::const_iterator i4 = i2;
json::iterator i1 = j2.begin();
json::const_iterator i2 = j2.cbegin();
json::iterator i3 = i1;
json::const_iterator i4 = i2;
}
// operator++
{
JSON j;
const JSON j_const = j;
json j;
const json j_const = j;
{
JSON::iterator i = j.begin();
json::iterator i = j.begin();
++i;
CHECK(i == j.end());
++i;
CHECK(i == j.end());
}
{
JSON::const_iterator i = j.begin();
json::const_iterator i = j.begin();
++i;
CHECK(i == j.end());
++i;
CHECK(i == j.end());
}
{
JSON::const_iterator i = j_const.begin();
json::const_iterator i = j_const.begin();
++i;
CHECK(i == j_const.end());
++i;
CHECK(i == j_const.end());
}
{
JSON::const_iterator i = j.cbegin();
json::const_iterator i = j.cbegin();
++i;
CHECK(i == j.cend());
++i;
CHECK(i == j.cend());
}
{
JSON::const_iterator i = j_const.cbegin();
json::const_iterator i = j_const.cbegin();
++i;
CHECK(i == j_const.cend());
++i;
......@@ -1468,13 +1468,13 @@ TEST_CASE("Iterators")
TEST_CASE("Comparisons")
{
JSON j1 = {0, 1, 2, 3, 4};
JSON j2 = {{"foo", "bar"}, {"baz", "bam"}};
JSON j3 = true;
JSON j4 = nullptr;
JSON j5 = 42;
JSON j6 = 23.42;
JSON j7 = "hello";
json j1 = {0, 1, 2, 3, 4};
json j2 = {{"foo", "bar"}, {"baz", "bam"}};
json j3 = true;
json j4 = nullptr;
json j5 = 42;
json j6 = 23.42;
json j7 = "hello";
CHECK((j1 == j1) == true);
CHECK((j1 == j2) == false);
......@@ -1594,167 +1594,167 @@ TEST_CASE("Parser")
SECTION("null")
{
// accept the exact values
CHECK(JSON::parse("null") == JSON(nullptr));
CHECK(json::parse("null") == json(nullptr));
// ignore whitespace
CHECK(JSON::parse(" null ") == JSON(nullptr));
CHECK(JSON::parse("\tnull\n") == JSON(nullptr));
CHECK(json::parse(" null ") == json(nullptr));
CHECK(json::parse("\tnull\n") == json(nullptr));
// 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
CHECK_THROWS_AS(JSON::parse("n"), 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("n"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("nu"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("nul"), std::invalid_argument);
}
SECTION("string")
{
// accept some values
CHECK(JSON::parse("\"\"") == JSON(""));
CHECK(JSON::parse("\"foo\"") == JSON("foo"));
CHECK(json::parse("\"\"") == json(""));
CHECK(json::parse("\"foo\"") == json("foo"));
// escape characters
CHECK_THROWS_AS(JSON::parse("\"\\\""), std::invalid_argument);
CHECK_NOTHROW(JSON::parse("\"\\\"\""));
CHECK_THROWS_AS(json::parse("\"\\\""), std::invalid_argument);
CHECK_NOTHROW(json::parse("\"\\\"\""));
// quotes must be closed
CHECK_THROWS_AS(JSON::parse("\""), std::invalid_argument);
CHECK_THROWS_AS(json::parse("\""), std::invalid_argument);
}
SECTION("boolean")
{
// accept the exact values
CHECK(JSON::parse("true") == JSON(true));
CHECK(JSON::parse("false") == JSON(false));
CHECK(json::parse("true") == json(true));
CHECK(json::parse("false") == json(false));
// ignore whitespace
CHECK(JSON::parse(" true ") == JSON(true));
CHECK(JSON::parse("\tfalse\n") == JSON(false));
CHECK(json::parse(" true ") == json(true));
CHECK(json::parse("\tfalse\n") == json(false));
// respect capitalization
CHECK_THROWS_AS(JSON::parse("True"), std::invalid_argument);
CHECK_THROWS_AS(JSON::parse("False"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("True"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("False"), std::invalid_argument);
// do not accept prefixes
CHECK_THROWS_AS(JSON::parse("t"), 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("f"), 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("fals"), 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("tru"), 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("fal"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("fals"), std::invalid_argument);
}
SECTION("number (int)")
{
// accept the exact values
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("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("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("17e0") == JSON(17));
CHECK(JSON::parse("17e1") == JSON(170));
CHECK(JSON::parse("17e3") == JSON(17000));
CHECK(JSON::parse("17e+0") == JSON(17));
CHECK(JSON::parse("17e+1") == JSON(170));
CHECK(JSON::parse("17e+3") == JSON(17000));
CHECK(JSON::parse("17E0") == JSON(17));
CHECK(JSON::parse("17E1") == JSON(170));
CHECK(JSON::parse("17E3") == JSON(17000));
CHECK(JSON::parse("17E+0") == JSON(17));
CHECK(JSON::parse("17E+1") == JSON(170));
CHECK(JSON::parse("17E+3") == JSON(17000));
CHECK(JSON::parse("10000e-0") == JSON(10000));
CHECK(JSON::parse("10000e-1") == JSON(1000));
CHECK(JSON::parse("10000e-4") == JSON(1));
CHECK(JSON::parse("10000E-0") == JSON(10000));
CHECK(JSON::parse("10000E-1") == JSON(1000));
CHECK(JSON::parse("10000E-4") == JSON(1));
CHECK(JSON::parse("17.0e0") == JSON(17));
CHECK(JSON::parse("17.0e1") == JSON(170));
CHECK(JSON::parse("17.0e3") == JSON(17000));
CHECK(JSON::parse("17.0e+0") == JSON(17));
CHECK(JSON::parse("17.0e+1") == JSON(170));
CHECK(JSON::parse("17.0e+3") == JSON(17000));
CHECK(JSON::parse("17.0E0") == JSON(17));
CHECK(JSON::parse("17.0E1") == JSON(170));
CHECK(JSON::parse("17.0E3") == JSON(17000));
CHECK(JSON::parse("17.0E+0") == JSON(17));
CHECK(JSON::parse("17.0E+1") == JSON(170));
CHECK(JSON::parse("17.0E+3") == JSON(17000));
CHECK(JSON::parse("10000.0e-0") == JSON(10000));
CHECK(JSON::parse("10000.0e-1") == JSON(1000));
CHECK(JSON::parse("10000.0e-4") == JSON(1));
CHECK(JSON::parse("10000.0E-0") == JSON(10000));
CHECK(JSON::parse("10000.0E-1") == JSON(1000));
CHECK(JSON::parse("10000.0E-4") == JSON(1));
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("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("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("17e0") == json(17));
CHECK(json::parse("17e1") == json(170));
CHECK(json::parse("17e3") == json(17000));
CHECK(json::parse("17e+0") == json(17));
CHECK(json::parse("17e+1") == json(170));
CHECK(json::parse("17e+3") == json(17000));
CHECK(json::parse("17E0") == json(17));
CHECK(json::parse("17E1") == json(170));
CHECK(json::parse("17E3") == json(17000));
CHECK(json::parse("17E+0") == json(17));
CHECK(json::parse("17E+1") == json(170));
CHECK(json::parse("17E+3") == json(17000));
CHECK(json::parse("10000e-0") == json(10000));
CHECK(json::parse("10000e-1") == json(1000));
CHECK(json::parse("10000e-4") == json(1));
CHECK(json::parse("10000E-0") == json(10000));
CHECK(json::parse("10000E-1") == json(1000));
CHECK(json::parse("10000E-4") == json(1));
CHECK(json::parse("17.0e0") == json(17));
CHECK(json::parse("17.0e1") == json(170));
CHECK(json::parse("17.0e3") == json(17000));
CHECK(json::parse("17.0e+0") == json(17));
CHECK(json::parse("17.0e+1") == json(170));
CHECK(json::parse("17.0e+3") == json(17000));
CHECK(json::parse("17.0E0") == json(17));
CHECK(json::parse("17.0E1") == json(170));
CHECK(json::parse("17.0E3") == json(17000));
CHECK(json::parse("17.0E+0") == json(17));
CHECK(json::parse("17.0E+1") == json(170));
CHECK(json::parse("17.0E+3") == json(17000));
CHECK(json::parse("10000.0e-0") == json(10000));
CHECK(json::parse("10000.0e-1") == json(1000));
CHECK(json::parse("10000.0e-4") == json(1));
CHECK(json::parse("10000.0E-0") == json(10000));
CHECK(json::parse("10000.0E-1") == json(1000));
CHECK(json::parse("10000.0E-4") == json(1));
// 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
//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
CHECK_THROWS_AS(JSON::parse("--1"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("--1"), std::invalid_argument);
// 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("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("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("INFINITY"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("infinity"), std::invalid_argument);
}
SECTION("number (float)")
{
// accept the exact values
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("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.5e1") == JSON(175));
CHECK(JSON::parse("17.5e3") == JSON(17500));
CHECK(JSON::parse("17.5e+0") == JSON(17.5));
CHECK(JSON::parse("17.5e+1") == JSON(175));
CHECK(JSON::parse("17.5e+3") == JSON(17500));
CHECK(JSON::parse("17.5E0") == JSON(17.5));
CHECK(JSON::parse("17.5E1") == JSON(175));
CHECK(JSON::parse("17.5E3") == JSON(17500));
CHECK(JSON::parse("17.5E+0") == JSON(17.5));
CHECK(JSON::parse("17.5E+1") == JSON(175));
CHECK(JSON::parse("17.5E+3") == JSON(17500));
CHECK(JSON::parse("10000.5e-0") == JSON(10000.5));
CHECK(JSON::parse("10000.5e-1") == JSON(1000.05));
CHECK(JSON::parse("10000.5e-4") == JSON(1.00005));
CHECK(JSON::parse("10000.5E-0") == JSON(10000.5));
CHECK(JSON::parse("10000.5E-1") == JSON(1000.05));
CHECK(JSON::parse("10000.5E-4") == JSON(1.00005));
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("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.5e1") == json(175));
CHECK(json::parse("17.5e3") == json(17500));
CHECK(json::parse("17.5e+0") == json(17.5));
CHECK(json::parse("17.5e+1") == json(175));
CHECK(json::parse("17.5e+3") == json(17500));
CHECK(json::parse("17.5E0") == json(17.5));
CHECK(json::parse("17.5E1") == json(175));
CHECK(json::parse("17.5E3") == json(17500));
CHECK(json::parse("17.5E+0") == json(17.5));
CHECK(json::parse("17.5E+1") == json(175));
CHECK(json::parse("17.5E+3") == json(17500));
CHECK(json::parse("10000.5e-0") == json(10000.5));
CHECK(json::parse("10000.5e-1") == json(1000.05));
CHECK(json::parse("10000.5e-4") == json(1.00005));
CHECK(json::parse("10000.5E-0") == json(10000.5));
CHECK(json::parse("10000.5E-1") == json(1000.05));
CHECK(json::parse("10000.5E-4") == json(1.00005));
}
SECTION("parse from C++ string")
{
std::string s = "{ \"foo\": [1,2,true] }";
JSON j = JSON::parse(s);
json j = json::parse(s);
CHECK(j["foo"].size() == 3);
}
......@@ -1762,7 +1762,7 @@ TEST_CASE("Parser")
{
std::stringstream s;
s << "{ \"foo\": [1,2,true] }";
JSON j;
json j;
j << s;
CHECK(j["foo"].size() == 3);
}
......@@ -1770,7 +1770,7 @@ TEST_CASE("Parser")
SECTION("user-defined string literal operator")
{
auto j1 = "[1,2,3]"_json;
JSON j2 = {1, 2, 3};
json j2 = {1, 2, 3};
CHECK(j1 == j2);
auto j3 = "{\"key\": \"value\"}"_json;
......@@ -1779,8 +1779,8 @@ TEST_CASE("Parser")
SECTION("Errors")
{
CHECK_THROWS_AS(JSON::parse(""), 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(""), std::invalid_argument);
CHECK_THROWS_AS(json::parse(std::string("")), 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