From c012b29ae5397af1608842ba915ad6b4133a0301 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 8 Jul 2015 16:55:29 +0200 Subject: [PATCH] worked on #102: more documentation and examples --- doc/Makefile | 2 + doc/examples/operator__equal.cpp | 23 +++ doc/examples/operator__equal.link | 1 + doc/examples/operator__equal.output | 4 + doc/examples/operator__greater.cpp | 23 +++ doc/examples/operator__greater.link | 1 + doc/examples/operator__greater.output | 4 + doc/examples/operator__greaterequal.cpp | 23 +++ doc/examples/operator__greaterequal.link | 1 + doc/examples/operator__greaterequal.output | 4 + doc/examples/operator__less.cpp | 23 +++ doc/examples/operator__less.link | 1 + doc/examples/operator__less.output | 4 + doc/examples/operator__lessequal.cpp | 23 +++ doc/examples/operator__lessequal.link | 1 + doc/examples/operator__lessequal.output | 4 + doc/examples/operator__notequal.cpp | 23 +++ doc/examples/operator__notequal.link | 1 + doc/examples/operator__notequal.output | 4 + doc/examples/push_back.cpp | 24 +++ doc/examples/push_back.link | 1 + doc/examples/push_back.output | 4 + doc/examples/push_back__object_t__value.cpp | 24 +++ doc/examples/push_back__object_t__value.link | 1 + .../push_back__object_t__value.output | 4 + doc/examples/swap__object_t.cpp | 19 ++ doc/examples/swap__object_t.link | 1 + doc/examples/swap__object_t.output | 2 + doc/examples/swap__string_t.cpp | 19 ++ doc/examples/swap__string_t.link | 1 + doc/examples/swap__string_t.output | 2 + src/json.hpp | 176 +++++++++++++----- src/json.hpp.re2c | 176 +++++++++++++----- 33 files changed, 538 insertions(+), 86 deletions(-) create mode 100644 doc/examples/operator__equal.cpp create mode 100644 doc/examples/operator__equal.link create mode 100644 doc/examples/operator__equal.output create mode 100644 doc/examples/operator__greater.cpp create mode 100644 doc/examples/operator__greater.link create mode 100644 doc/examples/operator__greater.output create mode 100644 doc/examples/operator__greaterequal.cpp create mode 100644 doc/examples/operator__greaterequal.link create mode 100644 doc/examples/operator__greaterequal.output create mode 100644 doc/examples/operator__less.cpp create mode 100644 doc/examples/operator__less.link create mode 100644 doc/examples/operator__less.output create mode 100644 doc/examples/operator__lessequal.cpp create mode 100644 doc/examples/operator__lessequal.link create mode 100644 doc/examples/operator__lessequal.output create mode 100644 doc/examples/operator__notequal.cpp create mode 100644 doc/examples/operator__notequal.link create mode 100644 doc/examples/operator__notequal.output create mode 100644 doc/examples/push_back.cpp create mode 100644 doc/examples/push_back.link create mode 100644 doc/examples/push_back.output create mode 100644 doc/examples/push_back__object_t__value.cpp create mode 100644 doc/examples/push_back__object_t__value.link create mode 100644 doc/examples/push_back__object_t__value.output create mode 100644 doc/examples/swap__object_t.cpp create mode 100644 doc/examples/swap__object_t.link create mode 100644 doc/examples/swap__object_t.output create mode 100644 doc/examples/swap__string_t.cpp create mode 100644 doc/examples/swap__string_t.link create mode 100644 doc/examples/swap__string_t.output diff --git a/doc/Makefile b/doc/Makefile index cee6129e..b303a785 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,5 +1,7 @@ SRCDIR = ../src +all: doxygen + clean: rm -fr me.nlohmann.json.docset html diff --git a/doc/examples/operator__equal.cpp b/doc/examples/operator__equal.cpp new file mode 100644 index 00000000..e40dc964 --- /dev/null +++ b/doc/examples/operator__equal.cpp @@ -0,0 +1,23 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.000000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " == " << array_2 << " " << (array_1 == array_2) << '\n'; + std::cout << object_1 << " == " << object_2 << " " << (object_1 == object_2) << '\n'; + std::cout << number_1 << " == " << number_2 << " " << (number_1 == number_2) << '\n'; + std::cout << string_1 << " == " << string_2 << " " << (string_1 == string_2) << '\n'; +} diff --git a/doc/examples/operator__equal.link b/doc/examples/operator__equal.link new file mode 100644 index 00000000..28e82044 --- /dev/null +++ b/doc/examples/operator__equal.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/operator__equal.output b/doc/examples/operator__equal.output new file mode 100644 index 00000000..e9dfd755 --- /dev/null +++ b/doc/examples/operator__equal.output @@ -0,0 +1,4 @@ +[1,2,3] == [1,2,4] false +{"A":"a","B":"b"} == {"A":"a","B":"b"} true +17 == 17 true +"foo" == "bar" false diff --git a/doc/examples/operator__greater.cpp b/doc/examples/operator__greater.cpp new file mode 100644 index 00000000..bd78b0ce --- /dev/null +++ b/doc/examples/operator__greater.cpp @@ -0,0 +1,23 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " == " << array_2 << " " << (array_1 > array_2) << '\n'; + std::cout << object_1 << " == " << object_2 << " " << (object_1 > object_2) << '\n'; + std::cout << number_1 << " == " << number_2 << " " << (number_1 > number_2) << '\n'; + std::cout << string_1 << " == " << string_2 << " " << (string_1 > string_2) << '\n'; +} diff --git a/doc/examples/operator__greater.link b/doc/examples/operator__greater.link new file mode 100644 index 00000000..5b13ba11 --- /dev/null +++ b/doc/examples/operator__greater.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/operator__greater.output b/doc/examples/operator__greater.output new file mode 100644 index 00000000..045847c3 --- /dev/null +++ b/doc/examples/operator__greater.output @@ -0,0 +1,4 @@ +[1,2,3] == [1,2,4] false +{"A":"a","B":"b"} == {"A":"a","B":"b"} false +17 == 17.0000000000001 false +"foo" == "bar" true diff --git a/doc/examples/operator__greaterequal.cpp b/doc/examples/operator__greaterequal.cpp new file mode 100644 index 00000000..df73b515 --- /dev/null +++ b/doc/examples/operator__greaterequal.cpp @@ -0,0 +1,23 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " >= " << array_2 << " " << (array_1 >= array_2) << '\n'; + std::cout << object_1 << " >= " << object_2 << " " << (object_1 >= object_2) << '\n'; + std::cout << number_1 << " >= " << number_2 << " " << (number_1 >= number_2) << '\n'; + std::cout << string_1 << " >= " << string_2 << " " << (string_1 >= string_2) << '\n'; +} diff --git a/doc/examples/operator__greaterequal.link b/doc/examples/operator__greaterequal.link new file mode 100644 index 00000000..76203276 --- /dev/null +++ b/doc/examples/operator__greaterequal.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/operator__greaterequal.output b/doc/examples/operator__greaterequal.output new file mode 100644 index 00000000..c7b91514 --- /dev/null +++ b/doc/examples/operator__greaterequal.output @@ -0,0 +1,4 @@ +[1,2,3] >= [1,2,4] false +{"A":"a","B":"b"} >= {"A":"a","B":"b"} true +17 >= 17.0000000000001 false +"foo" >= "bar" true diff --git a/doc/examples/operator__less.cpp b/doc/examples/operator__less.cpp new file mode 100644 index 00000000..68afac04 --- /dev/null +++ b/doc/examples/operator__less.cpp @@ -0,0 +1,23 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " == " << array_2 << " " << (array_1 < array_2) << '\n'; + std::cout << object_1 << " == " << object_2 << " " << (object_1 < object_2) << '\n'; + std::cout << number_1 << " == " << number_2 << " " << (number_1 < number_2) << '\n'; + std::cout << string_1 << " == " << string_2 << " " << (string_1 < string_2) << '\n'; +} diff --git a/doc/examples/operator__less.link b/doc/examples/operator__less.link new file mode 100644 index 00000000..949c3f83 --- /dev/null +++ b/doc/examples/operator__less.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/operator__less.output b/doc/examples/operator__less.output new file mode 100644 index 00000000..abbbc455 --- /dev/null +++ b/doc/examples/operator__less.output @@ -0,0 +1,4 @@ +[1,2,3] == [1,2,4] true +{"A":"a","B":"b"} == {"A":"a","B":"b"} false +17 == 17.0000000000001 true +"foo" == "bar" false diff --git a/doc/examples/operator__lessequal.cpp b/doc/examples/operator__lessequal.cpp new file mode 100644 index 00000000..98f99b4d --- /dev/null +++ b/doc/examples/operator__lessequal.cpp @@ -0,0 +1,23 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " <= " << array_2 << " " << (array_1 <= array_2) << '\n'; + std::cout << object_1 << " <= " << object_2 << " " << (object_1 <= object_2) << '\n'; + std::cout << number_1 << " <= " << number_2 << " " << (number_1 <= number_2) << '\n'; + std::cout << string_1 << " <= " << string_2 << " " << (string_1 <= string_2) << '\n'; +} diff --git a/doc/examples/operator__lessequal.link b/doc/examples/operator__lessequal.link new file mode 100644 index 00000000..8e2c58aa --- /dev/null +++ b/doc/examples/operator__lessequal.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/operator__lessequal.output b/doc/examples/operator__lessequal.output new file mode 100644 index 00000000..f7f0327e --- /dev/null +++ b/doc/examples/operator__lessequal.output @@ -0,0 +1,4 @@ +[1,2,3] <= [1,2,4] true +{"A":"a","B":"b"} <= {"A":"a","B":"b"} true +17 <= 17.0000000000001 true +"foo" <= "bar" false diff --git a/doc/examples/operator__notequal.cpp b/doc/examples/operator__notequal.cpp new file mode 100644 index 00000000..27182b25 --- /dev/null +++ b/doc/examples/operator__notequal.cpp @@ -0,0 +1,23 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.000000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " == " << array_2 << " " << (array_1 != array_2) << '\n'; + std::cout << object_1 << " == " << object_2 << " " << (object_1 != object_2) << '\n'; + std::cout << number_1 << " == " << number_2 << " " << (number_1 != number_2) << '\n'; + std::cout << string_1 << " == " << string_2 << " " << (string_1 != string_2) << '\n'; +} diff --git a/doc/examples/operator__notequal.link b/doc/examples/operator__notequal.link new file mode 100644 index 00000000..6a9d08f5 --- /dev/null +++ b/doc/examples/operator__notequal.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/operator__notequal.output b/doc/examples/operator__notequal.output new file mode 100644 index 00000000..ddd838b4 --- /dev/null +++ b/doc/examples/operator__notequal.output @@ -0,0 +1,4 @@ +[1,2,3] == [1,2,4] true +{"A":"a","B":"b"} == {"A":"a","B":"b"} false +17 == 17 false +"foo" == "bar" true diff --git a/doc/examples/push_back.cpp b/doc/examples/push_back.cpp new file mode 100644 index 00000000..8599999c --- /dev/null +++ b/doc/examples/push_back.cpp @@ -0,0 +1,24 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json array = {1, 2, 3, 4, 5}; + json null; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; + + // add values + array.push_back(6); + array += 7; + null += "first"; + null += "second"; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; +} diff --git a/doc/examples/push_back.link b/doc/examples/push_back.link new file mode 100644 index 00000000..a1781b84 --- /dev/null +++ b/doc/examples/push_back.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/push_back.output b/doc/examples/push_back.output new file mode 100644 index 00000000..3306b60e --- /dev/null +++ b/doc/examples/push_back.output @@ -0,0 +1,4 @@ +[1,2,3,4,5] +null +[1,2,3,4,5,6,7] +["first","second"] diff --git a/doc/examples/push_back__object_t__value.cpp b/doc/examples/push_back__object_t__value.cpp new file mode 100644 index 00000000..92f1c210 --- /dev/null +++ b/doc/examples/push_back__object_t__value.cpp @@ -0,0 +1,24 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values + object.push_back(json::object_t::value_type("three", 3)); + object += json::object_t::value_type("four", 4); + null += json::object_t::value_type("A", "a"); + null += json::object_t::value_type("B", "b"); + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; +} diff --git a/doc/examples/push_back__object_t__value.link b/doc/examples/push_back__object_t__value.link new file mode 100644 index 00000000..4744be03 --- /dev/null +++ b/doc/examples/push_back__object_t__value.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/push_back__object_t__value.output b/doc/examples/push_back__object_t__value.output new file mode 100644 index 00000000..b8a7d356 --- /dev/null +++ b/doc/examples/push_back__object_t__value.output @@ -0,0 +1,4 @@ +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +{"A":"a","B":"b"} diff --git a/doc/examples/swap__object_t.cpp b/doc/examples/swap__object_t.cpp new file mode 100644 index 00000000..aaed2fc4 --- /dev/null +++ b/doc/examples/swap__object_t.cpp @@ -0,0 +1,19 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create a JSON value + json value = { {"translation", {{"one", "eins"}, {"two", "zwei"}}} }; + + // create an object_t + json::object_t object = {{"cow", "Kuh"}, {"dog", "Hund"}}; + + // swap the object stored in the JSON value + value["translation"].swap(object); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "object = " << object << '\n'; +} diff --git a/doc/examples/swap__object_t.link b/doc/examples/swap__object_t.link new file mode 100644 index 00000000..6063f815 --- /dev/null +++ b/doc/examples/swap__object_t.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/swap__object_t.output b/doc/examples/swap__object_t.output new file mode 100644 index 00000000..b5c9791b --- /dev/null +++ b/doc/examples/swap__object_t.output @@ -0,0 +1,2 @@ +value = {"translation":{"cow":"Kuh","dog":"Hund"}} +object = {"one":"eins","two":"zwei"} diff --git a/doc/examples/swap__string_t.cpp b/doc/examples/swap__string_t.cpp new file mode 100644 index 00000000..4922f7c9 --- /dev/null +++ b/doc/examples/swap__string_t.cpp @@ -0,0 +1,19 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create a JSON value + json value = { "the good", "the bad", "the ugly" }; + + // create string_t + json::string_t string = "the fast"; + + // swap the object stored in the JSON value + value[1].swap(string); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "string = " << string << '\n'; +} diff --git a/doc/examples/swap__string_t.link b/doc/examples/swap__string_t.link new file mode 100644 index 00000000..15d703e2 --- /dev/null +++ b/doc/examples/swap__string_t.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/swap__string_t.output b/doc/examples/swap__string_t.output new file mode 100644 index 00000000..ae2a0976 --- /dev/null +++ b/doc/examples/swap__string_t.output @@ -0,0 +1,2 @@ +value = ["the good","the fast","the ugly"] +string = the bad diff --git a/src/json.hpp b/src/json.hpp index 2a4873b4..b8896637 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -57,11 +57,15 @@ namespace nlohmann { -/// namespace with internal helper functions -namespace internals +/*! +@brief unnamed namespace with internal helper functions +*/ +namespace { -// Helper to determine whether there's a key_type for T. -// http://stackoverflow.com/a/7728728/266378 +/*! +@brief Helper to determine whether there's a key_type for T. +@sa http://stackoverflow.com/a/7728728/266378 +*/ template struct has_mapped_type { @@ -71,6 +75,13 @@ struct has_mapped_type public: enum { value = sizeof(test(0)) == sizeof(char) }; }; + +/// "equality" comparison for floating point numbers +template +static bool approx(const T a, const T b) +{ + return not (a > b or a < b); +} } /*! @@ -107,7 +118,6 @@ http://en.cppreference.com/w/cpp/concept/Container): @note ObjectType trick from http://stackoverflow.com/a/9860911 @see RFC 7159 -@see ECMA 404 */ template < template class ObjectType = std::map, @@ -120,6 +130,13 @@ template < > class basic_json { + private: + /// workaround type for MSVC + using __basic_json = + basic_json; + + public: + ///////////////////// // container types // ///////////////////// @@ -127,12 +144,6 @@ class basic_json /// @name container types /// @{ - private: - /// workaround type for MSVC - using __basic_json = - basic_json; - - public: /// the type of elements in a basic_json container using value_type = basic_json; @@ -1711,7 +1722,7 @@ class basic_json not std::is_same<__basic_json, typename T::value_type>::value and not std::is_arithmetic::value and not std::is_convertible::value and - not internals::has_mapped_type::value + not has_mapped_type::value , int>::type = 0> T get_impl(T*) const { @@ -1766,7 +1777,7 @@ class basic_json template ::value and - not internals::has_mapped_type::value + not has_mapped_type::value , int>::type = 0> T get_impl(T*) const { @@ -3322,7 +3333,23 @@ class basic_json } } - /// add an object to an array + /*! + @brief add an object to an array + + Appends the given element @a value to the end of the JSON value. If the + function is called on a JSON null value, an empty array is created before + appending @a value. + + @param value the value to add to the JSON array + + @throw std::domain_error when called on a type other than JSON array or null + + @complexity Amortized constant. + + @liveexample{The example shows how `push_back` and `+=` can be used to add + elements to a JSON array. Note how the `null` value was silently converted + to a JSON array.,push_back} + */ void push_back(basic_json&& value) { // push_back only works for null objects or arrays @@ -3344,14 +3371,20 @@ class basic_json value.m_type = value_t::null; } - /// add an object to an array + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ reference operator+=(basic_json&& value) { push_back(std::move(value)); return *this; } - /// add an object to an array + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ void push_back(const basic_json& value) { // push_back only works for null objects or arrays @@ -3371,14 +3404,34 @@ class basic_json m_value.array->push_back(value); } - /// add an object to an array + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ reference operator+=(const basic_json& value) { push_back(value); return *this; } - /// add an object to an object + /*! + @brief add an object to an object + + Inserts the given element @a value to the JSON object. If the function is + called on a JSON null value, an empty object is created before inserting @a + value. + + @param value the value to add to the JSON object + + @throw std::domain_error when called on a type other than JSON object or + null + + @complexity Logarithmic in the size of the container, O(log(`size()`)). + + @liveexample{The example shows how `push_back` and `+=` can be used to add + elements to a JSON object. Note how the `null` value was silently converted + to a JSON object.,push_back__object_t__value} + */ void push_back(const typename object_t::value_type& value) { // push_back only works for null objects or objects @@ -3398,7 +3451,10 @@ class basic_json m_value.object->insert(value); } - /// add an object to an object + /*! + @brief add an object to an object + @copydoc push_back(const typename object_t::value_type&) + */ reference operator+=(const typename object_t::value_type& value) { push_back(value); @@ -3464,7 +3520,25 @@ class basic_json std::swap(*(m_value.array), other); } - /// swaps the contents + /*! + @brief exchanges the values + + Exchanges the contents of a JSON object with those of @a other. Does not + invoke any move, copy, or swap operations on individual elements. All + iterators and references remain valid. The past-the-end iterator is + invalidated. + + @param[in,out] other object to exchange the contents with + + @throw std::domain_error when JSON value is not an object + + @complexity Constant. + + @liveexample{The example below shows how JSON values can be + swapped.,swap__object_t} + + @ingroup container + */ void swap(object_t& other) { // swap only works for objects @@ -3473,11 +3547,29 @@ class basic_json throw std::domain_error("cannot use swap() with " + type_name()); } - // swap arrays + // swap objects std::swap(*(m_value.object), other); } - /// swaps the contents + /*! + @brief exchanges the values + + Exchanges the contents of a JSON string with those of @a other. Does not + invoke any move, copy, or swap operations on individual elements. All + iterators and references remain valid. The past-the-end iterator is + invalidated. + + @param[in,out] other string to exchange the contents with + + @throw std::domain_error when JSON value is not a string + + @complexity Constant. + + @liveexample{The example below shows how JSON values can be + swapped.,swap__string_t} + + @ingroup container + */ void swap(string_t& other) { // swap only works for strings @@ -3486,7 +3578,7 @@ class basic_json throw std::domain_error("cannot use swap() with " + type_name()); } - // swap arrays + // swap strings std::swap(*(m_value.string), other); } @@ -3518,7 +3610,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__equal} @ingroup container */ @@ -3573,7 +3666,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__notequal} @ingroup container */ @@ -3601,7 +3695,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__less} */ friend bool operator<(const_reference lhs, const_reference rhs) noexcept { @@ -3658,7 +3753,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__greater} */ friend bool operator<=(const_reference lhs, const_reference rhs) noexcept { @@ -3677,7 +3773,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__lessequal} */ friend bool operator>(const_reference lhs, const_reference rhs) noexcept { @@ -3696,7 +3793,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__greaterequal} */ friend bool operator>=(const_reference lhs, const_reference rhs) noexcept { @@ -4132,14 +4230,6 @@ class basic_json } } - /// "equality" comparison for floating point numbers - template - static bool approx(const T a, const T b) - { - return not (a > b or a < b); - } - - private: ////////////////////// // member variables // @@ -5445,7 +5535,7 @@ class basic_json This class organizes the lexical analysis during JSON deserialization. The core of it is a scanner generated by re2c that processes - a buffer and recognizes tokens according to RFC 7159 and ECMA-404. + a buffer and recognizes tokens according to RFC 7159. */ class lexer { @@ -5609,11 +5699,11 @@ class basic_json /*! This function implements a scanner for JSON. It is specified using - regular expressions that try to follow RFC 7159 and ECMA-404 as close - as possible. These regular expressions are then translated into a - deterministic finite automaton (DFA) by the tool re2c - . As a result, the translated code for this function - consists of a large block of code with goto jumps. + regular expressions that try to follow RFC 7159 as close as possible. + These regular expressions are then translated into a deterministic + finite automaton (DFA) by the tool re2c . As a result, + the translated code for this function consists of a large block of code + with goto jumps. @return the class of the next token read from the buffer */ diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 4258015f..bc823d60 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -57,11 +57,15 @@ namespace nlohmann { -/// namespace with internal helper functions -namespace internals +/*! +@brief unnamed namespace with internal helper functions +*/ +namespace { -// Helper to determine whether there's a key_type for T. -// http://stackoverflow.com/a/7728728/266378 +/*! +@brief Helper to determine whether there's a key_type for T. +@sa http://stackoverflow.com/a/7728728/266378 +*/ template struct has_mapped_type { @@ -71,6 +75,13 @@ struct has_mapped_type public: enum { value = sizeof(test(0)) == sizeof(char) }; }; + +/// "equality" comparison for floating point numbers +template +static bool approx(const T a, const T b) +{ + return not (a > b or a < b); +} } /*! @@ -107,7 +118,6 @@ http://en.cppreference.com/w/cpp/concept/Container): @note ObjectType trick from http://stackoverflow.com/a/9860911 @see RFC 7159 -@see ECMA 404 */ template < template class ObjectType = std::map, @@ -120,6 +130,13 @@ template < > class basic_json { + private: + /// workaround type for MSVC + using __basic_json = + basic_json; + + public: + ///////////////////// // container types // ///////////////////// @@ -127,12 +144,6 @@ class basic_json /// @name container types /// @{ - private: - /// workaround type for MSVC - using __basic_json = - basic_json; - - public: /// the type of elements in a basic_json container using value_type = basic_json; @@ -1711,7 +1722,7 @@ class basic_json not std::is_same<__basic_json, typename T::value_type>::value and not std::is_arithmetic::value and not std::is_convertible::value and - not internals::has_mapped_type::value + not has_mapped_type::value , int>::type = 0> T get_impl(T*) const { @@ -1766,7 +1777,7 @@ class basic_json template ::value and - not internals::has_mapped_type::value + not has_mapped_type::value , int>::type = 0> T get_impl(T*) const { @@ -3322,7 +3333,23 @@ class basic_json } } - /// add an object to an array + /*! + @brief add an object to an array + + Appends the given element @a value to the end of the JSON value. If the + function is called on a JSON null value, an empty array is created before + appending @a value. + + @param value the value to add to the JSON array + + @throw std::domain_error when called on a type other than JSON array or null + + @complexity Amortized constant. + + @liveexample{The example shows how `push_back` and `+=` can be used to add + elements to a JSON array. Note how the `null` value was silently converted + to a JSON array.,push_back} + */ void push_back(basic_json&& value) { // push_back only works for null objects or arrays @@ -3344,14 +3371,20 @@ class basic_json value.m_type = value_t::null; } - /// add an object to an array + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ reference operator+=(basic_json&& value) { push_back(std::move(value)); return *this; } - /// add an object to an array + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ void push_back(const basic_json& value) { // push_back only works for null objects or arrays @@ -3371,14 +3404,34 @@ class basic_json m_value.array->push_back(value); } - /// add an object to an array + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ reference operator+=(const basic_json& value) { push_back(value); return *this; } - /// add an object to an object + /*! + @brief add an object to an object + + Inserts the given element @a value to the JSON object. If the function is + called on a JSON null value, an empty object is created before inserting @a + value. + + @param value the value to add to the JSON object + + @throw std::domain_error when called on a type other than JSON object or + null + + @complexity Logarithmic in the size of the container, O(log(`size()`)). + + @liveexample{The example shows how `push_back` and `+=` can be used to add + elements to a JSON object. Note how the `null` value was silently converted + to a JSON object.,push_back__object_t__value} + */ void push_back(const typename object_t::value_type& value) { // push_back only works for null objects or objects @@ -3398,7 +3451,10 @@ class basic_json m_value.object->insert(value); } - /// add an object to an object + /*! + @brief add an object to an object + @copydoc push_back(const typename object_t::value_type&) + */ reference operator+=(const typename object_t::value_type& value) { push_back(value); @@ -3464,7 +3520,25 @@ class basic_json std::swap(*(m_value.array), other); } - /// swaps the contents + /*! + @brief exchanges the values + + Exchanges the contents of a JSON object with those of @a other. Does not + invoke any move, copy, or swap operations on individual elements. All + iterators and references remain valid. The past-the-end iterator is + invalidated. + + @param[in,out] other object to exchange the contents with + + @throw std::domain_error when JSON value is not an object + + @complexity Constant. + + @liveexample{The example below shows how JSON values can be + swapped.,swap__object_t} + + @ingroup container + */ void swap(object_t& other) { // swap only works for objects @@ -3473,11 +3547,29 @@ class basic_json throw std::domain_error("cannot use swap() with " + type_name()); } - // swap arrays + // swap objects std::swap(*(m_value.object), other); } - /// swaps the contents + /*! + @brief exchanges the values + + Exchanges the contents of a JSON string with those of @a other. Does not + invoke any move, copy, or swap operations on individual elements. All + iterators and references remain valid. The past-the-end iterator is + invalidated. + + @param[in,out] other string to exchange the contents with + + @throw std::domain_error when JSON value is not a string + + @complexity Constant. + + @liveexample{The example below shows how JSON values can be + swapped.,swap__string_t} + + @ingroup container + */ void swap(string_t& other) { // swap only works for strings @@ -3486,7 +3578,7 @@ class basic_json throw std::domain_error("cannot use swap() with " + type_name()); } - // swap arrays + // swap strings std::swap(*(m_value.string), other); } @@ -3518,7 +3610,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__equal} @ingroup container */ @@ -3573,7 +3666,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__notequal} @ingroup container */ @@ -3601,7 +3695,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__less} */ friend bool operator<(const_reference lhs, const_reference rhs) noexcept { @@ -3658,7 +3753,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__greater} */ friend bool operator<=(const_reference lhs, const_reference rhs) noexcept { @@ -3677,7 +3773,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__lessequal} */ friend bool operator>(const_reference lhs, const_reference rhs) noexcept { @@ -3696,7 +3793,8 @@ class basic_json @complexity Linear. - @todo Add example. + @liveexample{The example demonstrates comparing several JSON + types.,operator__greaterequal} */ friend bool operator>=(const_reference lhs, const_reference rhs) noexcept { @@ -4132,14 +4230,6 @@ class basic_json } } - /// "equality" comparison for floating point numbers - template - static bool approx(const T a, const T b) - { - return not (a > b or a < b); - } - - private: ////////////////////// // member variables // @@ -5445,7 +5535,7 @@ class basic_json This class organizes the lexical analysis during JSON deserialization. The core of it is a scanner generated by re2c that processes - a buffer and recognizes tokens according to RFC 7159 and ECMA-404. + a buffer and recognizes tokens according to RFC 7159. */ class lexer { @@ -5609,11 +5699,11 @@ class basic_json /*! This function implements a scanner for JSON. It is specified using - regular expressions that try to follow RFC 7159 and ECMA-404 as close - as possible. These regular expressions are then translated into a - deterministic finite automaton (DFA) by the tool re2c - . As a result, the translated code for this function - consists of a large block of code with goto jumps. + regular expressions that try to follow RFC 7159 as close as possible. + These regular expressions are then translated into a deterministic + finite automaton (DFA) by the tool re2c . As a result, + the translated code for this function consists of a large block of code + with goto jumps. @return the class of the next token read from the buffer */