From f63ff7727eb96dd7736fe6aa9c2c236531457cb3 Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 4 Jan 2015 20:43:25 +0100 Subject: [PATCH] renamed class from "JSON" to "son" --- Makefile.am | 6 +- README.md | 32 +- benchmark/parse.cc | 4 +- configure.ac | 2 +- doc/Reference.md | 30 +- src/{JSON.cc => json.cc} | 324 +++++------ src/{JSON.h => json.h} | 160 +++--- test/{JSON_unit.cc => json_unit.cc} | 838 ++++++++++++++-------------- 8 files changed, 698 insertions(+), 698 deletions(-) rename src/{JSON.cc => json.cc} (87%) rename src/{JSON.h => json.h} (77%) rename test/{JSON_unit.cc => json_unit.cc} (65%) diff --git a/Makefile.am b/Makefile.am index ce095de3..9310afa6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/README.md b/README.md index 1efa25fd..600af59f 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/benchmark/parse.cc b/benchmark/parse.cc index 02547afe..4ad5c079 100644 --- a/benchmark/parse.cc +++ b/benchmark/parse.cc @@ -1,8 +1,8 @@ -#include "JSON.h" +#include "json.h" int main() { - JSON j; + json j; j << std::cin; return 0; } diff --git a/configure.ac b/configure.ac index c4366568..18a30c6c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ 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]) diff --git a/doc/Reference.md b/doc/Reference.md index 0316fefd..5b11d98a 100644 --- a/doc/Reference.md +++ b/doc/Reference.md @@ -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::array_t` | `{}` | -| object | `value_type::object` | `std::map` | `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::array_t` | `{}` | +| object | `value_type::object` | `std::map` | `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` 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` 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` 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` type, `json::object_t` type, `json::object_t&&` rvalue reference | `{ {"key1", 42}, {"key2", false} }` | ## Number types diff --git a/src/JSON.cc b/src/json.cc similarity index 87% rename from src/JSON.cc rename to src/json.cc index 3c13b155..b7702080 100644 --- a/src/JSON.cc +++ b/src/json.cc @@ -9,7 +9,7 @@ @see https://github.com/nlohmann/json */ -#include "JSON.h" +#include "json.h" #include // std::isdigit, std::isspace #include // 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(); } -JSON::operator int() const +json::operator int() const { return get(); } -JSON::operator double() const +json::operator double() const { return get(); } -JSON::operator bool() const +json::operator bool() const { return get(); } -JSON::operator array_t() const +json::operator array_t() const { return get(); } -JSON::operator object_t() const +json::operator object_t() const { return get(); } -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(), 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 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 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); } diff --git a/src/JSON.h b/src/json.h similarity index 77% rename from src/JSON.h rename to src/json.h index 5d512fc4..d8a0526c 100644 --- a/src/JSON.h +++ b/src/json.h @@ -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; + using object_t = std::map; /// a type for an array - using array_t = std::vector; + using array_t = std::vector; /// 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; + using list_init_t = std::initializer_list; /// 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); diff --git a/test/JSON_unit.cc b/test/json_unit.cc similarity index 65% rename from test/JSON_unit.cc rename to test/json_unit.cc index 58fc2238..8bd62922 100644 --- a/test/JSON_unit.cc +++ b/test/json_unit.cc @@ -1,18 +1,18 @@ #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()); - CHECK_THROWS_AS(auto v = j.get(), std::logic_error); + CHECK_NOTHROW(auto v = j.get()); + CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); // transparent usage - auto id = [](JSON::array_t v) + auto id = [](json::array_t v) { return v; }; - CHECK(id(j) == j.get()); + CHECK(id(j) == j.get()); // 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() == v1); + json::array_t v1 = {"string", 1, 1.0, false, nullptr}; + json j1 = v1; + CHECK(j1.get() == v1); - JSON j2 = {"string", 1, 1.0, false, nullptr}; - JSON::array_t v2 = j2; - CHECK(j2.get() == v1); - CHECK(j2.get() == v2); + json j2 = {"string", 1, 1.0, false, nullptr}; + json::array_t v2 = j2; + CHECK(j2.get() == v1); + CHECK(j2.get() == 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 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(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(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() * 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(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(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(), std::logic_error); - CHECK_NOTHROW(auto v = j.get()); + CHECK_THROWS_AS(auto v = j.get(), std::logic_error); + CHECK_NOTHROW(auto v = j.get()); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); // transparent usage - auto id = [](JSON::object_t v) + auto id = [](json::object_t v) { return v; }; - CHECK(id(j) == j.get()); + CHECK(id(j) == j.get()); // 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() == v1); + json::object_t v1 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} }; + json j1 = v1; + CHECK(j1.get() == v1); - JSON j2 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} }; - JSON::object_t v2 = j2; - CHECK(j2.get() == v1); - CHECK(j2.get() == v2); + json j2 = { {"v1", "string"}, {"v2", 1}, {"v3", 1.0}, {"v4", false} }; + json::object_t v2 = j2; + CHECK(j2.get() == v1); + CHECK(j2.get() == 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() == 42); - j += JSON::object_t::value_type {"int_key2", 23}; + j += json::object_t::value_type {"int_key2", 23}; CHECK(j["int_key2"].get() == 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() == 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() == 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() == 1); CHECK(je["two"].get() == false); CHECK(je["three"].size() == 3); } { - JSON je; + json je; je += { {"one", 1}, {"two", false}, {"three", {1, 2, 3}} }; CHECK(je["one"].get() == 1); CHECK(je["two"].get() == 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(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(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(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(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(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()); - CHECK_THROWS_AS(auto v = j.get(), std::logic_error); + CHECK_NOTHROW(auto v = j.get()); + CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), 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()); - CHECK_THROWS_AS(auto v = j.get(), std::logic_error); + CHECK_NOTHROW(auto v = j.get()); + CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_NOTHROW(auto v = j.get()); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); @@ -783,7 +783,7 @@ TEST_CASE("string") CHECK(id(j) == j.get()); // 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() == v1); - JSON j2 = "Hello, world"; + json j2 = "Hello, world"; CHECK(j2.get() == "Hello, world"); std::string v3 = "Hello, world"; - JSON j3 = std::move(v3); + json j3 = std::move(v3); CHECK(j3.get() == "Hello, world"); } SECTION("Operators") { // clear() - JSON j1 = std::string("Hello, world"); + json j1 = std::string("Hello, world"); CHECK(j1.get() == "Hello, world"); j1.clear(); CHECK(j1.get() == ""); @@ -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()); - CHECK_THROWS_AS(auto v = j.get(), std::logic_error); + CHECK_NOTHROW(auto v = j.get()); + CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_NOTHROW(auto v = j.get()); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); @@ -865,7 +865,7 @@ TEST_CASE("boolean") CHECK(id(j) == j.get()); // 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() == v1); - JSON j2 = false; + json j2 = false; bool v2 = j2; CHECK(j2.get() == v2); } @@ -891,7 +891,7 @@ TEST_CASE("boolean") SECTION("Operators") { // clear() - JSON j1 = true; + json j1 = true; CHECK(j1.get() == true); j1.clear(); CHECK(j1.get() == 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()); - CHECK_THROWS_AS(auto v = j.get(), std::logic_error); + CHECK_NOTHROW(auto v = j.get()); + CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_NOTHROW(auto v = j.get()); @@ -944,7 +944,7 @@ TEST_CASE("number (int)") CHECK(id(j) == j.get()); // 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() == v1); - JSON j2 = 42; + json j2 = 42; int v2 = j2; CHECK(j2.get() == v2); } @@ -970,7 +970,7 @@ TEST_CASE("number (int)") SECTION("Operators") { // clear() - JSON j1 = 42; + json j1 = 42; CHECK(j1.get() == 42); j1.clear(); CHECK(j1.get() == 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()); - CHECK_THROWS_AS(auto v = j.get(), std::logic_error); + CHECK_NOTHROW(auto v = j.get()); + CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_THROWS_AS(auto v = j.get(), std::logic_error); CHECK_NOTHROW(auto v = j.get()); @@ -1030,7 +1030,7 @@ TEST_CASE("number (float)") CHECK(id(j) == j.get()); // 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() == v1); - JSON j2 = 2.7182818; + json j2 = 2.7182818; double v2 = j2; CHECK(j2.get() == v2); } @@ -1056,7 +1056,7 @@ TEST_CASE("number (float)") SECTION("Operators") { // clear() - JSON j1 = 3.1415926; + json j1 = 3.1415926; CHECK(j1.get() == 3.1415926); j1.clear(); CHECK(j1.get() == 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"; + 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"; + 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.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_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.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_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") == 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("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("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("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("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("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); } }