From c012b29ae5397af1608842ba915ad6b4133a0301 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/a74tSggkWP5Zo0Ee"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/TZmhplJw3tl08RFN"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/clvCFZxlFEerhtk8"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/85XpxnwbJZR1PVtz"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/JYP6JpBzl8Q9xQDZ"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/csiUCov9Mquff3ZZ"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/5ZglUDvkQ0VxYxQ4"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/xtErbxTG2iIC5wHh"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/g5pkLUCrBVoNPRyE"><b>online</b></a>
\ 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 <json.hpp>
+
+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 @@
+<a target="_blank" href="http://melpon.org/wandbox/permlink/UsEo3yK2GsjH8CyA"><b>online</b></a>
\ 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<typename T>
 struct has_mapped_type
 {
@@ -71,6 +75,13 @@ struct has_mapped_type
   public:
     enum { value = sizeof(test<T>(0)) == sizeof(char) };
 };
+
+/// "equality" comparison for floating point numbers
+template<typename T>
+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 <http://rfc7159.net/rfc7159>
-@see ECMA 404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>
 */
 template <
     template<typename U, typename V, typename... Args> class ObjectType = std::map,
@@ -120,6 +130,13 @@ template <
     >
 class basic_json
 {
+  private:
+    /// workaround type for MSVC
+    using __basic_json =
+        basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>;
+
+  public:
+
     /////////////////////
     // container types //
     /////////////////////
@@ -127,12 +144,6 @@ class basic_json
     /// @name container types
     /// @{
 
-  private:
-    /// workaround type for MSVC
-    using __basic_json =
-        basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>;
-
-  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<T>::value and
                   not std::is_convertible<std::string, T>::value and
-                  not internals::has_mapped_type<T>::value
+                  not has_mapped_type<T>::value
                   , int>::type = 0>
     T get_impl(T*) const
     {
@@ -1766,7 +1777,7 @@ class basic_json
     template <class T, typename
               std::enable_if<
                   std::is_same<basic_json, typename T::value_type>::value and
-                  not internals::has_mapped_type<T>::value
+                  not has_mapped_type<T>::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<typename T>
-    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 <http://re2c.org> 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
-        <http://re2c.org>. 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 <http://re2c.org>. 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<typename T>
 struct has_mapped_type
 {
@@ -71,6 +75,13 @@ struct has_mapped_type
   public:
     enum { value = sizeof(test<T>(0)) == sizeof(char) };
 };
+
+/// "equality" comparison for floating point numbers
+template<typename T>
+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 <http://rfc7159.net/rfc7159>
-@see ECMA 404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>
 */
 template <
     template<typename U, typename V, typename... Args> class ObjectType = std::map,
@@ -120,6 +130,13 @@ template <
     >
 class basic_json
 {
+  private:
+    /// workaround type for MSVC
+    using __basic_json =
+        basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>;
+
+  public:
+
     /////////////////////
     // container types //
     /////////////////////
@@ -127,12 +144,6 @@ class basic_json
     /// @name container types
     /// @{
 
-  private:
-    /// workaround type for MSVC
-    using __basic_json =
-        basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>;
-
-  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<T>::value and
                   not std::is_convertible<std::string, T>::value and
-                  not internals::has_mapped_type<T>::value
+                  not has_mapped_type<T>::value
                   , int>::type = 0>
     T get_impl(T*) const
     {
@@ -1766,7 +1777,7 @@ class basic_json
     template <class T, typename
               std::enable_if<
                   std::is_same<basic_json, typename T::value_type>::value and
-                  not internals::has_mapped_type<T>::value
+                  not has_mapped_type<T>::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<typename T>
-    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 <http://re2c.org> 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
-        <http://re2c.org>. 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 <http://re2c.org>. 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
         */