diff --git a/CMakeLists.txt b/CMakeLists.txt
index a6fc351..4e56052 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -146,9 +146,6 @@
 
 endif(${BMCWEB_BUILD_UT})
 
-# web static assets
-#add_subdirectory(static)
-
 # bmcweb
 add_executable(bmcweb ${WEBSERVER_MAIN} ${HDR_FILES} ${SRC_FILES})
 target_link_libraries(bmcweb boost-dbus)
diff --git a/crow/include/crow/app.h b/crow/include/crow/app.h
index 56434ee..3635b78 100644
--- a/crow/include/crow/app.h
+++ b/crow/include/crow/app.h
@@ -118,7 +118,7 @@
   }
 
   std::vector<std::string> get_routes() { return router_.get_routes(); }
-  std::vector<std::string> get_routes(std::string& parent) {
+  std::vector<std::string> get_routes(const std::string& parent) {
     return router_.get_routes(parent);
   }
 
diff --git a/crow/include/crow/http_connection.h b/crow/include/crow/http_connection.h
index 30d84db..fa0a23c 100644
--- a/crow/include/crow/http_connection.h
+++ b/crow/include/crow/http_connection.h
@@ -29,29 +29,33 @@
 namespace detail {
 template <typename MW>
 struct check_before_handle_arity_3_const {
-  template <typename T, void (T::*)(request&, response&, typename MW::context&)
-                            const = &T::before_handle>
+  template <typename T,
+            void (T::*)(request&, response&, typename MW::context&) const =
+                &T::before_handle>
   struct get {};
 };
 
 template <typename MW>
 struct check_before_handle_arity_3 {
-  template <typename T, void (T::*)(request&, response&,
-                                    typename MW::context&) = &T::before_handle>
+  template <typename T,
+            void (T::*)(request&, response&, typename MW::context&) =
+                &T::before_handle>
   struct get {};
 };
 
 template <typename MW>
 struct check_after_handle_arity_3_const {
-  template <typename T, void (T::*)(request&, response&, typename MW::context&)
-                            const = &T::after_handle>
+  template <typename T,
+            void (T::*)(request&, response&, typename MW::context&) const =
+                &T::after_handle>
   struct get {};
 };
 
 template <typename MW>
 struct check_after_handle_arity_3 {
-  template <typename T, void (T::*)(request&, response&,
-                                    typename MW::context&) = &T::after_handle>
+  template <typename T,
+            void (T::*)(request&, response&, typename MW::context&) =
+                &T::after_handle>
   struct get {};
 };
 
@@ -368,6 +372,7 @@
     buffers_.reserve(20);
 
     if (res.body.empty() && !res.json_value.empty()) {
+      res.json_mode();
       res.body = res.json_value.dump();
     }
 
diff --git a/crow/include/crow/http_response.h b/crow/include/crow/http_response.h
index e50d0b1..83684cc 100644
--- a/crow/include/crow/http_response.h
+++ b/crow/include/crow/http_response.h
@@ -83,11 +83,6 @@
 
   void write(const std::string& body_part) { body += body_part; }
 
-  template <std::size_t ArraySize>
-  void write(const std::array<char, ArraySize>& body_part) {
-    body.append(body_part.begin(), body_part.end());
-  }
-
   void end() {
     if (!completed_) {
       completed_ = true;
diff --git a/crow/include/crow/http_server.h b/crow/include/crow/http_server.h
index ffa5054..7811743 100644
--- a/crow/include/crow/http_server.h
+++ b/crow/include/crow/http_server.h
@@ -123,11 +123,15 @@
         };
         timer.async_wait(handler);
         init_count++;
-        try {
-          io_service_pool_[i]->run();
-        } catch (std::exception& e) {
-          CROW_LOG_ERROR << "Worker Crash: An uncaught exception occurred: "
-                         << e.what();
+        for (;;) {
+          try {
+            io_service_pool_[i]->run();
+            break;
+          } catch (std::exception& e) {
+            std::cerr << "Worker Crash: An uncaught exception occurred: "
+                      << e.what();
+          } catch (...) {
+          }
         }
       }));
     }
diff --git a/crow/include/crow/routing.h b/crow/include/crow/routing.h
index 7ab9541..9a83970 100644
--- a/crow/include/crow/routing.h
+++ b/crow/include/crow/routing.h
@@ -796,7 +796,9 @@
     if (rule.size() > 1 && rule.back() == '/') {
       std::string rule_without_trailing_slash = rule;
       rule_without_trailing_slash.pop_back();
-      trie_.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH);
+      rules_.emplace_back(ruleObject);
+      trie_.add(rule_without_trailing_slash, rules_.size() - 1);
+      //trie_.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH);
     }
   }
 
@@ -946,7 +948,7 @@
     return get_routes(root);
   }
 
-  std::vector<std::string> get_routes(std::string& parent) {
+  std::vector<std::string> get_routes(const std::string& parent) {
     std::vector<std::string> ret;
     // TODO(ed) this is so lazy, slow and unconcious of performance, but it
     // works
diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp
index 6dfc183..d331612 100644
--- a/include/nlohmann/json.hpp
+++ b/include/nlohmann/json.hpp
@@ -29,21 +29,21 @@
 #ifndef NLOHMANN_JSON_HPP
 #define NLOHMANN_JSON_HPP
 
-#include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
+#include <algorithm> // all_of, copy, fill, find, for_each, generate_n, none_of, remove, reverse, transform
 #include <array> // array
 #include <cassert> // assert
-#include <cctype> // isdigit
 #include <ciso646> // and, not, or
+#include <clocale> // lconv, localeconv
 #include <cmath> // isfinite, labs, ldexp, signbit
 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
 #include <cstdint> // int64_t, uint64_t
 #include <cstdlib> // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull
-#include <cstring> // strlen
+#include <cstring> // memcpy, strlen
 #include <forward_list> // forward_list
 #include <functional> // function, hash, less
 #include <initializer_list> // initializer_list
-#include <iomanip> // setw
-#include <iostream> // istream, ostream
+#include <iomanip> // hex
+#include <iosfwd>   // istream, ostream
 #include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
 #include <limits> // numeric_limits
 #include <locale> // locale
@@ -51,10 +51,10 @@
 #include <memory> // addressof, allocator, allocator_traits, unique_ptr
 #include <numeric> // accumulate
 #include <sstream> // stringstream
-#include <stdexcept> // domain_error, invalid_argument, out_of_range
 #include <string> // getline, stoi, string, to_string
 #include <type_traits> // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type
 #include <utility> // declval, forward, make_pair, move, pair, swap
+#include <valarray> // valarray
 #include <vector> // vector
 
 // exclude unsupported compilers
@@ -62,7 +62,7 @@
     #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
         #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
-#elif defined(__GNUC__)
+#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
     #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
         #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
@@ -90,7 +90,7 @@
 #endif
 
 // allow to disable exceptions
-#if not defined(JSON_NOEXCEPTION) || defined(__EXCEPTIONS)
+#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION)
     #define JSON_THROW(exception) throw exception
     #define JSON_TRY try
     #define JSON_CATCH(exception) catch(exception)
@@ -100,6 +100,15 @@
     #define JSON_CATCH(exception) if(false)
 #endif
 
+// manual branch prediction
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+    #define JSON_LIKELY(x)      __builtin_expect(!!(x), 1)
+    #define JSON_UNLIKELY(x)    __builtin_expect(!!(x), 0)
+#else
+    #define JSON_LIKELY(x)      x
+    #define JSON_UNLIKELY(x)    x
+#endif
+
 /*!
 @brief namespace for Niels Lohmann
 @see https://github.com/nlohmann
@@ -107,6 +116,38 @@
 */
 namespace nlohmann
 {
+template<typename = void, typename = void>
+struct adl_serializer;
+
+// forward declaration of basic_json (required to split the class)
+template<template<typename U, typename V, typename... Args> class ObjectType =
+         std::map,
+         template<typename U, typename... Args> class ArrayType = std::vector,
+         class StringType = std::string, class BooleanType = bool,
+         class NumberIntegerType = std::int64_t,
+         class NumberUnsignedType = std::uint64_t,
+         class NumberFloatType = double,
+         template<typename U> class AllocatorType = std::allocator,
+         template<typename T, typename SFINAE = void> class JSONSerializer =
+         adl_serializer>
+class basic_json;
+
+// Ugly macros to avoid uglier copy-paste when specializing basic_json
+// This is only temporary and will be removed in 3.0
+
+#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
+    template<template<typename, typename, typename...> class ObjectType,   \
+             template<typename, typename...> class ArrayType,              \
+             class StringType, class BooleanType, class NumberIntegerType, \
+             class NumberUnsignedType, class NumberFloatType,              \
+             template<typename> class AllocatorType,                       \
+             template<typename, typename = void> class JSONSerializer>
+
+#define NLOHMANN_BASIC_JSON_TPL                                            \
+    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
+    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
+    AllocatorType, JSONSerializer>
+
 
 /*!
 @brief unnamed namespace with internal helper functions
@@ -118,6 +159,325 @@
 */
 namespace detail
 {
+////////////////
+// exceptions //
+////////////////
+
+/*!
+@brief general exception of the @ref basic_json class
+
+This class is an extension of `std::exception` objects with a member @a id for
+exception ids. It is used as the base class for all exceptions thrown by the
+@ref basic_json class. This class can hence be used as "wildcard" to catch
+exceptions.
+
+Subclasses:
+- @ref parse_error for exceptions indicating a parse error
+- @ref invalid_iterator for exceptions indicating errors with iterators
+- @ref type_error for exceptions indicating executing a member function with
+                  a wrong type
+- @ref out_of_range for exceptions indicating access out of the defined range
+- @ref other_error for exceptions indicating other library errors
+
+@internal
+@note To have nothrow-copy-constructible exceptions, we internally use
+      `std::runtime_error` which can cope with arbitrary-length error messages.
+      Intermediate strings are built with static functions and then passed to
+      the actual constructor.
+@endinternal
+
+@liveexample{The following code shows how arbitrary library exceptions can be
+caught.,exception}
+
+@since version 3.0.0
+*/
+class exception : public std::exception
+{
+  public:
+    /// returns the explanatory string
+    const char* what() const noexcept override
+    {
+        return m.what();
+    }
+
+    /// the id of the exception
+    const int id;
+
+  protected:
+    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
+
+    static std::string name(const std::string& ename, int id_)
+    {
+        return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
+    }
+
+  private:
+    /// an exception object as storage for error messages
+    std::runtime_error m;
+};
+
+/*!
+@brief exception indicating a parse error
+
+This excpetion is thrown by the library when a parse error occurs. Parse errors
+can occur during the deserialization of JSON text, CBOR, MessagePack, as well
+as when using JSON Patch.
+
+Member @a byte holds the byte index of the last read character in the input
+file.
+
+Exceptions have ids 1xx.
+
+name / id                      | example message | description
+------------------------------ | --------------- | -------------------------
+json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
+json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
+json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
+json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
+json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
+json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number wihtout a leading `0`.
+json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
+json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
+json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
+json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
+json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xf8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
+json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
+
+@note For an input with n bytes, 1 is the index of the first character and n+1
+      is the index of the terminating null byte or the end of file. This also
+      holds true when reading a byte vector (CBOR or MessagePack).
+
+@liveexample{The following code shows how a `parse_error` exception can be
+caught.,parse_error}
+
+@sa @ref exception for the base class of the library exceptions
+@sa @ref invalid_iterator for exceptions indicating errors with iterators
+@sa @ref type_error for exceptions indicating executing a member function with
+                    a wrong type
+@sa @ref out_of_range for exceptions indicating access out of the defined range
+@sa @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class parse_error : public exception
+{
+  public:
+    /*!
+    @brief create a parse error exception
+    @param[in] id_       the id of the exception
+    @param[in] byte_     the byte index where the error occurred (or 0 if the
+                         position cannot be determined)
+    @param[in] what_arg  the explanatory string
+    @return parse_error object
+    */
+    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
+    {
+        std::string w = exception::name("parse_error", id_) + "parse error" +
+                        (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
+                        ": " + what_arg;
+        return parse_error(id_, byte_, w.c_str());
+    }
+
+    /*!
+    @brief byte index of the parse error
+
+    The byte index of the last read character in the input file.
+
+    @note For an input with n bytes, 1 is the index of the first character and
+          n+1 is the index of the terminating null byte or the end of file.
+          This also holds true when reading a byte vector (CBOR or MessagePack).
+    */
+    const std::size_t byte;
+
+  private:
+    parse_error(int id_, std::size_t byte_, const char* what_arg)
+        : exception(id_, what_arg), byte(byte_) {}
+};
+
+/*!
+@brief exception indicating errors with iterators
+
+This exception is thrown if iterators passed to a library function do not match
+the expected semantics.
+
+Exceptions have ids 2xx.
+
+name / id                           | example message | description
+----------------------------------- | --------------- | -------------------------
+json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
+json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
+json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
+json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
+json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
+json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
+json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
+json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
+json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
+json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
+json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
+json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
+json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
+json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
+
+@liveexample{The following code shows how an `invalid_iterator` exception can be
+caught.,invalid_iterator}
+
+@sa @ref exception for the base class of the library exceptions
+@sa @ref parse_error for exceptions indicating a parse error
+@sa @ref type_error for exceptions indicating executing a member function with
+                    a wrong type
+@sa @ref out_of_range for exceptions indicating access out of the defined range
+@sa @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class invalid_iterator : public exception
+{
+  public:
+    static invalid_iterator create(int id_, const std::string& what_arg)
+    {
+        std::string w = exception::name("invalid_iterator", id_) + what_arg;
+        return invalid_iterator(id_, w.c_str());
+    }
+
+  private:
+    invalid_iterator(int id_, const char* what_arg)
+        : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating executing a member function with a wrong type
+
+This exception is thrown in case of a type error; that is, a library function is
+executed on a JSON value whose type does not match the expected semantics.
+
+Exceptions have ids 3xx.
+
+name / id                     | example message | description
+----------------------------- | --------------- | -------------------------
+json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
+json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
+json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t&.
+json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
+json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
+json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
+json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
+json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
+json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
+json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
+json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
+json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
+json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
+json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
+json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
+
+@liveexample{The following code shows how a `type_error` exception can be
+caught.,type_error}
+
+@sa @ref exception for the base class of the library exceptions
+@sa @ref parse_error for exceptions indicating a parse error
+@sa @ref invalid_iterator for exceptions indicating errors with iterators
+@sa @ref out_of_range for exceptions indicating access out of the defined range
+@sa @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class type_error : public exception
+{
+  public:
+    static type_error create(int id_, const std::string& what_arg)
+    {
+        std::string w = exception::name("type_error", id_) + what_arg;
+        return type_error(id_, w.c_str());
+    }
+
+  private:
+    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating access out of the defined range
+
+This exception is thrown in case a library function is called on an input
+parameter that exceeds the expected range, for instance in case of array
+indices or nonexisting object keys.
+
+Exceptions have ids 4xx.
+
+name / id                       | example message | description
+------------------------------- | --------------- | -------------------------
+json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
+json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
+json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
+json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
+json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
+json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
+
+@liveexample{The following code shows how an `out_of_range` exception can be
+caught.,out_of_range}
+
+@sa @ref exception for the base class of the library exceptions
+@sa @ref parse_error for exceptions indicating a parse error
+@sa @ref invalid_iterator for exceptions indicating errors with iterators
+@sa @ref type_error for exceptions indicating executing a member function with
+                    a wrong type
+@sa @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class out_of_range : public exception
+{
+  public:
+    static out_of_range create(int id_, const std::string& what_arg)
+    {
+        std::string w = exception::name("out_of_range", id_) + what_arg;
+        return out_of_range(id_, w.c_str());
+    }
+
+  private:
+    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating other library errors
+
+This exception is thrown in case of errors that cannot be classified with the
+other exception types.
+
+Exceptions have ids 5xx.
+
+name / id                      | example message | description
+------------------------------ | --------------- | -------------------------
+json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
+json.exception.other_error.502 | invalid object size for conversion | Some conversions to user-defined types impose constraints on the object size (e.g. std::pair)
+
+@sa @ref exception for the base class of the library exceptions
+@sa @ref parse_error for exceptions indicating a parse error
+@sa @ref invalid_iterator for exceptions indicating errors with iterators
+@sa @ref type_error for exceptions indicating executing a member function with
+                    a wrong type
+@sa @ref out_of_range for exceptions indicating access out of the defined range
+
+@liveexample{The following code shows how an `other_error` exception can be
+caught.,other_error}
+
+@since version 3.0.0
+*/
+class other_error : public exception
+{
+  public:
+    static other_error create(int id_, const std::string& what_arg)
+    {
+        std::string w = exception::name("other_error", id_) + what_arg;
+        return other_error(id_, w.c_str());
+    }
+
+  private:
+    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+
+
+
 ///////////////////////////
 // JSON type enumeration //
 ///////////////////////////
@@ -148,15 +508,15 @@
 */
 enum class value_t : uint8_t
 {
-    null,            ///< null value
-    object,          ///< object (unordered set of name/value pairs)
-    array,           ///< array (ordered collection of values)
-    string,          ///< string value
-    boolean,         ///< boolean value
-    number_integer,  ///< number value (signed integer)
-    number_unsigned, ///< number value (unsigned integer)
-    number_float,    ///< number value (floating-point)
-    discarded        ///< discarded by the the parser callback function
+    null,             ///< null value
+    object,           ///< object (unordered set of name/value pairs)
+    array,            ///< array (ordered collection of values)
+    string,           ///< string value
+    boolean,          ///< boolean value
+    number_integer,   ///< number value (signed integer)
+    number_unsigned,  ///< number value (unsigned integer)
+    number_float,     ///< number value (floating-point)
+    discarded         ///< discarded by the the parser callback function
 };
 
 /*!
@@ -183,13 +543,8 @@
     };
 
     // discarded values are not comparable
-    if (lhs == value_t::discarded or rhs == value_t::discarded)
-    {
-        return false;
-    }
-
-    return order[static_cast<std::size_t>(lhs)] <
-           order[static_cast<std::size_t>(rhs)];
+    return lhs != value_t::discarded and rhs != value_t::discarded and
+           order[static_cast<std::size_t>(lhs)] < order[static_cast<std::size_t>(rhs)];
 }
 
 
@@ -197,6 +552,11 @@
 // helpers //
 /////////////
 
+template<typename> struct is_basic_json : std::false_type {};
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
+
 // alias templates to reduce boilerplate
 template<bool B, typename T = void>
 using enable_if_t = typename std::enable_if<B, T>::type;
@@ -204,11 +564,38 @@
 template<typename T>
 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
 
-// taken from http://stackoverflow.com/a/26936864/266378
-template<typename T>
-using is_unscoped_enum =
-    std::integral_constant<bool, std::is_convertible<T, int>::value and
-    std::is_enum<T>::value>;
+// implementation of C++14 index_sequence and affiliates
+// source: https://stackoverflow.com/a/32223343
+template<std::size_t... Ints>
+struct index_sequence
+{
+    using type = index_sequence;
+    using value_type = std::size_t;
+    static constexpr std::size_t size() noexcept
+    {
+        return sizeof...(Ints);
+    }
+};
+
+template<class Sequence1, class Sequence2>
+struct merge_and_renumber;
+
+template<std::size_t... I1, std::size_t... I2>
+struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
+        : index_sequence < I1..., (sizeof...(I1) + I2)... >
+          {};
+
+template<std::size_t N>
+struct make_index_sequence
+    : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
+      typename make_index_sequence < N - N / 2 >::type >
+{};
+
+template<> struct make_index_sequence<0> : index_sequence<> { };
+template<> struct make_index_sequence<1> : index_sequence<0> { };
+
+template<typename... Ts>
+using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
 
 /*
 Implementation of two C++17 constructs: conjunction, negation. This is needed
@@ -263,6 +650,14 @@
         j.m_value = s;
         j.assert_invariant();
     }
+
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
+    {
+        j.m_type = value_t::string;
+        j.m_value = std::move(s);
+        j.assert_invariant();
+    }
 };
 
 template<>
@@ -271,16 +666,8 @@
     template<typename BasicJsonType>
     static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
     {
-        // replace infinity and NAN by null
-        if (not std::isfinite(val))
-        {
-            j = BasicJsonType{};
-        }
-        else
-        {
-            j.m_type = value_t::number_float;
-            j.m_value = val;
-        }
+        j.m_type = value_t::number_float;
+        j.m_value = val;
         j.assert_invariant();
     }
 };
@@ -320,6 +707,14 @@
         j.assert_invariant();
     }
 
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
+    {
+        j.m_type = value_t::array;
+        j.m_value = std::move(arr);
+        j.assert_invariant();
+    }
+
     template<typename BasicJsonType, typename CompatibleArrayType,
              enable_if_t<not std::is_same<CompatibleArrayType,
                                           typename BasicJsonType::array_t>::value,
@@ -332,6 +727,30 @@
         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
         j.assert_invariant();
     }
+
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, const std::vector<bool>& arr)
+    {
+        j.m_type = value_t::array;
+        j.m_value = value_t::array;
+        j.m_value.array->reserve(arr.size());
+        for (bool x : arr)
+        {
+            j.m_value.array->push_back(x);
+        }
+        j.assert_invariant();
+    }
+
+    template<typename BasicJsonType, typename T,
+             enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+    static void construct(BasicJsonType& j, const std::valarray<T>& arr)
+    {
+        j.m_type = value_t::array;
+        j.m_value = value_t::array;
+        j.m_value.array->resize(arr.size());
+        std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
+        j.assert_invariant();
+    }
 };
 
 template<>
@@ -345,10 +764,17 @@
         j.assert_invariant();
     }
 
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
+    {
+        j.m_type = value_t::object;
+        j.m_value = std::move(obj);
+        j.assert_invariant();
+    }
+
     template<typename BasicJsonType, typename CompatibleObjectType,
              enable_if_t<not std::is_same<CompatibleObjectType,
-                                          typename BasicJsonType::object_t>::value,
-                         int> = 0>
+                                          typename BasicJsonType::object_t>::value, int> = 0>
     static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
     {
         using std::begin;
@@ -401,10 +827,8 @@
 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
 {
     static constexpr auto value =
-        std::is_constructible<typename RealType::key_type,
-        typename CompatibleObjectType::key_type>::value and
-        std::is_constructible<typename RealType::mapped_type,
-        typename CompatibleObjectType::mapped_type>::value;
+        std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
+        std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
 };
 
 template<class BasicJsonType, class CompatibleObjectType>
@@ -423,8 +847,7 @@
     static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
                                   std::is_same<T, typename BasicJsonType::const_iterator>::value or
                                   std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
-                                  std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value or
-                                  std::is_same<T, typename BasicJsonType::json_pointer>::value;
+                                  std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
 };
 
 template<class BasicJsonType, class CompatibleArrayType>
@@ -452,8 +875,7 @@
     using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
 
     static constexpr auto value =
-        std::is_constructible<RealIntegerType,
-        CompatibleNumberIntegerType>::value and
+        std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
         CompatibleLimits::is_integer and
         RealLimits::is_signed == CompatibleLimits::is_signed;
 };
@@ -538,6 +960,12 @@
     external_constructor<value_t::string>::construct(j, s);
 }
 
+template <typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
+{
+    external_constructor<value_t::string>::construct(j, std::move(s));
+}
+
 template<typename BasicJsonType, typename FloatType,
          enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
 void to_json(BasicJsonType& j, FloatType val) noexcept
@@ -563,11 +991,18 @@
     external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
 }
 
-template<typename BasicJsonType, typename UnscopedEnumType,
-         enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
-void to_json(BasicJsonType& j, UnscopedEnumType e) noexcept
+template<typename BasicJsonType, typename EnumType,
+         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+void to_json(BasicJsonType& j, EnumType e) noexcept
 {
-    external_constructor<value_t::number_integer>::construct(j, e);
+    using underlying_type = typename std::underlying_type<EnumType>::type;
+    external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, const std::vector<bool>& e)
+{
+    external_constructor<value_t::array>::construct(j, e);
 }
 
 template <
@@ -576,20 +1011,65 @@
         is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
         std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
         int > = 0 >
-void to_json(BasicJsonType& j, const  CompatibleArrayType& arr)
+void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
 {
     external_constructor<value_t::array>::construct(j, arr);
 }
 
+template <typename BasicJsonType, typename T,
+          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+void to_json(BasicJsonType& j, std::valarray<T> arr)
+{
+    external_constructor<value_t::array>::construct(j, std::move(arr));
+}
+
+template <typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
+{
+    external_constructor<value_t::array>::construct(j, std::move(arr));
+}
+
 template <
     typename BasicJsonType, typename CompatibleObjectType,
     enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
                 int> = 0 >
-void to_json(BasicJsonType& j, const  CompatibleObjectType& arr)
+void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
 {
-    external_constructor<value_t::object>::construct(j, arr);
+    external_constructor<value_t::object>::construct(j, obj);
 }
 
+template <typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
+{
+    external_constructor<value_t::object>::construct(j, std::move(obj));
+}
+
+template<typename BasicJsonType, typename T, std::size_t N,
+         enable_if_t<not std::is_constructible<
+                         typename BasicJsonType::string_t, T (&)[N]>::value,
+                     int> = 0>
+void to_json(BasicJsonType& j, T (&arr)[N])
+{
+    external_constructor<value_t::array>::construct(j, arr);
+}
+
+template<typename BasicJsonType, typename... Args>
+void to_json(BasicJsonType& j, const std::pair<Args...>& p)
+{
+    j = {p.first, p.second};
+}
+
+template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
+{
+    j = {std::get<Idx>(t)...};
+}
+
+template<typename BasicJsonType, typename... Args>
+void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
+{
+    to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
+}
 
 ///////////////
 // from_json //
@@ -607,36 +1087,31 @@
     {
         case value_t::number_unsigned:
         {
-            val = static_cast<ArithmeticType>(
-                      *j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
             break;
         }
         case value_t::number_integer:
         {
-            val = static_cast<ArithmeticType>(
-                      *j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
             break;
         }
         case value_t::number_float:
         {
-            val = static_cast<ArithmeticType>(
-                      *j.template get_ptr<const typename BasicJsonType::number_float_t*>());
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
             break;
         }
+
         default:
-        {
-            JSON_THROW(
-                std::domain_error("type must be number, but is " + j.type_name()));
-        }
+            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
     }
 }
 
 template<typename BasicJsonType>
 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
 {
-    if (not j.is_boolean())
+    if (JSON_UNLIKELY(not j.is_boolean()))
     {
-        JSON_THROW(std::domain_error("type must be boolean, but is " + j.type_name()));
+        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
     }
     b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
 }
@@ -644,9 +1119,9 @@
 template<typename BasicJsonType>
 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
 {
-    if (not j.is_string())
+    if (JSON_UNLIKELY(not j.is_string()))
     {
-        JSON_THROW(std::domain_error("type must be string, but is " + j.type_name()));
+        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
     }
     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
 }
@@ -669,52 +1144,57 @@
     get_arithmetic_value(j, val);
 }
 
-template<typename BasicJsonType, typename UnscopedEnumType,
-         enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
-void from_json(const BasicJsonType& j, UnscopedEnumType& e)
+template<typename BasicJsonType, typename EnumType,
+         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+void from_json(const BasicJsonType& j, EnumType& e)
 {
-    typename std::underlying_type<UnscopedEnumType>::type val;
+    typename std::underlying_type<EnumType>::type val;
     get_arithmetic_value(j, val);
-    e = static_cast<UnscopedEnumType>(val);
+    e = static_cast<EnumType>(val);
 }
 
 template<typename BasicJsonType>
 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
 {
-    if (not j.is_array())
+    if (JSON_UNLIKELY(not j.is_array()))
     {
-        JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
+        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
     }
     arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
 }
 
 // forward_list doesn't have an insert method
-template<typename BasicJsonType, typename T, typename Allocator>
+template<typename BasicJsonType, typename T, typename Allocator,
+         enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
 {
-    // do not perform the check when user wants to retrieve jsons
-    // (except when it's null.. ?)
-    if (j.is_null())
+    if (JSON_UNLIKELY(not j.is_array()))
     {
-        JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
+        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
     }
-    if (not std::is_same<T, BasicJsonType>::value)
+    std::transform(j.rbegin(), j.rend(),
+                   std::front_inserter(l), [](const BasicJsonType & i)
     {
-        if (not j.is_array())
-        {
-            JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
-        }
-    }
-    for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
+        return i.template get<T>();
+    });
+}
+
+// valarray doesn't have an insert method
+template<typename BasicJsonType, typename T,
+         enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
+void from_json(const BasicJsonType& j, std::valarray<T>& l)
+{
+    if (JSON_UNLIKELY(not j.is_array()))
     {
-        l.push_front(it->template get<T>());
+        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
     }
+    l.resize(j.size());
+    std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
 }
 
 template<typename BasicJsonType, typename CompatibleArrayType>
-void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>)
+void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/)
 {
-    using std::begin;
     using std::end;
 
     std::transform(j.begin(), j.end(),
@@ -727,17 +1207,16 @@
 }
 
 template<typename BasicJsonType, typename CompatibleArrayType>
-auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>)
+auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
 -> decltype(
     arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
     void())
 {
-    using std::begin;
     using std::end;
 
     arr.reserve(j.size());
-    std::transform(
-        j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
+    std::transform(j.begin(), j.end(),
+                   std::inserter(arr, end(arr)), [](const BasicJsonType & i)
     {
         // get<BasicJsonType>() returns *this, this won't call a from_json
         // method when value_type is BasicJsonType
@@ -745,43 +1224,47 @@
     });
 }
 
+template<typename BasicJsonType, typename T, std::size_t N>
+void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
+{
+    for (std::size_t i = 0; i < N; ++i)
+    {
+        arr[i] = j.at(i).template get<T>();
+    }
+}
+
 template<typename BasicJsonType, typename CompatibleArrayType,
          enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
+                     std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
                      not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
 {
-    if (j.is_null())
+    if (JSON_UNLIKELY(not j.is_array()))
     {
-        JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
+        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
     }
 
-    // when T == BasicJsonType, do not check if value_t is correct
-    if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
-    {
-        if (not j.is_array())
-        {
-            JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
-        }
-    }
-    from_json_array_impl(j, arr, priority_tag<1> {});
+    from_json_array_impl(j, arr, priority_tag<2> {});
 }
 
 template<typename BasicJsonType, typename CompatibleObjectType,
          enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
 {
-    if (not j.is_object())
+    if (JSON_UNLIKELY(not j.is_object()))
     {
-        JSON_THROW(std::domain_error("type must be object, but is " + j.type_name()));
+        JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
     }
 
     auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
-    using std::begin;
-    using std::end;
-    // we could avoid the assignment, but this might require a for loop, which
-    // might be less efficient than the container constructor for some
-    // containers (would it?)
-    obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
+    using value_type = typename CompatibleObjectType::value_type;
+    std::transform(
+        inner_object->begin(), inner_object->end(),
+        std::inserter(obj, obj.begin()),
+        [](typename BasicJsonType::object_t::value_type const & p)
+    {
+        return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
+    });
 }
 
 // overload for arithmetic types, not chosen for basic_json template arguments
@@ -820,25 +1303,42 @@
             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
             break;
         }
+
         default:
-        {
-            JSON_THROW(std::domain_error("type must be number, but is " + j.type_name()));
-        }
+            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
     }
 }
 
+template<typename BasicJsonType, typename A1, typename A2>
+void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
+{
+    p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
+}
+
+template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
+{
+    t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
+}
+
+template<typename BasicJsonType, typename... Args>
+void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
+{
+    from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
+}
+
 struct to_json_fn
 {
   private:
     template<typename BasicJsonType, typename T>
-    auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
+    auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
     -> decltype(to_json(j, std::forward<T>(val)), void())
     {
         return to_json(j, std::forward<T>(val));
     }
 
     template<typename BasicJsonType, typename T>
-    void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept
+    void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept
     {
         static_assert(sizeof(BasicJsonType) == 0,
                       "could not find to_json() method in T's namespace");
@@ -857,7 +1357,7 @@
 {
   private:
     template<typename BasicJsonType, typename T>
-    auto call(const BasicJsonType& j, T& val, priority_tag<1>) const
+    auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const
     noexcept(noexcept(from_json(j, val)))
     -> decltype(from_json(j, val), void())
     {
@@ -865,7 +1365,7 @@
     }
 
     template<typename BasicJsonType, typename T>
-    void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept
+    void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
     {
         static_assert(sizeof(BasicJsonType) == 0,
                       "could not find from_json() method in T's namespace");
@@ -889,8 +1389,5459 @@
 
 template<typename T>
 constexpr T static_const<T>::value;
-} // namespace detail
 
+////////////////////
+// input adapters //
+////////////////////
+
+/// abstract input adapter interface
+struct input_adapter_protocol
+{
+    virtual int get_character() = 0;
+    virtual std::string read(std::size_t offset, std::size_t length) = 0;
+    virtual ~input_adapter_protocol() = default;
+};
+
+/// a type to simplify interfaces
+using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
+
+/// input adapter for cached stream input
+template<std::size_t BufferSize>
+class cached_input_stream_adapter : public input_adapter_protocol
+{
+  public:
+    explicit cached_input_stream_adapter(std::istream& i)
+        : is(i), start_position(is.tellg())
+    {
+        fill_buffer();
+
+        // skip byte order mark
+        if (fill_size >= 3 and buffer[0] == '\xEF' and buffer[1] == '\xBB' and buffer[2] == '\xBF')
+        {
+            buffer_pos += 3;
+            processed_chars += 3;
+        }
+    }
+
+    ~cached_input_stream_adapter() override
+    {
+        // clear stream flags
+        is.clear();
+        // We initially read a lot of characters into the buffer, and we may
+        // not have processed all of them. Therefore, we need to "rewind" the
+        // stream after the last processed char.
+        is.seekg(start_position);
+        is.ignore(static_cast<std::streamsize>(processed_chars));
+        // clear stream flags
+        is.clear();
+    }
+
+    int get_character() override
+    {
+        // check if refilling is necessary and possible
+        if (buffer_pos == fill_size and not eof)
+        {
+            fill_buffer();
+
+            // check and remember that filling did not yield new input
+            if (fill_size == 0)
+            {
+                eof = true;
+                return std::char_traits<char>::eof();
+            }
+
+            // the buffer is ready
+            buffer_pos = 0;
+        }
+
+        ++processed_chars;
+        assert(buffer_pos < buffer.size());
+        return buffer[buffer_pos++] & 0xFF;
+    }
+
+    std::string read(std::size_t offset, std::size_t length) override
+    {
+        // create buffer
+        std::string result(length, '\0');
+
+        // save stream position
+        const auto current_pos = is.tellg();
+        // save stream flags
+        const auto flags = is.rdstate();
+
+        // clear stream flags
+        is.clear();
+        // set stream position
+        is.seekg(static_cast<std::streamoff>(offset));
+        // read bytes
+        is.read(&result[0], static_cast<std::streamsize>(length));
+
+        // reset stream position
+        is.seekg(current_pos);
+        // reset stream flags
+        is.setstate(flags);
+
+        return result;
+    }
+
+  private:
+    void fill_buffer()
+    {
+        // fill
+        is.read(buffer.data(), static_cast<std::streamsize>(buffer.size()));
+        // store number of bytes in the buffer
+        fill_size = static_cast<size_t>(is.gcount());
+    }
+
+    /// the associated input stream
+    std::istream& is;
+
+    /// chars returned via get_character()
+    std::size_t processed_chars = 0;
+    /// chars processed in the current buffer
+    std::size_t buffer_pos = 0;
+
+    /// whether stream reached eof
+    bool eof = false;
+    /// how many chars have been copied to the buffer by last (re)fill
+    std::size_t fill_size = 0;
+
+    /// position of the stream when we started
+    const std::streampos start_position;
+
+    /// internal buffer
+    std::array<char, BufferSize> buffer{{}};
+};
+
+/// input adapter for buffer input
+class input_buffer_adapter : public input_adapter_protocol
+{
+  public:
+    input_buffer_adapter(const char* b, const std::size_t l)
+        : cursor(b), limit(b + l), start(b)
+    {
+        // skip byte order mark
+        if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF')
+        {
+            cursor += 3;
+        }
+    }
+
+    // delete because of pointer members
+    input_buffer_adapter(const input_buffer_adapter&) = delete;
+    input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
+
+    int get_character() noexcept override
+    {
+        if (JSON_LIKELY(cursor < limit))
+        {
+            return *(cursor++) & 0xFF;
+        }
+
+        return std::char_traits<char>::eof();
+    }
+
+    std::string read(std::size_t offset, std::size_t length) override
+    {
+        // avoid reading too many characters
+        const auto max_length = static_cast<size_t>(limit - start);
+        return std::string(start + offset, (std::min)(length, max_length - offset));
+    }
+
+  private:
+    /// pointer to the current character
+    const char* cursor;
+    /// pointer past the last character
+    const char* limit;
+    /// pointer to the first character
+    const char* start;
+};
+
+class input_adapter
+{
+  public:
+    // native support
+
+    /// input adapter for input stream
+    input_adapter(std::istream& i)
+        : ia(std::make_shared<cached_input_stream_adapter<16384>>(i)) {}
+
+    /// input adapter for input stream
+    input_adapter(std::istream&& i)
+        : ia(std::make_shared<cached_input_stream_adapter<16384>>(i)) {}
+
+    /// input adapter for buffer
+    template<typename CharT,
+             typename std::enable_if<
+                 std::is_pointer<CharT>::value and
+                 std::is_integral<
+                     typename std::remove_pointer<CharT>::type>::value and
+                 sizeof(typename std::remove_pointer<CharT>::type) == 1,
+                 int>::type = 0>
+    input_adapter(CharT b, std::size_t l)
+        : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
+
+    // derived support
+
+    /// input adapter for string literal
+    template<typename CharT,
+             typename std::enable_if<
+                 std::is_pointer<CharT>::value and
+                 std::is_integral<
+                     typename std::remove_pointer<CharT>::type>::value and
+                 sizeof(typename std::remove_pointer<CharT>::type) == 1,
+                 int>::type = 0>
+    input_adapter(CharT b)
+        : input_adapter(reinterpret_cast<const char*>(b),
+                        std::strlen(reinterpret_cast<const char*>(b))) {}
+
+    /// input adapter for iterator range with contiguous storage
+    template<class IteratorType,
+             typename std::enable_if<
+                 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category,
+                              std::random_access_iterator_tag>::value,
+                 int>::type = 0>
+    input_adapter(IteratorType first, IteratorType last)
+    {
+        // assertion to check that the iterator range is indeed contiguous,
+        // see http://stackoverflow.com/a/35008842/266378 for more discussion
+        assert(std::accumulate(
+                   first, last, std::pair<bool, int>(true, 0),
+                   [&first](std::pair<bool, int> res, decltype(*first) val)
+        {
+            res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
+            return res;
+        }).first);
+
+        // assertion to check that each element is 1 byte long
+        static_assert(
+            sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
+            "each element in the iterator range must have the size of 1 byte");
+
+        const auto len = static_cast<size_t>(std::distance(first, last));
+        if (JSON_LIKELY(len > 0))
+        {
+            // there is at least one element: use the address of first
+            ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
+        }
+        else
+        {
+            // the address of first cannot be used: use nullptr
+            ia = std::make_shared<input_buffer_adapter>(nullptr, len);
+        }
+    }
+
+    /// input adapter for array
+    template<class T, std::size_t N>
+    input_adapter(T (&array)[N])
+        : input_adapter(std::begin(array), std::end(array)) {}
+
+    /// input adapter for contiguous container
+    template <
+        class ContiguousContainer,
+        typename std::enable_if <
+            not std::is_pointer<ContiguousContainer>::value and
+            std::is_base_of<std::random_access_iterator_tag,
+                            typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
+            int >::type = 0 >
+    input_adapter(const ContiguousContainer& c)
+        : input_adapter(std::begin(c), std::end(c)) {}
+
+    operator input_adapter_t()
+    {
+        return ia;
+    }
+
+  private:
+    /// the actual adapter
+    input_adapter_t ia = nullptr;
+};
+
+//////////////////////
+// lexer and parser //
+//////////////////////
+
+/*!
+@brief lexical analysis
+
+This class organizes the lexical analysis during JSON deserialization.
+*/
+template<typename BasicJsonType>
+class lexer
+{
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+
+  public:
+    /// token types for the parser
+    enum class token_type
+    {
+        uninitialized,    ///< indicating the scanner is uninitialized
+        literal_true,     ///< the `true` literal
+        literal_false,    ///< the `false` literal
+        literal_null,     ///< the `null` literal
+        value_string,     ///< a string -- use get_string() for actual value
+        value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
+        value_integer,    ///< a signed integer -- use get_number_integer() for actual value
+        value_float,      ///< an floating point number -- use get_number_float() for actual value
+        begin_array,      ///< the character for array begin `[`
+        begin_object,     ///< the character for object begin `{`
+        end_array,        ///< the character for array end `]`
+        end_object,       ///< the character for object end `}`
+        name_separator,   ///< the name separator `:`
+        value_separator,  ///< the value separator `,`
+        parse_error,      ///< indicating a parse error
+        end_of_input,     ///< indicating the end of the input buffer
+        literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
+    };
+
+    /// return name of values of type token_type (only used for errors)
+    static const char* token_type_name(const token_type t) noexcept
+    {
+        switch (t)
+        {
+            case token_type::uninitialized:
+                return "<uninitialized>";
+            case token_type::literal_true:
+                return "true literal";
+            case token_type::literal_false:
+                return "false literal";
+            case token_type::literal_null:
+                return "null literal";
+            case token_type::value_string:
+                return "string literal";
+            case lexer::token_type::value_unsigned:
+            case lexer::token_type::value_integer:
+            case lexer::token_type::value_float:
+                return "number literal";
+            case token_type::begin_array:
+                return "'['";
+            case token_type::begin_object:
+                return "'{'";
+            case token_type::end_array:
+                return "']'";
+            case token_type::end_object:
+                return "'}'";
+            case token_type::name_separator:
+                return "':'";
+            case token_type::value_separator:
+                return "','";
+            case token_type::parse_error:
+                return "<parse error>";
+            case token_type::end_of_input:
+                return "end of input";
+            case token_type::literal_or_value:
+                return "'[', '{', or a literal";
+            default: // catch non-enum values
+                return "unknown token"; // LCOV_EXCL_LINE
+        }
+    }
+
+    explicit lexer(detail::input_adapter_t adapter)
+        : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
+
+    // delete because of pointer members
+    lexer(const lexer&) = delete;
+    lexer& operator=(lexer&) = delete;
+
+  private:
+    /////////////////////
+    // locales
+    /////////////////////
+
+    /// return the locale-dependent decimal point
+    static char get_decimal_point() noexcept
+    {
+        const auto loc = localeconv();
+        assert(loc != nullptr);
+        return (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
+    }
+
+    /////////////////////
+    // scan functions
+    /////////////////////
+
+    /*!
+    @brief get codepoint from 4 hex characters following `\u`
+
+    For input "\u c1 c2 c3 c4" the codepoint is:
+      (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
+    = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
+
+    Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
+    must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
+    conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
+    between the ASCII value of the character and the desired integer value.
+
+    @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
+            non-hex character)
+    */
+    int get_codepoint()
+    {
+        // this function only makes sense after reading `\u`
+        assert(current == 'u');
+        int codepoint = 0;
+
+        const auto factors = { 12, 8, 4, 0 };
+        for (const auto factor : factors)
+        {
+            get();
+
+            if (current >= '0' and current <= '9')
+            {
+                codepoint += ((current - 0x30) << factor);
+            }
+            else if (current >= 'A' and current <= 'F')
+            {
+                codepoint += ((current - 0x37) << factor);
+            }
+            else if (current >= 'a' and current <= 'f')
+            {
+                codepoint += ((current - 0x57) << factor);
+            }
+            else
+            {
+                return -1;
+            }
+        }
+
+        assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
+        return codepoint;
+    }
+
+    /*!
+    @brief check if the next byte(s) are inside a given range
+
+    Adds the current byte and, for each passed range, reads a new byte and
+    checks if it is inside the range. If a violation was detected, set up an
+    error message and return false. Otherwise, return true.
+
+    @return true if and only if no range violation was detected
+    */
+    bool next_byte_in_range(std::initializer_list<int> ranges)
+    {
+        assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
+        add(current);
+
+        for (auto range = ranges.begin(); range != ranges.end(); ++range)
+        {
+            get();
+            if (JSON_LIKELY(*range <= current and current <= *(++range)))
+            {
+                add(current);
+            }
+            else
+            {
+                error_message = "invalid string: ill-formed UTF-8 byte";
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /*!
+    @brief scan a string literal
+
+    This function scans a string according to Sect. 7 of RFC 7159. While
+    scanning, bytes are escaped and copied into buffer yytext. Then the
+    function returns successfully, yytext is null-terminated and yylen
+    contains the number of bytes in the string.
+
+    @return token_type::value_string if string could be successfully scanned,
+            token_type::parse_error otherwise
+
+    @note In case of errors, variable error_message contains a textual
+          description.
+    */
+    token_type scan_string()
+    {
+        // reset yytext (ignore opening quote)
+        reset();
+
+        // we entered the function by reading an open quote
+        assert(current == '\"');
+
+        while (true)
+        {
+            // get next character
+            switch (get())
+            {
+                // end of file while parsing string
+                case std::char_traits<char>::eof():
+                {
+                    error_message = "invalid string: missing closing quote";
+                    return token_type::parse_error;
+                }
+
+                // closing quote
+                case '\"':
+                {
+                    // terminate yytext
+                    add('\0');
+                    --yylen;
+                    return token_type::value_string;
+                }
+
+                // escapes
+                case '\\':
+                {
+                    switch (get())
+                    {
+                        // quotation mark
+                        case '\"':
+                            add('\"');
+                            break;
+                        // reverse solidus
+                        case '\\':
+                            add('\\');
+                            break;
+                        // solidus
+                        case '/':
+                            add('/');
+                            break;
+                        // backspace
+                        case 'b':
+                            add('\b');
+                            break;
+                        // form feed
+                        case 'f':
+                            add('\f');
+                            break;
+                        // line feed
+                        case 'n':
+                            add('\n');
+                            break;
+                        // carriage return
+                        case 'r':
+                            add('\r');
+                            break;
+                        // tab
+                        case 't':
+                            add('\t');
+                            break;
+
+                        // unicode escapes
+                        case 'u':
+                        {
+                            int codepoint;
+                            const int codepoint1 = get_codepoint();
+
+                            if (JSON_UNLIKELY(codepoint1 == -1))
+                            {
+                                error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+                                return token_type::parse_error;
+                            }
+
+                            // check if code point is a high surrogate
+                            if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
+                            {
+                                // expect next \uxxxx entry
+                                if (JSON_LIKELY(get() == '\\' and get() == 'u'))
+                                {
+                                    const int codepoint2 = get_codepoint();
+
+                                    if (JSON_UNLIKELY(codepoint2 == -1))
+                                    {
+                                        error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+                                        return token_type::parse_error;
+                                    }
+
+                                    // check if codepoint2 is a low surrogate
+                                    if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
+                                    {
+                                        codepoint =
+                                            // high surrogate occupies the most significant 22 bits
+                                            (codepoint1 << 10)
+                                            // low surrogate occupies the least significant 15 bits
+                                            + codepoint2
+                                            // there is still the 0xD800, 0xDC00 and 0x10000 noise
+                                            // in the result so we have to subtract with:
+                                            // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
+                                            - 0x35FDC00;
+                                    }
+                                    else
+                                    {
+                                        error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
+                                        return token_type::parse_error;
+                                    }
+                                }
+                                else
+                                {
+                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
+                                    return token_type::parse_error;
+                                }
+                            }
+                            else
+                            {
+                                if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
+                                {
+                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
+                                    return token_type::parse_error;
+                                }
+
+                                // only work with first code point
+                                codepoint = codepoint1;
+                            }
+
+                            // result of the above calculation yields a proper codepoint
+                            assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
+
+                            // translate code point to bytes
+                            if (codepoint < 0x80)
+                            {
+                                // 1-byte characters: 0xxxxxxx (ASCII)
+                                add(codepoint);
+                            }
+                            else if (codepoint <= 0x7ff)
+                            {
+                                // 2-byte characters: 110xxxxx 10xxxxxx
+                                add(0xC0 | (codepoint >> 6));
+                                add(0x80 | (codepoint & 0x3F));
+                            }
+                            else if (codepoint <= 0xffff)
+                            {
+                                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
+                                add(0xE0 | (codepoint >> 12));
+                                add(0x80 | ((codepoint >> 6) & 0x3F));
+                                add(0x80 | (codepoint & 0x3F));
+                            }
+                            else
+                            {
+                                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+                                add(0xF0 | (codepoint >> 18));
+                                add(0x80 | ((codepoint >> 12) & 0x3F));
+                                add(0x80 | ((codepoint >> 6) & 0x3F));
+                                add(0x80 | (codepoint & 0x3F));
+                            }
+
+                            break;
+                        }
+
+                        // other characters after escape
+                        default:
+                            error_message = "invalid string: forbidden character after backslash";
+                            return token_type::parse_error;
+                    }
+
+                    break;
+                }
+
+                // invalid control characters
+                case 0x00:
+                case 0x01:
+                case 0x02:
+                case 0x03:
+                case 0x04:
+                case 0x05:
+                case 0x06:
+                case 0x07:
+                case 0x08:
+                case 0x09:
+                case 0x0a:
+                case 0x0b:
+                case 0x0c:
+                case 0x0d:
+                case 0x0e:
+                case 0x0f:
+                case 0x10:
+                case 0x11:
+                case 0x12:
+                case 0x13:
+                case 0x14:
+                case 0x15:
+                case 0x16:
+                case 0x17:
+                case 0x18:
+                case 0x19:
+                case 0x1a:
+                case 0x1b:
+                case 0x1c:
+                case 0x1d:
+                case 0x1e:
+                case 0x1f:
+                {
+                    error_message = "invalid string: control character must be escaped";
+                    return token_type::parse_error;
+                }
+
+                // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
+                case 0x20:
+                case 0x21:
+                case 0x23:
+                case 0x24:
+                case 0x25:
+                case 0x26:
+                case 0x27:
+                case 0x28:
+                case 0x29:
+                case 0x2a:
+                case 0x2b:
+                case 0x2c:
+                case 0x2d:
+                case 0x2e:
+                case 0x2f:
+                case 0x30:
+                case 0x31:
+                case 0x32:
+                case 0x33:
+                case 0x34:
+                case 0x35:
+                case 0x36:
+                case 0x37:
+                case 0x38:
+                case 0x39:
+                case 0x3a:
+                case 0x3b:
+                case 0x3c:
+                case 0x3d:
+                case 0x3e:
+                case 0x3f:
+                case 0x40:
+                case 0x41:
+                case 0x42:
+                case 0x43:
+                case 0x44:
+                case 0x45:
+                case 0x46:
+                case 0x47:
+                case 0x48:
+                case 0x49:
+                case 0x4a:
+                case 0x4b:
+                case 0x4c:
+                case 0x4d:
+                case 0x4e:
+                case 0x4f:
+                case 0x50:
+                case 0x51:
+                case 0x52:
+                case 0x53:
+                case 0x54:
+                case 0x55:
+                case 0x56:
+                case 0x57:
+                case 0x58:
+                case 0x59:
+                case 0x5a:
+                case 0x5b:
+                case 0x5d:
+                case 0x5e:
+                case 0x5f:
+                case 0x60:
+                case 0x61:
+                case 0x62:
+                case 0x63:
+                case 0x64:
+                case 0x65:
+                case 0x66:
+                case 0x67:
+                case 0x68:
+                case 0x69:
+                case 0x6a:
+                case 0x6b:
+                case 0x6c:
+                case 0x6d:
+                case 0x6e:
+                case 0x6f:
+                case 0x70:
+                case 0x71:
+                case 0x72:
+                case 0x73:
+                case 0x74:
+                case 0x75:
+                case 0x76:
+                case 0x77:
+                case 0x78:
+                case 0x79:
+                case 0x7a:
+                case 0x7b:
+                case 0x7c:
+                case 0x7d:
+                case 0x7e:
+                case 0x7f:
+                {
+                    add(current);
+                    break;
+                }
+
+                // U+0080..U+07FF: bytes C2..DF 80..BF
+                case 0xc2:
+                case 0xc3:
+                case 0xc4:
+                case 0xc5:
+                case 0xc6:
+                case 0xc7:
+                case 0xc8:
+                case 0xc9:
+                case 0xca:
+                case 0xcb:
+                case 0xcc:
+                case 0xcd:
+                case 0xce:
+                case 0xcf:
+                case 0xd0:
+                case 0xd1:
+                case 0xd2:
+                case 0xd3:
+                case 0xd4:
+                case 0xd5:
+                case 0xd6:
+                case 0xd7:
+                case 0xd8:
+                case 0xd9:
+                case 0xda:
+                case 0xdb:
+                case 0xdc:
+                case 0xdd:
+                case 0xde:
+                case 0xdf:
+                {
+                    if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
+                case 0xe0:
+                {
+                    if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
+                // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
+                case 0xe1:
+                case 0xe2:
+                case 0xe3:
+                case 0xe4:
+                case 0xe5:
+                case 0xe6:
+                case 0xe7:
+                case 0xe8:
+                case 0xe9:
+                case 0xea:
+                case 0xeb:
+                case 0xec:
+                case 0xee:
+                case 0xef:
+                {
+                    if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+D000..U+D7FF: bytes ED 80..9F 80..BF
+                case 0xed:
+                {
+                    if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
+                case 0xf0:
+                {
+                    if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
+                case 0xf1:
+                case 0xf2:
+                case 0xf3:
+                {
+                    if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
+                case 0xf4:
+                {
+                    if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // remaining bytes (80..C1 and F5..FF) are ill-formed
+                default:
+                {
+                    error_message = "invalid string: ill-formed UTF-8 byte";
+                    return token_type::parse_error;
+                }
+            }
+        }
+    }
+
+    static void strtof(float& f, const char* str, char** endptr) noexcept
+    {
+        f = std::strtof(str, endptr);
+    }
+
+    static void strtof(double& f, const char* str, char** endptr) noexcept
+    {
+        f = std::strtod(str, endptr);
+    }
+
+    static void strtof(long double& f, const char* str, char** endptr) noexcept
+    {
+        f = std::strtold(str, endptr);
+    }
+
+    /*!
+    @brief scan a number literal
+
+    This function scans a string according to Sect. 6 of RFC 7159.
+
+    The function is realized with a deterministic finite state machine derived
+    from the grammar described in RFC 7159. Starting in state "init", the
+    input is read and used to determined the next state. Only state "done"
+    accepts the number. State "error" is a trap state to model errors. In the
+    table below, "anything" means any character but the ones listed before.
+
+    state    | 0        | 1-9      | e E      | +       | -       | .        | anything
+    ---------|----------|----------|----------|---------|---------|----------|-----------
+    init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
+    minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
+    zero     | done     | done     | exponent | done    | done    | decimal1 | done
+    any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
+    decimal1 | decimal2 | [error]  | [error]  | [error] | [error] | [error]  | [error]
+    decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
+    exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
+    sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
+    any2     | any2     | any2     | done     | done    | done    | done     | done
+
+    The state machine is realized with one label per state (prefixed with
+    "scan_number_") and `goto` statements between them. The state machine
+    contains cycles, but any cycle can be left when EOF is read. Therefore,
+    the function is guaranteed to terminate.
+
+    During scanning, the read bytes are stored in yytext. This string is
+    then converted to a signed integer, an unsigned integer, or a
+    floating-point number.
+
+    @return token_type::value_unsigned, token_type::value_integer, or
+            token_type::value_float if number could be successfully scanned,
+            token_type::parse_error otherwise
+
+    @note The scanner is independent of the current locale. Internally, the
+          locale's decimal point is used instead of `.` to work with the
+          locale-dependent converters.
+    */
+    token_type scan_number()
+    {
+        // reset yytext to store the number's bytes
+        reset();
+
+        // the type of the parsed number; initially set to unsigned; will be
+        // changed if minus sign, decimal point or exponent is read
+        token_type number_type = token_type::value_unsigned;
+
+        // state (init): we just found out we need to scan a number
+        switch (current)
+        {
+            case '-':
+            {
+                add(current);
+                goto scan_number_minus;
+            }
+
+            case '0':
+            {
+                add(current);
+                goto scan_number_zero;
+            }
+
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any1;
+            }
+
+            default:
+            {
+                // all other characters are rejected outside scan_number()
+                assert(false); // LCOV_EXCL_LINE
+            }
+        }
+
+scan_number_minus:
+        // state: we just parsed a leading minus sign
+        number_type = token_type::value_integer;
+        switch (get())
+        {
+            case '0':
+            {
+                add(current);
+                goto scan_number_zero;
+            }
+
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any1;
+            }
+
+            default:
+            {
+                error_message = "invalid number; expected digit after '-'";
+                return token_type::parse_error;
+            }
+        }
+
+scan_number_zero:
+        // state: we just parse a zero (maybe with a leading minus sign)
+        switch (get())
+        {
+            case '.':
+            {
+                add(decimal_point_char);
+                goto scan_number_decimal1;
+            }
+
+            case 'e':
+            case 'E':
+            {
+                add(current);
+                goto scan_number_exponent;
+            }
+
+            default:
+                goto scan_number_done;
+        }
+
+scan_number_any1:
+        // state: we just parsed a number 0-9 (maybe with a leading minus sign)
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any1;
+            }
+
+            case '.':
+            {
+                add(decimal_point_char);
+                goto scan_number_decimal1;
+            }
+
+            case 'e':
+            case 'E':
+            {
+                add(current);
+                goto scan_number_exponent;
+            }
+
+            default:
+                goto scan_number_done;
+        }
+
+scan_number_decimal1:
+        // state: we just parsed a decimal point
+        number_type = token_type::value_float;
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_decimal2;
+            }
+
+            default:
+            {
+                error_message = "invalid number; expected digit after '.'";
+                return token_type::parse_error;
+            }
+        }
+
+scan_number_decimal2:
+        // we just parsed at least one number after a decimal point
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_decimal2;
+            }
+
+            case 'e':
+            case 'E':
+            {
+                add(current);
+                goto scan_number_exponent;
+            }
+
+            default:
+                goto scan_number_done;
+        }
+
+scan_number_exponent:
+        // we just parsed an exponent
+        number_type = token_type::value_float;
+        switch (get())
+        {
+            case '+':
+            case '-':
+            {
+                add(current);
+                goto scan_number_sign;
+            }
+
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any2;
+            }
+
+            default:
+            {
+                error_message =
+                    "invalid number; expected '+', '-', or digit after exponent";
+                return token_type::parse_error;
+            }
+        }
+
+scan_number_sign:
+        // we just parsed an exponent sign
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any2;
+            }
+
+            default:
+            {
+                error_message = "invalid number; expected digit after exponent sign";
+                return token_type::parse_error;
+            }
+        }
+
+scan_number_any2:
+        // we just parsed a number after the exponent or exponent sign
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any2;
+            }
+
+            default:
+                goto scan_number_done;
+        }
+
+scan_number_done:
+        // unget the character after the number (we only read it to know that
+        // we are done scanning a number)
+        --chars_read;
+        next_unget = true;
+
+        // terminate token
+        add('\0');
+        --yylen;
+
+        char* endptr = nullptr;
+        errno = 0;
+
+        // try to parse integers first and fall back to floats
+        if (number_type == token_type::value_unsigned)
+        {
+            const auto x = std::strtoull(yytext.data(), &endptr, 10);
+
+            // we checked the number format before
+            assert(endptr == yytext.data() + yylen);
+
+            if (errno == 0)
+            {
+                value_unsigned = static_cast<number_unsigned_t>(x);
+                if (value_unsigned == x)
+                {
+                    return token_type::value_unsigned;
+                }
+            }
+        }
+        else if (number_type == token_type::value_integer)
+        {
+            const auto x = std::strtoll(yytext.data(), &endptr, 10);
+
+            // we checked the number format before
+            assert(endptr == yytext.data() + yylen);
+
+            if (errno == 0)
+            {
+                value_integer = static_cast<number_integer_t>(x);
+                if (value_integer == x)
+                {
+                    return token_type::value_integer;
+                }
+            }
+        }
+
+        // this code is reached if we parse a floating-point number or if an
+        // integer conversion above failed
+        strtof(value_float, yytext.data(), &endptr);
+
+        // we checked the number format before
+        assert(endptr == yytext.data() + yylen);
+
+        return token_type::value_float;
+    }
+
+    /*!
+    @param[in] literal_text  the literal text to expect
+    @param[in] length        the length of the passed literal text
+    @param[in] return_type   the token type to return on success
+    */
+    token_type scan_literal(const char* literal_text, const std::size_t length,
+                            token_type return_type)
+    {
+        assert(current == literal_text[0]);
+        for (std::size_t i = 1; i < length; ++i)
+        {
+            if (JSON_UNLIKELY(get() != literal_text[i]))
+            {
+                error_message = "invalid literal";
+                return token_type::parse_error;
+            }
+        }
+        return return_type;
+    }
+
+    /////////////////////
+    // input management
+    /////////////////////
+
+    /// reset yytext
+    void reset() noexcept
+    {
+        yylen = 0;
+        start_pos = chars_read - 1;
+    }
+
+    /// get a character from the input
+    int get()
+    {
+        ++chars_read;
+        return next_unget ? (next_unget = false, current)
+               : (current = ia->get_character());
+    }
+
+    /// add a character to yytext
+    void add(int c)
+    {
+        // resize yytext if necessary; this condition is deemed unlikely,
+        // because we start with a 1024-byte buffer
+        if (JSON_UNLIKELY((yylen + 1 > yytext.capacity())))
+        {
+            yytext.resize(2 * yytext.capacity(), '\0');
+        }
+        assert(yylen < yytext.size());
+        yytext[yylen++] = static_cast<char>(c);
+    }
+
+  public:
+    /////////////////////
+    // value getters
+    /////////////////////
+
+    /// return integer value
+    constexpr number_integer_t get_number_integer() const noexcept
+    {
+        return value_integer;
+    }
+
+    /// return unsigned integer value
+    constexpr number_unsigned_t get_number_unsigned() const noexcept
+    {
+        return value_unsigned;
+    }
+
+    /// return floating-point value
+    constexpr number_float_t get_number_float() const noexcept
+    {
+        return value_float;
+    }
+
+    /// return string value
+    const std::string get_string()
+    {
+        // yytext cannot be returned as char*, because it may contain a null
+        // byte (parsed as "\u0000")
+        return std::string(yytext.data(), yylen);
+    }
+
+    /////////////////////
+    // diagnostics
+    /////////////////////
+
+    /// return position of last read token
+    constexpr std::size_t get_position() const noexcept
+    {
+        return chars_read;
+    }
+
+    /// return the last read token (for errors only)
+    std::string get_token_string() const
+    {
+        // get the raw byte sequence of the last token
+        std::string s = ia->read(start_pos, chars_read - start_pos);
+
+        // escape control characters
+        std::string result;
+        for (auto c : s)
+        {
+            if (c == '\0' or c == std::char_traits<char>::eof())
+            {
+                // ignore EOF
+                continue;
+            }
+            else if ('\x00' <= c and c <= '\x1f')
+            {
+                // escape control characters
+                std::stringstream ss;
+                ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
+                   << std::hex << static_cast<int>(c) << ">";
+                result += ss.str();
+            }
+            else
+            {
+                // add character as is
+                result.push_back(c);
+            }
+        }
+
+        return result;
+    }
+
+    /// return syntax error message
+    constexpr const char* get_error_message() const noexcept
+    {
+        return error_message;
+    }
+
+    /////////////////////
+    // actual scanner
+    /////////////////////
+
+    token_type scan()
+    {
+        // read next character and ignore whitespace
+        do
+        {
+            get();
+        }
+        while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
+
+        switch (current)
+        {
+            // structural characters
+            case '[':
+                return token_type::begin_array;
+            case ']':
+                return token_type::end_array;
+            case '{':
+                return token_type::begin_object;
+            case '}':
+                return token_type::end_object;
+            case ':':
+                return token_type::name_separator;
+            case ',':
+                return token_type::value_separator;
+
+            // literals
+            case 't':
+                return scan_literal("true", 4, token_type::literal_true);
+            case 'f':
+                return scan_literal("false", 5, token_type::literal_false);
+            case 'n':
+                return scan_literal("null", 4, token_type::literal_null);
+
+            // string
+            case '\"':
+                return scan_string();
+
+            // number
+            case '-':
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                return scan_number();
+
+            // end of input (the null byte is needed when parsing from
+            // string literals)
+            case '\0':
+            case std::char_traits<char>::eof():
+                return token_type::end_of_input;
+
+            // error
+            default:
+                error_message = "invalid literal";
+                return token_type::parse_error;
+        }
+    }
+
+  private:
+    /// input adapter
+    detail::input_adapter_t ia = nullptr;
+
+    /// the current character
+    int current = std::char_traits<char>::eof();
+
+    /// whether get() should return the last character again
+    bool next_unget = false;
+
+    /// the number of characters read
+    std::size_t chars_read = 0;
+    /// the start position of the current token
+    std::size_t start_pos = 0;
+
+    /// buffer for variable-length tokens (numbers, strings)
+    std::vector<char> yytext = std::vector<char>(1024, '\0');
+    /// current index in yytext
+    std::size_t yylen = 0;
+
+    /// a description of occurred lexer errors
+    const char* error_message = "";
+
+    // number values
+    number_integer_t value_integer = 0;
+    number_unsigned_t value_unsigned = 0;
+    number_float_t value_float = 0;
+
+    /// the decimal point
+    const char decimal_point_char = '.';
+};
+
+/*!
+@brief syntax analysis
+
+This class implements a recursive decent parser.
+*/
+template<typename BasicJsonType>
+class parser
+{
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using lexer_t = lexer<BasicJsonType>;
+    using token_type = typename lexer_t::token_type;
+
+  public:
+    enum class parse_event_t : uint8_t
+    {
+        /// the parser read `{` and started to process a JSON object
+        object_start,
+        /// the parser read `}` and finished processing a JSON object
+        object_end,
+        /// the parser read `[` and started to process a JSON array
+        array_start,
+        /// the parser read `]` and finished processing a JSON array
+        array_end,
+        /// the parser read a key of a value in an object
+        key,
+        /// the parser finished reading a JSON value
+        value
+    };
+
+    using parser_callback_t =
+        std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
+
+    /// a parser reading from an input adapter
+    explicit parser(detail::input_adapter_t adapter,
+                    const parser_callback_t cb = nullptr,
+                    const bool allow_exceptions_ = true)
+        : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
+    {}
+
+    /*!
+    @brief public parser interface
+
+    @param[in] strict      whether to expect the last token to be EOF
+    @param[in,out] result  parsed JSON value
+
+    @throw parse_error.101 in case of an unexpected token
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+    */
+    void parse(const bool strict, BasicJsonType& result)
+    {
+        // read first token
+        get_token();
+
+        parse_internal(true, result);
+        result.assert_invariant();
+
+        // in strict mode, input must be completely read
+        if (strict)
+        {
+            get_token();
+            expect(token_type::end_of_input);
+        }
+
+        // in case of an error, return discarded value
+        if (errored)
+        {
+            result = value_t::discarded;
+            return;
+        }
+
+        // set top-level value to null if it was discarded by the callback
+        // function
+        if (result.is_discarded())
+        {
+            result = nullptr;
+        }
+    }
+
+    /*!
+    @brief public accept interface
+
+    @param[in] strict  whether to expect the last token to be EOF
+    @return whether the input is a proper JSON text
+    */
+    bool accept(const bool strict = true)
+    {
+        // read first token
+        get_token();
+
+        if (not accept_internal())
+        {
+            return false;
+        }
+
+        // strict => last token must be EOF
+        return not strict or (get_token() == token_type::end_of_input);
+    }
+
+  private:
+    /*!
+    @brief the actual parser
+    @throw parse_error.101 in case of an unexpected token
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+    */
+    void parse_internal(bool keep, BasicJsonType& result)
+    {
+        // never parse after a parse error was detected
+        assert(not errored);
+
+        // start with a discarded value
+        if (not result.is_discarded())
+        {
+            result.m_value.destroy(result.m_type);
+            result.m_type = value_t::discarded;
+        }
+
+        switch (last_token)
+        {
+            case token_type::begin_object:
+            {
+                if (keep)
+                {
+                    if (callback)
+                    {
+                        keep = callback(depth++, parse_event_t::object_start, result);
+                    }
+
+                    if (not callback or keep)
+                    {
+                        // explicitly set result to object to cope with {}
+                        result.m_type = value_t::object;
+                        result.m_value = value_t::object;
+                    }
+                }
+
+                // read next token
+                get_token();
+
+                // closing } -> we are done
+                if (last_token == token_type::end_object)
+                {
+                    if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
+                    {
+                        result.m_value.destroy(result.m_type);
+                        result.m_type = value_t::discarded;
+                    }
+                    break;
+                }
+
+                // parse values
+                std::string key;
+                BasicJsonType value;
+                while (true)
+                {
+                    // store key
+                    if (not expect(token_type::value_string))
+                    {
+                        return;
+                    }
+                    key = m_lexer.get_string();
+
+                    bool keep_tag = false;
+                    if (keep)
+                    {
+                        if (callback)
+                        {
+                            BasicJsonType k(key);
+                            keep_tag = callback(depth, parse_event_t::key, k);
+                        }
+                        else
+                        {
+                            keep_tag = true;
+                        }
+                    }
+
+                    // parse separator (:)
+                    get_token();
+                    if (not expect(token_type::name_separator))
+                    {
+                        return;
+                    }
+
+                    // parse and add value
+                    get_token();
+                    value.m_value.destroy(value.m_type);
+                    value.m_type = value_t::discarded;
+                    parse_internal(keep, value);
+
+                    if (JSON_UNLIKELY(errored))
+                    {
+                        return;
+                    }
+
+                    if (keep and keep_tag and not value.is_discarded())
+                    {
+                        result.m_value.object->emplace(std::move(key), std::move(value));
+                    }
+
+                    // comma -> next value
+                    get_token();
+                    if (last_token == token_type::value_separator)
+                    {
+                        get_token();
+                        continue;
+                    }
+
+                    // closing }
+                    if (not expect(token_type::end_object))
+                    {
+                        return;
+                    }
+                    break;
+                }
+
+                if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
+                {
+                    result.m_value.destroy(result.m_type);
+                    result.m_type = value_t::discarded;
+                }
+                break;
+            }
+
+            case token_type::begin_array:
+            {
+                if (keep)
+                {
+                    if (callback)
+                    {
+                        keep = callback(depth++, parse_event_t::array_start, result);
+                    }
+
+                    if (not callback or keep)
+                    {
+                        // explicitly set result to array to cope with []
+                        result.m_type = value_t::array;
+                        result.m_value = value_t::array;
+                    }
+                }
+
+                // read next token
+                get_token();
+
+                // closing ] -> we are done
+                if (last_token == token_type::end_array)
+                {
+                    if (callback and not callback(--depth, parse_event_t::array_end, result))
+                    {
+                        result.m_value.destroy(result.m_type);
+                        result.m_type = value_t::discarded;
+                    }
+                    break;
+                }
+
+                // parse values
+                BasicJsonType value;
+                while (true)
+                {
+                    // parse value
+                    value.m_value.destroy(value.m_type);
+                    value.m_type = value_t::discarded;
+                    parse_internal(keep, value);
+
+                    if (JSON_UNLIKELY(errored))
+                    {
+                        return;
+                    }
+
+                    if (keep and not value.is_discarded())
+                    {
+                        result.m_value.array->push_back(std::move(value));
+                    }
+
+                    // comma -> next value
+                    get_token();
+                    if (last_token == token_type::value_separator)
+                    {
+                        get_token();
+                        continue;
+                    }
+
+                    // closing ]
+                    if (not expect(token_type::end_array))
+                    {
+                        return;
+                    }
+                    break;
+                }
+
+                if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
+                {
+                    result.m_value.destroy(result.m_type);
+                    result.m_type = value_t::discarded;
+                }
+                break;
+            }
+
+            case token_type::literal_null:
+            {
+                result.m_type = value_t::null;
+                break;
+            }
+
+            case token_type::value_string:
+            {
+                result.m_type = value_t::string;
+                result.m_value = m_lexer.get_string();
+                break;
+            }
+
+            case token_type::literal_true:
+            {
+                result.m_type = value_t::boolean;
+                result.m_value = true;
+                break;
+            }
+
+            case token_type::literal_false:
+            {
+                result.m_type = value_t::boolean;
+                result.m_value = false;
+                break;
+            }
+
+            case token_type::value_unsigned:
+            {
+                result.m_type = value_t::number_unsigned;
+                result.m_value = m_lexer.get_number_unsigned();
+                break;
+            }
+
+            case token_type::value_integer:
+            {
+                result.m_type = value_t::number_integer;
+                result.m_value = m_lexer.get_number_integer();
+                break;
+            }
+
+            case token_type::value_float:
+            {
+                result.m_type = value_t::number_float;
+                result.m_value = m_lexer.get_number_float();
+
+                // throw in case of infinity or NAN
+                if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
+                {
+                    if (allow_exceptions)
+                    {
+                        JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
+                                                        m_lexer.get_token_string() + "'"));
+                    }
+                    expect(token_type::uninitialized);
+                }
+                break;
+            }
+
+            case token_type::parse_error:
+            {
+                // using "uninitialized" to avoid "expected" message
+                if (not expect(token_type::uninitialized))
+                {
+                    return;
+                }
+                break; // LCOV_EXCL_LINE
+            }
+
+            default:
+            {
+                // the last token was unexpected; we expected a value
+                if (not expect(token_type::literal_or_value))
+                {
+                    return;
+                }
+                break; // LCOV_EXCL_LINE
+            }
+        }
+
+        if (keep and callback and not callback(depth, parse_event_t::value, result))
+        {
+            result.m_type = value_t::discarded;
+        }
+    }
+
+    /*!
+    @brief the acutal acceptor
+
+    @invariant 1. The last token is not yet processed. Therefore, the caller
+                  of this function must make sure a token has been read.
+               2. When this function returns, the last token is processed.
+                  That is, the last read character was already considered.
+
+    This invariant makes sure that no token needs to be "unput".
+    */
+    bool accept_internal()
+    {
+        switch (last_token)
+        {
+            case token_type::begin_object:
+            {
+                // read next token
+                get_token();
+
+                // closing } -> we are done
+                if (last_token == token_type::end_object)
+                {
+                    return true;
+                }
+
+                // parse values
+                while (true)
+                {
+                    // parse key
+                    if (last_token != token_type::value_string)
+                    {
+                        return false;
+                    }
+
+                    // parse separator (:)
+                    get_token();
+                    if (last_token != token_type::name_separator)
+                    {
+                        return false;
+                    }
+
+                    // parse value
+                    get_token();
+                    if (not accept_internal())
+                    {
+                        return false;
+                    }
+
+                    // comma -> next value
+                    get_token();
+                    if (last_token == token_type::value_separator)
+                    {
+                        get_token();
+                        continue;
+                    }
+
+                    // closing }
+                    return (last_token == token_type::end_object);
+                }
+            }
+
+            case token_type::begin_array:
+            {
+                // read next token
+                get_token();
+
+                // closing ] -> we are done
+                if (last_token == token_type::end_array)
+                {
+                    return true;
+                }
+
+                // parse values
+                while (true)
+                {
+                    // parse value
+                    if (not accept_internal())
+                    {
+                        return false;
+                    }
+
+                    // comma -> next value
+                    get_token();
+                    if (last_token == token_type::value_separator)
+                    {
+                        get_token();
+                        continue;
+                    }
+
+                    // closing ]
+                    return (last_token == token_type::end_array);
+                }
+            }
+
+            case token_type::value_float:
+            {
+                // reject infinity or NAN
+                return std::isfinite(m_lexer.get_number_float());
+            }
+
+            case token_type::literal_false:
+            case token_type::literal_null:
+            case token_type::literal_true:
+            case token_type::value_integer:
+            case token_type::value_string:
+            case token_type::value_unsigned:
+                return true;
+
+            default: // the last token was unexpected
+                return false;
+        }
+    }
+
+    /// get next token from lexer
+    token_type get_token()
+    {
+        return (last_token = m_lexer.scan());
+    }
+
+    /*!
+    @throw parse_error.101 if expected token did not occur
+    */
+    bool expect(token_type t)
+    {
+        if (JSON_UNLIKELY(t != last_token))
+        {
+            errored = true;
+            expected = t;
+            if (allow_exceptions)
+            {
+                throw_exception();
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    [[noreturn]] void throw_exception() const
+    {
+        std::string error_msg = "syntax error - ";
+        if (last_token == token_type::parse_error)
+        {
+            error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
+                         m_lexer.get_token_string() + "'";
+        }
+        else
+        {
+            error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
+        }
+
+        if (expected != token_type::uninitialized)
+        {
+            error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
+        }
+
+        JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
+    }
+
+  private:
+    /// current level of recursion
+    int depth = 0;
+    /// callback function
+    const parser_callback_t callback = nullptr;
+    /// the type of the last read token
+    token_type last_token = token_type::uninitialized;
+    /// the lexer
+    lexer_t m_lexer;
+    /// whether a syntax error occurred
+    bool errored = false;
+    /// possible reason for the syntax error
+    token_type expected = token_type::uninitialized;
+    /// whether to throw exceptions in case of errors
+    const bool allow_exceptions = true;
+};
+
+///////////////
+// iterators //
+///////////////
+
+/*!
+@brief an iterator for primitive JSON types
+
+This class models an iterator for primitive JSON types (boolean, number,
+string). It's only purpose is to allow the iterator/const_iterator classes
+to "iterate" over primitive values. Internally, the iterator is modeled by
+a `difference_type` variable. Value begin_value (`0`) models the begin,
+end_value (`1`) models past the end.
+*/
+class primitive_iterator_t
+{
+  public:
+    using difference_type = std::ptrdiff_t;
+
+    constexpr difference_type get_value() const noexcept
+    {
+        return m_it;
+    }
+
+    /// set iterator to a defined beginning
+    void set_begin() noexcept
+    {
+        m_it = begin_value;
+    }
+
+    /// set iterator to a defined past the end
+    void set_end() noexcept
+    {
+        m_it = end_value;
+    }
+
+    /// return whether the iterator can be dereferenced
+    constexpr bool is_begin() const noexcept
+    {
+        return m_it == begin_value;
+    }
+
+    /// return whether the iterator is at end
+    constexpr bool is_end() const noexcept
+    {
+        return m_it == end_value;
+    }
+
+    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+    {
+        return lhs.m_it == rhs.m_it;
+    }
+
+    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+    {
+        return lhs.m_it < rhs.m_it;
+    }
+
+    primitive_iterator_t operator+(difference_type i)
+    {
+        auto result = *this;
+        result += i;
+        return result;
+    }
+
+    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+    {
+        return lhs.m_it - rhs.m_it;
+    }
+
+    friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
+    {
+        return os << it.m_it;
+    }
+
+    primitive_iterator_t& operator++()
+    {
+        ++m_it;
+        return *this;
+    }
+
+    primitive_iterator_t operator++(int)
+    {
+        auto result = *this;
+        m_it++;
+        return result;
+    }
+
+    primitive_iterator_t& operator--()
+    {
+        --m_it;
+        return *this;
+    }
+
+    primitive_iterator_t operator--(int)
+    {
+        auto result = *this;
+        m_it--;
+        return result;
+    }
+
+    primitive_iterator_t& operator+=(difference_type n)
+    {
+        m_it += n;
+        return *this;
+    }
+
+    primitive_iterator_t& operator-=(difference_type n)
+    {
+        m_it -= n;
+        return *this;
+    }
+
+  private:
+    static constexpr difference_type begin_value = 0;
+    static constexpr difference_type end_value = begin_value + 1;
+
+    /// iterator as signed integer type
+    difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
+};
+
+/*!
+@brief an iterator value
+
+@note This structure could easily be a union, but MSVC currently does not allow
+unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
+*/
+template<typename BasicJsonType> struct internal_iterator
+{
+    /// iterator for JSON objects
+    typename BasicJsonType::object_t::iterator object_iterator {};
+    /// iterator for JSON arrays
+    typename BasicJsonType::array_t::iterator array_iterator {};
+    /// generic iterator for all other types
+    primitive_iterator_t primitive_iterator {};
+};
+
+template<typename IteratorType> class iteration_proxy;
+
+/*!
+@brief a template for a random access iterator for the @ref basic_json class
+
+This class implements a both iterators (iterator and const_iterator) for the
+@ref basic_json class.
+
+@note An iterator is called *initialized* when a pointer to a JSON value has
+      been set (e.g., by a constructor or a copy assignment). If the iterator is
+      default-constructed, it is *uninitialized* and most methods are undefined.
+      **The library uses assertions to detect calls on uninitialized iterators.**
+
+@requirement The class satisfies the following concept requirements:
+-
+[RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
+  The iterator that can be moved to point (forward and backward) to any
+  element in constant time.
+
+@since version 1.0.0, simplified in version 2.0.9
+*/
+template<typename BasicJsonType>
+class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJsonType>
+{
+    /// allow basic_json to access private members
+    friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
+    friend BasicJsonType;
+    friend iteration_proxy<iter_impl>;
+
+    using object_t = typename BasicJsonType::object_t;
+    using array_t = typename BasicJsonType::array_t;
+    // make sure BasicJsonType is basic_json or const basic_json
+    static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
+                  "iter_impl only accepts (const) basic_json");
+
+  public:
+    /// the type of the values when the iterator is dereferenced
+    using value_type = typename BasicJsonType::value_type;
+    /// a type to represent differences between iterators
+    using difference_type = typename BasicJsonType::difference_type;
+    /// defines a pointer to the type iterated over (value_type)
+    using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
+          typename BasicJsonType::const_pointer,
+          typename BasicJsonType::pointer>::type;
+    /// defines a reference to the type iterated over (value_type)
+    using reference =
+        typename std::conditional<std::is_const<BasicJsonType>::value,
+        typename BasicJsonType::const_reference,
+        typename BasicJsonType::reference>::type;
+    /// the category of the iterator
+    using iterator_category = std::bidirectional_iterator_tag;
+
+    /// default constructor
+    iter_impl() = default;
+
+    /*!
+    @brief constructor for a given JSON instance
+    @param[in] object  pointer to a JSON object for this iterator
+    @pre object != nullptr
+    @post The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    explicit iter_impl(pointer object) noexcept : m_object(object)
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                m_it.object_iterator = typename object_t::iterator();
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_it.array_iterator = typename array_t::iterator();
+                break;
+            }
+
+            default:
+            {
+                m_it.primitive_iterator = primitive_iterator_t();
+                break;
+            }
+        }
+    }
+
+    /*!
+    @note The conventional copy constructor and copy assignment are implicitly
+          defined. Combined with the following converting constructor and
+          assignment, they support: (1) copy from iterator to iterator, (2)
+          copy from const iterator to const iterator, and (3) conversion from
+          iterator to const iterator. However conversion from const iterator
+          to iterator is not defined.
+    */
+
+    /*!
+    @brief converting constructor
+    @param[in] other  non-const iterator to copy from
+    @note It is not checked whether @a other is initialized.
+    */
+    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
+        : m_object(other.m_object), m_it(other.m_it) {}
+
+    /*!
+    @brief converting assignment
+    @param[in,out] other  non-const iterator to copy from
+    @return const/non-const iterator
+    @note It is not checked whether @a other is initialized.
+    */
+    iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
+    {
+        m_object = other.m_object;
+        m_it = other.m_it;
+        return *this;
+    }
+
+  private:
+    /*!
+    @brief set the iterator to the first value
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    void set_begin() noexcept
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                m_it.object_iterator = m_object->m_value.object->begin();
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_it.array_iterator = m_object->m_value.array->begin();
+                break;
+            }
+
+            case value_t::null:
+            {
+                // set to end so begin()==end() is true: null is empty
+                m_it.primitive_iterator.set_end();
+                break;
+            }
+
+            default:
+            {
+                m_it.primitive_iterator.set_begin();
+                break;
+            }
+        }
+    }
+
+    /*!
+    @brief set the iterator past the last value
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    void set_end() noexcept
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                m_it.object_iterator = m_object->m_value.object->end();
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_it.array_iterator = m_object->m_value.array->end();
+                break;
+            }
+
+            default:
+            {
+                m_it.primitive_iterator.set_end();
+                break;
+            }
+        }
+    }
+
+  public:
+    /*!
+    @brief return a reference to the value pointed to by the iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    reference operator*() const
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                assert(m_it.object_iterator != m_object->m_value.object->end());
+                return m_it.object_iterator->second;
+            }
+
+            case value_t::array:
+            {
+                assert(m_it.array_iterator != m_object->m_value.array->end());
+                return *m_it.array_iterator;
+            }
+
+            case value_t::null:
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+            default:
+            {
+                if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
+                {
+                    return *m_object;
+                }
+
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+            }
+        }
+    }
+
+    /*!
+    @brief dereference the iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    pointer operator->() const
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                assert(m_it.object_iterator != m_object->m_value.object->end());
+                return &(m_it.object_iterator->second);
+            }
+
+            case value_t::array:
+            {
+                assert(m_it.array_iterator != m_object->m_value.array->end());
+                return &*m_it.array_iterator;
+            }
+
+            default:
+            {
+                if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
+                {
+                    return m_object;
+                }
+
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+            }
+        }
+    }
+
+    /*!
+    @brief post-increment (it++)
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl operator++(int)
+    {
+        auto result = *this;
+        ++(*this);
+        return result;
+    }
+
+    /*!
+    @brief pre-increment (++it)
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl& operator++()
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                std::advance(m_it.object_iterator, 1);
+                break;
+            }
+
+            case value_t::array:
+            {
+                std::advance(m_it.array_iterator, 1);
+                break;
+            }
+
+            default:
+            {
+                ++m_it.primitive_iterator;
+                break;
+            }
+        }
+
+        return *this;
+    }
+
+    /*!
+    @brief post-decrement (it--)
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl operator--(int)
+    {
+        auto result = *this;
+        --(*this);
+        return result;
+    }
+
+    /*!
+    @brief pre-decrement (--it)
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl& operator--()
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                std::advance(m_it.object_iterator, -1);
+                break;
+            }
+
+            case value_t::array:
+            {
+                std::advance(m_it.array_iterator, -1);
+                break;
+            }
+
+            default:
+            {
+                --m_it.primitive_iterator;
+                break;
+            }
+        }
+
+        return *this;
+    }
+
+    /*!
+    @brief  comparison: equal
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator==(const iter_impl& other) const
+    {
+        // if objects are not the same, the comparison is undefined
+        if (JSON_UNLIKELY(m_object != other.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+        }
+
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                return (m_it.object_iterator == other.m_it.object_iterator);
+
+            case value_t::array:
+                return (m_it.array_iterator == other.m_it.array_iterator);
+
+            default:
+                return (m_it.primitive_iterator == other.m_it.primitive_iterator);
+        }
+    }
+
+    /*!
+    @brief  comparison: not equal
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator!=(const iter_impl& other) const
+    {
+        return not operator==(other);
+    }
+
+    /*!
+    @brief  comparison: smaller
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator<(const iter_impl& other) const
+    {
+        // if objects are not the same, the comparison is undefined
+        if (JSON_UNLIKELY(m_object != other.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+        }
+
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
+
+            case value_t::array:
+                return (m_it.array_iterator < other.m_it.array_iterator);
+
+            default:
+                return (m_it.primitive_iterator < other.m_it.primitive_iterator);
+        }
+    }
+
+    /*!
+    @brief  comparison: less than or equal
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator<=(const iter_impl& other) const
+    {
+        return not other.operator < (*this);
+    }
+
+    /*!
+    @brief  comparison: greater than
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator>(const iter_impl& other) const
+    {
+        return not operator<=(other);
+    }
+
+    /*!
+    @brief  comparison: greater than or equal
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator>=(const iter_impl& other) const
+    {
+        return not operator<(other);
+    }
+
+    /*!
+    @brief  add to iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl& operator+=(difference_type i)
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+
+            case value_t::array:
+            {
+                std::advance(m_it.array_iterator, i);
+                break;
+            }
+
+            default:
+            {
+                m_it.primitive_iterator += i;
+                break;
+            }
+        }
+
+        return *this;
+    }
+
+    /*!
+    @brief  subtract from iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl& operator-=(difference_type i)
+    {
+        return operator+=(-i);
+    }
+
+    /*!
+    @brief  add to iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl operator+(difference_type i) const
+    {
+        auto result = *this;
+        result += i;
+        return result;
+    }
+
+    /*!
+    @brief  addition of distance and iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    friend iter_impl operator+(difference_type i, const iter_impl& it)
+    {
+        auto result = it;
+        result += i;
+        return result;
+    }
+
+    /*!
+    @brief  subtract from iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl operator-(difference_type i) const
+    {
+        auto result = *this;
+        result -= i;
+        return result;
+    }
+
+    /*!
+    @brief  return difference
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    difference_type operator-(const iter_impl& other) const
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+
+            case value_t::array:
+                return m_it.array_iterator - other.m_it.array_iterator;
+
+            default:
+                return m_it.primitive_iterator - other.m_it.primitive_iterator;
+        }
+    }
+
+    /*!
+    @brief  access to successor
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    reference operator[](difference_type n) const
+    {
+        assert(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
+
+            case value_t::array:
+                return *std::next(m_it.array_iterator, n);
+
+            case value_t::null:
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+            default:
+            {
+                if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
+                {
+                    return *m_object;
+                }
+
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+            }
+        }
+    }
+
+    /*!
+    @brief  return the key of an object iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    typename object_t::key_type key() const
+    {
+        assert(m_object != nullptr);
+
+        if (JSON_LIKELY(m_object->is_object()))
+        {
+            return m_it.object_iterator->first;
+        }
+
+        JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
+    }
+
+    /*!
+    @brief  return the value of an iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    reference value() const
+    {
+        return operator*();
+    }
+
+  private:
+    /// associated JSON instance
+    pointer m_object = nullptr;
+    /// the actual iterator of the associated instance
+    internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it = {};
+};
+
+/// proxy class for the iterator_wrapper functions
+template<typename IteratorType> class iteration_proxy
+{
+  private:
+    /// helper class for iteration
+    class iteration_proxy_internal
+    {
+      private:
+        /// the iterator
+        IteratorType anchor;
+        /// an index for arrays (used to create key names)
+        std::size_t array_index = 0;
+
+      public:
+        explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
+
+        /// dereference operator (needed for range-based for)
+        iteration_proxy_internal& operator*()
+        {
+            return *this;
+        }
+
+        /// increment operator (needed for range-based for)
+        iteration_proxy_internal& operator++()
+        {
+            ++anchor;
+            ++array_index;
+
+            return *this;
+        }
+
+        /// inequality operator (needed for range-based for)
+        bool operator!=(const iteration_proxy_internal& o) const noexcept
+        {
+            return anchor != o.anchor;
+        }
+
+        /// return key of the iterator
+        std::string key() const
+        {
+            assert(anchor.m_object != nullptr);
+
+            switch (anchor.m_object->type())
+            {
+                // use integer array index as key
+                case value_t::array:
+                    return std::to_string(array_index);
+
+                // use key from the object
+                case value_t::object:
+                    return anchor.key();
+
+                // use an empty key for all primitive types
+                default:
+                    return "";
+            }
+        }
+
+        /// return value of the iterator
+        typename IteratorType::reference value() const
+        {
+            return anchor.value();
+        }
+    };
+
+    /// the container to iterate
+    typename IteratorType::reference container;
+
+  public:
+    /// construct iteration proxy from a container
+    explicit iteration_proxy(typename IteratorType::reference cont)
+        : container(cont) {}
+
+    /// return iterator begin (needed for range-based for)
+    iteration_proxy_internal begin() noexcept
+    {
+        return iteration_proxy_internal(container.begin());
+    }
+
+    /// return iterator end (needed for range-based for)
+    iteration_proxy_internal end() noexcept
+    {
+        return iteration_proxy_internal(container.end());
+    }
+};
+
+/*!
+@brief a template for a reverse iterator class
+
+@tparam Base the base iterator type to reverse. Valid types are @ref
+iterator (to create @ref reverse_iterator) and @ref const_iterator (to
+create @ref const_reverse_iterator).
+
+@requirement The class satisfies the following concept requirements:
+-
+[RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
+  The iterator that can be moved to point (forward and backward) to any
+  element in constant time.
+- [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
+  It is possible to write to the pointed-to element (only if @a Base is
+  @ref iterator).
+
+@since version 1.0.0
+*/
+template<typename Base>
+class json_reverse_iterator : public std::reverse_iterator<Base>
+{
+  public:
+    using difference_type = std::ptrdiff_t;
+    /// shortcut to the reverse iterator adaptor
+    using base_iterator = std::reverse_iterator<Base>;
+    /// the reference type for the pointed-to element
+    using reference = typename Base::reference;
+
+    /// create reverse iterator from iterator
+    json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
+        : base_iterator(it) {}
+
+    /// create reverse iterator from base class
+    json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
+
+    /// post-increment (it++)
+    json_reverse_iterator operator++(int)
+    {
+        return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
+    }
+
+    /// pre-increment (++it)
+    json_reverse_iterator& operator++()
+    {
+        return static_cast<json_reverse_iterator&>(base_iterator::operator++());
+    }
+
+    /// post-decrement (it--)
+    json_reverse_iterator operator--(int)
+    {
+        return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
+    }
+
+    /// pre-decrement (--it)
+    json_reverse_iterator& operator--()
+    {
+        return static_cast<json_reverse_iterator&>(base_iterator::operator--());
+    }
+
+    /// add to iterator
+    json_reverse_iterator& operator+=(difference_type i)
+    {
+        return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
+    }
+
+    /// add to iterator
+    json_reverse_iterator operator+(difference_type i) const
+    {
+        return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
+    }
+
+    /// subtract from iterator
+    json_reverse_iterator operator-(difference_type i) const
+    {
+        return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
+    }
+
+    /// return difference
+    difference_type operator-(const json_reverse_iterator& other) const
+    {
+        return base_iterator(*this) - base_iterator(other);
+    }
+
+    /// access to successor
+    reference operator[](difference_type n) const
+    {
+        return *(this->operator+(n));
+    }
+
+    /// return the key of an object iterator
+    auto key() const -> decltype(std::declval<Base>().key())
+    {
+        auto it = --this->base();
+        return it.key();
+    }
+
+    /// return the value of an iterator
+    reference value() const
+    {
+        auto it = --this->base();
+        return it.operator * ();
+    }
+};
+
+/////////////////////
+// output adapters //
+/////////////////////
+
+/// abstract output adapter interface
+template<typename CharType> struct output_adapter_protocol
+{
+    virtual void write_character(CharType c) = 0;
+    virtual void write_characters(const CharType* s, std::size_t length) = 0;
+    virtual ~output_adapter_protocol() = default;
+};
+
+/// a type to simplify interfaces
+template<typename CharType>
+using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
+
+/// output adapter for byte vectors
+template<typename CharType>
+class output_vector_adapter : public output_adapter_protocol<CharType>
+{
+  public:
+    explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
+
+    void write_character(CharType c) override
+    {
+        v.push_back(c);
+    }
+
+    void write_characters(const CharType* s, std::size_t length) override
+    {
+        std::copy(s, s + length, std::back_inserter(v));
+    }
+
+  private:
+    std::vector<CharType>& v;
+};
+
+/// output adapter for output streams
+template<typename CharType>
+class output_stream_adapter : public output_adapter_protocol<CharType>
+{
+  public:
+    explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
+
+    void write_character(CharType c) override
+    {
+        stream.put(c);
+    }
+
+    void write_characters(const CharType* s, std::size_t length) override
+    {
+        stream.write(s, static_cast<std::streamsize>(length));
+    }
+
+  private:
+    std::basic_ostream<CharType>& stream;
+};
+
+/// output adapter for basic_string
+template<typename CharType>
+class output_string_adapter : public output_adapter_protocol<CharType>
+{
+  public:
+    explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {}
+
+    void write_character(CharType c) override
+    {
+        str.push_back(c);
+    }
+
+    void write_characters(const CharType* s, std::size_t length) override
+    {
+        str.append(s, length);
+    }
+
+  private:
+    std::basic_string<CharType>& str;
+};
+
+template<typename CharType>
+class output_adapter
+{
+  public:
+    output_adapter(std::vector<CharType>& vec)
+        : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
+
+    output_adapter(std::basic_ostream<CharType>& s)
+        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
+
+    output_adapter(std::basic_string<CharType>& s)
+        : oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
+
+    operator output_adapter_t<CharType>()
+    {
+        return oa;
+    }
+
+  private:
+    output_adapter_t<CharType> oa = nullptr;
+};
+
+//////////////////////////////
+// binary reader and writer //
+//////////////////////////////
+
+/*!
+@brief deserialization of CBOR and MessagePack values
+*/
+template<typename BasicJsonType>
+class binary_reader
+{
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+
+  public:
+    /*!
+    @brief create a binary reader
+
+    @param[in] adapter  input adapter to read from
+    */
+    explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
+    {
+        assert(ia);
+    }
+
+    /*!
+    @brief create a JSON value from CBOR input
+
+    @param[in] strict  whether to expect the input to be consumed completed
+    @return JSON value created from CBOR input
+
+    @throw parse_error.110 if input ended unexpectedly or the end of file was
+                           not reached when @a strict was set to true
+    @throw parse_error.112 if unsupported byte was read
+    */
+    BasicJsonType parse_cbor(const bool strict)
+    {
+        const auto res = parse_cbor_internal();
+        if (strict)
+        {
+            get();
+            check_eof(true);
+        }
+        return res;
+    }
+
+    /*!
+    @brief create a JSON value from MessagePack input
+
+    @param[in] strict  whether to expect the input to be consumed completed
+    @return JSON value created from MessagePack input
+
+    @throw parse_error.110 if input ended unexpectedly or the end of file was
+                           not reached when @a strict was set to true
+    @throw parse_error.112 if unsupported byte was read
+    */
+    BasicJsonType parse_msgpack(const bool strict)
+    {
+        const auto res = parse_msgpack_internal();
+        if (strict)
+        {
+            get();
+            check_eof(true);
+        }
+        return res;
+    }
+
+    /*!
+    @brief determine system byte order
+
+    @return true if and only if system's byte order is little endian
+
+    @note from http://stackoverflow.com/a/1001328/266378
+    */
+    static constexpr bool little_endianess(int num = 1) noexcept
+    {
+        return (*reinterpret_cast<char*>(&num) == 1);
+    }
+
+  private:
+    /*!
+    @param[in] get_char  whether a new character should be retrieved from the
+                         input (true, default) or whether the last read
+                         character should be considered instead
+    */
+    BasicJsonType parse_cbor_internal(const bool get_char = true)
+    {
+        switch (get_char ? get() : current)
+        {
+            // EOF
+            case std::char_traits<char>::eof():
+                JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
+
+            // Integer 0x00..0x17 (0..23)
+            case 0x00:
+            case 0x01:
+            case 0x02:
+            case 0x03:
+            case 0x04:
+            case 0x05:
+            case 0x06:
+            case 0x07:
+            case 0x08:
+            case 0x09:
+            case 0x0a:
+            case 0x0b:
+            case 0x0c:
+            case 0x0d:
+            case 0x0e:
+            case 0x0f:
+            case 0x10:
+            case 0x11:
+            case 0x12:
+            case 0x13:
+            case 0x14:
+            case 0x15:
+            case 0x16:
+            case 0x17:
+                return static_cast<number_unsigned_t>(current);
+
+            case 0x18: // Unsigned integer (one-byte uint8_t follows)
+                return get_number<uint8_t>();
+
+            case 0x19: // Unsigned integer (two-byte uint16_t follows)
+                return get_number<uint16_t>();
+
+            case 0x1a: // Unsigned integer (four-byte uint32_t follows)
+                return get_number<uint32_t>();
+
+            case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
+                return get_number<uint64_t>();
+
+            // Negative integer -1-0x00..-1-0x17 (-1..-24)
+            case 0x20:
+            case 0x21:
+            case 0x22:
+            case 0x23:
+            case 0x24:
+            case 0x25:
+            case 0x26:
+            case 0x27:
+            case 0x28:
+            case 0x29:
+            case 0x2a:
+            case 0x2b:
+            case 0x2c:
+            case 0x2d:
+            case 0x2e:
+            case 0x2f:
+            case 0x30:
+            case 0x31:
+            case 0x32:
+            case 0x33:
+            case 0x34:
+            case 0x35:
+            case 0x36:
+            case 0x37:
+                return static_cast<int8_t>(0x20 - 1 - current);
+
+            case 0x38: // Negative integer (one-byte uint8_t follows)
+            {
+                // must be uint8_t !
+                return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
+            }
+
+            case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
+            {
+                return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
+            }
+
+            case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
+            {
+                return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
+            }
+
+            case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
+            {
+                return static_cast<number_integer_t>(-1) -
+                       static_cast<number_integer_t>(get_number<uint64_t>());
+            }
+
+            // UTF-8 string (0x00..0x17 bytes follow)
+            case 0x60:
+            case 0x61:
+            case 0x62:
+            case 0x63:
+            case 0x64:
+            case 0x65:
+            case 0x66:
+            case 0x67:
+            case 0x68:
+            case 0x69:
+            case 0x6a:
+            case 0x6b:
+            case 0x6c:
+            case 0x6d:
+            case 0x6e:
+            case 0x6f:
+            case 0x70:
+            case 0x71:
+            case 0x72:
+            case 0x73:
+            case 0x74:
+            case 0x75:
+            case 0x76:
+            case 0x77:
+            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
+            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
+            case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
+            case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
+            case 0x7f: // UTF-8 string (indefinite length)
+            {
+                return get_cbor_string();
+            }
+
+            // array (0x00..0x17 data items follow)
+            case 0x80:
+            case 0x81:
+            case 0x82:
+            case 0x83:
+            case 0x84:
+            case 0x85:
+            case 0x86:
+            case 0x87:
+            case 0x88:
+            case 0x89:
+            case 0x8a:
+            case 0x8b:
+            case 0x8c:
+            case 0x8d:
+            case 0x8e:
+            case 0x8f:
+            case 0x90:
+            case 0x91:
+            case 0x92:
+            case 0x93:
+            case 0x94:
+            case 0x95:
+            case 0x96:
+            case 0x97:
+            {
+                return get_cbor_array(current & 0x1f);
+            }
+
+            case 0x98: // array (one-byte uint8_t for n follows)
+            {
+                return get_cbor_array(get_number<uint8_t>());
+            }
+
+            case 0x99: // array (two-byte uint16_t for n follow)
+            {
+                return get_cbor_array(get_number<uint16_t>());
+            }
+
+            case 0x9a: // array (four-byte uint32_t for n follow)
+            {
+                return get_cbor_array(get_number<uint32_t>());
+            }
+
+            case 0x9b: // array (eight-byte uint64_t for n follow)
+            {
+                return get_cbor_array(get_number<uint64_t>());
+            }
+
+            case 0x9f: // array (indefinite length)
+            {
+                BasicJsonType result = value_t::array;
+                while (get() != 0xff)
+                {
+                    result.push_back(parse_cbor_internal(false));
+                }
+                return result;
+            }
+
+            // map (0x00..0x17 pairs of data items follow)
+            case 0xa0:
+            case 0xa1:
+            case 0xa2:
+            case 0xa3:
+            case 0xa4:
+            case 0xa5:
+            case 0xa6:
+            case 0xa7:
+            case 0xa8:
+            case 0xa9:
+            case 0xaa:
+            case 0xab:
+            case 0xac:
+            case 0xad:
+            case 0xae:
+            case 0xaf:
+            case 0xb0:
+            case 0xb1:
+            case 0xb2:
+            case 0xb3:
+            case 0xb4:
+            case 0xb5:
+            case 0xb6:
+            case 0xb7:
+            {
+                return get_cbor_object(current & 0x1f);
+            }
+
+            case 0xb8: // map (one-byte uint8_t for n follows)
+            {
+                return get_cbor_object(get_number<uint8_t>());
+            }
+
+            case 0xb9: // map (two-byte uint16_t for n follow)
+            {
+                return get_cbor_object(get_number<uint16_t>());
+            }
+
+            case 0xba: // map (four-byte uint32_t for n follow)
+            {
+                return get_cbor_object(get_number<uint32_t>());
+            }
+
+            case 0xbb: // map (eight-byte uint64_t for n follow)
+            {
+                return get_cbor_object(get_number<uint64_t>());
+            }
+
+            case 0xbf: // map (indefinite length)
+            {
+                BasicJsonType result = value_t::object;
+                while (get() != 0xff)
+                {
+                    auto key = get_cbor_string();
+                    result[key] = parse_cbor_internal();
+                }
+                return result;
+            }
+
+            case 0xf4: // false
+            {
+                return false;
+            }
+
+            case 0xf5: // true
+            {
+                return true;
+            }
+
+            case 0xf6: // null
+            {
+                return value_t::null;
+            }
+
+            case 0xf9: // Half-Precision Float (two-byte IEEE 754)
+            {
+                const int byte1 = get();
+                check_eof();
+                const int byte2 = get();
+                check_eof();
+
+                // code from RFC 7049, Appendix D, Figure 3:
+                // As half-precision floating-point numbers were only added
+                // to IEEE 754 in 2008, today's programming platforms often
+                // still only have limited support for them. It is very
+                // easy to include at least decoding support for them even
+                // without such support. An example of a small decoder for
+                // half-precision floating-point numbers in the C language
+                // is shown in Fig. 3.
+                const int half = (byte1 << 8) + byte2;
+                const int exp = (half >> 10) & 0x1f;
+                const int mant = half & 0x3ff;
+                double val;
+                if (exp == 0)
+                {
+                    val = std::ldexp(mant, -24);
+                }
+                else if (exp != 31)
+                {
+                    val = std::ldexp(mant + 1024, exp - 25);
+                }
+                else
+                {
+                    val = (mant == 0) ? std::numeric_limits<double>::infinity()
+                          : std::numeric_limits<double>::quiet_NaN();
+                }
+                return (half & 0x8000) != 0 ? -val : val;
+            }
+
+            case 0xfa: // Single-Precision Float (four-byte IEEE 754)
+            {
+                return get_number<float>();
+            }
+
+            case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
+            {
+                return get_number<double>();
+            }
+
+            default: // anything else (0xFF is handled inside the other types)
+            {
+                std::stringstream ss;
+                ss << std::setw(2) << std::setfill('0') << std::hex << current;
+                JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + ss.str()));
+            }
+        }
+    }
+
+    BasicJsonType parse_msgpack_internal()
+    {
+        switch (get())
+        {
+            // EOF
+            case std::char_traits<char>::eof():
+                JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
+
+            // positive fixint
+            case 0x00:
+            case 0x01:
+            case 0x02:
+            case 0x03:
+            case 0x04:
+            case 0x05:
+            case 0x06:
+            case 0x07:
+            case 0x08:
+            case 0x09:
+            case 0x0a:
+            case 0x0b:
+            case 0x0c:
+            case 0x0d:
+            case 0x0e:
+            case 0x0f:
+            case 0x10:
+            case 0x11:
+            case 0x12:
+            case 0x13:
+            case 0x14:
+            case 0x15:
+            case 0x16:
+            case 0x17:
+            case 0x18:
+            case 0x19:
+            case 0x1a:
+            case 0x1b:
+            case 0x1c:
+            case 0x1d:
+            case 0x1e:
+            case 0x1f:
+            case 0x20:
+            case 0x21:
+            case 0x22:
+            case 0x23:
+            case 0x24:
+            case 0x25:
+            case 0x26:
+            case 0x27:
+            case 0x28:
+            case 0x29:
+            case 0x2a:
+            case 0x2b:
+            case 0x2c:
+            case 0x2d:
+            case 0x2e:
+            case 0x2f:
+            case 0x30:
+            case 0x31:
+            case 0x32:
+            case 0x33:
+            case 0x34:
+            case 0x35:
+            case 0x36:
+            case 0x37:
+            case 0x38:
+            case 0x39:
+            case 0x3a:
+            case 0x3b:
+            case 0x3c:
+            case 0x3d:
+            case 0x3e:
+            case 0x3f:
+            case 0x40:
+            case 0x41:
+            case 0x42:
+            case 0x43:
+            case 0x44:
+            case 0x45:
+            case 0x46:
+            case 0x47:
+            case 0x48:
+            case 0x49:
+            case 0x4a:
+            case 0x4b:
+            case 0x4c:
+            case 0x4d:
+            case 0x4e:
+            case 0x4f:
+            case 0x50:
+            case 0x51:
+            case 0x52:
+            case 0x53:
+            case 0x54:
+            case 0x55:
+            case 0x56:
+            case 0x57:
+            case 0x58:
+            case 0x59:
+            case 0x5a:
+            case 0x5b:
+            case 0x5c:
+            case 0x5d:
+            case 0x5e:
+            case 0x5f:
+            case 0x60:
+            case 0x61:
+            case 0x62:
+            case 0x63:
+            case 0x64:
+            case 0x65:
+            case 0x66:
+            case 0x67:
+            case 0x68:
+            case 0x69:
+            case 0x6a:
+            case 0x6b:
+            case 0x6c:
+            case 0x6d:
+            case 0x6e:
+            case 0x6f:
+            case 0x70:
+            case 0x71:
+            case 0x72:
+            case 0x73:
+            case 0x74:
+            case 0x75:
+            case 0x76:
+            case 0x77:
+            case 0x78:
+            case 0x79:
+            case 0x7a:
+            case 0x7b:
+            case 0x7c:
+            case 0x7d:
+            case 0x7e:
+            case 0x7f:
+                return static_cast<number_unsigned_t>(current);
+
+            // fixmap
+            case 0x80:
+            case 0x81:
+            case 0x82:
+            case 0x83:
+            case 0x84:
+            case 0x85:
+            case 0x86:
+            case 0x87:
+            case 0x88:
+            case 0x89:
+            case 0x8a:
+            case 0x8b:
+            case 0x8c:
+            case 0x8d:
+            case 0x8e:
+            case 0x8f:
+            {
+                return get_msgpack_object(current & 0x0f);
+            }
+
+            // fixarray
+            case 0x90:
+            case 0x91:
+            case 0x92:
+            case 0x93:
+            case 0x94:
+            case 0x95:
+            case 0x96:
+            case 0x97:
+            case 0x98:
+            case 0x99:
+            case 0x9a:
+            case 0x9b:
+            case 0x9c:
+            case 0x9d:
+            case 0x9e:
+            case 0x9f:
+            {
+                return get_msgpack_array(current & 0x0f);
+            }
+
+            // fixstr
+            case 0xa0:
+            case 0xa1:
+            case 0xa2:
+            case 0xa3:
+            case 0xa4:
+            case 0xa5:
+            case 0xa6:
+            case 0xa7:
+            case 0xa8:
+            case 0xa9:
+            case 0xaa:
+            case 0xab:
+            case 0xac:
+            case 0xad:
+            case 0xae:
+            case 0xaf:
+            case 0xb0:
+            case 0xb1:
+            case 0xb2:
+            case 0xb3:
+            case 0xb4:
+            case 0xb5:
+            case 0xb6:
+            case 0xb7:
+            case 0xb8:
+            case 0xb9:
+            case 0xba:
+            case 0xbb:
+            case 0xbc:
+            case 0xbd:
+            case 0xbe:
+            case 0xbf:
+                return get_msgpack_string();
+
+            case 0xc0: // nil
+                return value_t::null;
+
+            case 0xc2: // false
+                return false;
+
+            case 0xc3: // true
+                return true;
+
+            case 0xca: // float 32
+                return get_number<float>();
+
+            case 0xcb: // float 64
+                return get_number<double>();
+
+            case 0xcc: // uint 8
+                return get_number<uint8_t>();
+
+            case 0xcd: // uint 16
+                return get_number<uint16_t>();
+
+            case 0xce: // uint 32
+                return get_number<uint32_t>();
+
+            case 0xcf: // uint 64
+                return get_number<uint64_t>();
+
+            case 0xd0: // int 8
+                return get_number<int8_t>();
+
+            case 0xd1: // int 16
+                return get_number<int16_t>();
+
+            case 0xd2: // int 32
+                return get_number<int32_t>();
+
+            case 0xd3: // int 64
+                return get_number<int64_t>();
+
+            case 0xd9: // str 8
+            case 0xda: // str 16
+            case 0xdb: // str 32
+                return get_msgpack_string();
+
+            case 0xdc: // array 16
+            {
+                return get_msgpack_array(get_number<uint16_t>());
+            }
+
+            case 0xdd: // array 32
+            {
+                return get_msgpack_array(get_number<uint32_t>());
+            }
+
+            case 0xde: // map 16
+            {
+                return get_msgpack_object(get_number<uint16_t>());
+            }
+
+            case 0xdf: // map 32
+            {
+                return get_msgpack_object(get_number<uint32_t>());
+            }
+
+            // positive fixint
+            case 0xe0:
+            case 0xe1:
+            case 0xe2:
+            case 0xe3:
+            case 0xe4:
+            case 0xe5:
+            case 0xe6:
+            case 0xe7:
+            case 0xe8:
+            case 0xe9:
+            case 0xea:
+            case 0xeb:
+            case 0xec:
+            case 0xed:
+            case 0xee:
+            case 0xef:
+            case 0xf0:
+            case 0xf1:
+            case 0xf2:
+            case 0xf3:
+            case 0xf4:
+            case 0xf5:
+            case 0xf6:
+            case 0xf7:
+            case 0xf8:
+            case 0xf9:
+            case 0xfa:
+            case 0xfb:
+            case 0xfc:
+            case 0xfd:
+            case 0xfe:
+            case 0xff:
+                return static_cast<int8_t>(current);
+
+            default: // anything else
+            {
+                std::stringstream ss;
+                ss << std::setw(2) << std::setfill('0') << std::hex << current;
+                JSON_THROW(parse_error::create(112, chars_read,
+                                               "error reading MessagePack; last byte: 0x" + ss.str()));
+            }
+        }
+    }
+
+    /*!
+    @brief get next character from the input
+
+    This function provides the interface to the used input adapter. It does
+    not throw in case the input reached EOF, but returns
+    `std::char_traits<char>::eof()` in that case.
+
+    @return character read from the input
+    */
+    int get()
+    {
+        ++chars_read;
+        return (current = ia->get_character());
+    }
+
+    /*
+    @brief read a number from the input
+
+    @tparam NumberType the type of the number
+
+    @return number of type @a NumberType
+
+    @note This function needs to respect the system's endianess, because
+          bytes in CBOR and MessagePack are stored in network order (big
+          endian) and therefore need reordering on little endian systems.
+
+    @throw parse_error.110 if input has less than `sizeof(NumberType)` bytes
+    */
+    template<typename NumberType> NumberType get_number()
+    {
+        // step 1: read input into array with system's byte order
+        std::array<uint8_t, sizeof(NumberType)> vec;
+        for (std::size_t i = 0; i < sizeof(NumberType); ++i)
+        {
+            get();
+            check_eof();
+
+            // reverse byte order prior to conversion if necessary
+            if (is_little_endian)
+            {
+                vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
+            }
+            else
+            {
+                vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
+            }
+        }
+
+        // step 2: convert array into number of type T and return
+        NumberType result;
+        std::memcpy(&result, vec.data(), sizeof(NumberType));
+        return result;
+    }
+
+    /*!
+    @brief create a string by reading characters from the input
+
+    @param[in] len number of bytes to read
+
+    @note We can not reserve @a len bytes for the result, because @a len
+          may be too large. Usually, @ref check_eof() detects the end of
+          the input before we run out of string memory.
+
+    @return string created by reading @a len bytes
+
+    @throw parse_error.110 if input has less than @a len bytes
+    */
+    template<typename NumberType>
+    std::string get_string(const NumberType len)
+    {
+        std::string result;
+        std::generate_n(std::back_inserter(result), len, [this]()
+        {
+            get();
+            check_eof();
+            return static_cast<char>(current);
+        });
+        return result;
+    }
+
+    /*!
+    @brief reads a CBOR string
+
+    This function first reads starting bytes to determine the expected
+    string length and then copies this number of bytes into a string.
+    Additionally, CBOR's strings with indefinite lengths are supported.
+
+    @return string
+
+    @throw parse_error.110 if input ended
+    @throw parse_error.113 if an unexpected byte is read
+    */
+    std::string get_cbor_string()
+    {
+        check_eof();
+
+        switch (current)
+        {
+            // UTF-8 string (0x00..0x17 bytes follow)
+            case 0x60:
+            case 0x61:
+            case 0x62:
+            case 0x63:
+            case 0x64:
+            case 0x65:
+            case 0x66:
+            case 0x67:
+            case 0x68:
+            case 0x69:
+            case 0x6a:
+            case 0x6b:
+            case 0x6c:
+            case 0x6d:
+            case 0x6e:
+            case 0x6f:
+            case 0x70:
+            case 0x71:
+            case 0x72:
+            case 0x73:
+            case 0x74:
+            case 0x75:
+            case 0x76:
+            case 0x77:
+            {
+                return get_string(current & 0x1f);
+            }
+
+            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
+            {
+                return get_string(get_number<uint8_t>());
+            }
+
+            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
+            {
+                return get_string(get_number<uint16_t>());
+            }
+
+            case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
+            {
+                return get_string(get_number<uint32_t>());
+            }
+
+            case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
+            {
+                return get_string(get_number<uint64_t>());
+            }
+
+            case 0x7f: // UTF-8 string (indefinite length)
+            {
+                std::string result;
+                while (get() != 0xff)
+                {
+                    check_eof();
+                    result.push_back(static_cast<char>(current));
+                }
+                return result;
+            }
+
+            default:
+            {
+                std::stringstream ss;
+                ss << std::setw(2) << std::setfill('0') << std::hex << current;
+                JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + ss.str()));
+            }
+        }
+    }
+
+    template<typename NumberType>
+    BasicJsonType get_cbor_array(const NumberType len)
+    {
+        BasicJsonType result = value_t::array;
+        std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
+        {
+            return parse_cbor_internal();
+        });
+        return result;
+    }
+
+    template<typename NumberType>
+    BasicJsonType get_cbor_object(const NumberType len)
+    {
+        BasicJsonType result = value_t::object;
+        std::generate_n(std::inserter(*result.m_value.object,
+                                      result.m_value.object->end()),
+                        len, [this]()
+        {
+            get();
+            auto key = get_cbor_string();
+            auto val = parse_cbor_internal();
+            return std::make_pair(std::move(key), std::move(val));
+        });
+        return result;
+    }
+
+    /*!
+    @brief reads a MessagePack string
+
+    This function first reads starting bytes to determine the expected
+    string length and then copies this number of bytes into a string.
+
+    @return string
+
+    @throw parse_error.110 if input ended
+    @throw parse_error.113 if an unexpected byte is read
+    */
+    std::string get_msgpack_string()
+    {
+        check_eof();
+
+        switch (current)
+        {
+            // fixstr
+            case 0xa0:
+            case 0xa1:
+            case 0xa2:
+            case 0xa3:
+            case 0xa4:
+            case 0xa5:
+            case 0xa6:
+            case 0xa7:
+            case 0xa8:
+            case 0xa9:
+            case 0xaa:
+            case 0xab:
+            case 0xac:
+            case 0xad:
+            case 0xae:
+            case 0xaf:
+            case 0xb0:
+            case 0xb1:
+            case 0xb2:
+            case 0xb3:
+            case 0xb4:
+            case 0xb5:
+            case 0xb6:
+            case 0xb7:
+            case 0xb8:
+            case 0xb9:
+            case 0xba:
+            case 0xbb:
+            case 0xbc:
+            case 0xbd:
+            case 0xbe:
+            case 0xbf:
+            {
+                return get_string(current & 0x1f);
+            }
+
+            case 0xd9: // str 8
+            {
+                return get_string(get_number<uint8_t>());
+            }
+
+            case 0xda: // str 16
+            {
+                return get_string(get_number<uint16_t>());
+            }
+
+            case 0xdb: // str 32
+            {
+                return get_string(get_number<uint32_t>());
+            }
+
+            default:
+            {
+                std::stringstream ss;
+                ss << std::setw(2) << std::setfill('0') << std::hex << current;
+                JSON_THROW(parse_error::create(113, chars_read,
+                                               "expected a MessagePack string; last byte: 0x" + ss.str()));
+            }
+        }
+    }
+
+    template<typename NumberType>
+    BasicJsonType get_msgpack_array(const NumberType len)
+    {
+        BasicJsonType result = value_t::array;
+        std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
+        {
+            return parse_msgpack_internal();
+        });
+        return result;
+    }
+
+    template<typename NumberType>
+    BasicJsonType get_msgpack_object(const NumberType len)
+    {
+        BasicJsonType result = value_t::object;
+        std::generate_n(std::inserter(*result.m_value.object,
+                                      result.m_value.object->end()),
+                        len, [this]()
+        {
+            get();
+            auto key = get_msgpack_string();
+            auto val = parse_msgpack_internal();
+            return std::make_pair(std::move(key), std::move(val));
+        });
+        return result;
+    }
+
+    /*!
+    @brief check if input ended
+    @throw parse_error.110 if input ended
+    */
+    void check_eof(const bool expect_eof = false) const
+    {
+        if (expect_eof)
+        {
+            if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
+            {
+                JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
+            }
+        }
+        else
+        {
+            if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
+            {
+                JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
+            }
+        }
+    }
+
+  private:
+    /// input adapter
+    input_adapter_t ia = nullptr;
+
+    /// the current character
+    int current = std::char_traits<char>::eof();
+
+    /// the number of characters read
+    std::size_t chars_read = 0;
+
+    /// whether we can assume little endianess
+    const bool is_little_endian = little_endianess();
+};
+
+/*!
+@brief serialization to CBOR and MessagePack values
+*/
+template<typename BasicJsonType, typename CharType>
+class binary_writer
+{
+  public:
+    /*!
+    @brief create a binary writer
+
+    @param[in] adapter  output adapter to write to
+    */
+    explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
+    {
+        assert(oa);
+    }
+
+    /*!
+    @brief[in] j  JSON value to serialize
+    */
+    void write_cbor(const BasicJsonType& j)
+    {
+        switch (j.type())
+        {
+            case value_t::null:
+            {
+                oa->write_character(static_cast<CharType>(0xf6));
+                break;
+            }
+
+            case value_t::boolean:
+            {
+                oa->write_character(j.m_value.boolean
+                                    ? static_cast<CharType>(0xf5)
+                                    : static_cast<CharType>(0xf4));
+                break;
+            }
+
+            case value_t::number_integer:
+            {
+                if (j.m_value.number_integer >= 0)
+                {
+                    // CBOR does not differentiate between positive signed
+                    // integers and unsigned integers. Therefore, we used the
+                    // code from the value_t::number_unsigned case here.
+                    if (j.m_value.number_integer <= 0x17)
+                    {
+                        write_number(static_cast<uint8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
+                    {
+                        oa->write_character(static_cast<CharType>(0x18));
+                        write_number(static_cast<uint8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
+                    {
+                        oa->write_character(static_cast<CharType>(0x19));
+                        write_number(static_cast<uint16_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
+                    {
+                        oa->write_character(static_cast<CharType>(0x1a));
+                        write_number(static_cast<uint32_t>(j.m_value.number_integer));
+                    }
+                    else
+                    {
+                        oa->write_character(static_cast<CharType>(0x1b));
+                        write_number(static_cast<uint64_t>(j.m_value.number_integer));
+                    }
+                }
+                else
+                {
+                    // The conversions below encode the sign in the first
+                    // byte, and the value is converted to a positive number.
+                    const auto positive_number = -1 - j.m_value.number_integer;
+                    if (j.m_value.number_integer >= -24)
+                    {
+                        write_number(static_cast<uint8_t>(0x20 + positive_number));
+                    }
+                    else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
+                    {
+                        oa->write_character(static_cast<CharType>(0x38));
+                        write_number(static_cast<uint8_t>(positive_number));
+                    }
+                    else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
+                    {
+                        oa->write_character(static_cast<CharType>(0x39));
+                        write_number(static_cast<uint16_t>(positive_number));
+                    }
+                    else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
+                    {
+                        oa->write_character(static_cast<CharType>(0x3a));
+                        write_number(static_cast<uint32_t>(positive_number));
+                    }
+                    else
+                    {
+                        oa->write_character(static_cast<CharType>(0x3b));
+                        write_number(static_cast<uint64_t>(positive_number));
+                    }
+                }
+                break;
+            }
+
+            case value_t::number_unsigned:
+            {
+                if (j.m_value.number_unsigned <= 0x17)
+                {
+                    write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
+                {
+                    oa->write_character(static_cast<CharType>(0x18));
+                    write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
+                {
+                    oa->write_character(static_cast<CharType>(0x19));
+                    write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
+                {
+                    oa->write_character(static_cast<CharType>(0x1a));
+                    write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
+                }
+                else
+                {
+                    oa->write_character(static_cast<CharType>(0x1b));
+                    write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
+                }
+                break;
+            }
+
+            case value_t::number_float: // Double-Precision Float
+            {
+                oa->write_character(static_cast<CharType>(0xfb));
+                write_number(j.m_value.number_float);
+                break;
+            }
+
+            case value_t::string:
+            {
+                // step 1: write control byte and the string length
+                const auto N = j.m_value.string->size();
+                if (N <= 0x17)
+                {
+                    write_number(static_cast<uint8_t>(0x60 + N));
+                }
+                else if (N <= 0xff)
+                {
+                    oa->write_character(static_cast<CharType>(0x78));
+                    write_number(static_cast<uint8_t>(N));
+                }
+                else if (N <= 0xffff)
+                {
+                    oa->write_character(static_cast<CharType>(0x79));
+                    write_number(static_cast<uint16_t>(N));
+                }
+                else if (N <= 0xffffffff)
+                {
+                    oa->write_character(static_cast<CharType>(0x7a));
+                    write_number(static_cast<uint32_t>(N));
+                }
+                // LCOV_EXCL_START
+                else if (N <= 0xffffffffffffffff)
+                {
+                    oa->write_character(static_cast<CharType>(0x7b));
+                    write_number(static_cast<uint64_t>(N));
+                }
+                // LCOV_EXCL_STOP
+
+                // step 2: write the string
+                oa->write_characters(
+                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
+                    j.m_value.string->size());
+                break;
+            }
+
+            case value_t::array:
+            {
+                // step 1: write control byte and the array size
+                const auto N = j.m_value.array->size();
+                if (N <= 0x17)
+                {
+                    write_number(static_cast<uint8_t>(0x80 + N));
+                }
+                else if (N <= 0xff)
+                {
+                    oa->write_character(static_cast<CharType>(0x98));
+                    write_number(static_cast<uint8_t>(N));
+                }
+                else if (N <= 0xffff)
+                {
+                    oa->write_character(static_cast<CharType>(0x99));
+                    write_number(static_cast<uint16_t>(N));
+                }
+                else if (N <= 0xffffffff)
+                {
+                    oa->write_character(static_cast<CharType>(0x9a));
+                    write_number(static_cast<uint32_t>(N));
+                }
+                // LCOV_EXCL_START
+                else if (N <= 0xffffffffffffffff)
+                {
+                    oa->write_character(static_cast<CharType>(0x9b));
+                    write_number(static_cast<uint64_t>(N));
+                }
+                // LCOV_EXCL_STOP
+
+                // step 2: write each element
+                for (const auto& el : *j.m_value.array)
+                {
+                    write_cbor(el);
+                }
+                break;
+            }
+
+            case value_t::object:
+            {
+                // step 1: write control byte and the object size
+                const auto N = j.m_value.object->size();
+                if (N <= 0x17)
+                {
+                    write_number(static_cast<uint8_t>(0xa0 + N));
+                }
+                else if (N <= 0xff)
+                {
+                    oa->write_character(static_cast<CharType>(0xb8));
+                    write_number(static_cast<uint8_t>(N));
+                }
+                else if (N <= 0xffff)
+                {
+                    oa->write_character(static_cast<CharType>(0xb9));
+                    write_number(static_cast<uint16_t>(N));
+                }
+                else if (N <= 0xffffffff)
+                {
+                    oa->write_character(static_cast<CharType>(0xba));
+                    write_number(static_cast<uint32_t>(N));
+                }
+                // LCOV_EXCL_START
+                else if (N <= 0xffffffffffffffff)
+                {
+                    oa->write_character(static_cast<CharType>(0xbb));
+                    write_number(static_cast<uint64_t>(N));
+                }
+                // LCOV_EXCL_STOP
+
+                // step 2: write each element
+                for (const auto& el : *j.m_value.object)
+                {
+                    write_cbor(el.first);
+                    write_cbor(el.second);
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+    }
+
+    /*!
+    @brief[in] j  JSON value to serialize
+    */
+    void write_msgpack(const BasicJsonType& j)
+    {
+        switch (j.type())
+        {
+            case value_t::null: // nil
+            {
+                oa->write_character(static_cast<CharType>(0xc0));
+                break;
+            }
+
+            case value_t::boolean: // true and false
+            {
+                oa->write_character(j.m_value.boolean
+                                    ? static_cast<CharType>(0xc3)
+                                    : static_cast<CharType>(0xc2));
+                break;
+            }
+
+            case value_t::number_integer:
+            {
+                if (j.m_value.number_integer >= 0)
+                {
+                    // MessagePack does not differentiate between positive
+                    // signed integers and unsigned integers. Therefore, we used
+                    // the code from the value_t::number_unsigned case here.
+                    if (j.m_value.number_unsigned < 128)
+                    {
+                        // positive fixnum
+                        write_number(static_cast<uint8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
+                    {
+                        // uint 8
+                        oa->write_character(static_cast<CharType>(0xcc));
+                        write_number(static_cast<uint8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
+                    {
+                        // uint 16
+                        oa->write_character(static_cast<CharType>(0xcd));
+                        write_number(static_cast<uint16_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
+                    {
+                        // uint 32
+                        oa->write_character(static_cast<CharType>(0xce));
+                        write_number(static_cast<uint32_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
+                    {
+                        // uint 64
+                        oa->write_character(static_cast<CharType>(0xcf));
+                        write_number(static_cast<uint64_t>(j.m_value.number_integer));
+                    }
+                }
+                else
+                {
+                    if (j.m_value.number_integer >= -32)
+                    {
+                        // negative fixnum
+                        write_number(static_cast<int8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
+                             j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
+                    {
+                        // int 8
+                        oa->write_character(static_cast<CharType>(0xd0));
+                        write_number(static_cast<int8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
+                             j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
+                    {
+                        // int 16
+                        oa->write_character(static_cast<CharType>(0xd1));
+                        write_number(static_cast<int16_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
+                             j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
+                    {
+                        // int 32
+                        oa->write_character(static_cast<CharType>(0xd2));
+                        write_number(static_cast<int32_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
+                             j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
+                    {
+                        // int 64
+                        oa->write_character(static_cast<CharType>(0xd3));
+                        write_number(static_cast<int64_t>(j.m_value.number_integer));
+                    }
+                }
+                break;
+            }
+
+            case value_t::number_unsigned:
+            {
+                if (j.m_value.number_unsigned < 128)
+                {
+                    // positive fixnum
+                    write_number(static_cast<uint8_t>(j.m_value.number_integer));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
+                {
+                    // uint 8
+                    oa->write_character(static_cast<CharType>(0xcc));
+                    write_number(static_cast<uint8_t>(j.m_value.number_integer));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
+                {
+                    // uint 16
+                    oa->write_character(static_cast<CharType>(0xcd));
+                    write_number(static_cast<uint16_t>(j.m_value.number_integer));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
+                {
+                    // uint 32
+                    oa->write_character(static_cast<CharType>(0xce));
+                    write_number(static_cast<uint32_t>(j.m_value.number_integer));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
+                {
+                    // uint 64
+                    oa->write_character(static_cast<CharType>(0xcf));
+                    write_number(static_cast<uint64_t>(j.m_value.number_integer));
+                }
+                break;
+            }
+
+            case value_t::number_float: // float 64
+            {
+                oa->write_character(static_cast<CharType>(0xcb));
+                write_number(j.m_value.number_float);
+                break;
+            }
+
+            case value_t::string:
+            {
+                // step 1: write control byte and the string length
+                const auto N = j.m_value.string->size();
+                if (N <= 31)
+                {
+                    // fixstr
+                    write_number(static_cast<uint8_t>(0xa0 | N));
+                }
+                else if (N <= 255)
+                {
+                    // str 8
+                    oa->write_character(static_cast<CharType>(0xd9));
+                    write_number(static_cast<uint8_t>(N));
+                }
+                else if (N <= 65535)
+                {
+                    // str 16
+                    oa->write_character(static_cast<CharType>(0xda));
+                    write_number(static_cast<uint16_t>(N));
+                }
+                else if (N <= 4294967295)
+                {
+                    // str 32
+                    oa->write_character(static_cast<CharType>(0xdb));
+                    write_number(static_cast<uint32_t>(N));
+                }
+
+                // step 2: write the string
+                oa->write_characters(
+                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
+                    j.m_value.string->size());
+                break;
+            }
+
+            case value_t::array:
+            {
+                // step 1: write control byte and the array size
+                const auto N = j.m_value.array->size();
+                if (N <= 15)
+                {
+                    // fixarray
+                    write_number(static_cast<uint8_t>(0x90 | N));
+                }
+                else if (N <= 0xffff)
+                {
+                    // array 16
+                    oa->write_character(static_cast<CharType>(0xdc));
+                    write_number(static_cast<uint16_t>(N));
+                }
+                else if (N <= 0xffffffff)
+                {
+                    // array 32
+                    oa->write_character(static_cast<CharType>(0xdd));
+                    write_number(static_cast<uint32_t>(N));
+                }
+
+                // step 2: write each element
+                for (const auto& el : *j.m_value.array)
+                {
+                    write_msgpack(el);
+                }
+                break;
+            }
+
+            case value_t::object:
+            {
+                // step 1: write control byte and the object size
+                const auto N = j.m_value.object->size();
+                if (N <= 15)
+                {
+                    // fixmap
+                    write_number(static_cast<uint8_t>(0x80 | (N & 0xf)));
+                }
+                else if (N <= 65535)
+                {
+                    // map 16
+                    oa->write_character(static_cast<CharType>(0xde));
+                    write_number(static_cast<uint16_t>(N));
+                }
+                else if (N <= 4294967295)
+                {
+                    // map 32
+                    oa->write_character(static_cast<CharType>(0xdf));
+                    write_number(static_cast<uint32_t>(N));
+                }
+
+                // step 2: write each element
+                for (const auto& el : *j.m_value.object)
+                {
+                    write_msgpack(el.first);
+                    write_msgpack(el.second);
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+    }
+
+  private:
+    /*
+    @brief write a number to output input
+
+    @param[in] n number of type @a NumberType
+    @tparam NumberType the type of the number
+
+    @note This function needs to respect the system's endianess, because bytes
+          in CBOR and MessagePack are stored in network order (big endian) and
+          therefore need reordering on little endian systems.
+    */
+    template<typename NumberType> void write_number(NumberType n)
+    {
+        // step 1: write number to array of length NumberType
+        std::array<CharType, sizeof(NumberType)> vec;
+        std::memcpy(vec.data(), &n, sizeof(NumberType));
+
+        // step 2: write array to output (with possible reordering)
+        if (is_little_endian)
+        {
+            // reverse byte order prior to conversion if necessary
+            std::reverse(vec.begin(), vec.end());
+        }
+
+        oa->write_characters(vec.data(), sizeof(NumberType));
+    }
+
+  private:
+    /// whether we can assume little endianess
+    const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
+
+    /// the output
+    output_adapter_t<CharType> oa = nullptr;
+};
+
+///////////////////
+// serialization //
+///////////////////
+
+template<typename BasicJsonType>
+class serializer
+{
+    using string_t = typename BasicJsonType::string_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+  public:
+    /*!
+    @param[in] s  output stream to serialize to
+    @param[in] ichar  indentation character to use
+    */
+    serializer(output_adapter_t<char> s, const char ichar)
+        : o(std::move(s)), loc(std::localeconv()),
+          thousands_sep(loc->thousands_sep == nullptr ? '\0' : loc->thousands_sep[0]),
+          decimal_point(loc->decimal_point == nullptr ? '\0' : loc->decimal_point[0]),
+          indent_char(ichar), indent_string(512, indent_char) {}
+
+    // delete because of pointer members
+    serializer(const serializer&) = delete;
+    serializer& operator=(const serializer&) = delete;
+
+    /*!
+    @brief internal implementation of the serialization function
+
+    This function is called by the public member function dump and organizes
+    the serialization internally. The indentation level is propagated as
+    additional parameter. In case of arrays and objects, the function is
+    called recursively.
+
+    - strings and object keys are escaped using `escape_string()`
+    - integer numbers are converted implicitly via `operator<<`
+    - floating-point numbers are converted to a string using `"%g"` format
+
+    @param[in] val             value to serialize
+    @param[in] pretty_print    whether the output shall be pretty-printed
+    @param[in] indent_step     the indent level
+    @param[in] current_indent  the current indent level (only used internally)
+    */
+    void dump(const BasicJsonType& val, const bool pretty_print,
+              const bool ensure_ascii,
+              const unsigned int indent_step,
+              const unsigned int current_indent = 0)
+    {
+        switch (val.m_type)
+        {
+            case value_t::object:
+            {
+                if (val.m_value.object->empty())
+                {
+                    o->write_characters("{}", 2);
+                    return;
+                }
+
+                if (pretty_print)
+                {
+                    o->write_characters("{\n", 2);
+
+                    // variable to hold indentation for recursive calls
+                    const auto new_indent = current_indent + indent_step;
+                    if (JSON_UNLIKELY(indent_string.size() < new_indent))
+                    {
+                        indent_string.resize(indent_string.size() * 2, ' ');
+                    }
+
+                    // first n-1 elements
+                    auto i = val.m_value.object->cbegin();
+                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
+                    {
+                        o->write_characters(indent_string.c_str(), new_indent);
+                        o->write_character('\"');
+                        dump_escaped(i->first, ensure_ascii);
+                        o->write_characters("\": ", 3);
+                        dump(i->second, true, ensure_ascii, indent_step, new_indent);
+                        o->write_characters(",\n", 2);
+                    }
+
+                    // last element
+                    assert(i != val.m_value.object->cend());
+                    assert(std::next(i) == val.m_value.object->cend());
+                    o->write_characters(indent_string.c_str(), new_indent);
+                    o->write_character('\"');
+                    dump_escaped(i->first, ensure_ascii);
+                    o->write_characters("\": ", 3);
+                    dump(i->second, true, ensure_ascii, indent_step, new_indent);
+
+                    o->write_character('\n');
+                    o->write_characters(indent_string.c_str(), current_indent);
+                    o->write_character('}');
+                }
+                else
+                {
+                    o->write_character('{');
+
+                    // first n-1 elements
+                    auto i = val.m_value.object->cbegin();
+                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
+                    {
+                        o->write_character('\"');
+                        dump_escaped(i->first, ensure_ascii);
+                        o->write_characters("\":", 2);
+                        dump(i->second, false, ensure_ascii, indent_step, current_indent);
+                        o->write_character(',');
+                    }
+
+                    // last element
+                    assert(i != val.m_value.object->cend());
+                    assert(std::next(i) == val.m_value.object->cend());
+                    o->write_character('\"');
+                    dump_escaped(i->first, ensure_ascii);
+                    o->write_characters("\":", 2);
+                    dump(i->second, false, ensure_ascii, indent_step, current_indent);
+
+                    o->write_character('}');
+                }
+
+                return;
+            }
+
+            case value_t::array:
+            {
+                if (val.m_value.array->empty())
+                {
+                    o->write_characters("[]", 2);
+                    return;
+                }
+
+                if (pretty_print)
+                {
+                    o->write_characters("[\n", 2);
+
+                    // variable to hold indentation for recursive calls
+                    const auto new_indent = current_indent + indent_step;
+                    if (JSON_UNLIKELY(indent_string.size() < new_indent))
+                    {
+                        indent_string.resize(indent_string.size() * 2, ' ');
+                    }
+
+                    // first n-1 elements
+                    for (auto i = val.m_value.array->cbegin();
+                            i != val.m_value.array->cend() - 1; ++i)
+                    {
+                        o->write_characters(indent_string.c_str(), new_indent);
+                        dump(*i, true, ensure_ascii, indent_step, new_indent);
+                        o->write_characters(",\n", 2);
+                    }
+
+                    // last element
+                    assert(not val.m_value.array->empty());
+                    o->write_characters(indent_string.c_str(), new_indent);
+                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
+
+                    o->write_character('\n');
+                    o->write_characters(indent_string.c_str(), current_indent);
+                    o->write_character(']');
+                }
+                else
+                {
+                    o->write_character('[');
+
+                    // first n-1 elements
+                    for (auto i = val.m_value.array->cbegin();
+                            i != val.m_value.array->cend() - 1; ++i)
+                    {
+                        dump(*i, false, ensure_ascii, indent_step, current_indent);
+                        o->write_character(',');
+                    }
+
+                    // last element
+                    assert(not val.m_value.array->empty());
+                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
+
+                    o->write_character(']');
+                }
+
+                return;
+            }
+
+            case value_t::string:
+            {
+                o->write_character('\"');
+                dump_escaped(*val.m_value.string, ensure_ascii);
+                o->write_character('\"');
+                return;
+            }
+
+            case value_t::boolean:
+            {
+                if (val.m_value.boolean)
+                {
+                    o->write_characters("true", 4);
+                }
+                else
+                {
+                    o->write_characters("false", 5);
+                }
+                return;
+            }
+
+            case value_t::number_integer:
+            {
+                dump_integer(val.m_value.number_integer);
+                return;
+            }
+
+            case value_t::number_unsigned:
+            {
+                dump_integer(val.m_value.number_unsigned);
+                return;
+            }
+
+            case value_t::number_float:
+            {
+                dump_float(val.m_value.number_float);
+                return;
+            }
+
+            case value_t::discarded:
+            {
+                o->write_characters("<discarded>", 11);
+                return;
+            }
+
+            case value_t::null:
+            {
+                o->write_characters("null", 4);
+                return;
+            }
+        }
+    }
+
+  private:
+    /*!
+    @brief returns the number of expected bytes following in UTF-8 string
+
+    @param[in]  u  the first byte of a UTF-8 string
+    @return  the number of expected bytes following
+    */
+    static constexpr std::size_t bytes_following(const uint8_t u)
+    {
+        return ((u <= 127) ? 0
+                : ((192 <= u and u <= 223) ? 1
+                   : ((224 <= u and u <= 239) ? 2
+                      : ((240 <= u and u <= 247) ? 3 : std::string::npos))));
+    }
+
+    /*!
+    @brief calculates the extra space to escape a JSON string
+
+    @param[in] s  the string to escape
+    @param[in] ensure_ascii  whether to escape non-ASCII characters with
+                             \uXXXX sequences
+    @return the number of characters required to escape string @a s
+
+    @complexity Linear in the length of string @a s.
+    */
+    static std::size_t extra_space(const string_t& s,
+                                   const bool ensure_ascii) noexcept
+    {
+        std::size_t res = 0;
+
+        for (std::size_t i = 0; i < s.size(); ++i)
+        {
+            switch (s[i])
+            {
+                // control characters that can be escaped with a backslash
+                case '"':
+                case '\\':
+                case '\b':
+                case '\f':
+                case '\n':
+                case '\r':
+                case '\t':
+                {
+                    // from c (1 byte) to \x (2 bytes)
+                    res += 1;
+                    break;
+                }
+
+                // control characters that need \uxxxx escaping
+                case 0x00:
+                case 0x01:
+                case 0x02:
+                case 0x03:
+                case 0x04:
+                case 0x05:
+                case 0x06:
+                case 0x07:
+                case 0x0b:
+                case 0x0e:
+                case 0x0f:
+                case 0x10:
+                case 0x11:
+                case 0x12:
+                case 0x13:
+                case 0x14:
+                case 0x15:
+                case 0x16:
+                case 0x17:
+                case 0x18:
+                case 0x19:
+                case 0x1a:
+                case 0x1b:
+                case 0x1c:
+                case 0x1d:
+                case 0x1e:
+                case 0x1f:
+                {
+                    // from c (1 byte) to \uxxxx (6 bytes)
+                    res += 5;
+                    break;
+                }
+
+                default:
+                {
+                    if (ensure_ascii and (s[i] & 0x80 or s[i] == 0x7F))
+                    {
+                        const auto bytes = bytes_following(static_cast<uint8_t>(s[i]));
+                        if (bytes == std::string::npos)
+                        {
+                            // invalid characters are treated as is, so no
+                            // additional space will be used
+                            break;
+                        }
+
+                        if (bytes == 3)
+                        {
+                            // codepoints that need 4 bytes (i.e., 3 additional
+                            // bytes) in UTF-8 need a surrogate pair when \u
+                            // escaping is used: from 4 bytes to \uxxxx\uxxxx
+                            // (12 bytes)
+                            res += (12 - bytes - 1);
+                        }
+                        else
+                        {
+                            // from x bytes to \uxxxx (6 bytes)
+                            res += (6 - bytes - 1);
+                        }
+
+                        // skip the additional bytes
+                        i += bytes;
+                    }
+                    break;
+                }
+            }
+        }
+
+        return res;
+    }
+
+    static void escape_codepoint(int codepoint, string_t& result, std::size_t& pos)
+    {
+        // expecting a proper codepoint
+        assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
+
+        // the last written character was the backslash before the 'u'
+        assert(result[pos] == '\\');
+
+        // write the 'u'
+        result[++pos] = 'u';
+
+        // convert a number 0..15 to its hex representation (0..f)
+        static const std::array<char, 16> hexify =
+        {
+            {
+                '0', '1', '2', '3', '4', '5', '6', '7',
+                '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+            }
+        };
+
+        if (codepoint < 0x10000)
+        {
+            // codepoints U+0000..U+FFFF can be represented as \uxxxx.
+            result[++pos] = hexify[(codepoint >> 12) & 0x0F];
+            result[++pos] = hexify[(codepoint >> 8) & 0x0F];
+            result[++pos] = hexify[(codepoint >> 4) & 0x0F];
+            result[++pos] = hexify[codepoint & 0x0F];
+        }
+        else
+        {
+            // codepoints U+10000..U+10FFFF need a surrogate pair to be
+            // represented as \uxxxx\uxxxx.
+            // http://www.unicode.org/faq/utf_bom.html#utf16-4
+            codepoint -= 0x10000;
+            const int high_surrogate = 0xD800 | ((codepoint >> 10) & 0x3FF);
+            const int low_surrogate = 0xDC00 | (codepoint & 0x3FF);
+            result[++pos] = hexify[(high_surrogate >> 12) & 0x0F];
+            result[++pos] = hexify[(high_surrogate >> 8) & 0x0F];
+            result[++pos] = hexify[(high_surrogate >> 4) & 0x0F];
+            result[++pos] = hexify[high_surrogate & 0x0F];
+            ++pos;  // backslash is already in output
+            result[++pos] = 'u';
+            result[++pos] = hexify[(low_surrogate >> 12) & 0x0F];
+            result[++pos] = hexify[(low_surrogate >> 8) & 0x0F];
+            result[++pos] = hexify[(low_surrogate >> 4) & 0x0F];
+            result[++pos] = hexify[low_surrogate & 0x0F];
+        }
+
+        ++pos;
+    }
+
+    /*!
+    @brief dump escaped string
+
+    Escape a string by replacing certain special characters by a sequence of an
+    escape character (backslash) and another character and other control
+    characters by a sequence of "\u" followed by a four-digit hex
+    representation. The escaped string is written to output stream @a o.
+
+    @param[in] s  the string to escape
+    @param[in] ensure_ascii  whether to escape non-ASCII characters with
+                             \uXXXX sequences
+
+    @complexity Linear in the length of string @a s.
+    */
+    void dump_escaped(const string_t& s, const bool ensure_ascii) const
+    {
+        const auto space = extra_space(s, ensure_ascii);
+        if (space == 0)
+        {
+            o->write_characters(s.c_str(), s.size());
+            return;
+        }
+
+        // create a result string of necessary size
+        string_t result(s.size() + space, '\\');
+        std::size_t pos = 0;
+
+        for (std::size_t i = 0; i < s.size(); ++i)
+        {
+            switch (s[i])
+            {
+                case '"': // quotation mark (0x22)
+                {
+                    result[pos + 1] = '"';
+                    pos += 2;
+                    break;
+                }
+
+                case '\\': // reverse solidus (0x5c)
+                {
+                    // nothing to change
+                    pos += 2;
+                    break;
+                }
+
+                case '\b': // backspace (0x08)
+                {
+                    result[pos + 1] = 'b';
+                    pos += 2;
+                    break;
+                }
+
+                case '\f': // formfeed (0x0c)
+                {
+                    result[pos + 1] = 'f';
+                    pos += 2;
+                    break;
+                }
+
+                case '\n': // newline (0x0a)
+                {
+                    result[pos + 1] = 'n';
+                    pos += 2;
+                    break;
+                }
+
+                case '\r': // carriage return (0x0d)
+                {
+                    result[pos + 1] = 'r';
+                    pos += 2;
+                    break;
+                }
+
+                case '\t': // horizontal tab (0x09)
+                {
+                    result[pos + 1] = 't';
+                    pos += 2;
+                    break;
+                }
+
+                default:
+                {
+                    // escape control characters (0x00..0x1F) or, if
+                    // ensure_ascii parameter is used, non-ASCII characters
+                    if ((0x00 <= s[i] and s[i] <= 0x1F) or
+                            (ensure_ascii and (s[i] & 0x80 or s[i] == 0x7F)))
+                    {
+                        const auto bytes = bytes_following(static_cast<uint8_t>(s[i]));
+                        if (bytes == std::string::npos)
+                        {
+                            // copy invalid character as is
+                            result[pos++] = s[i];
+                            break;
+                        }
+
+                        // check that the additional bytes are present
+                        assert(i + bytes < s.size());
+
+                        // to use \uxxxx escaping, we first need to caluclate
+                        // the codepoint from the UTF-8 bytes
+                        int codepoint = 0;
+
+                        assert(0 <= bytes and bytes <= 3);
+                        switch (bytes)
+                        {
+                            case 0:
+                            {
+                                codepoint = s[i] & 0xFF;
+                                break;
+                            }
+
+                            case 1:
+                            {
+                                codepoint = ((s[i] & 0x3F) << 6)
+                                            + (s[i + 1] & 0x7F);
+                                break;
+                            }
+
+                            case 2:
+                            {
+                                codepoint = ((s[i] & 0x1F) << 12)
+                                            + ((s[i + 1] & 0x7F) << 6)
+                                            + (s[i + 2] & 0x7F);
+                                break;
+                            }
+
+                            case 3:
+                            {
+                                codepoint = ((s[i] & 0xF) << 18)
+                                            + ((s[i + 1] & 0x7F) << 12)
+                                            + ((s[i + 2] & 0x7F) << 6)
+                                            + (s[i + 3] & 0x7F);
+                                break;
+                            }
+
+                            default:
+                                break;  // LCOV_EXCL_LINE
+                        }
+
+                        escape_codepoint(codepoint, result, pos);
+                        i += bytes;
+                    }
+                    else
+                    {
+                        // all other characters are added as-is
+                        result[pos++] = s[i];
+                    }
+                    break;
+                }
+            }
+        }
+
+        assert(pos == result.size());
+        o->write_characters(result.c_str(), result.size());
+    }
+
+    /*!
+    @brief dump an integer
+
+    Dump a given integer to output stream @a o. Works internally with
+    @a number_buffer.
+
+    @param[in] x  integer number (signed or unsigned) to dump
+    @tparam NumberType either @a number_integer_t or @a number_unsigned_t
+    */
+    template <
+        typename NumberType,
+        detail::enable_if_t<std::is_same<NumberType, number_unsigned_t>::value or
+                            std::is_same<NumberType, number_integer_t>::value,
+                            int> = 0 >
+    void dump_integer(NumberType x)
+    {
+        // special case for "0"
+        if (x == 0)
+        {
+            o->write_character('0');
+            return;
+        }
+
+        const bool is_negative = (x <= 0) and (x != 0);  // see issue #755
+        std::size_t i = 0;
+
+        while (x != 0)
+        {
+            // spare 1 byte for '\0'
+            assert(i < number_buffer.size() - 1);
+
+            const auto digit = std::labs(static_cast<long>(x % 10));
+            number_buffer[i++] = static_cast<char>('0' + digit);
+            x /= 10;
+        }
+
+        if (is_negative)
+        {
+            // make sure there is capacity for the '-'
+            assert(i < number_buffer.size() - 2);
+            number_buffer[i++] = '-';
+        }
+
+        std::reverse(number_buffer.begin(), number_buffer.begin() + i);
+        o->write_characters(number_buffer.data(), i);
+    }
+
+    /*!
+    @brief dump a floating-point number
+
+    Dump a given floating-point number to output stream @a o. Works internally
+    with @a number_buffer.
+
+    @param[in] x  floating-point number to dump
+    */
+    void dump_float(number_float_t x)
+    {
+        // NaN / inf
+        if (not std::isfinite(x) or std::isnan(x))
+        {
+            o->write_characters("null", 4);
+            return;
+        }
+
+        // get number of digits for a text -> float -> text round-trip
+        static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
+
+        // the actual conversion
+        std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
+
+        // negative value indicates an error
+        assert(len > 0);
+        // check if buffer was large enough
+        assert(static_cast<std::size_t>(len) < number_buffer.size());
+
+        // erase thousands separator
+        if (thousands_sep != '\0')
+        {
+            const auto end = std::remove(number_buffer.begin(),
+                                         number_buffer.begin() + len, thousands_sep);
+            std::fill(end, number_buffer.end(), '\0');
+            assert((end - number_buffer.begin()) <= len);
+            len = (end - number_buffer.begin());
+        }
+
+        // convert decimal point to '.'
+        if (decimal_point != '\0' and decimal_point != '.')
+        {
+            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
+            if (dec_pos != number_buffer.end())
+            {
+                *dec_pos = '.';
+            }
+        }
+
+        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
+
+        // determine if need to append ".0"
+        const bool value_is_int_like =
+            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
+                         [](char c)
+        {
+            return (c == '.' or c == 'e');
+        });
+
+        if (value_is_int_like)
+        {
+            o->write_characters(".0", 2);
+        }
+    }
+
+  private:
+    /// the output of the serializer
+    output_adapter_t<char> o = nullptr;
+
+    /// a (hopefully) large enough character buffer
+    std::array<char, 64> number_buffer{{}};
+
+    /// the locale
+    const std::lconv* loc = nullptr;
+    /// the locale's thousand separator character
+    const char thousands_sep = '\0';
+    /// the locale's decimal point character
+    const char decimal_point = '\0';
+
+    /// the indentation character
+    const char indent_char;
+
+    /// the indentation string
+    string_t indent_string;
+};
+
+template<typename BasicJsonType>
+class json_ref
+{
+  public:
+    using value_type = BasicJsonType;
+
+    json_ref(value_type&& value)
+        : owned_value(std::move(value)),
+          value_ref(&owned_value),
+          is_rvalue(true)
+    {}
+
+    json_ref(const value_type& value)
+        : value_ref(const_cast<value_type*>(&value)),
+          is_rvalue(false)
+    {}
+
+    json_ref(std::initializer_list<json_ref> init)
+        : owned_value(init),
+          value_ref(&owned_value),
+          is_rvalue(true)
+    {}
+
+    template <class... Args>
+    json_ref(Args... args)
+        : owned_value(std::forward<Args>(args)...),
+          value_ref(&owned_value),
+          is_rvalue(true)
+    {}
+
+    // class should be movable only
+    json_ref(json_ref&&) = default;
+    json_ref(const json_ref&) = delete;
+    json_ref& operator=(const json_ref&) = delete;
+
+    value_type moved_or_copied() const
+    {
+        if (is_rvalue)
+        {
+            return std::move(*value_ref);
+        }
+        return *value_ref;
+    }
+
+    value_type const& operator*() const
+    {
+        return *static_cast<value_type const*>(value_ref);
+    }
+
+    value_type const* operator->() const
+    {
+        return static_cast<value_type const*>(value_ref);
+    }
+
+  private:
+    mutable value_type owned_value = nullptr;
+    value_type* value_ref = nullptr;
+    const bool is_rvalue;
+};
+
+} // namespace detail
 
 /// namespace to hold default `to_json` / `from_json` functions
 namespace
@@ -907,7 +6858,7 @@
 ([argument-dependent lookup](http://en.cppreference.com/w/cpp/language/adl))
 for serialization.
 */
-template<typename = void, typename = void>
+template<typename, typename>
 struct adl_serializer
 {
     /*!
@@ -943,6 +6894,326 @@
     }
 };
 
+/*!
+@brief JSON Pointer
+
+A JSON pointer defines a string syntax for identifying a specific value
+within a JSON document. It can be used with functions `at` and
+`operator[]`. Furthermore, JSON pointers are the base for JSON patches.
+
+@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
+
+@since version 2.0.0
+*/
+class json_pointer
+{
+    /// allow basic_json to access private members
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    friend class basic_json;
+
+  public:
+    /*!
+    @brief create JSON pointer
+
+    Create a JSON pointer according to the syntax described in
+    [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
+
+    @param[in] s  string representing the JSON pointer; if omitted, the empty
+                  string is assumed which references the whole JSON value
+
+    @throw parse_error.107 if the given JSON pointer @a s is nonempty and
+    does not begin with a slash (`/`); see example below
+
+    @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s
+    is not followed by `0` (representing `~`) or `1` (representing `/`);
+    see example below
+
+    @liveexample{The example shows the construction several valid JSON
+    pointers as well as the exceptional behavior.,json_pointer}
+
+    @since version 2.0.0
+    */
+    explicit json_pointer(const std::string& s = "") : reference_tokens(split(s)) {}
+
+    /*!
+    @brief return a string representation of the JSON pointer
+
+    @invariant For each JSON pointer `ptr`, it holds:
+    @code {.cpp}
+    ptr == json_pointer(ptr.to_string());
+    @endcode
+
+    @return a string representation of the JSON pointer
+
+    @liveexample{The example shows the result of `to_string`.,
+    json_pointer__to_string}
+
+    @since version 2.0.0
+    */
+    std::string to_string() const noexcept
+    {
+        return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
+                               std::string{},
+                               [](const std::string & a, const std::string & b)
+        {
+            return a + "/" + escape(b);
+        });
+    }
+
+    /// @copydoc to_string()
+    operator std::string() const
+    {
+        return to_string();
+    }
+
+  private:
+    /*!
+    @brief remove and return last reference pointer
+    @throw out_of_range.405 if JSON pointer has no parent
+    */
+    std::string pop_back()
+    {
+        if (JSON_UNLIKELY(is_root()))
+        {
+            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+        }
+
+        auto last = reference_tokens.back();
+        reference_tokens.pop_back();
+        return last;
+    }
+
+    /// return whether pointer points to the root document
+    bool is_root() const
+    {
+        return reference_tokens.empty();
+    }
+
+    json_pointer top() const
+    {
+        if (JSON_UNLIKELY(is_root()))
+        {
+            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+        }
+
+        json_pointer result = *this;
+        result.reference_tokens = {reference_tokens[0]};
+        return result;
+    }
+
+
+    /*!
+    @brief create and return a reference to the pointed to value
+
+    @complexity Linear in the number of reference tokens.
+
+    @throw parse_error.109 if array index is not a number
+    @throw type_error.313 if value cannot be unflattened
+    */
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    NLOHMANN_BASIC_JSON_TPL& get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const;
+
+    /*!
+    @brief return a reference to the pointed to value
+
+    @note This version does not throw if a value is not present, but tries to
+          create nested values instead. For instance, calling this function
+          with pointer `"/this/that"` on a null value is equivalent to calling
+          `operator[]("this").operator[]("that")` on that value, effectively
+          changing the null value to an object.
+
+    @param[in] ptr  a JSON value
+
+    @return reference to the JSON value pointed to by the JSON pointer
+
+    @complexity Linear in the length of the JSON pointer.
+
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+    */
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    NLOHMANN_BASIC_JSON_TPL& get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const;
+
+    /*!
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.402  if the array index '-' is used
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+    */
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    NLOHMANN_BASIC_JSON_TPL& get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const;
+
+    /*!
+    @brief return a const reference to the pointed to value
+
+    @param[in] ptr  a JSON value
+
+    @return const reference to the JSON value pointed to by the JSON
+    pointer
+
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.402  if the array index '-' is used
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+    */
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    const NLOHMANN_BASIC_JSON_TPL& get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const;
+
+    /*!
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.402  if the array index '-' is used
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+    */
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    const NLOHMANN_BASIC_JSON_TPL& get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const;
+
+    /*!
+    @brief split the string input to reference tokens
+
+    @note This function is only called by the json_pointer constructor.
+          All exceptions below are documented there.
+
+    @throw parse_error.107  if the pointer is not empty or begins with '/'
+    @throw parse_error.108  if character '~' is not followed by '0' or '1'
+    */
+    static std::vector<std::string> split(const std::string& reference_string)
+    {
+        std::vector<std::string> result;
+
+        // special case: empty reference string -> no reference tokens
+        if (reference_string.empty())
+        {
+            return result;
+        }
+
+        // check if nonempty reference string begins with slash
+        if (JSON_UNLIKELY(reference_string[0] != '/'))
+        {
+            JSON_THROW(detail::parse_error::create(107, 1,
+                                                   "JSON pointer must be empty or begin with '/' - was: '" +
+                                                   reference_string + "'"));
+        }
+
+        // extract the reference tokens:
+        // - slash: position of the last read slash (or end of string)
+        // - start: position after the previous slash
+        for (
+            // search for the first slash after the first character
+            std::size_t slash = reference_string.find_first_of('/', 1),
+            // set the beginning of the first reference token
+            start = 1;
+            // we can stop if start == string::npos+1 = 0
+            start != 0;
+            // set the beginning of the next reference token
+            // (will eventually be 0 if slash == std::string::npos)
+            start = slash + 1,
+            // find next slash
+            slash = reference_string.find_first_of('/', start))
+        {
+            // use the text between the beginning of the reference token
+            // (start) and the last slash (slash).
+            auto reference_token = reference_string.substr(start, slash - start);
+
+            // check reference tokens are properly escaped
+            for (std::size_t pos = reference_token.find_first_of('~');
+                    pos != std::string::npos;
+                    pos = reference_token.find_first_of('~', pos + 1))
+            {
+                assert(reference_token[pos] == '~');
+
+                // ~ must be followed by 0 or 1
+                if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
+                                  (reference_token[pos + 1] != '0' and
+                                   reference_token[pos + 1] != '1')))
+                {
+                    JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
+                }
+            }
+
+            // finally, store the reference token
+            unescape(reference_token);
+            result.push_back(reference_token);
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief replace all occurrences of a substring by another string
+
+    @param[in,out] s  the string to manipulate; changed so that all
+                   occurrences of @a f are replaced with @a t
+    @param[in]     f  the substring to replace with @a t
+    @param[in]     t  the string to replace @a f
+
+    @pre The search string @a f must not be empty. **This precondition is
+    enforced with an assertion.**
+
+    @since version 2.0.0
+    */
+    static void replace_substring(std::string& s, const std::string& f,
+                                  const std::string& t)
+    {
+        assert(not f.empty());
+        for (auto pos = s.find(f);                // find first occurrence of f
+                pos != std::string::npos;         // make sure f was found
+                s.replace(pos, f.size(), t),      // replace with t, and
+                pos = s.find(f, pos + t.size()))  // find next occurrence of f
+        {}
+    }
+
+    /// escape "~"" to "~0" and "/" to "~1"
+    static std::string escape(std::string s)
+    {
+        replace_substring(s, "~", "~0");
+        replace_substring(s, "/", "~1");
+        return s;
+    }
+
+    /// unescape "~1" to tilde and "~0" to slash (order is important!)
+    static void unescape(std::string& s)
+    {
+        replace_substring(s, "~1", "/");
+        replace_substring(s, "~0", "~");
+    }
+
+    /*!
+    @param[in] reference_string  the reference string to the current value
+    @param[in] value             the value to consider
+    @param[in,out] result        the result object to insert values to
+
+    @note Empty objects or arrays are flattened to `null`.
+    */
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    static void flatten(const std::string& reference_string,
+                        const NLOHMANN_BASIC_JSON_TPL& value,
+                        NLOHMANN_BASIC_JSON_TPL& result);
+
+    /*!
+    @param[in] value  flattened JSON
+
+    @return unflattened JSON
+
+    @throw parse_error.109 if array index is not a number
+    @throw type_error.314  if value is not an object
+    @throw type_error.315  if object values are not primitive
+    @throw type_error.313  if value cannot be unflattened
+    */
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    static NLOHMANN_BASIC_JSON_TPL
+    unflatten(const NLOHMANN_BASIC_JSON_TPL& value);
+
+    friend bool operator==(json_pointer const& lhs,
+                           json_pointer const& rhs) noexcept;
+
+    friend bool operator!=(json_pointer const& lhs,
+                           json_pointer const& rhs) noexcept;
+
+    /// the reference tokens
+    std::vector<std::string> reference_tokens;
+};
 
 /*!
 @brief a class to store JSON values
@@ -1025,35 +7296,78 @@
 
 @nosubgrouping
 */
-template <
-    template<typename U, typename V, typename... Args> class ObjectType = std::map,
-    template<typename U, typename... Args> class ArrayType = std::vector,
-    class StringType = std::string,
-    class BooleanType = bool,
-    class NumberIntegerType = std::int64_t,
-    class NumberUnsignedType = std::uint64_t,
-    class NumberFloatType = double,
-    template<typename U> class AllocatorType = std::allocator,
-    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer
-    >
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
 class basic_json
 {
   private:
     template<detail::value_t> friend struct detail::external_constructor;
+    friend ::nlohmann::json_pointer;
+    friend ::nlohmann::detail::parser<basic_json>;
+    friend ::nlohmann::detail::serializer<basic_json>;
+    template<typename BasicJsonType>
+    friend class ::nlohmann::detail::iter_impl;
+    template<typename BasicJsonType, typename CharType>
+    friend class ::nlohmann::detail::binary_writer;
+    template<typename BasicJsonType>
+    friend class ::nlohmann::detail::binary_reader;
+
     /// workaround type for MSVC
-    using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
-          BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
-          AllocatorType, JSONSerializer>;
+    using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
+
+    // convenience aliases for types residing in namespace detail;
+    using lexer = ::nlohmann::detail::lexer<basic_json>;
+    using parser = ::nlohmann::detail::parser<basic_json>;
+
+    using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
+    template<typename BasicJsonType>
+    using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
+    template<typename BasicJsonType>
+    using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
+    template<typename Iterator>
+    using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
+    template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
+
+    template<typename CharType>
+    using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
+
+    using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
+    template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
+
+    using serializer = ::nlohmann::detail::serializer<basic_json>;
 
   public:
     using value_t = detail::value_t;
     // forward declarations
-    template<typename U> class iter_impl;
-    template<typename Base> class json_reverse_iterator;
-    class json_pointer;
+    using json_pointer = ::nlohmann::json_pointer;
     template<typename T, typename SFINAE>
     using json_serializer = JSONSerializer<T, SFINAE>;
 
+    using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
+
+    ////////////////
+    // exceptions //
+    ////////////////
+
+    /// @name exceptions
+    /// Classes to implement user-defined exceptions.
+    /// @{
+
+    /// @copydoc detail::exception
+    using exception = detail::exception;
+    /// @copydoc detail::parse_error
+    using parse_error = detail::parse_error;
+    /// @copydoc detail::invalid_iterator
+    using invalid_iterator = detail::invalid_iterator;
+    /// @copydoc detail::type_error
+    using type_error = detail::type_error;
+    /// @copydoc detail::out_of_range
+    using out_of_range = detail::out_of_range;
+    /// @copydoc detail::other_error
+    using other_error = detail::other_error;
+
+    /// @}
+
+
     /////////////////////
     // container types //
     /////////////////////
@@ -1123,6 +7437,9 @@
     @liveexample{The following code shows an example output of the `meta()`
     function.,meta}
 
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
     @complexity Constant.
 
     @since 2.1.0
@@ -1136,10 +7453,7 @@
         result["url"] = "https://github.com/nlohmann/json";
         result["version"] =
         {
-            {"string", "2.1.1"},
-            {"major", 2},
-            {"minor", 1},
-            {"patch", 1}
+            {"string", "2.1.1"}, {"major", 2}, {"minor", 1}, {"patch", 1}
         };
 
 #ifdef _WIN32
@@ -1154,10 +7468,10 @@
         result["platform"] = "unknown";
 #endif
 
-#if defined(__clang__)
-        result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
-#elif defined(__ICC) || defined(__INTEL_COMPILER)
+#if defined(__ICC) || defined(__INTEL_COMPILER)
         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
+#elif defined(__clang__)
+        result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
 #elif defined(__GNUC__) || defined(__GNUG__)
         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
 #elif defined(__HP_cc) || defined(__HP_aCC)
@@ -1252,7 +7566,7 @@
     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
     > An implementation may set limits on the maximum depth of nesting.
 
-    In this class, the object's limit of nesting is not constraint explicitly.
+    In this class, the object's limit of nesting is not explicitly constrained.
     However, a maximum depth of nesting may be introduced by the compiler or
     runtime environment. A theoretical limit can be queried by calling the
     @ref max_size function of a JSON object.
@@ -1311,7 +7625,7 @@
     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
     > An implementation may set limits on the maximum depth of nesting.
 
-    In this class, the array's limit of nesting is not constraint explicitly.
+    In this class, the array's limit of nesting is not explicitly constrained.
     However, a maximum depth of nesting may be introduced by the compiler or
     runtime environment. A theoretical limit can be queried by calling the
     @ref max_size function of a JSON array.
@@ -1745,9 +8059,9 @@
 
                 default:
                 {
-                    if (t == value_t::null)
+                    if (JSON_UNLIKELY(t == value_t::null))
                     {
-                        JSON_THROW(std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
+                        JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
                     }
                     break;
                 }
@@ -1760,17 +8074,70 @@
             string = create<string_t>(value);
         }
 
+        /// constructor for rvalue strings
+        json_value(string_t&& value)
+        {
+            string = create<string_t>(std::move(value));
+        }
+
         /// constructor for objects
         json_value(const object_t& value)
         {
             object = create<object_t>(value);
         }
 
+        /// constructor for rvalue objects
+        json_value(object_t&& value)
+        {
+            object = create<object_t>(std::move(value));
+        }
+
         /// constructor for arrays
         json_value(const array_t& value)
         {
             array = create<array_t>(value);
         }
+
+        /// constructor for rvalue arrays
+        json_value(array_t&& value)
+        {
+            array = create<array_t>(std::move(value));
+        }
+
+        void destroy(value_t t)
+        {
+            switch (t)
+            {
+                case value_t::object:
+                {
+                    AllocatorType<object_t> alloc;
+                    alloc.destroy(object);
+                    alloc.deallocate(object, 1);
+                    break;
+                }
+
+                case value_t::array:
+                {
+                    AllocatorType<array_t> alloc;
+                    alloc.destroy(array);
+                    alloc.deallocate(array, 1);
+                    break;
+                }
+
+                case value_t::string:
+                {
+                    AllocatorType<string_t> alloc;
+                    alloc.destroy(string);
+                    alloc.deallocate(string, 1);
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+        }
     };
 
     /*!
@@ -1794,31 +8161,7 @@
     // JSON parser callback //
     //////////////////////////
 
-    /*!
-    @brief JSON callback events
-
-    This enumeration lists the parser events that can trigger calling a
-    callback function of type @ref parser_callback_t during parsing.
-
-    @image html callback_events.png "Example when certain parse events are triggered"
-
-    @since version 1.0.0
-    */
-    enum class parse_event_t : uint8_t
-    {
-        /// the parser read `{` and started to process a JSON object
-        object_start,
-        /// the parser read `}` and finished processing a JSON object
-        object_end,
-        /// the parser read `[` and started to process a JSON array
-        array_start,
-        /// the parser read `]` and finished processing a JSON array
-        array_end,
-        /// the parser read a key of a value in an object
-        key,
-        /// the parser finished reading a JSON value
-        value
-    };
+    using parse_event_t = typename parser::parse_event_t;
 
     /*!
     @brief per-element parser callback type
@@ -1872,9 +8215,7 @@
 
     @since version 1.0.0
     */
-    using parser_callback_t = std::function<bool(int depth,
-                              parse_event_t event,
-                              basic_json& parsed)>;
+    using parser_callback_t = typename parser::parser_callback_t;
 
 
     //////////////////
@@ -1901,20 +8242,22 @@
     object      | `{}`
     array       | `[]`
 
-    @param[in] value_type  the type of the value to create
+    @param[in] v  the type of the value to create
 
     @complexity Constant.
 
-    @throw std::bad_alloc if allocation for object, array, or string value
-    fails
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
 
     @liveexample{The following code shows the constructor for different @ref
     value_t values,basic_json__value_t}
 
+    @sa @ref clear() -- restores the postcondition of this constructor
+
     @since version 1.0.0
     */
-    basic_json(const value_t value_type)
-        : m_type(value_type), m_value(value_type)
+    basic_json(const value_t v)
+        : m_type(v), m_value(v)
     {
         assert_invariant();
     }
@@ -1955,9 +8298,9 @@
     following types:
     - **arrays**: @ref array_t and all kinds of compatible containers such as
       `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
-      `std::array`, `std::set`, `std::unordered_set`, `std::multiset`, and
-      `unordered_multiset` with a `value_type` from which a @ref basic_json
-      value can be constructed.
+      `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
+      `std::multiset`, and `std::unordered_multiset` with a `value_type` from
+      which a @ref basic_json value can be constructed.
     - **objects**: @ref object_t and all kinds of compatible associative
       containers such as `std::map`, `std::unordered_map`, `std::multimap`,
       and `std::unordered_multimap` with a `key_type` compatible to
@@ -1983,13 +8326,16 @@
 
     @tparam U = `uncvref_t<CompatibleType>`
 
-    @param[in] val the value to be forwarded
+    @param[in] val the value to be forwarded to the respective constructor
 
     @complexity Usually linear in the size of the passed @a val, also
                 depending on the implementation of the called `to_json()`
                 method.
 
-    @throw what `json_serializer<U>::to_json()` throws
+    @exceptionsafety Depends on the called constructor. For types directly
+    supported by the library (i.e., all types for which no `to_json()` function
+    was provided), strong guarantee holds: if an exception is thrown, there are
+    no changes to any JSON value.
 
     @liveexample{The following code shows the constructor with several
     compatible types.,basic_json__CompatibleType}
@@ -2029,7 +8375,7 @@
 
     1. The empty initializer list is written as `{}` which is exactly an empty
        JSON object.
-    2. C++ has now way of describing mapped types other than to list a list of
+    2. C++ has no way of describing mapped types other than to list a list of
        pairs. As JSON requires that keys must be of type string, rule 2 is the
        weakest constraint one can pose on initializer lists to interpret them
        as an object.
@@ -2039,10 +8385,10 @@
     With the rules described above, the following JSON values cannot be
     expressed by an initializer list:
 
-    - the empty array (`[]`): use @ref array(std::initializer_list<basic_json>)
+    - the empty array (`[]`): use @ref array(initializer_list_t)
       with an empty initializer list in this case
     - arrays whose elements satisfy rule 2: use @ref
-      array(std::initializer_list<basic_json>) with the same initializer list
+      array(initializer_list_t) with the same initializer list
       in this case
 
     @note When used without parentheses around an empty initializer list, @ref
@@ -2054,41 +8400,46 @@
     @param[in] type_deduction internal parameter; when set to `true`, the type
     of the JSON value is deducted from the initializer list @a init; when set
     to `false`, the type provided via @a manual_type is forced. This mode is
-    used by the functions @ref array(std::initializer_list<basic_json>) and
-    @ref object(std::initializer_list<basic_json>).
+    used by the functions @ref array(initializer_list_t) and
+    @ref object(initializer_list_t).
 
     @param[in] manual_type internal parameter; when @a type_deduction is set
     to `false`, the created JSON value will use the provided type (only @ref
     value_t::array and @ref value_t::object are valid); when @a type_deduction
     is set to `true`, this parameter has no effect
 
-    @throw std::domain_error if @a type_deduction is `false`, @a manual_type
-    is `value_t::object`, but @a init contains an element which is not a pair
-    whose first element is a string; example: `"cannot create object from
-    initializer list"`
+    @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
+    `value_t::object`, but @a init contains an element which is not a pair
+    whose first element is a string. In this case, the constructor could not
+    create an object. If @a type_deduction would have be `true`, an array
+    would have been created. See @ref object(initializer_list_t)
+    for an example.
 
     @complexity Linear in the size of the initializer list @a init.
 
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
     @liveexample{The example below shows how JSON values are created from
     initializer lists.,basic_json__list_init_t}
 
-    @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
+    @sa @ref array(initializer_list_t) -- create a JSON array
     value from an initializer list
-    @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
+    @sa @ref object(initializer_list_t) -- create a JSON object
     value from an initializer list
 
     @since version 1.0.0
     */
-    basic_json(std::initializer_list<basic_json> init,
+    basic_json(initializer_list_t init,
                bool type_deduction = true,
                value_t manual_type = value_t::array)
     {
         // check if each element is an array with two elements whose first
         // element is a string
         bool is_an_object = std::all_of(init.begin(), init.end(),
-                                        [](const basic_json & element)
+                                        [](const detail::json_ref<basic_json>& element_ref)
         {
-            return element.is_array() and element.size() == 2 and element[0].is_string();
+            return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
         });
 
         // adjust type if type deduction is not wanted
@@ -2101,9 +8452,9 @@
             }
 
             // if object is wanted but impossible, throw an exception
-            if (manual_type == value_t::object and not is_an_object)
+            if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
             {
-                JSON_THROW(std::domain_error("cannot create object from initializer list"));
+                JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
             }
         }
 
@@ -2113,16 +8464,19 @@
             m_type = value_t::object;
             m_value = value_t::object;
 
-            std::for_each(init.begin(), init.end(), [this](const basic_json & element)
+            std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
             {
-                m_value.object->emplace(*(element[0].m_value.string), element[1]);
+                auto element = element_ref.moved_or_copied();
+                m_value.object->emplace(
+                    std::move(*((*element.m_value.array)[0].m_value.string)),
+                    std::move((*element.m_value.array)[1]));
             });
         }
         else
         {
             // the initializer list describes an array -> create array
             m_type = value_t::array;
-            m_value.array = create<array_t>(init);
+            m_value.array = create<array_t>(init.begin(), init.end());
         }
 
         assert_invariant();
@@ -2137,7 +8491,7 @@
 
     @note This function is only needed to express two edge cases that cannot
     be realized with the initializer list constructor (@ref
-    basic_json(std::initializer_list<basic_json>, bool, value_t)). These cases
+    basic_json(initializer_list_t, bool, value_t)). These cases
     are:
     1. creating an array whose elements are all pairs whose first element is a
     string -- in this case, the initializer list constructor would create an
@@ -2152,18 +8506,20 @@
 
     @complexity Linear in the size of @a init.
 
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
     @liveexample{The following code shows an example for the `array`
     function.,array}
 
-    @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
+    @sa @ref basic_json(initializer_list_t, bool, value_t) --
     create a JSON value from an initializer list
-    @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
+    @sa @ref object(initializer_list_t) -- create a JSON object
     value from an initializer list
 
     @since version 1.0.0
     */
-    static basic_json array(std::initializer_list<basic_json> init =
-                                std::initializer_list<basic_json>())
+    static basic_json array(initializer_list_t init = {})
     {
         return basic_json(init, false, value_t::array);
     }
@@ -2176,34 +8532,37 @@
     the initializer list is empty, the empty object `{}` is created.
 
     @note This function is only added for symmetry reasons. In contrast to the
-    related function @ref array(std::initializer_list<basic_json>), there are
+    related function @ref array(initializer_list_t), there are
     no cases which can only be expressed by this function. That is, any
     initializer list @a init can also be passed to the initializer list
-    constructor @ref basic_json(std::initializer_list<basic_json>, bool,
-    value_t).
+    constructor @ref basic_json(initializer_list_t, bool, value_t).
 
     @param[in] init  initializer list to create an object from (optional)
 
     @return JSON object value
 
-    @throw std::domain_error if @a init is not a pair whose first elements are
-    strings; thrown by
-    @ref basic_json(std::initializer_list<basic_json>, bool, value_t)
+    @throw type_error.301 if @a init is not a list of pairs whose first
+    elements are strings. In this case, no object can be created. When such a
+    value is passed to @ref basic_json(initializer_list_t, bool, value_t),
+    an array would have been created from the passed initializer list @a init.
+    See example below.
 
     @complexity Linear in the size of @a init.
 
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
     @liveexample{The following code shows an example for the `object`
     function.,object}
 
-    @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
+    @sa @ref basic_json(initializer_list_t, bool, value_t) --
     create a JSON value from an initializer list
-    @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
+    @sa @ref array(initializer_list_t) -- create a JSON array
     value from an initializer list
 
     @since version 1.0.0
     */
-    static basic_json object(std::initializer_list<basic_json> init =
-                                 std::initializer_list<basic_json>())
+    static basic_json object(initializer_list_t init = {})
     {
         return basic_json(init, false, value_t::object);
     }
@@ -2212,14 +8571,18 @@
     @brief construct an array with count copies of given value
 
     Constructs a JSON array value by creating @a cnt copies of a passed value.
-    In case @a cnt is `0`, an empty array is created. As postcondition,
-    `std::distance(begin(),end()) == cnt` holds.
+    In case @a cnt is `0`, an empty array is created.
 
     @param[in] cnt  the number of JSON copies of @a val to create
     @param[in] val  the JSON value to copy
 
+    @post `std::distance(begin(),end()) == cnt` holds.
+
     @complexity Linear in @a cnt.
 
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
     @liveexample{The following code shows examples for the @ref
     basic_json(size_type\, const basic_json&)
     constructor.,basic_json__size_type_basic_json}
@@ -2238,12 +8601,13 @@
 
     Constructs the JSON value with the contents of the range `[first, last)`.
     The semantics depends on the different types a JSON value can have:
-    - In case of primitive types (number, boolean, or string), @a first must
-      be `begin()` and @a last must be `end()`. In this case, the value is
-      copied. Otherwise, std::out_of_range is thrown.
+    - In case of a null type, invalid_iterator.206 is thrown.
+    - In case of other primitive types (number, boolean, or string), @a first
+      must be `begin()` and @a last must be `end()`. In this case, the value is
+      copied. Otherwise, invalid_iterator.204 is thrown.
     - In case of structured types (array, object), the constructor behaves as
-      similar versions for `std::vector`.
-    - In case of a null type, std::domain_error is thrown.
+      similar versions for `std::vector` or `std::map`; that is, a JSON array
+      or object is constructed from the values in the range.
 
     @tparam InputIT an input iterator type (@ref iterator or @ref
     const_iterator)
@@ -2252,19 +8616,36 @@
     @param[in] last end of the range to copy from (excluded)
 
     @pre Iterators @a first and @a last must be initialized. **This
-         precondition is enforced with an assertion.**
+         precondition is enforced with an assertion (see warning).** If
+         assertions are switched off, a violation of this precondition yields
+         undefined behavior.
 
-    @throw std::domain_error if iterators are not compatible; that is, do not
-    belong to the same JSON value; example: `"iterators are not compatible"`
-    @throw std::out_of_range if iterators are for a primitive type (number,
-    boolean, or string) where an out of range error can be detected easily;
-    example: `"iterators out of range"`
-    @throw std::bad_alloc if allocation for object, array, or string fails
-    @throw std::domain_error if called with a null value; example: `"cannot
-    use construct with iterators from null"`
+    @pre Range `[first, last)` is valid. Usually, this precondition cannot be
+         checked efficiently. Only certain edge cases are detected; see the
+         description of the exceptions below. A violation of this precondition
+         yields undefined behavior.
+
+    @warning A precondition is enforced with a runtime assertion that will
+             result in calling `std::abort` if this precondition is not met.
+             Assertions can be disabled by defining `NDEBUG` at compile time.
+             See http://en.cppreference.com/w/cpp/error/assert for more
+             information.
+
+    @throw invalid_iterator.201 if iterators @a first and @a last are not
+    compatible (i.e., do not belong to the same JSON value). In this case,
+    the range `[first, last)` is undefined.
+    @throw invalid_iterator.204 if iterators @a first and @a last belong to a
+    primitive type (number, boolean, or string), but @a first does not point
+    to the first element any more. In this case, the range `[first, last)` is
+    undefined. See example code below.
+    @throw invalid_iterator.206 if iterators @a first and @a last belong to a
+    null value. In this case, the range `[first, last)` is undefined.
 
     @complexity Linear in distance between @a first and @a last.
 
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
     @liveexample{The example below shows several ways to create JSON values by
     specifying a subrange with iterators.,basic_json__InputIt_InputIt}
 
@@ -2279,9 +8660,9 @@
         assert(last.m_object != nullptr);
 
         // make sure iterator fits the current value
-        if (first.m_object != last.m_object)
+        if (JSON_UNLIKELY(first.m_object != last.m_object))
         {
-            JSON_THROW(std::domain_error("iterators are not compatible"));
+            JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
         }
 
         // copy type from first iterator
@@ -2296,17 +8677,16 @@
             case value_t::number_unsigned:
             case value_t::string:
             {
-                if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
+                if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
+                                  or not last.m_it.primitive_iterator.is_end()))
                 {
-                    JSON_THROW(std::out_of_range("iterators out of range"));
+                    JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
                 }
                 break;
             }
 
             default:
-            {
                 break;
-            }
         }
 
         switch (m_type)
@@ -2356,53 +8736,23 @@
             }
 
             default:
-            {
-                JSON_THROW(std::domain_error("cannot use construct with iterators from " + first.m_object->type_name()));
-            }
+                JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
+                                                    std::string(first.m_object->type_name())));
         }
 
         assert_invariant();
     }
 
-    /*!
-    @brief construct a JSON value given an input stream
-
-    @param[in,out] i  stream to read a serialized JSON value from
-    @param[in] cb a parser callback function of type @ref parser_callback_t
-    which is used to control the deserialization by filtering unwanted values
-    (optional)
-
-    @complexity Linear in the length of the input. The parser is a predictive
-    LL(1) parser. The complexity can be higher if the parser callback function
-    @a cb has a super-linear complexity.
-
-    @note A UTF-8 byte order mark is silently ignored.
-
-    @deprecated This constructor is deprecated and will be removed in version
-      3.0.0 to unify the interface of the library. Deserialization will be
-      done by stream operators or by calling one of the `parse` functions,
-      e.g. @ref parse(std::istream&, const parser_callback_t). That is, calls
-      like `json j(i);` for an input stream @a i need to be replaced by
-      `json j = json::parse(i);`. See the example below.
-
-    @liveexample{The example below demonstrates constructing a JSON value from
-    a `std::stringstream` with and without callback
-    function.,basic_json__istream}
-
-    @since version 2.0.0, deprecated in version 2.0.3, to be removed in
-           version 3.0.0
-    */
-    JSON_DEPRECATED
-    explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
-    {
-        *this = parser(i, cb).parse();
-        assert_invariant();
-    }
 
     ///////////////////////////////////////
     // other constructors and destructor //
     ///////////////////////////////////////
 
+    /// @private
+    basic_json(const detail::json_ref<basic_json>& ref)
+        : basic_json(ref.moved_or_copied())
+    {}
+
     /*!
     @brief copy constructor
 
@@ -2410,16 +8760,19 @@
 
     @param[in] other  the JSON value to copy
 
+    @post `*this == other`
+
     @complexity Linear in the size of @a other.
 
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
     @requirement This function helps `basic_json` satisfying the
     [Container](http://en.cppreference.com/w/cpp/concept/Container)
     requirements:
     - The complexity is linear.
     - As postcondition, it holds: `other == basic_json(other)`.
 
-    @throw std::bad_alloc if allocation for object, array, or string fails.
-
     @liveexample{The following code shows an example for the copy
     constructor.,basic_json__basic_json}
 
@@ -2476,9 +8829,7 @@
             }
 
             default:
-            {
                 break;
-            }
         }
 
         assert_invariant();
@@ -2493,10 +8844,18 @@
 
     @param[in,out] other  value to move to this object
 
-    @post @a other is a JSON null value
+    @post `*this` has the same value as @a other before the call.
+    @post @a other is a JSON null value.
 
     @complexity Constant.
 
+    @exceptionsafety No-throw guarantee: this constructor never throws
+    exceptions.
+
+    @requirement This function helps `basic_json` satisfying the
+    [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible)
+    requirements.
+
     @liveexample{The code below shows the move constructor explicitly called
     via std::move.,basic_json__moveconstructor}
 
@@ -2521,7 +8880,7 @@
 
     Copy assignment operator. Copies a JSON value via the "copy and swap"
     strategy: It is expressed in terms of the copy constructor, destructor,
-    and the swap() member function.
+    and the `swap()` member function.
 
     @param[in] other  value to copy from
 
@@ -2575,39 +8934,7 @@
     ~basic_json()
     {
         assert_invariant();
-
-        switch (m_type)
-        {
-            case value_t::object:
-            {
-                AllocatorType<object_t> alloc;
-                alloc.destroy(m_value.object);
-                alloc.deallocate(m_value.object, 1);
-                break;
-            }
-
-            case value_t::array:
-            {
-                AllocatorType<array_t> alloc;
-                alloc.destroy(m_value.array);
-                alloc.deallocate(m_value.array, 1);
-                break;
-            }
-
-            case value_t::string:
-            {
-                AllocatorType<string_t> alloc;
-                alloc.destroy(m_value.string);
-                alloc.deallocate(m_value.string, 1);
-                break;
-            }
-
-            default:
-            {
-                // all other types need no specific destructor
-                break;
-            }
-        }
+        m_value.destroy(m_type);
     }
 
     /// @}
@@ -2626,38 +8953,50 @@
 
     Serialization function for JSON values. The function tries to mimic
     Python's `json.dumps()` function, and currently supports its @a indent
-    parameter.
+    and @a ensure_ascii parameters.
 
     @param[in] indent If indent is nonnegative, then array elements and object
     members will be pretty-printed with that indent level. An indent level of
     `0` will only insert newlines. `-1` (the default) selects the most compact
     representation.
+    @param[in] indent_char The character to use for indentation if @a indent is
+    greater than `0`. The default is ` ` (space).
+    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
+    in the output are escaped with \uXXXX sequences, and the result consists
+    of ASCII characters only.
 
     @return string containing the serialization of the JSON value
 
     @complexity Linear.
 
-    @liveexample{The following example shows the effect of different @a indent
-    parameters to the result of the serialization.,dump}
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @liveexample{The following example shows the effect of different @a indent\,
+    @a indent_char\, and @a ensure_ascii parameters to the result of the
+    serialization.,dump}
 
     @see https://docs.python.org/2/library/json.html#json.dump
 
-    @since version 1.0.0
+    @since version 1.0.0; indentation character @a indent_char and option
+           @a ensure_ascii added in version 3.0.0
     */
-    string_t dump(const int indent = -1) const
+    string_t dump(const int indent = -1, const char indent_char = ' ',
+                  const bool ensure_ascii = false) const
     {
-        std::stringstream ss;
+        string_t result;
+        serializer s(detail::output_adapter<char>(result), indent_char);
 
         if (indent >= 0)
         {
-            dump(ss, true, static_cast<unsigned int>(indent));
+            s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
         }
         else
         {
-            dump(ss, false, 0);
+            s.dump(*this, false, ensure_ascii, 0);
         }
 
-        return ss.str();
+        return result;
     }
 
     /*!
@@ -2667,6 +9006,17 @@
     enumeration.
 
     @return the type of the JSON value
+            Value type                | return value
+            ------------------------- | -------------------------
+            null                      | value_t::null
+            boolean                   | value_t::boolean
+            string                    | value_t::string
+            number (integer)          | value_t::number_integer
+            number (unsigned integer) | value_t::number_unsigned
+            number (foating-point)    | value_t::number_float
+            object                    | value_t::object
+            array                     | value_t::array
+            discarded                 | value_t::discarded
 
     @complexity Constant.
 
@@ -2676,6 +9026,9 @@
     @liveexample{The following code exemplifies `type()` for all JSON
     types.,type}
 
+    @sa @ref operator value_t() -- return the type of the JSON value (implicit)
+    @sa @ref type_name() -- return the type as string
+
     @since version 1.0.0
     */
     constexpr value_t type() const noexcept
@@ -2686,8 +9039,8 @@
     /*!
     @brief return whether type is primitive
 
-    This function returns true iff the JSON type is primitive (string, number,
-    boolean, or null).
+    This function returns true if and only if the JSON type is primitive
+    (string, number, boolean, or null).
 
     @return `true` if type is primitive (string, number, boolean, or null),
     `false` otherwise.
@@ -2716,8 +9069,8 @@
     /*!
     @brief return whether type is structured
 
-    This function returns true iff the JSON type is structured (array or
-    object).
+    This function returns true if and only if the JSON type is structured
+    (array or object).
 
     @return `true` if type is structured (array or object), `false` otherwise.
 
@@ -2743,7 +9096,7 @@
     /*!
     @brief return whether value is null
 
-    This function returns true iff the JSON value is null.
+    This function returns true if and only if the JSON value is null.
 
     @return `true` if type is null, `false` otherwise.
 
@@ -2759,13 +9112,13 @@
     */
     constexpr bool is_null() const noexcept
     {
-        return m_type == value_t::null;
+        return (m_type == value_t::null);
     }
 
     /*!
     @brief return whether value is a boolean
 
-    This function returns true iff the JSON value is a boolean.
+    This function returns true if and only if the JSON value is a boolean.
 
     @return `true` if type is boolean, `false` otherwise.
 
@@ -2781,14 +9134,14 @@
     */
     constexpr bool is_boolean() const noexcept
     {
-        return m_type == value_t::boolean;
+        return (m_type == value_t::boolean);
     }
 
     /*!
     @brief return whether value is a number
 
-    This function returns true iff the JSON value is a number. This includes
-    both integer and floating-point values.
+    This function returns true if and only if the JSON value is a number. This
+    includes both integer (signed and unsigned) and floating-point values.
 
     @return `true` if type is number (regardless whether integer, unsigned
     integer or floating-type), `false` otherwise.
@@ -2817,8 +9170,8 @@
     /*!
     @brief return whether value is an integer number
 
-    This function returns true iff the JSON value is an integer or unsigned
-    integer number. This excludes floating-point values.
+    This function returns true if and only if the JSON value is a signed or
+    unsigned integer number. This excludes floating-point values.
 
     @return `true` if type is an integer or unsigned integer number, `false`
     otherwise.
@@ -2840,14 +9193,14 @@
     */
     constexpr bool is_number_integer() const noexcept
     {
-        return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
+        return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
     }
 
     /*!
     @brief return whether value is an unsigned integer number
 
-    This function returns true iff the JSON value is an unsigned integer
-    number. This excludes floating-point and (signed) integer values.
+    This function returns true if and only if the JSON value is an unsigned
+    integer number. This excludes floating-point and signed integer values.
 
     @return `true` if type is an unsigned integer number, `false` otherwise.
 
@@ -2868,14 +9221,14 @@
     */
     constexpr bool is_number_unsigned() const noexcept
     {
-        return m_type == value_t::number_unsigned;
+        return (m_type == value_t::number_unsigned);
     }
 
     /*!
     @brief return whether value is a floating-point number
 
-    This function returns true iff the JSON value is a floating-point number.
-    This excludes integer and unsigned integer values.
+    This function returns true if and only if the JSON value is a
+    floating-point number. This excludes signed and unsigned integer values.
 
     @return `true` if type is a floating-point number, `false` otherwise.
 
@@ -2896,13 +9249,13 @@
     */
     constexpr bool is_number_float() const noexcept
     {
-        return m_type == value_t::number_float;
+        return (m_type == value_t::number_float);
     }
 
     /*!
     @brief return whether value is an object
 
-    This function returns true iff the JSON value is an object.
+    This function returns true if and only if the JSON value is an object.
 
     @return `true` if type is object, `false` otherwise.
 
@@ -2918,13 +9271,13 @@
     */
     constexpr bool is_object() const noexcept
     {
-        return m_type == value_t::object;
+        return (m_type == value_t::object);
     }
 
     /*!
     @brief return whether value is an array
 
-    This function returns true iff the JSON value is an array.
+    This function returns true if and only if the JSON value is an array.
 
     @return `true` if type is array, `false` otherwise.
 
@@ -2940,13 +9293,13 @@
     */
     constexpr bool is_array() const noexcept
     {
-        return m_type == value_t::array;
+        return (m_type == value_t::array);
     }
 
     /*!
     @brief return whether value is a string
 
-    This function returns true iff the JSON value is a string.
+    This function returns true if and only if the JSON value is a string.
 
     @return `true` if type is string, `false` otherwise.
 
@@ -2962,14 +9315,14 @@
     */
     constexpr bool is_string() const noexcept
     {
-        return m_type == value_t::string;
+        return (m_type == value_t::string);
     }
 
     /*!
     @brief return whether value is discarded
 
-    This function returns true iff the JSON value was discarded during parsing
-    with a callback function (see @ref parser_callback_t).
+    This function returns true if and only if the JSON value was discarded
+    during parsing with a callback function (see @ref parser_callback_t).
 
     @note This function will always be `false` for JSON values after parsing.
     That is, discarded values can only occur during parsing, but will be
@@ -2989,7 +9342,7 @@
     */
     constexpr bool is_discarded() const noexcept
     {
-        return m_type == value_t::discarded;
+        return (m_type == value_t::discarded);
     }
 
     /*!
@@ -3008,6 +9361,9 @@
     @liveexample{The following code exemplifies the @ref value_t operator for
     all JSON types.,operator__value_t}
 
+    @sa @ref type() -- return the type of the JSON value (explicit)
+    @sa @ref type_name() -- return the type as string
+
     @since version 1.0.0
     */
     constexpr operator value_t() const noexcept
@@ -3025,12 +9381,12 @@
     /// get a boolean (explicit)
     boolean_t get_impl(boolean_t* /*unused*/) const
     {
-        if (is_boolean())
+        if (JSON_LIKELY(is_boolean()))
         {
             return m_value.boolean;
         }
 
-        JSON_THROW(std::domain_error("type must be boolean, but is " + type_name()));
+        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
     }
 
     /// get a pointer to the value (object)
@@ -3120,30 +9476,26 @@
     /*!
     @brief helper function to implement get_ref()
 
-    This funcion helps to implement get_ref() without code duplication for
+    This function helps to implement get_ref() without code duplication for
     const and non-const overloads
 
     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
 
-    @throw std::domain_error if ReferenceType does not match underlying value
+    @throw type_error.303 if ReferenceType does not match underlying value
     type of the current JSON
     */
     template<typename ReferenceType, typename ThisType>
     static ReferenceType get_ref_impl(ThisType& obj)
     {
-        // helper type
-        using PointerType = typename std::add_pointer<ReferenceType>::type;
-
         // delegate the call to get_ptr<>()
-        auto ptr = obj.template get_ptr<PointerType>();
+        auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
 
-        if (ptr != nullptr)
+        if (JSON_LIKELY(ptr != nullptr))
         {
             return *ptr;
         }
 
-        JSON_THROW(std::domain_error("incompatible ReferenceType for get_ref, actual type is " +
-                                     obj.type_name()));
+        JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
     }
 
   public:
@@ -3194,9 +9546,9 @@
     This overloads is chosen if:
     - @a ValueType is not @ref basic_json,
     - @ref json_serializer<ValueType> has a `from_json()` method of the form
-      `void from_json(const @ref basic_json&, ValueType&)`, and
+      `void from_json(const basic_json&, ValueType&)`, and
     - @ref json_serializer<ValueType> does not have a `from_json()` method of
-      the form `ValueType from_json(const @ref basic_json&)`
+      the form `ValueType from_json(const basic_json&)`
 
     @tparam ValueTypeCV the provided value type
     @tparam ValueType the returned value type
@@ -3255,7 +9607,7 @@
     This overloads is chosen if:
     - @a ValueType is not @ref basic_json and
     - @ref json_serializer<ValueType> has a `from_json()` method of the form
-      `ValueType from_json(const @ref basic_json&)`
+      `ValueType from_json(const basic_json&)`
 
     @note If @ref json_serializer<ValueType> has both overloads of
     `from_json()`, this one is chosen.
@@ -3404,7 +9756,7 @@
             , "incompatible pointer type");
 
         // delegate the call to get_impl_ptr<>() const
-        return get_impl_ptr(static_cast<const PointerType>(nullptr));
+        return get_impl_ptr(static_cast<PointerType>(nullptr));
     }
 
     /*!
@@ -3422,10 +9774,10 @@
 
     @return reference to the internally stored JSON value if the requested
     reference type @a ReferenceType fits to the JSON value; throws
-    std::domain_error otherwise
+    type_error.303 otherwise
 
-    @throw std::domain_error in case passed type @a ReferenceType is
-    incompatible with the stored JSON value
+    @throw type_error.303 in case passed type @a ReferenceType is incompatible
+    with the stored JSON value; see example below
 
     @complexity Constant.
 
@@ -3468,8 +9820,9 @@
 
     @return copy of the JSON value, converted to type @a ValueType
 
-    @throw std::domain_error in case passed type @a ValueType is incompatible
-    to JSON, thrown by @ref get() const
+    @throw type_error.302 in case passed type @a ValueType is incompatible
+    to the JSON value type (e.g., the JSON value is of type boolean, but a
+    string is requested); see example below
 
     @complexity Linear in the size of the JSON value.
 
@@ -3484,10 +9837,14 @@
     */
     template < typename ValueType, typename std::enable_if <
                    not std::is_pointer<ValueType>::value and
+                   not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
                    not std::is_same<ValueType, typename string_t::value_type>::value
 #ifndef _MSC_VER  // fix for issue #167 operator<< ambiguity under VS2015
                    and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
 #endif
+#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER >1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
+                   and not std::is_same<ValueType, typename std::string_view>::value
+#endif
                    , int >::type = 0 >
     operator ValueType() const
     {
@@ -3516,22 +9873,26 @@
 
     @return reference to the element at index @a idx
 
-    @throw std::domain_error if the JSON value is not an array; example:
-    `"cannot use at() with string"`
-    @throw std::out_of_range if the index @a idx is out of range of the array;
-    that is, `idx >= size()`; example: `"array index 7 is out of range"`
+    @throw type_error.304 if the JSON value is not an array; in this case,
+    calling `at` with an index makes no sense. See example below.
+    @throw out_of_range.401 if the index @a idx is out of range of the array;
+    that is, `idx >= size()`. See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
 
     @complexity Constant.
 
-    @liveexample{The example below shows how array elements can be read and
-    written using `at()`.,at__size_type}
-
     @since version 1.0.0
+
+    @liveexample{The example below shows how array elements can be read and
+    written using `at()`. It also demonstrates the different exceptions that
+    can be thrown.,at__size_type}
     */
     reference at(size_type idx)
     {
         // at only works for arrays
-        if (is_array())
+        if (JSON_LIKELY(is_array()))
         {
             JSON_TRY
             {
@@ -3540,12 +9901,12 @@
             JSON_CATCH (std::out_of_range&)
             {
                 // create better exception explanation
-                JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
+                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
             }
         }
         else
         {
-            JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
+            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
         }
     }
 
@@ -3559,22 +9920,26 @@
 
     @return const reference to the element at index @a idx
 
-    @throw std::domain_error if the JSON value is not an array; example:
-    `"cannot use at() with string"`
-    @throw std::out_of_range if the index @a idx is out of range of the array;
-    that is, `idx >= size()`; example: `"array index 7 is out of range"`
+    @throw type_error.304 if the JSON value is not an array; in this case,
+    calling `at` with an index makes no sense. See example below.
+    @throw out_of_range.401 if the index @a idx is out of range of the array;
+    that is, `idx >= size()`. See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
 
     @complexity Constant.
 
-    @liveexample{The example below shows how array elements can be read using
-    `at()`.,at__size_type_const}
-
     @since version 1.0.0
+
+    @liveexample{The example below shows how array elements can be read using
+    `at()`. It also demonstrates the different exceptions that can be thrown.,
+    at__size_type_const}
     */
     const_reference at(size_type idx) const
     {
         // at only works for arrays
-        if (is_array())
+        if (JSON_LIKELY(is_array()))
         {
             JSON_TRY
             {
@@ -3583,12 +9948,12 @@
             JSON_CATCH (std::out_of_range&)
             {
                 // create better exception explanation
-                JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
+                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
             }
         }
         else
         {
-            JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
+            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
         }
     }
 
@@ -3602,26 +9967,30 @@
 
     @return reference to the element at key @a key
 
-    @throw std::domain_error if the JSON value is not an object; example:
-    `"cannot use at() with boolean"`
-    @throw std::out_of_range if the key @a key is is not stored in the object;
-    that is, `find(key) == end()`; example: `"key "the fast" not found"`
+    @throw type_error.304 if the JSON value is not an object; in this case,
+    calling `at` with a key makes no sense. See example below.
+    @throw out_of_range.403 if the key @a key is is not stored in the object;
+    that is, `find(key) == end()`. See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
 
     @complexity Logarithmic in the size of the container.
 
-    @liveexample{The example below shows how object elements can be read and
-    written using `at()`.,at__object_t_key_type}
-
     @sa @ref operator[](const typename object_t::key_type&) for unchecked
     access by reference
     @sa @ref value() for access by value with a default value
 
     @since version 1.0.0
+
+    @liveexample{The example below shows how object elements can be read and
+    written using `at()`. It also demonstrates the different exceptions that
+    can be thrown.,at__object_t_key_type}
     */
     reference at(const typename object_t::key_type& key)
     {
         // at only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             JSON_TRY
             {
@@ -3630,12 +9999,12 @@
             JSON_CATCH (std::out_of_range&)
             {
                 // create better exception explanation
-                JSON_THROW(std::out_of_range("key '" + key + "' not found"));
+                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
             }
         }
         else
         {
-            JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
+            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
         }
     }
 
@@ -3649,26 +10018,30 @@
 
     @return const reference to the element at key @a key
 
-    @throw std::domain_error if the JSON value is not an object; example:
-    `"cannot use at() with boolean"`
-    @throw std::out_of_range if the key @a key is is not stored in the object;
-    that is, `find(key) == end()`; example: `"key "the fast" not found"`
+    @throw type_error.304 if the JSON value is not an object; in this case,
+    calling `at` with a key makes no sense. See example below.
+    @throw out_of_range.403 if the key @a key is is not stored in the object;
+    that is, `find(key) == end()`. See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
 
     @complexity Logarithmic in the size of the container.
 
-    @liveexample{The example below shows how object elements can be read using
-    `at()`.,at__object_t_key_type_const}
-
     @sa @ref operator[](const typename object_t::key_type&) for unchecked
     access by reference
     @sa @ref value() for access by value with a default value
 
     @since version 1.0.0
+
+    @liveexample{The example below shows how object elements can be read using
+    `at()`. It also demonstrates the different exceptions that can be thrown.,
+    at__object_t_key_type_const}
     */
     const_reference at(const typename object_t::key_type& key) const
     {
         // at only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             JSON_TRY
             {
@@ -3677,12 +10050,12 @@
             JSON_CATCH (std::out_of_range&)
             {
                 // create better exception explanation
-                JSON_THROW(std::out_of_range("key '" + key + "' not found"));
+                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
             }
         }
         else
         {
-            JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
+            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
         }
     }
 
@@ -3699,8 +10072,8 @@
 
     @return reference to the element at index @a idx
 
-    @throw std::domain_error if JSON is not an array or null; example:
-    `"cannot use operator[] with string"`
+    @throw type_error.305 if the JSON value is not an array or null; in that
+    cases, using the [] operator with an index makes no sense.
 
     @complexity Constant if @a idx is in the range of the array. Otherwise
     linear in `idx - size()`.
@@ -3722,7 +10095,7 @@
         }
 
         // operator[] only works for arrays
-        if (is_array())
+        if (JSON_LIKELY(is_array()))
         {
             // fill up array with null values if given idx is outside range
             if (idx >= m_value.array->size())
@@ -3735,7 +10108,7 @@
             return m_value.array->operator[](idx);
         }
 
-        JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
+        JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
     }
 
     /*!
@@ -3747,8 +10120,8 @@
 
     @return const reference to the element at index @a idx
 
-    @throw std::domain_error if JSON is not an array; example: `"cannot use
-    operator[] with null"`
+    @throw type_error.305 if the JSON value is not an array; in that cases,
+    using the [] operator with an index makes no sense.
 
     @complexity Constant.
 
@@ -3760,12 +10133,12 @@
     const_reference operator[](size_type idx) const
     {
         // const operator[] only works for arrays
-        if (is_array())
+        if (JSON_LIKELY(is_array()))
         {
             return m_value.array->operator[](idx);
         }
 
-        JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
+        JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
     }
 
     /*!
@@ -3781,8 +10154,8 @@
 
     @return reference to the element at key @a key
 
-    @throw std::domain_error if JSON is not an object or null; example:
-    `"cannot use operator[] with string"`
+    @throw type_error.305 if the JSON value is not an object or null; in that
+    cases, using the [] operator with a key makes no sense.
 
     @complexity Logarithmic in the size of the container.
 
@@ -3806,12 +10179,12 @@
         }
 
         // operator[] only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             return m_value.object->operator[](key);
         }
 
-        JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
+        JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
     }
 
     /*!
@@ -3830,8 +10203,8 @@
     @pre The element with key @a key must exist. **This precondition is
          enforced with an assertion.**
 
-    @throw std::domain_error if JSON is not an object; example: `"cannot use
-    operator[] with null"`
+    @throw type_error.305 if the JSON value is not an object; in that cases,
+    using the [] operator with a key makes no sense.
 
     @complexity Logarithmic in the size of the container.
 
@@ -3847,13 +10220,13 @@
     const_reference operator[](const typename object_t::key_type& key) const
     {
         // const operator[] only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             assert(m_value.object->find(key) != m_value.object->end());
             return m_value.object->find(key)->second;
         }
 
-        JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
+        JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
     }
 
     /*!
@@ -3869,76 +10242,8 @@
 
     @return reference to the element at key @a key
 
-    @throw std::domain_error if JSON is not an object or null; example:
-    `"cannot use operator[] with string"`
-
-    @complexity Logarithmic in the size of the container.
-
-    @liveexample{The example below shows how object elements can be read and
-    written using the `[]` operator.,operatorarray__key_type}
-
-    @sa @ref at(const typename object_t::key_type&) for access by reference
-    with range checking
-    @sa @ref value() for access by value with a default value
-
-    @since version 1.0.0
-    */
-    template<typename T, std::size_t n>
-    reference operator[](T * (&key)[n])
-    {
-        return operator[](static_cast<const T>(key));
-    }
-
-    /*!
-    @brief read-only access specified object element
-
-    Returns a const reference to the element at with specified key @a key. No
-    bounds checking is performed.
-
-    @warning If the element with key @a key does not exist, the behavior is
-    undefined.
-
-    @note This function is required for compatibility reasons with Clang.
-
-    @param[in] key  key of the element to access
-
-    @return const reference to the element at key @a key
-
-    @throw std::domain_error if JSON is not an object; example: `"cannot use
-    operator[] with null"`
-
-    @complexity Logarithmic in the size of the container.
-
-    @liveexample{The example below shows how object elements can be read using
-    the `[]` operator.,operatorarray__key_type_const}
-
-    @sa @ref at(const typename object_t::key_type&) for access by reference
-    with range checking
-    @sa @ref value() for access by value with a default value
-
-    @since version 1.0.0
-    */
-    template<typename T, std::size_t n>
-    const_reference operator[](T * (&key)[n]) const
-    {
-        return operator[](static_cast<const T>(key));
-    }
-
-    /*!
-    @brief access specified object element
-
-    Returns a reference to the element at with specified key @a key.
-
-    @note If @a key is not found in the object, then it is silently added to
-    the object and filled with a `null` value to make `key` a valid reference.
-    In case the value was `null` before, it is converted to an object.
-
-    @param[in] key  key of the element to access
-
-    @return reference to the element at key @a key
-
-    @throw std::domain_error if JSON is not an object or null; example:
-    `"cannot use operator[] with string"`
+    @throw type_error.305 if the JSON value is not an object or null; in that
+    cases, using the [] operator with a key makes no sense.
 
     @complexity Logarithmic in the size of the container.
 
@@ -3963,12 +10268,12 @@
         }
 
         // at only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             return m_value.object->operator[](key);
         }
 
-        JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
+        JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
     }
 
     /*!
@@ -3987,8 +10292,8 @@
     @pre The element with key @a key must exist. **This precondition is
          enforced with an assertion.**
 
-    @throw std::domain_error if JSON is not an object; example: `"cannot use
-    operator[] with null"`
+    @throw type_error.305 if the JSON value is not an object; in that cases,
+    using the [] operator with a key makes no sense.
 
     @complexity Logarithmic in the size of the container.
 
@@ -4005,13 +10310,13 @@
     const_reference operator[](T* key) const
     {
         // at only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             assert(m_value.object->find(key) != m_value.object->end());
             return m_value.object->find(key)->second;
         }
 
-        JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
+        JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
     }
 
     /*!
@@ -4024,7 +10329,7 @@
     @code {.cpp}
     try {
         return at(key);
-    } catch(std::out_of_range) {
+    } catch(out_of_range) {
         return default_value;
     }
     @endcode
@@ -4047,8 +10352,8 @@
     @return copy of the element at key @a key or @a default_value if @a key
     is not found
 
-    @throw std::domain_error if JSON is not an object; example: `"cannot use
-    value() with null"`
+    @throw type_error.306 if the JSON value is not an objec; in that cases,
+    using `value()` with a key makes no sense.
 
     @complexity Logarithmic in the size of the container.
 
@@ -4064,10 +10369,10 @@
     */
     template<class ValueType, typename std::enable_if<
                  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
-    ValueType value(const typename object_t::key_type& key, ValueType default_value) const
+    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
     {
         // at only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             // if key is found, return value and given default value otherwise
             const auto it = find(key);
@@ -4078,10 +10383,8 @@
 
             return default_value;
         }
-        else
-        {
-            JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
-        }
+
+        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
     }
 
     /*!
@@ -4103,7 +10406,7 @@
     @code {.cpp}
     try {
         return at(ptr);
-    } catch(std::out_of_range) {
+    } catch(out_of_range) {
         return default_value;
     }
     @endcode
@@ -4122,8 +10425,8 @@
     @return copy of the element at key @a key or @a default_value if @a key
     is not found
 
-    @throw std::domain_error if JSON is not an object; example: `"cannot use
-    value() with null"`
+    @throw type_error.306 if the JSON value is not an objec; in that cases,
+    using `value()` with a key makes no sense.
 
     @complexity Logarithmic in the size of the container.
 
@@ -4136,23 +10439,23 @@
     */
     template<class ValueType, typename std::enable_if<
                  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
-    ValueType value(const json_pointer& ptr, ValueType default_value) const
+    ValueType value(const json_pointer& ptr, const ValueType& default_value) const
     {
         // at only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             // if pointer resolves a value, return it or use default value
             JSON_TRY
             {
                 return ptr.get_checked(this);
             }
-            JSON_CATCH (std::out_of_range&)
+            JSON_CATCH (out_of_range&)
             {
                 return default_value;
             }
         }
 
-        JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
+        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
     }
 
     /*!
@@ -4181,7 +10484,7 @@
     assertions**).
     @post The JSON value remains unchanged.
 
-    @throw std::out_of_range when called on `null` value
+    @throw invalid_iterator.214 when called on `null` value
 
     @liveexample{The following code shows an example for `front()`.,front}
 
@@ -4224,7 +10527,8 @@
     assertions**).
     @post The JSON value remains unchanged.
 
-    @throw std::out_of_range when called on `null` value.
+    @throw invalid_iterator.214 when called on a `null` value. See example
+    below.
 
     @liveexample{The following code shows an example for `back()`.,back}
 
@@ -4268,11 +10572,12 @@
     @post Invalidates iterators and references at or after the point of the
     erase, including the `end()` iterator.
 
-    @throw std::domain_error if called on a `null` value; example: `"cannot
-    use erase() with null"`
-    @throw std::domain_error if called on an iterator which does not belong to
-    the current JSON value; example: `"iterator does not fit current value"`
-    @throw std::out_of_range if called on a primitive type with invalid
+    @throw type_error.307 if called on a `null` value; example: `"cannot use
+    erase() with null"`
+    @throw invalid_iterator.202 if called on an iterator which does not belong
+    to the current JSON value; example: `"iterator does not fit current
+    value"`
+    @throw invalid_iterator.205 if called on a primitive type with invalid
     iterator (i.e., any iterator which is not `begin()`); example: `"iterator
     out of range"`
 
@@ -4301,9 +10606,9 @@
     IteratorType erase(IteratorType pos)
     {
         // make sure iterator fits the current value
-        if (this != pos.m_object)
+        if (JSON_UNLIKELY(this != pos.m_object))
         {
-            JSON_THROW(std::domain_error("iterator does not fit current value"));
+            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
         }
 
         IteratorType result = end();
@@ -4316,9 +10621,9 @@
             case value_t::number_unsigned:
             case value_t::string:
             {
-                if (not pos.m_it.primitive_iterator.is_begin())
+                if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
                 {
-                    JSON_THROW(std::out_of_range("iterator out of range"));
+                    JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
                 }
 
                 if (is_string())
@@ -4347,9 +10652,7 @@
             }
 
             default:
-            {
-                JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
-            }
+                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
         }
 
         return result;
@@ -4375,11 +10678,11 @@
     @post Invalidates iterators and references at or after the point of the
     erase, including the `end()` iterator.
 
-    @throw std::domain_error if called on a `null` value; example: `"cannot
-    use erase() with null"`
-    @throw std::domain_error if called on iterators which does not belong to
-    the current JSON value; example: `"iterators do not fit current value"`
-    @throw std::out_of_range if called on a primitive type with invalid
+    @throw type_error.307 if called on a `null` value; example: `"cannot use
+    erase() with null"`
+    @throw invalid_iterator.203 if called on iterators which does not belong
+    to the current JSON value; example: `"iterators do not fit current value"`
+    @throw invalid_iterator.204 if called on a primitive type with invalid
     iterators (i.e., if `first != begin()` and `last != end()`); example:
     `"iterators out of range"`
 
@@ -4408,9 +10711,9 @@
     IteratorType erase(IteratorType first, IteratorType last)
     {
         // make sure iterator fits the current value
-        if (this != first.m_object or this != last.m_object)
+        if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
         {
-            JSON_THROW(std::domain_error("iterators do not fit current value"));
+            JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
         }
 
         IteratorType result = end();
@@ -4423,9 +10726,10 @@
             case value_t::number_unsigned:
             case value_t::string:
             {
-                if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
+                if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
+                                or not last.m_it.primitive_iterator.is_end()))
                 {
-                    JSON_THROW(std::out_of_range("iterators out of range"));
+                    JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
                 }
 
                 if (is_string())
@@ -4456,9 +10760,7 @@
             }
 
             default:
-            {
-                JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
-            }
+                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
         }
 
         return result;
@@ -4478,7 +10780,7 @@
     @post References and iterators to the erased elements are invalidated.
     Other references and iterators are not affected.
 
-    @throw std::domain_error when called on a type other than JSON object;
+    @throw type_error.307 when called on a type other than JSON object;
     example: `"cannot use erase() with null"`
 
     @complexity `log(size()) + count(key)`
@@ -4496,12 +10798,12 @@
     size_type erase(const typename object_t::key_type& key)
     {
         // this erase only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             return m_value.object->erase(key);
         }
 
-        JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
+        JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
     }
 
     /*!
@@ -4511,9 +10813,9 @@
 
     @param[in] idx index of the element to remove
 
-    @throw std::domain_error when called on a type other than JSON array;
+    @throw type_error.307 when called on a type other than JSON object;
     example: `"cannot use erase() with null"`
-    @throw std::out_of_range when `idx >= size()`; example: `"array index 17
+    @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
     is out of range"`
 
     @complexity Linear in distance between @a idx and the end of the container.
@@ -4531,18 +10833,18 @@
     void erase(const size_type idx)
     {
         // this erase only works for arrays
-        if (is_array())
+        if (JSON_LIKELY(is_array()))
         {
-            if (idx >= size())
+            if (JSON_UNLIKELY(idx >= size()))
             {
-                JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
+                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
             }
 
             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
         }
         else
         {
-            JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
+            JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
         }
     }
 
@@ -4916,10 +11218,6 @@
         return const_reverse_iterator(cbegin());
     }
 
-  private:
-    // forward declaration
-    template<typename IteratorType> class iteration_proxy;
-
   public:
     /*!
     @brief wrapper to access iterator member functions in range-based for
@@ -4929,6 +11227,8 @@
     reference to the JSON values is returned, so there is no access to the
     underlying iterator.
 
+    @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
+
     @note The name of this function is not yet final and may change in the
     future.
     */
@@ -4956,9 +11256,9 @@
     /// @{
 
     /*!
-    @brief checks whether the container is empty
+    @brief checks whether the container is empty.
 
-    Checks if a JSON value has no elements.
+    Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
 
     @return The return value depends on the different types and is
             defined as follows:
@@ -4971,23 +11271,27 @@
             object      | result of function `object_t::empty()`
             array       | result of function `array_t::empty()`
 
-    @note This function does not return whether a string stored as JSON value
-    is empty - it returns whether the JSON container itself is empty which is
-    false in the case of a string.
+    @liveexample{The following code uses `empty()` to check if a JSON
+    object contains any elements.,empty}
 
     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
     the Container concept; that is, their `empty()` functions have constant
     complexity.
 
+    @iterators No changes.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @note This function does not return whether a string stored as JSON value
+    is empty - it returns whether the JSON container itself is empty which is
+    false in the case of a string.
+
     @requirement This function helps `basic_json` satisfying the
     [Container](http://en.cppreference.com/w/cpp/concept/Container)
     requirements:
     - The complexity is constant.
     - Has the semantics of `begin() == end()`.
 
-    @liveexample{The following code uses `empty()` to check if a JSON
-    object contains any elements.,empty}
-
     @sa @ref size() -- returns the number of elements
 
     @since version 1.0.0
@@ -5038,23 +11342,27 @@
             object      | result of function object_t::size()
             array       | result of function array_t::size()
 
-    @note This function does not return the length of a string stored as JSON
-    value - it returns the number of elements in the JSON value which is 1 in
-    the case of a string.
+    @liveexample{The following code calls `size()` on the different value
+    types.,size}
 
     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
     the Container concept; that is, their size() functions have constant
     complexity.
 
+    @iterators No changes.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @note This function does not return the length of a string stored as JSON
+    value - it returns the number of elements in the JSON value which is 1 in
+    the case of a string.
+
     @requirement This function helps `basic_json` satisfying the
     [Container](http://en.cppreference.com/w/cpp/concept/Container)
     requirements:
     - The complexity is constant.
     - Has the semantics of `std::distance(begin(), end())`.
 
-    @liveexample{The following code calls `size()` on the different value
-    types.,size}
-
     @sa @ref empty() -- checks whether the container is empty
     @sa @ref max_size() -- returns the maximal number of elements
 
@@ -5108,10 +11416,17 @@
             object      | result of function `object_t::max_size()`
             array       | result of function `array_t::max_size()`
 
+    @liveexample{The following code calls `max_size()` on the different value
+    types. Note the output is implementation specific.,max_size}
+
     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
     the Container concept; that is, their `max_size()` functions have constant
     complexity.
 
+    @iterators No changes.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
     @requirement This function helps `basic_json` satisfying the
     [Container](http://en.cppreference.com/w/cpp/concept/Container)
     requirements:
@@ -5119,9 +11434,6 @@
     - Has the semantics of returning `b.size()` where `b` is the largest
       possible JSON value.
 
-    @liveexample{The following code calls `max_size()` on the different value
-    types. Note the output is implementation specific.,max_size}
-
     @sa @ref size() -- returns the number of elements
 
     @since version 1.0.0
@@ -5164,7 +11476,8 @@
     @brief clears the contents
 
     Clears the content of a JSON value and resets it to the default value as
-    if @ref basic_json(value_t) would have been called:
+    if @ref basic_json(value_t) would have been called with the current value
+    type from @ref type():
 
     Value type  | initial value
     ----------- | -------------
@@ -5175,11 +11488,24 @@
     object      | `{}`
     array       | `[]`
 
-    @complexity Linear in the size of the JSON value.
+    @post Has the same effect as calling
+    @code {.cpp}
+    *this = basic_json(type());
+    @endcode
 
     @liveexample{The example below shows the effect of `clear()` to different
     JSON types.,clear}
 
+    @complexity Linear in the size of the JSON value.
+
+    @iterators All iterators, pointers and references related to this container
+               are invalidated.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @sa @ref basic_json(value_t) -- constructor that creates an object with the
+        same value than calling `clear()`
+
     @since version 1.0.0
     */
     void clear() noexcept
@@ -5229,9 +11555,7 @@
             }
 
             default:
-            {
                 break;
-            }
         }
     }
 
@@ -5244,7 +11568,7 @@
 
     @param[in] val the value to add to the JSON array
 
-    @throw std::domain_error when called on a type other than JSON array or
+    @throw type_error.308 when called on a type other than JSON array or
     null; example: `"cannot use push_back() with number"`
 
     @complexity Amortized constant.
@@ -5258,9 +11582,9 @@
     void push_back(basic_json&& val)
     {
         // push_back only works for null objects or arrays
-        if (not(is_null() or is_array()))
+        if (JSON_UNLIKELY(not(is_null() or is_array())))
         {
-            JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
+            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
         }
 
         // transform null object into an array
@@ -5294,9 +11618,9 @@
     void push_back(const basic_json& val)
     {
         // push_back only works for null objects or arrays
-        if (not(is_null() or is_array()))
+        if (JSON_UNLIKELY(not(is_null() or is_array())))
         {
-            JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
+            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
         }
 
         // transform null object into an array
@@ -5330,7 +11654,7 @@
 
     @param[in] val the value to add to the JSON object
 
-    @throw std::domain_error when called on a type other than JSON object or
+    @throw type_error.308 when called on a type other than JSON object or
     null; example: `"cannot use push_back() with number"`
 
     @complexity Logarithmic in the size of the container, O(log(`size()`)).
@@ -5344,9 +11668,9 @@
     void push_back(const typename object_t::value_type& val)
     {
         // push_back only works for null objects or objects
-        if (not(is_null() or is_object()))
+        if (JSON_UNLIKELY(not(is_null() or is_object())))
         {
-            JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
+            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
         }
 
         // transform null object into an object
@@ -5384,7 +11708,7 @@
     @ref push_back(const typename object_t::value_type&). Otherwise, @a init
     is converted to a JSON value and added using @ref push_back(basic_json&&).
 
-    @param init  an initializer list
+    @param[in] init  an initializer list
 
     @complexity Linear in the size of the initializer list @a init.
 
@@ -5396,12 +11720,13 @@
     @liveexample{The example shows how initializer lists are treated as
     objects when possible.,push_back__initializer_list}
     */
-    void push_back(std::initializer_list<basic_json> init)
+    void push_back(initializer_list_t init)
     {
-        if (is_object() and init.size() == 2 and init.begin()->is_string())
+        if (is_object() and init.size() == 2 and (*init.begin())->is_string())
         {
-            const string_t key = *init.begin();
-            push_back(typename object_t::value_type(key, *(init.begin() + 1)));
+            basic_json&& key = init.begin()->moved_or_copied();
+            push_back(typename object_t::value_type(
+                          std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
         }
         else
         {
@@ -5411,9 +11736,9 @@
 
     /*!
     @brief add an object to an object
-    @copydoc push_back(std::initializer_list<basic_json>)
+    @copydoc push_back(initializer_list_t)
     */
-    reference operator+=(std::initializer_list<basic_json> init)
+    reference operator+=(initializer_list_t init)
     {
         push_back(init);
         return *this;
@@ -5429,7 +11754,7 @@
     @param[in] args arguments to forward to a constructor of @ref basic_json
     @tparam Args compatible types to create a @ref basic_json object
 
-    @throw std::domain_error when called on a type other than JSON array or
+    @throw type_error.311 when called on a type other than JSON array or
     null; example: `"cannot use emplace_back() with number"`
 
     @complexity Amortized constant.
@@ -5444,9 +11769,9 @@
     void emplace_back(Args&& ... args)
     {
         // emplace_back only works for null objects or arrays
-        if (not(is_null() or is_array()))
+        if (JSON_UNLIKELY(not(is_null() or is_array())))
         {
-            JSON_THROW(std::domain_error("cannot use emplace_back() with " + type_name()));
+            JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
         }
 
         // transform null object into an array
@@ -5476,7 +11801,7 @@
             already-existing element if no insertion happened, and a bool
             denoting whether the insertion took place.
 
-    @throw std::domain_error when called on a type other than JSON object or
+    @throw type_error.311 when called on a type other than JSON object or
     null; example: `"cannot use emplace() with number"`
 
     @complexity Logarithmic in the size of the container, O(log(`size()`)).
@@ -5492,9 +11817,9 @@
     std::pair<iterator, bool> emplace(Args&& ... args)
     {
         // emplace only works for null objects or arrays
-        if (not(is_null() or is_object()))
+        if (JSON_UNLIKELY(not(is_null() or is_object())))
         {
-            JSON_THROW(std::domain_error("cannot use emplace() with " + type_name()));
+            JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
         }
 
         // transform null object into an object
@@ -5525,10 +11850,10 @@
     @param[in] val element to insert
     @return iterator pointing to the inserted @a val.
 
-    @throw std::domain_error if called on JSON values other than arrays;
+    @throw type_error.309 if called on JSON values other than arrays;
     example: `"cannot use insert() with string"`
-    @throw std::domain_error if @a pos is not an iterator of *this; example:
-    `"iterator does not fit current value"`
+    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+    example: `"iterator does not fit current value"`
 
     @complexity Constant plus linear in the distance between @a pos and end of
     the container.
@@ -5540,12 +11865,12 @@
     iterator insert(const_iterator pos, const basic_json& val)
     {
         // insert only works for arrays
-        if (is_array())
+        if (JSON_LIKELY(is_array()))
         {
             // check if iterator pos fits to this JSON value
-            if (pos.m_object != this)
+            if (JSON_UNLIKELY(pos.m_object != this))
             {
-                JSON_THROW(std::domain_error("iterator does not fit current value"));
+                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
             }
 
             // insert to array and return iterator
@@ -5554,7 +11879,7 @@
             return result;
         }
 
-        JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
+        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
     }
 
     /*!
@@ -5578,10 +11903,10 @@
     @return iterator pointing to the first element inserted, or @a pos if
     `cnt==0`
 
-    @throw std::domain_error if called on JSON values other than arrays;
-    example: `"cannot use insert() with string"`
-    @throw std::domain_error if @a pos is not an iterator of *this; example:
-    `"iterator does not fit current value"`
+    @throw type_error.309 if called on JSON values other than arrays; example:
+    `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+    example: `"iterator does not fit current value"`
 
     @complexity Linear in @a cnt plus linear in the distance between @a pos
     and end of the container.
@@ -5593,12 +11918,12 @@
     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
     {
         // insert only works for arrays
-        if (is_array())
+        if (JSON_LIKELY(is_array()))
         {
             // check if iterator pos fits to this JSON value
-            if (pos.m_object != this)
+            if (JSON_UNLIKELY(pos.m_object != this))
             {
-                JSON_THROW(std::domain_error("iterator does not fit current value"));
+                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
             }
 
             // insert to array and return iterator
@@ -5607,7 +11932,7 @@
             return result;
         }
 
-        JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
+        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
     }
 
     /*!
@@ -5620,13 +11945,13 @@
     @param[in] first begin of the range of elements to insert
     @param[in] last end of the range of elements to insert
 
-    @throw std::domain_error if called on JSON values other than arrays;
-    example: `"cannot use insert() with string"`
-    @throw std::domain_error if @a pos is not an iterator of *this; example:
-    `"iterator does not fit current value"`
-    @throw std::domain_error if @a first and @a last do not belong to the same
-    JSON value; example: `"iterators do not fit"`
-    @throw std::domain_error if @a first or @a last are iterators into
+    @throw type_error.309 if called on JSON values other than arrays; example:
+    `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+    example: `"iterator does not fit current value"`
+    @throw invalid_iterator.210 if @a first and @a last do not belong to the
+    same JSON value; example: `"iterators do not fit"`
+    @throw invalid_iterator.211 if @a first or @a last are iterators into
     container for which insert is called; example: `"passed iterators may not
     belong to container"`
 
@@ -5643,26 +11968,26 @@
     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
     {
         // insert only works for arrays
-        if (not is_array())
+        if (JSON_UNLIKELY(not is_array()))
         {
-            JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
+            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
         }
 
         // check if iterator pos fits to this JSON value
-        if (pos.m_object != this)
+        if (JSON_UNLIKELY(pos.m_object != this))
         {
-            JSON_THROW(std::domain_error("iterator does not fit current value"));
+            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
         }
 
         // check if range iterators belong to the same JSON object
-        if (first.m_object != last.m_object)
+        if (JSON_UNLIKELY(first.m_object != last.m_object))
         {
-            JSON_THROW(std::domain_error("iterators do not fit"));
+            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
         }
 
-        if (first.m_object == this or last.m_object == this)
+        if (JSON_UNLIKELY(first.m_object == this or last.m_object == this))
         {
-            JSON_THROW(std::domain_error("passed iterators may not belong to container"));
+            JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
         }
 
         // insert to array and return iterator
@@ -5683,10 +12008,10 @@
     the end() iterator
     @param[in] ilist initializer list to insert the values from
 
-    @throw std::domain_error if called on JSON values other than arrays;
-    example: `"cannot use insert() with string"`
-    @throw std::domain_error if @a pos is not an iterator of *this; example:
-    `"iterator does not fit current value"`
+    @throw type_error.309 if called on JSON values other than arrays; example:
+    `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+    example: `"iterator does not fit current value"`
 
     @return iterator pointing to the first element inserted, or @a pos if
     `ilist` is empty
@@ -5698,27 +12023,178 @@
 
     @since version 1.0.0
     */
-    iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
+    iterator insert(const_iterator pos, initializer_list_t ilist)
     {
         // insert only works for arrays
-        if (not is_array())
+        if (JSON_UNLIKELY(not is_array()))
         {
-            JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
+            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
         }
 
         // check if iterator pos fits to this JSON value
-        if (pos.m_object != this)
+        if (JSON_UNLIKELY(pos.m_object != this))
         {
-            JSON_THROW(std::domain_error("iterator does not fit current value"));
+            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
         }
 
         // insert to array and return iterator
         iterator result(this);
-        result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
+        result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
         return result;
     }
 
     /*!
+    @brief inserts elements
+
+    Inserts elements from range `[first, last)`.
+
+    @param[in] first begin of the range of elements to insert
+    @param[in] last end of the range of elements to insert
+
+    @throw type_error.309 if called on JSON values other than objects; example:
+    `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if iterator @a first or @a last does does not
+    point to an object; example: `"iterators first and last must point to
+    objects"`
+    @throw invalid_iterator.210 if @a first and @a last do not belong to the
+    same JSON value; example: `"iterators do not fit"`
+
+    @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
+    of elements to insert.
+
+    @liveexample{The example shows how `insert()` is used.,insert__range_object}
+
+    @since version 3.0.0
+    */
+    void insert(const_iterator first, const_iterator last)
+    {
+        // insert only works for objects
+        if (JSON_UNLIKELY(not is_object()))
+        {
+            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+        }
+
+        // check if range iterators belong to the same JSON object
+        if (JSON_UNLIKELY(first.m_object != last.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+        }
+
+        // passed iterators must belong to objects
+        if (JSON_UNLIKELY(not first.m_object->is_object()
+                          or not last.m_object->is_object()))
+        {
+            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+        }
+
+        m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
+    }
+
+    /*!
+    @brief updates a JSON object from another object, overwriting existing keys
+
+    Inserts all values from JSON object @a j and overwrites existing keys.
+
+    @param[in] j  JSON object to read values from
+
+    @throw type_error.312 if called on JSON values other than objects; example:
+    `"cannot use update() with string"`
+
+    @complexity O(N*log(size() + N)), where N is the number of elements to
+                insert.
+
+    @liveexample{The example shows how `update()` is used.,update}
+
+    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
+
+    @since version 3.0.0
+    */
+    void update(const_reference j)
+    {
+        // implicitly convert null value to an empty object
+        if (is_null())
+        {
+            m_type = value_t::object;
+            m_value.object = create<object_t>();
+            assert_invariant();
+        }
+
+        if (JSON_UNLIKELY(not is_object()))
+        {
+            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
+        }
+        if (JSON_UNLIKELY(not j.is_object()))
+        {
+            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
+        }
+
+        for (auto it = j.begin(); it != j.end(); ++it)
+        {
+            m_value.object->operator[](it.key()) = it.value();
+        }
+    }
+
+    /*!
+    @brief updates a JSON object from another object, overwriting existing keys
+
+    Inserts all values from from range `[first, last)` and overwrites existing
+    keys.
+
+    @param[in] first begin of the range of elements to insert
+    @param[in] last end of the range of elements to insert
+
+    @throw type_error.312 if called on JSON values other than objects; example:
+    `"cannot use update() with string"`
+    @throw invalid_iterator.202 if iterator @a first or @a last does does not
+    point to an object; example: `"iterators first and last must point to
+    objects"`
+    @throw invalid_iterator.210 if @a first and @a last do not belong to the
+    same JSON value; example: `"iterators do not fit"`
+
+    @complexity O(N*log(size() + N)), where N is the number of elements to
+                insert.
+
+    @liveexample{The example shows how `update()` is used__range.,update}
+
+    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
+
+    @since version 3.0.0
+    */
+    void update(const_iterator first, const_iterator last)
+    {
+        // implicitly convert null value to an empty object
+        if (is_null())
+        {
+            m_type = value_t::object;
+            m_value.object = create<object_t>();
+            assert_invariant();
+        }
+
+        if (JSON_UNLIKELY(not is_object()))
+        {
+            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
+        }
+
+        // check if range iterators belong to the same JSON object
+        if (JSON_UNLIKELY(first.m_object != last.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+        }
+
+        // passed iterators must belong to objects
+        if (JSON_UNLIKELY(not first.m_object->is_object()
+                          or not first.m_object->is_object()))
+        {
+            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+        }
+
+        for (auto it = first; it != last; ++it)
+        {
+            m_value.object->operator[](it.key()) = it.value();
+        }
+    }
+
+    /*!
     @brief exchanges the values
 
     Exchanges the contents of the JSON value with those of @a other. Does not
@@ -5757,8 +12233,8 @@
 
     @param[in,out] other array to exchange the contents with
 
-    @throw std::domain_error when JSON value is not an array; example:
-    `"cannot use swap() with string"`
+    @throw type_error.310 when JSON value is not an array; example: `"cannot
+    use swap() with string"`
 
     @complexity Constant.
 
@@ -5770,13 +12246,13 @@
     void swap(array_t& other)
     {
         // swap only works for arrays
-        if (is_array())
+        if (JSON_LIKELY(is_array()))
         {
             std::swap(*(m_value.array), other);
         }
         else
         {
-            JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
+            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
         }
     }
 
@@ -5790,7 +12266,7 @@
 
     @param[in,out] other object to exchange the contents with
 
-    @throw std::domain_error when JSON value is not an object; example:
+    @throw type_error.310 when JSON value is not an object; example:
     `"cannot use swap() with string"`
 
     @complexity Constant.
@@ -5803,13 +12279,13 @@
     void swap(object_t& other)
     {
         // swap only works for objects
-        if (is_object())
+        if (JSON_LIKELY(is_object()))
         {
             std::swap(*(m_value.object), other);
         }
         else
         {
-            JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
+            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
         }
     }
 
@@ -5823,7 +12299,7 @@
 
     @param[in,out] other string to exchange the contents with
 
-    @throw std::domain_error when JSON value is not a string; example: `"cannot
+    @throw type_error.310 when JSON value is not a string; example: `"cannot
     use swap() with boolean"`
 
     @complexity Constant.
@@ -5836,13 +12312,13 @@
     void swap(string_t& other)
     {
         // swap only works for strings
-        if (is_string())
+        if (JSON_LIKELY(is_string()))
         {
             std::swap(*(m_value.string), other);
         }
         else
         {
-            JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
+            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
         }
     }
 
@@ -5861,17 +12337,33 @@
 
     Compares two JSON values for equality according to the following rules:
     - Two JSON values are equal if (1) they are from the same type and (2)
-      their stored values are the same.
+      their stored values are the same according to their respective
+      `operator==`.
     - Integer and floating-point numbers are automatically converted before
-      comparison. Floating-point numbers are compared indirectly: two
-      floating-point numbers `f1` and `f2` are considered equal if neither
-      `f1 > f2` nor `f2 > f1` holds.
+      comparison. Note than two NaN values are always treated as unequal.
     - Two JSON null values are equal.
 
+    @note Floating-point inside JSON values numbers are compared with
+    `json::number_float_t::operator==` which is `double::operator==` by
+    default. To compare floating-point while respecting an epsilon, an alternative
+    [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
+    could be used, for instance
+    @code {.cpp}
+    template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
+    inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
+    {
+        return std::abs(a - b) <= epsilon;
+    }
+    @endcode
+
+    @note NaN values never compare equal to themselves or to other NaN values.
+
     @param[in] lhs  first JSON value to consider
     @param[in] rhs  second JSON value to consider
     @return whether the values @a lhs and @a rhs are equal
 
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
     @complexity Linear.
 
     @liveexample{The example demonstrates comparing several JSON
@@ -5889,66 +12381,56 @@
             switch (lhs_type)
             {
                 case value_t::array:
-                {
-                    return *lhs.m_value.array == *rhs.m_value.array;
-                }
+                    return (*lhs.m_value.array == *rhs.m_value.array);
+
                 case value_t::object:
-                {
-                    return *lhs.m_value.object == *rhs.m_value.object;
-                }
+                    return (*lhs.m_value.object == *rhs.m_value.object);
+
                 case value_t::null:
-                {
                     return true;
-                }
+
                 case value_t::string:
-                {
-                    return *lhs.m_value.string == *rhs.m_value.string;
-                }
+                    return (*lhs.m_value.string == *rhs.m_value.string);
+
                 case value_t::boolean:
-                {
-                    return lhs.m_value.boolean == rhs.m_value.boolean;
-                }
+                    return (lhs.m_value.boolean == rhs.m_value.boolean);
+
                 case value_t::number_integer:
-                {
-                    return lhs.m_value.number_integer == rhs.m_value.number_integer;
-                }
+                    return (lhs.m_value.number_integer == rhs.m_value.number_integer);
+
                 case value_t::number_unsigned:
-                {
-                    return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
-                }
+                    return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
+
                 case value_t::number_float:
-                {
-                    return lhs.m_value.number_float == rhs.m_value.number_float;
-                }
+                    return (lhs.m_value.number_float == rhs.m_value.number_float);
+
                 default:
-                {
                     return false;
-                }
             }
         }
         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
         {
-            return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
+            return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
         }
         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
         {
-            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
+            return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
         }
         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
         {
-            return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
+            return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
         }
         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
         {
-            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
+            return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
         }
         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
         {
-            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
+            return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
         }
         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
         {
-            return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
+            return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
         }
 
         return false;
@@ -5987,6 +12469,8 @@
 
     @complexity Linear.
 
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
     @liveexample{The example demonstrates comparing several JSON
     types.,operator__notequal}
 
@@ -6038,6 +12522,8 @@
 
     @complexity Linear.
 
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
     @liveexample{The example demonstrates comparing several JSON
     types.,operator__less}
 
@@ -6053,41 +12539,31 @@
             switch (lhs_type)
             {
                 case value_t::array:
-                {
-                    return *lhs.m_value.array < *rhs.m_value.array;
-                }
+                    return (*lhs.m_value.array) < (*rhs.m_value.array);
+
                 case value_t::object:
-                {
                     return *lhs.m_value.object < *rhs.m_value.object;
-                }
+
                 case value_t::null:
-                {
                     return false;
-                }
+
                 case value_t::string:
-                {
                     return *lhs.m_value.string < *rhs.m_value.string;
-                }
+
                 case value_t::boolean:
-                {
                     return lhs.m_value.boolean < rhs.m_value.boolean;
-                }
+
                 case value_t::number_integer:
-                {
                     return lhs.m_value.number_integer < rhs.m_value.number_integer;
-                }
+
                 case value_t::number_unsigned:
-                {
                     return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
-                }
+
                 case value_t::number_float:
-                {
                     return lhs.m_value.number_float < rhs.m_value.number_float;
-                }
+
                 default:
-                {
                     return false;
-                }
             }
         }
         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
@@ -6122,6 +12598,28 @@
     }
 
     /*!
+    @brief comparison: less than
+    @copydoc operator<(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return (lhs < basic_json(rhs));
+    }
+
+    /*!
+    @brief comparison: less than
+    @copydoc operator<(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return (basic_json(lhs) < rhs);
+    }
+
+    /*!
     @brief comparison: less than or equal
 
     Compares whether one JSON value @a lhs is less than or equal to another
@@ -6133,6 +12631,8 @@
 
     @complexity Linear.
 
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
     @liveexample{The example demonstrates comparing several JSON
     types.,operator__greater}
 
@@ -6144,6 +12644,28 @@
     }
 
     /*!
+    @brief comparison: less than or equal
+    @copydoc operator<=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return (lhs <= basic_json(rhs));
+    }
+
+    /*!
+    @brief comparison: less than or equal
+    @copydoc operator<=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return (basic_json(lhs) <= rhs);
+    }
+
+    /*!
     @brief comparison: greater than
 
     Compares whether one JSON value @a lhs is greater than another
@@ -6155,6 +12677,8 @@
 
     @complexity Linear.
 
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
     @liveexample{The example demonstrates comparing several JSON
     types.,operator__lessequal}
 
@@ -6166,6 +12690,28 @@
     }
 
     /*!
+    @brief comparison: greater than
+    @copydoc operator>(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return (lhs > basic_json(rhs));
+    }
+
+    /*!
+    @brief comparison: greater than
+    @copydoc operator>(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return (basic_json(lhs) > rhs);
+    }
+
+    /*!
     @brief comparison: greater than or equal
 
     Compares whether one JSON value @a lhs is greater than or equal to another
@@ -6177,6 +12723,8 @@
 
     @complexity Linear.
 
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
     @liveexample{The example demonstrates comparing several JSON
     types.,operator__greaterequal}
 
@@ -6187,8 +12735,29 @@
         return not (lhs < rhs);
     }
 
-    /// @}
+    /*!
+    @brief comparison: greater than or equal
+    @copydoc operator>=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return (lhs >= basic_json(rhs));
+    }
 
+    /*!
+    @brief comparison: greater than or equal
+    @copydoc operator>=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return (basic_json(lhs) >= rhs);
+    }
+
+    /// @}
 
     ///////////////////
     // serialization //
@@ -6201,11 +12770,17 @@
     @brief serialize to stream
 
     Serialize the given JSON value @a j to the output stream @a o. The JSON
-    value will be serialized using the @ref dump member function. The
-    indentation of the output can be controlled with the member variable
-    `width` of the output stream @a o. For instance, using the manipulator
-    `std::setw(4)` on @a o sets the indentation level to `4` and the
-    serialization result is the same as calling `dump(4)`.
+    value will be serialized using the @ref dump member function.
+
+    - The indentation of the output can be controlled with the member variable
+      `width` of the output stream @a o. For instance, using the manipulator
+      `std::setw(4)` on @a o sets the indentation level to `4` and the
+      serialization result is the same as calling `dump(4)`.
+
+    - The indentation characrer can be controlled with the member variable
+      `fill` of the output stream @a o. For instance, the manipulator
+      `std::setfill('\\t')` sets indentation to use a tab character rather than
+      the default space character.
 
     @param[in,out] o  stream to serialize to
     @param[in] j  JSON value to serialize
@@ -6217,7 +12792,7 @@
     @liveexample{The example below shows the serialization with different
     parameters to `width` to adjust the indentation level.,operator_serialize}
 
-    @since version 1.0.0
+    @since version 1.0.0; indentaction character added in version 3.0.0
     */
     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
     {
@@ -6229,15 +12804,20 @@
         o.width(0);
 
         // do the actual serialization
-        j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
-
+        serializer s(detail::output_adapter<char>(o), o.fill());
+        s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
         return o;
     }
 
     /*!
     @brief serialize to stream
-    @copydoc operator<<(std::ostream&, const basic_json&)
+    @deprecated This stream operator is deprecated and will be removed in a
+                future version of the library. Please use
+                @ref operator<<(std::ostream&, const basic_json&)
+                instead; that is, replace calls like `j >> o;` with `o << j;`.
+    @since version 1.0.0; deprecated since version 3.0.0
     */
+    JSON_DEPRECATED
     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
     {
         return o << j;
@@ -6254,21 +12834,47 @@
     /// @{
 
     /*!
-    @brief deserialize from an array
+    @brief deserialize from a compatible input
 
-    This function reads from an array of 1-byte values.
+    This function reads from a compatible input. Examples are:
+    - an array of 1-byte values
+    - strings with character/literal type with size of 1 byte
+    - input streams
+    - container with contiguous storage of 1-byte values. Compatible container
+      types include `std::vector`, `std::string`, `std::array`,
+      `std::valarray`, and `std::initializer_list`. Furthermore, C-style
+      arrays can be used with `std::begin()`/`std::end()`. User-defined
+      containers can be used as long as they implement random-access iterators
+      and a contiguous storage.
 
     @pre Each element of the container has a size of 1 byte. Violating this
     precondition yields undefined behavior. **This precondition is enforced
     with a static assertion.**
 
-    @param[in] array  array to read from
+    @pre The container storage is contiguous. Violating this precondition
+    yields undefined behavior. **This precondition is enforced with an
+    assertion.**
+    @pre Each element of the container has a size of 1 byte. Violating this
+    precondition yields undefined behavior. **This precondition is enforced
+    with a static assertion.**
+
+    @warning There is no way to enforce all preconditions at compile-time. If
+             the function is called with a noncompliant container and with
+             assertions switched off, the behavior is undefined and will most
+             likely yield segmentation violation.
+
+    @param[in] i  input to read from
     @param[in] cb  a parser callback function of type @ref parser_callback_t
     which is used to control the deserialization by filtering unwanted values
     (optional)
 
     @return result of the deserialization
 
+    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
+    of input; expected string literal""`
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+
     @complexity Linear in the length of the input. The parser is a predictive
     LL(1) parser. The complexity can be higher if the parser callback function
     @a cb has a super-linear complexity.
@@ -6278,90 +12884,46 @@
     @liveexample{The example below demonstrates the `parse()` function reading
     from an array.,parse__array__parser_callback_t}
 
-    @since version 2.0.3
-    */
-    template<class T, std::size_t N>
-    static basic_json parse(T (&array)[N],
-                            const parser_callback_t cb = nullptr)
-    {
-        // delegate the call to the iterator-range parse overload
-        return parse(std::begin(array), std::end(array), cb);
-    }
-
-    /*!
-    @brief deserialize from string literal
-
-    @tparam CharT character/literal type with size of 1 byte
-    @param[in] s  string literal to read a serialized JSON value from
-    @param[in] cb a parser callback function of type @ref parser_callback_t
-    which is used to control the deserialization by filtering unwanted values
-    (optional)
-
-    @return result of the deserialization
-
-    @complexity Linear in the length of the input. The parser is a predictive
-    LL(1) parser. The complexity can be higher if the parser callback function
-    @a cb has a super-linear complexity.
-
-    @note A UTF-8 byte order mark is silently ignored.
-    @note String containers like `std::string` or @ref string_t can be parsed
-          with @ref parse(const ContiguousContainer&, const parser_callback_t)
-
     @liveexample{The example below demonstrates the `parse()` function with
     and without callback function.,parse__string__parser_callback_t}
 
-    @sa @ref parse(std::istream&, const parser_callback_t) for a version that
-    reads from an input stream
-
-    @since version 1.0.0 (originally for @ref string_t)
-    */
-    template<typename CharT, typename std::enable_if<
-                 std::is_pointer<CharT>::value and
-                 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
-                 sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
-    static basic_json parse(const CharT s,
-                            const parser_callback_t cb = nullptr)
-    {
-        return parser(reinterpret_cast<const char*>(s), cb).parse();
-    }
-
-    /*!
-    @brief deserialize from stream
-
-    @param[in,out] i  stream to read a serialized JSON value from
-    @param[in] cb a parser callback function of type @ref parser_callback_t
-    which is used to control the deserialization by filtering unwanted values
-    (optional)
-
-    @return result of the deserialization
-
-    @complexity Linear in the length of the input. The parser is a predictive
-    LL(1) parser. The complexity can be higher if the parser callback function
-    @a cb has a super-linear complexity.
-
-    @note A UTF-8 byte order mark is silently ignored.
-
     @liveexample{The example below demonstrates the `parse()` function with
     and without callback function.,parse__istream__parser_callback_t}
 
-    @sa @ref parse(const CharT, const parser_callback_t) for a version
-    that reads from a string
+    @liveexample{The example below demonstrates the `parse()` function reading
+    from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
 
-    @since version 1.0.0
+    @since version 2.0.3 (contiguous containers)
     */
-    static basic_json parse(std::istream& i,
-                            const parser_callback_t cb = nullptr)
+    static basic_json parse(detail::input_adapter i,
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true)
     {
-        return parser(i, cb).parse();
+        basic_json result;
+        parser(i, cb, allow_exceptions).parse(true, result);
+        return result;
     }
 
     /*!
-    @copydoc parse(std::istream&, const parser_callback_t)
+    @copydoc basic_json parse(detail::input_adapter, const parser_callback_t)
     */
-    static basic_json parse(std::istream&& i,
-                            const parser_callback_t cb = nullptr)
+    static basic_json parse(detail::input_adapter& i,
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true)
     {
-        return parser(i, cb).parse();
+        basic_json result;
+        parser(i, cb, allow_exceptions).parse(true, result);
+        return result;
+    }
+
+    static bool accept(detail::input_adapter i)
+    {
+        return parser(i).accept(true);
+    }
+
+    static bool accept(detail::input_adapter& i)
+    {
+        return parser(i).accept(true);
     }
 
     /*!
@@ -6394,6 +12956,10 @@
 
     @return result of the deserialization
 
+    @throw parse_error.101 in case of an unexpected token
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+
     @complexity Linear in the length of the input. The parser is a predictive
     LL(1) parser. The complexity can be higher if the parser callback function
     @a cb has a super-linear complexity.
@@ -6410,82 +12976,35 @@
                      std::random_access_iterator_tag,
                      typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
     static basic_json parse(IteratorType first, IteratorType last,
-                            const parser_callback_t cb = nullptr)
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true)
     {
-        // assertion to check that the iterator range is indeed contiguous,
-        // see http://stackoverflow.com/a/35008842/266378 for more discussion
-        assert(std::accumulate(first, last, std::pair<bool, int>(true, 0),
-                               [&first](std::pair<bool, int> res, decltype(*first) val)
-        {
-            res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
-            return res;
-        }).first);
+        basic_json result;
+        parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
+        return result;
+    }
 
-        // assertion to check that each element is 1 byte long
-        static_assert(sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
-                      "each element in the iterator range must have the size of 1 byte");
-
-        // if iterator range is empty, create a parser with an empty string
-        // to generate "unexpected EOF" error message
-        if (std::distance(first, last) <= 0)
-        {
-            return parser("").parse();
-        }
-
-        return parser(first, last, cb).parse();
+    template<class IteratorType, typename std::enable_if<
+                 std::is_base_of<
+                     std::random_access_iterator_tag,
+                     typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
+    static bool accept(IteratorType first, IteratorType last)
+    {
+        return parser(detail::input_adapter(first, last)).accept(true);
     }
 
     /*!
-    @brief deserialize from a container with contiguous storage
-
-    This function reads from a container with contiguous storage of 1-byte
-    values. Compatible container types include `std::vector`, `std::string`,
-    `std::array`, and `std::initializer_list`. User-defined containers can be
-    used as long as they implement random-access iterators and a contiguous
-    storage.
-
-    @pre The container storage is contiguous. Violating this precondition
-    yields undefined behavior. **This precondition is enforced with an
-    assertion.**
-    @pre Each element of the container has a size of 1 byte. Violating this
-    precondition yields undefined behavior. **This precondition is enforced
-    with a static assertion.**
-
-    @warning There is no way to enforce all preconditions at compile-time. If
-             the function is called with a noncompliant container and with
-             assertions switched off, the behavior is undefined and will most
-             likely yield segmentation violation.
-
-    @tparam ContiguousContainer container type with contiguous storage
-    @param[in] c  container to read from
-    @param[in] cb  a parser callback function of type @ref parser_callback_t
-    which is used to control the deserialization by filtering unwanted values
-    (optional)
-
-    @return result of the deserialization
-
-    @complexity Linear in the length of the input. The parser is a predictive
-    LL(1) parser. The complexity can be higher if the parser callback function
-    @a cb has a super-linear complexity.
-
-    @note A UTF-8 byte order mark is silently ignored.
-
-    @liveexample{The example below demonstrates the `parse()` function reading
-    from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
-
-    @since version 2.0.3
+    @brief deserialize from stream
+    @deprecated This stream operator is deprecated and will be removed in a
+                future version of the library. Please use
+                @ref operator>>(std::istream&, basic_json&)
+                instead; that is, replace calls like `j << i;` with `i >> j;`.
+    @since version 1.0.0; deprecated since version 3.0.0
     */
-    template<class ContiguousContainer, typename std::enable_if<
-                 not std::is_pointer<ContiguousContainer>::value and
-                 std::is_base_of<
-                     std::random_access_iterator_tag,
-                     typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
-                 , int>::type = 0>
-    static basic_json parse(const ContiguousContainer& c,
-                            const parser_callback_t cb = nullptr)
+    JSON_DEPRECATED
+    friend std::istream& operator<<(basic_json& j, std::istream& i)
     {
-        // delegate the call to the iterator-range parse overload
-        return parse(std::begin(c), std::end(c), cb);
+        return operator>>(i, j);
     }
 
     /*!
@@ -6496,7 +13015,9 @@
     @param[in,out] i  input stream to read a serialized JSON value from
     @param[in,out] j  JSON value to write the deserialized input to
 
-    @throw std::invalid_argument in case of parse errors
+    @throw parse_error.101 in case of an unexpected token
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
 
     @complexity Linear in the length of the input. The parser is a predictive
     LL(1) parser.
@@ -6511,1538 +13032,14 @@
 
     @since version 1.0.0
     */
-    friend std::istream& operator<<(basic_json& j, std::istream& i)
-    {
-        j = parser(i).parse();
-        return i;
-    }
-
-    /*!
-    @brief deserialize from stream
-    @copydoc operator<<(basic_json&, std::istream&)
-    */
     friend std::istream& operator>>(std::istream& i, basic_json& j)
     {
-        j = parser(i).parse();
+        parser(detail::input_adapter(i)).parse(false, j);
         return i;
     }
 
     /// @}
 
-    //////////////////////////////////////////
-    // binary serialization/deserialization //
-    //////////////////////////////////////////
-
-    /// @name binary serialization/deserialization support
-    /// @{
-
-  private:
-    /*!
-    @note Some code in the switch cases has been copied, because otherwise
-          copilers would complain about implicit fallthrough and there is no
-          portable attribute to mute such warnings.
-    */
-    template<typename T>
-    static void add_to_vector(std::vector<uint8_t>& vec, size_t bytes, const T number)
-    {
-        assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8);
-
-        switch (bytes)
-        {
-            case 8:
-            {
-                vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 070) & 0xff));
-                vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 060) & 0xff));
-                vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 050) & 0xff));
-                vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 040) & 0xff));
-                vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
-                vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
-                vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
-                vec.push_back(static_cast<uint8_t>(number & 0xff));
-                break;
-            }
-
-            case 4:
-            {
-                vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
-                vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
-                vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
-                vec.push_back(static_cast<uint8_t>(number & 0xff));
-                break;
-            }
-
-            case 2:
-            {
-                vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
-                vec.push_back(static_cast<uint8_t>(number & 0xff));
-                break;
-            }
-
-            case 1:
-            {
-                vec.push_back(static_cast<uint8_t>(number & 0xff));
-                break;
-            }
-        }
-    }
-
-    /*!
-    @brief take sufficient bytes from a vector to fill an integer variable
-
-    In the context of binary serialization formats, we need to read several
-    bytes from a byte vector and combine them to multi-byte integral data
-    types.
-
-    @param[in] vec  byte vector to read from
-    @param[in] current_index  the position in the vector after which to read
-
-    @return the next sizeof(T) bytes from @a vec, in reverse order as T
-
-    @tparam T the integral return type
-
-    @throw std::out_of_range if there are less than sizeof(T)+1 bytes in the
-           vector @a vec to read
-
-    In the for loop, the bytes from the vector are copied in reverse order into
-    the return value. In the figures below, let sizeof(T)=4 and `i` be the loop
-    variable.
-
-    Precondition:
-
-    vec:   |   |   | a | b | c | d |      T: |   |   |   |   |
-                 ^               ^             ^                ^
-           current_index         i            ptr        sizeof(T)
-
-    Postcondition:
-
-    vec:   |   |   | a | b | c | d |      T: | d | c | b | a |
-                 ^   ^                                     ^
-                 |   i                                    ptr
-           current_index
-
-    @sa Code adapted from <http://stackoverflow.com/a/41031865/266378>.
-    */
-    template<typename T>
-    static T get_from_vector(const std::vector<uint8_t>& vec, const size_t current_index)
-    {
-        if (current_index + sizeof(T) + 1 > vec.size())
-        {
-            JSON_THROW(std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector"));
-        }
-
-        T result;
-        auto* ptr = reinterpret_cast<uint8_t*>(&result);
-        for (size_t i = 0; i < sizeof(T); ++i)
-        {
-            *ptr++ = vec[current_index + sizeof(T) - i];
-        }
-        return result;
-    }
-
-    /*!
-    @brief create a MessagePack serialization of a given JSON value
-
-    This is a straightforward implementation of the MessagePack specification.
-
-    @param[in] j  JSON value to serialize
-    @param[in,out] v  byte vector to write the serialization to
-
-    @sa https://github.com/msgpack/msgpack/blob/master/spec.md
-    */
-    static void to_msgpack_internal(const basic_json& j, std::vector<uint8_t>& v)
-    {
-        switch (j.type())
-        {
-            case value_t::null:
-            {
-                // nil
-                v.push_back(0xc0);
-                break;
-            }
-
-            case value_t::boolean:
-            {
-                // true and false
-                v.push_back(j.m_value.boolean ? 0xc3 : 0xc2);
-                break;
-            }
-
-            case value_t::number_integer:
-            {
-                if (j.m_value.number_integer >= 0)
-                {
-                    // MessagePack does not differentiate between positive
-                    // signed integers and unsigned integers. Therefore, we
-                    // used the code from the value_t::number_unsigned case
-                    // here.
-                    if (j.m_value.number_unsigned < 128)
-                    {
-                        // positive fixnum
-                        add_to_vector(v, 1, j.m_value.number_unsigned);
-                    }
-                    else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
-                    {
-                        // uint 8
-                        v.push_back(0xcc);
-                        add_to_vector(v, 1, j.m_value.number_unsigned);
-                    }
-                    else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
-                    {
-                        // uint 16
-                        v.push_back(0xcd);
-                        add_to_vector(v, 2, j.m_value.number_unsigned);
-                    }
-                    else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
-                    {
-                        // uint 32
-                        v.push_back(0xce);
-                        add_to_vector(v, 4, j.m_value.number_unsigned);
-                    }
-                    else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
-                    {
-                        // uint 64
-                        v.push_back(0xcf);
-                        add_to_vector(v, 8, j.m_value.number_unsigned);
-                    }
-                }
-                else
-                {
-                    if (j.m_value.number_integer >= -32)
-                    {
-                        // negative fixnum
-                        add_to_vector(v, 1, j.m_value.number_integer);
-                    }
-                    else if (j.m_value.number_integer >= std::numeric_limits<int8_t>::min() and j.m_value.number_integer <= std::numeric_limits<int8_t>::max())
-                    {
-                        // int 8
-                        v.push_back(0xd0);
-                        add_to_vector(v, 1, j.m_value.number_integer);
-                    }
-                    else if (j.m_value.number_integer >= std::numeric_limits<int16_t>::min() and j.m_value.number_integer <= std::numeric_limits<int16_t>::max())
-                    {
-                        // int 16
-                        v.push_back(0xd1);
-                        add_to_vector(v, 2, j.m_value.number_integer);
-                    }
-                    else if (j.m_value.number_integer >= std::numeric_limits<int32_t>::min() and j.m_value.number_integer <= std::numeric_limits<int32_t>::max())
-                    {
-                        // int 32
-                        v.push_back(0xd2);
-                        add_to_vector(v, 4, j.m_value.number_integer);
-                    }
-                    else if (j.m_value.number_integer >= std::numeric_limits<int64_t>::min() and j.m_value.number_integer <= std::numeric_limits<int64_t>::max())
-                    {
-                        // int 64
-                        v.push_back(0xd3);
-                        add_to_vector(v, 8, j.m_value.number_integer);
-                    }
-                }
-                break;
-            }
-
-            case value_t::number_unsigned:
-            {
-                if (j.m_value.number_unsigned < 128)
-                {
-                    // positive fixnum
-                    add_to_vector(v, 1, j.m_value.number_unsigned);
-                }
-                else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
-                {
-                    // uint 8
-                    v.push_back(0xcc);
-                    add_to_vector(v, 1, j.m_value.number_unsigned);
-                }
-                else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
-                {
-                    // uint 16
-                    v.push_back(0xcd);
-                    add_to_vector(v, 2, j.m_value.number_unsigned);
-                }
-                else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
-                {
-                    // uint 32
-                    v.push_back(0xce);
-                    add_to_vector(v, 4, j.m_value.number_unsigned);
-                }
-                else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
-                {
-                    // uint 64
-                    v.push_back(0xcf);
-                    add_to_vector(v, 8, j.m_value.number_unsigned);
-                }
-                break;
-            }
-
-            case value_t::number_float:
-            {
-                // float 64
-                v.push_back(0xcb);
-                const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
-                for (size_t i = 0; i < 8; ++i)
-                {
-                    v.push_back(helper[7 - i]);
-                }
-                break;
-            }
-
-            case value_t::string:
-            {
-                const auto N = j.m_value.string->size();
-                if (N <= 31)
-                {
-                    // fixstr
-                    v.push_back(static_cast<uint8_t>(0xa0 | N));
-                }
-                else if (N <= 255)
-                {
-                    // str 8
-                    v.push_back(0xd9);
-                    add_to_vector(v, 1, N);
-                }
-                else if (N <= 65535)
-                {
-                    // str 16
-                    v.push_back(0xda);
-                    add_to_vector(v, 2, N);
-                }
-                else if (N <= 4294967295)
-                {
-                    // str 32
-                    v.push_back(0xdb);
-                    add_to_vector(v, 4, N);
-                }
-
-                // append string
-                std::copy(j.m_value.string->begin(), j.m_value.string->end(),
-                          std::back_inserter(v));
-                break;
-            }
-
-            case value_t::array:
-            {
-                const auto N = j.m_value.array->size();
-                if (N <= 15)
-                {
-                    // fixarray
-                    v.push_back(static_cast<uint8_t>(0x90 | N));
-                }
-                else if (N <= 0xffff)
-                {
-                    // array 16
-                    v.push_back(0xdc);
-                    add_to_vector(v, 2, N);
-                }
-                else if (N <= 0xffffffff)
-                {
-                    // array 32
-                    v.push_back(0xdd);
-                    add_to_vector(v, 4, N);
-                }
-
-                // append each element
-                for (const auto& el : *j.m_value.array)
-                {
-                    to_msgpack_internal(el, v);
-                }
-                break;
-            }
-
-            case value_t::object:
-            {
-                const auto N = j.m_value.object->size();
-                if (N <= 15)
-                {
-                    // fixmap
-                    v.push_back(static_cast<uint8_t>(0x80 | (N & 0xf)));
-                }
-                else if (N <= 65535)
-                {
-                    // map 16
-                    v.push_back(0xde);
-                    add_to_vector(v, 2, N);
-                }
-                else if (N <= 4294967295)
-                {
-                    // map 32
-                    v.push_back(0xdf);
-                    add_to_vector(v, 4, N);
-                }
-
-                // append each element
-                for (const auto& el : *j.m_value.object)
-                {
-                    to_msgpack_internal(el.first, v);
-                    to_msgpack_internal(el.second, v);
-                }
-                break;
-            }
-
-            default:
-            {
-                break;
-            }
-        }
-    }
-
-    /*!
-    @brief create a CBOR serialization of a given JSON value
-
-    This is a straightforward implementation of the CBOR specification.
-
-    @param[in] j  JSON value to serialize
-    @param[in,out] v  byte vector to write the serialization to
-
-    @sa https://tools.ietf.org/html/rfc7049
-    */
-    static void to_cbor_internal(const basic_json& j, std::vector<uint8_t>& v)
-    {
-        switch (j.type())
-        {
-            case value_t::null:
-            {
-                v.push_back(0xf6);
-                break;
-            }
-
-            case value_t::boolean:
-            {
-                v.push_back(j.m_value.boolean ? 0xf5 : 0xf4);
-                break;
-            }
-
-            case value_t::number_integer:
-            {
-                if (j.m_value.number_integer >= 0)
-                {
-                    // CBOR does not differentiate between positive signed
-                    // integers and unsigned integers. Therefore, we used the
-                    // code from the value_t::number_unsigned case here.
-                    if (j.m_value.number_integer <= 0x17)
-                    {
-                        add_to_vector(v, 1, j.m_value.number_integer);
-                    }
-                    else if (j.m_value.number_integer <= std::numeric_limits<uint8_t>::max())
-                    {
-                        v.push_back(0x18);
-                        // one-byte uint8_t
-                        add_to_vector(v, 1, j.m_value.number_integer);
-                    }
-                    else if (j.m_value.number_integer <= std::numeric_limits<uint16_t>::max())
-                    {
-                        v.push_back(0x19);
-                        // two-byte uint16_t
-                        add_to_vector(v, 2, j.m_value.number_integer);
-                    }
-                    else if (j.m_value.number_integer <= std::numeric_limits<uint32_t>::max())
-                    {
-                        v.push_back(0x1a);
-                        // four-byte uint32_t
-                        add_to_vector(v, 4, j.m_value.number_integer);
-                    }
-                    else
-                    {
-                        v.push_back(0x1b);
-                        // eight-byte uint64_t
-                        add_to_vector(v, 8, j.m_value.number_integer);
-                    }
-                }
-                else
-                {
-                    // The conversions below encode the sign in the first
-                    // byte, and the value is converted to a positive number.
-                    const auto positive_number = -1 - j.m_value.number_integer;
-                    if (j.m_value.number_integer >= -24)
-                    {
-                        v.push_back(static_cast<uint8_t>(0x20 + positive_number));
-                    }
-                    else if (positive_number <= std::numeric_limits<uint8_t>::max())
-                    {
-                        // int 8
-                        v.push_back(0x38);
-                        add_to_vector(v, 1, positive_number);
-                    }
-                    else if (positive_number <= std::numeric_limits<uint16_t>::max())
-                    {
-                        // int 16
-                        v.push_back(0x39);
-                        add_to_vector(v, 2, positive_number);
-                    }
-                    else if (positive_number <= std::numeric_limits<uint32_t>::max())
-                    {
-                        // int 32
-                        v.push_back(0x3a);
-                        add_to_vector(v, 4, positive_number);
-                    }
-                    else
-                    {
-                        // int 64
-                        v.push_back(0x3b);
-                        add_to_vector(v, 8, positive_number);
-                    }
-                }
-                break;
-            }
-
-            case value_t::number_unsigned:
-            {
-                if (j.m_value.number_unsigned <= 0x17)
-                {
-                    v.push_back(static_cast<uint8_t>(j.m_value.number_unsigned));
-                }
-                else if (j.m_value.number_unsigned <= 0xff)
-                {
-                    v.push_back(0x18);
-                    // one-byte uint8_t
-                    add_to_vector(v, 1, j.m_value.number_unsigned);
-                }
-                else if (j.m_value.number_unsigned <= 0xffff)
-                {
-                    v.push_back(0x19);
-                    // two-byte uint16_t
-                    add_to_vector(v, 2, j.m_value.number_unsigned);
-                }
-                else if (j.m_value.number_unsigned <= 0xffffffff)
-                {
-                    v.push_back(0x1a);
-                    // four-byte uint32_t
-                    add_to_vector(v, 4, j.m_value.number_unsigned);
-                }
-                else if (j.m_value.number_unsigned <= 0xffffffffffffffff)
-                {
-                    v.push_back(0x1b);
-                    // eight-byte uint64_t
-                    add_to_vector(v, 8, j.m_value.number_unsigned);
-                }
-                break;
-            }
-
-            case value_t::number_float:
-            {
-                // Double-Precision Float
-                v.push_back(0xfb);
-                const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
-                for (size_t i = 0; i < 8; ++i)
-                {
-                    v.push_back(helper[7 - i]);
-                }
-                break;
-            }
-
-            case value_t::string:
-            {
-                const auto N = j.m_value.string->size();
-                if (N <= 0x17)
-                {
-                    v.push_back(0x60 + static_cast<uint8_t>(N));  // 1 byte for string + size
-                }
-                else if (N <= 0xff)
-                {
-                    v.push_back(0x78);  // one-byte uint8_t for N
-                    add_to_vector(v, 1, N);
-                }
-                else if (N <= 0xffff)
-                {
-                    v.push_back(0x79);  // two-byte uint16_t for N
-                    add_to_vector(v, 2, N);
-                }
-                else if (N <= 0xffffffff)
-                {
-                    v.push_back(0x7a); // four-byte uint32_t for N
-                    add_to_vector(v, 4, N);
-                }
-                // LCOV_EXCL_START
-                else if (N <= 0xffffffffffffffff)
-                {
-                    v.push_back(0x7b);  // eight-byte uint64_t for N
-                    add_to_vector(v, 8, N);
-                }
-                // LCOV_EXCL_STOP
-
-                // append string
-                std::copy(j.m_value.string->begin(), j.m_value.string->end(),
-                          std::back_inserter(v));
-                break;
-            }
-
-            case value_t::array:
-            {
-                const auto N = j.m_value.array->size();
-                if (N <= 0x17)
-                {
-                    v.push_back(0x80 + static_cast<uint8_t>(N));  // 1 byte for array + size
-                }
-                else if (N <= 0xff)
-                {
-                    v.push_back(0x98);  // one-byte uint8_t for N
-                    add_to_vector(v, 1, N);
-                }
-                else if (N <= 0xffff)
-                {
-                    v.push_back(0x99);  // two-byte uint16_t for N
-                    add_to_vector(v, 2, N);
-                }
-                else if (N <= 0xffffffff)
-                {
-                    v.push_back(0x9a);  // four-byte uint32_t for N
-                    add_to_vector(v, 4, N);
-                }
-                // LCOV_EXCL_START
-                else if (N <= 0xffffffffffffffff)
-                {
-                    v.push_back(0x9b);  // eight-byte uint64_t for N
-                    add_to_vector(v, 8, N);
-                }
-                // LCOV_EXCL_STOP
-
-                // append each element
-                for (const auto& el : *j.m_value.array)
-                {
-                    to_cbor_internal(el, v);
-                }
-                break;
-            }
-
-            case value_t::object:
-            {
-                const auto N = j.m_value.object->size();
-                if (N <= 0x17)
-                {
-                    v.push_back(0xa0 + static_cast<uint8_t>(N));  // 1 byte for object + size
-                }
-                else if (N <= 0xff)
-                {
-                    v.push_back(0xb8);
-                    add_to_vector(v, 1, N);  // one-byte uint8_t for N
-                }
-                else if (N <= 0xffff)
-                {
-                    v.push_back(0xb9);
-                    add_to_vector(v, 2, N);  // two-byte uint16_t for N
-                }
-                else if (N <= 0xffffffff)
-                {
-                    v.push_back(0xba);
-                    add_to_vector(v, 4, N);  // four-byte uint32_t for N
-                }
-                // LCOV_EXCL_START
-                else if (N <= 0xffffffffffffffff)
-                {
-                    v.push_back(0xbb);
-                    add_to_vector(v, 8, N);  // eight-byte uint64_t for N
-                }
-                // LCOV_EXCL_STOP
-
-                // append each element
-                for (const auto& el : *j.m_value.object)
-                {
-                    to_cbor_internal(el.first, v);
-                    to_cbor_internal(el.second, v);
-                }
-                break;
-            }
-
-            default:
-            {
-                break;
-            }
-        }
-    }
-
-
-    /*
-    @brief checks if given lengths do not exceed the size of a given vector
-
-    To secure the access to the byte vector during CBOR/MessagePack
-    deserialization, bytes are copied from the vector into buffers. This
-    function checks if the number of bytes to copy (@a len) does not exceed
-    the size @s size of the vector. Additionally, an @a offset is given from
-    where to start reading the bytes.
-
-    This function checks whether reading the bytes is safe; that is, offset is
-    a valid index in the vector, offset+len
-
-    @param[in] size    size of the byte vector
-    @param[in] len     number of bytes to read
-    @param[in] offset  offset where to start reading
-
-    vec:  x x x x x X X X X X
-          ^         ^         ^
-          0         offset    len
-
-    @throws out_of_range if `len > v.size()`
-    */
-    static void check_length(const size_t size, const size_t len, const size_t offset)
-    {
-        // simple case: requested length is greater than the vector's length
-        if (len > size or offset > size)
-        {
-            JSON_THROW(std::out_of_range("len out of range"));
-        }
-
-        // second case: adding offset would result in overflow
-        if ((size > (std::numeric_limits<size_t>::max() - offset)))
-        {
-            JSON_THROW(std::out_of_range("len+offset out of range"));
-        }
-
-        // last case: reading past the end of the vector
-        if (len + offset > size)
-        {
-            JSON_THROW(std::out_of_range("len+offset out of range"));
-        }
-    }
-
-    /*!
-    @brief create a JSON value from a given MessagePack vector
-
-    @param[in] v  MessagePack serialization
-    @param[in] idx  byte index to start reading from @a v
-
-    @return deserialized JSON value
-
-    @throw std::invalid_argument if unsupported features from MessagePack were
-    used in the given vector @a v or if the input is not valid MessagePack
-    @throw std::out_of_range if the given vector ends prematurely
-
-    @sa https://github.com/msgpack/msgpack/blob/master/spec.md
-    */
-    static basic_json from_msgpack_internal(const std::vector<uint8_t>& v, size_t& idx)
-    {
-        // make sure reading 1 byte is safe
-        check_length(v.size(), 1, idx);
-
-        // store and increment index
-        const size_t current_idx = idx++;
-
-        if (v[current_idx] <= 0xbf)
-        {
-            if (v[current_idx] <= 0x7f) // positive fixint
-            {
-                return v[current_idx];
-            }
-            if (v[current_idx] <= 0x8f) // fixmap
-            {
-                basic_json result = value_t::object;
-                const size_t len = v[current_idx] & 0x0f;
-                for (size_t i = 0; i < len; ++i)
-                {
-                    std::string key = from_msgpack_internal(v, idx);
-                    result[key] = from_msgpack_internal(v, idx);
-                }
-                return result;
-            }
-            else if (v[current_idx] <= 0x9f) // fixarray
-            {
-                basic_json result = value_t::array;
-                const size_t len = v[current_idx] & 0x0f;
-                for (size_t i = 0; i < len; ++i)
-                {
-                    result.push_back(from_msgpack_internal(v, idx));
-                }
-                return result;
-            }
-            else // fixstr
-            {
-                const size_t len = v[current_idx] & 0x1f;
-                const size_t offset = current_idx + 1;
-                idx += len; // skip content bytes
-                check_length(v.size(), len, offset);
-                return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-            }
-        }
-        else if (v[current_idx] >= 0xe0) // negative fixint
-        {
-            return static_cast<int8_t>(v[current_idx]);
-        }
-        else
-        {
-            switch (v[current_idx])
-            {
-                case 0xc0: // nil
-                {
-                    return value_t::null;
-                }
-
-                case 0xc2: // false
-                {
-                    return false;
-                }
-
-                case 0xc3: // true
-                {
-                    return true;
-                }
-
-                case 0xca: // float 32
-                {
-                    // copy bytes in reverse order into the double variable
-                    float res;
-                    for (size_t byte = 0; byte < sizeof(float); ++byte)
-                    {
-                        reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
-                    }
-                    idx += sizeof(float); // skip content bytes
-                    return res;
-                }
-
-                case 0xcb: // float 64
-                {
-                    // copy bytes in reverse order into the double variable
-                    double res;
-                    for (size_t byte = 0; byte < sizeof(double); ++byte)
-                    {
-                        reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
-                    }
-                    idx += sizeof(double); // skip content bytes
-                    return res;
-                }
-
-                case 0xcc: // uint 8
-                {
-                    idx += 1; // skip content byte
-                    return get_from_vector<uint8_t>(v, current_idx);
-                }
-
-                case 0xcd: // uint 16
-                {
-                    idx += 2; // skip 2 content bytes
-                    return get_from_vector<uint16_t>(v, current_idx);
-                }
-
-                case 0xce: // uint 32
-                {
-                    idx += 4; // skip 4 content bytes
-                    return get_from_vector<uint32_t>(v, current_idx);
-                }
-
-                case 0xcf: // uint 64
-                {
-                    idx += 8; // skip 8 content bytes
-                    return get_from_vector<uint64_t>(v, current_idx);
-                }
-
-                case 0xd0: // int 8
-                {
-                    idx += 1; // skip content byte
-                    return get_from_vector<int8_t>(v, current_idx);
-                }
-
-                case 0xd1: // int 16
-                {
-                    idx += 2; // skip 2 content bytes
-                    return get_from_vector<int16_t>(v, current_idx);
-                }
-
-                case 0xd2: // int 32
-                {
-                    idx += 4; // skip 4 content bytes
-                    return get_from_vector<int32_t>(v, current_idx);
-                }
-
-                case 0xd3: // int 64
-                {
-                    idx += 8; // skip 8 content bytes
-                    return get_from_vector<int64_t>(v, current_idx);
-                }
-
-                case 0xd9: // str 8
-                {
-                    const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
-                    const size_t offset = current_idx + 2;
-                    idx += len + 1; // skip size byte + content bytes
-                    check_length(v.size(), len, offset);
-                    return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-                }
-
-                case 0xda: // str 16
-                {
-                    const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
-                    const size_t offset = current_idx + 3;
-                    idx += len + 2; // skip 2 size bytes + content bytes
-                    check_length(v.size(), len, offset);
-                    return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-                }
-
-                case 0xdb: // str 32
-                {
-                    const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
-                    const size_t offset = current_idx + 5;
-                    idx += len + 4; // skip 4 size bytes + content bytes
-                    check_length(v.size(), len, offset);
-                    return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-                }
-
-                case 0xdc: // array 16
-                {
-                    basic_json result = value_t::array;
-                    const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
-                    idx += 2; // skip 2 size bytes
-                    for (size_t i = 0; i < len; ++i)
-                    {
-                        result.push_back(from_msgpack_internal(v, idx));
-                    }
-                    return result;
-                }
-
-                case 0xdd: // array 32
-                {
-                    basic_json result = value_t::array;
-                    const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
-                    idx += 4; // skip 4 size bytes
-                    for (size_t i = 0; i < len; ++i)
-                    {
-                        result.push_back(from_msgpack_internal(v, idx));
-                    }
-                    return result;
-                }
-
-                case 0xde: // map 16
-                {
-                    basic_json result = value_t::object;
-                    const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
-                    idx += 2; // skip 2 size bytes
-                    for (size_t i = 0; i < len; ++i)
-                    {
-                        std::string key = from_msgpack_internal(v, idx);
-                        result[key] = from_msgpack_internal(v, idx);
-                    }
-                    return result;
-                }
-
-                case 0xdf: // map 32
-                {
-                    basic_json result = value_t::object;
-                    const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
-                    idx += 4; // skip 4 size bytes
-                    for (size_t i = 0; i < len; ++i)
-                    {
-                        std::string key = from_msgpack_internal(v, idx);
-                        result[key] = from_msgpack_internal(v, idx);
-                    }
-                    return result;
-                }
-
-                default:
-                {
-                    JSON_THROW(std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
-                }
-            }
-        }
-    }
-
-    /*!
-    @brief create a JSON value from a given CBOR vector
-
-    @param[in] v  CBOR serialization
-    @param[in] idx  byte index to start reading from @a v
-
-    @return deserialized JSON value
-
-    @throw std::invalid_argument if unsupported features from CBOR were used in
-    the given vector @a v or if the input is not valid CBOR
-    @throw std::out_of_range if the given vector ends prematurely
-
-    @sa https://tools.ietf.org/html/rfc7049
-    */
-    static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
-    {
-        // store and increment index
-        const size_t current_idx = idx++;
-
-        switch (v.at(current_idx))
-        {
-            // Integer 0x00..0x17 (0..23)
-            case 0x00:
-            case 0x01:
-            case 0x02:
-            case 0x03:
-            case 0x04:
-            case 0x05:
-            case 0x06:
-            case 0x07:
-            case 0x08:
-            case 0x09:
-            case 0x0a:
-            case 0x0b:
-            case 0x0c:
-            case 0x0d:
-            case 0x0e:
-            case 0x0f:
-            case 0x10:
-            case 0x11:
-            case 0x12:
-            case 0x13:
-            case 0x14:
-            case 0x15:
-            case 0x16:
-            case 0x17:
-            {
-                return v[current_idx];
-            }
-
-            case 0x18: // Unsigned integer (one-byte uint8_t follows)
-            {
-                idx += 1; // skip content byte
-                return get_from_vector<uint8_t>(v, current_idx);
-            }
-
-            case 0x19: // Unsigned integer (two-byte uint16_t follows)
-            {
-                idx += 2; // skip 2 content bytes
-                return get_from_vector<uint16_t>(v, current_idx);
-            }
-
-            case 0x1a: // Unsigned integer (four-byte uint32_t follows)
-            {
-                idx += 4; // skip 4 content bytes
-                return get_from_vector<uint32_t>(v, current_idx);
-            }
-
-            case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
-            {
-                idx += 8; // skip 8 content bytes
-                return get_from_vector<uint64_t>(v, current_idx);
-            }
-
-            // Negative integer -1-0x00..-1-0x17 (-1..-24)
-            case 0x20:
-            case 0x21:
-            case 0x22:
-            case 0x23:
-            case 0x24:
-            case 0x25:
-            case 0x26:
-            case 0x27:
-            case 0x28:
-            case 0x29:
-            case 0x2a:
-            case 0x2b:
-            case 0x2c:
-            case 0x2d:
-            case 0x2e:
-            case 0x2f:
-            case 0x30:
-            case 0x31:
-            case 0x32:
-            case 0x33:
-            case 0x34:
-            case 0x35:
-            case 0x36:
-            case 0x37:
-            {
-                return static_cast<int8_t>(0x20 - 1 - v[current_idx]);
-            }
-
-            case 0x38: // Negative integer (one-byte uint8_t follows)
-            {
-                idx += 1; // skip content byte
-                // must be uint8_t !
-                return static_cast<number_integer_t>(-1) - get_from_vector<uint8_t>(v, current_idx);
-            }
-
-            case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
-            {
-                idx += 2; // skip 2 content bytes
-                return static_cast<number_integer_t>(-1) - get_from_vector<uint16_t>(v, current_idx);
-            }
-
-            case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
-            {
-                idx += 4; // skip 4 content bytes
-                return static_cast<number_integer_t>(-1) - get_from_vector<uint32_t>(v, current_idx);
-            }
-
-            case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
-            {
-                idx += 8; // skip 8 content bytes
-                return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_from_vector<uint64_t>(v, current_idx));
-            }
-
-            // UTF-8 string (0x00..0x17 bytes follow)
-            case 0x60:
-            case 0x61:
-            case 0x62:
-            case 0x63:
-            case 0x64:
-            case 0x65:
-            case 0x66:
-            case 0x67:
-            case 0x68:
-            case 0x69:
-            case 0x6a:
-            case 0x6b:
-            case 0x6c:
-            case 0x6d:
-            case 0x6e:
-            case 0x6f:
-            case 0x70:
-            case 0x71:
-            case 0x72:
-            case 0x73:
-            case 0x74:
-            case 0x75:
-            case 0x76:
-            case 0x77:
-            {
-                const auto len = static_cast<size_t>(v[current_idx] - 0x60);
-                const size_t offset = current_idx + 1;
-                idx += len; // skip content bytes
-                check_length(v.size(), len, offset);
-                return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-            }
-
-            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
-            {
-                const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
-                const size_t offset = current_idx + 2;
-                idx += len + 1; // skip size byte + content bytes
-                check_length(v.size(), len, offset);
-                return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-            }
-
-            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
-            {
-                const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
-                const size_t offset = current_idx + 3;
-                idx += len + 2; // skip 2 size bytes + content bytes
-                check_length(v.size(), len, offset);
-                return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-            }
-
-            case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
-            {
-                const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
-                const size_t offset = current_idx + 5;
-                idx += len + 4; // skip 4 size bytes + content bytes
-                check_length(v.size(), len, offset);
-                return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-            }
-
-            case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
-            {
-                const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
-                const size_t offset = current_idx + 9;
-                idx += len + 8; // skip 8 size bytes + content bytes
-                check_length(v.size(), len, offset);
-                return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
-            }
-
-            case 0x7f: // UTF-8 string (indefinite length)
-            {
-                std::string result;
-                while (v.at(idx) != 0xff)
-                {
-                    string_t s = from_cbor_internal(v, idx);
-                    result += s;
-                }
-                // skip break byte (0xFF)
-                idx += 1;
-                return result;
-            }
-
-            // array (0x00..0x17 data items follow)
-            case 0x80:
-            case 0x81:
-            case 0x82:
-            case 0x83:
-            case 0x84:
-            case 0x85:
-            case 0x86:
-            case 0x87:
-            case 0x88:
-            case 0x89:
-            case 0x8a:
-            case 0x8b:
-            case 0x8c:
-            case 0x8d:
-            case 0x8e:
-            case 0x8f:
-            case 0x90:
-            case 0x91:
-            case 0x92:
-            case 0x93:
-            case 0x94:
-            case 0x95:
-            case 0x96:
-            case 0x97:
-            {
-                basic_json result = value_t::array;
-                const auto len = static_cast<size_t>(v[current_idx] - 0x80);
-                for (size_t i = 0; i < len; ++i)
-                {
-                    result.push_back(from_cbor_internal(v, idx));
-                }
-                return result;
-            }
-
-            case 0x98: // array (one-byte uint8_t for n follows)
-            {
-                basic_json result = value_t::array;
-                const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
-                idx += 1; // skip 1 size byte
-                for (size_t i = 0; i < len; ++i)
-                {
-                    result.push_back(from_cbor_internal(v, idx));
-                }
-                return result;
-            }
-
-            case 0x99: // array (two-byte uint16_t for n follow)
-            {
-                basic_json result = value_t::array;
-                const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
-                idx += 2; // skip 4 size bytes
-                for (size_t i = 0; i < len; ++i)
-                {
-                    result.push_back(from_cbor_internal(v, idx));
-                }
-                return result;
-            }
-
-            case 0x9a: // array (four-byte uint32_t for n follow)
-            {
-                basic_json result = value_t::array;
-                const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
-                idx += 4; // skip 4 size bytes
-                for (size_t i = 0; i < len; ++i)
-                {
-                    result.push_back(from_cbor_internal(v, idx));
-                }
-                return result;
-            }
-
-            case 0x9b: // array (eight-byte uint64_t for n follow)
-            {
-                basic_json result = value_t::array;
-                const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
-                idx += 8; // skip 8 size bytes
-                for (size_t i = 0; i < len; ++i)
-                {
-                    result.push_back(from_cbor_internal(v, idx));
-                }
-                return result;
-            }
-
-            case 0x9f: // array (indefinite length)
-            {
-                basic_json result = value_t::array;
-                while (v.at(idx) != 0xff)
-                {
-                    result.push_back(from_cbor_internal(v, idx));
-                }
-                // skip break byte (0xFF)
-                idx += 1;
-                return result;
-            }
-
-            // map (0x00..0x17 pairs of data items follow)
-            case 0xa0:
-            case 0xa1:
-            case 0xa2:
-            case 0xa3:
-            case 0xa4:
-            case 0xa5:
-            case 0xa6:
-            case 0xa7:
-            case 0xa8:
-            case 0xa9:
-            case 0xaa:
-            case 0xab:
-            case 0xac:
-            case 0xad:
-            case 0xae:
-            case 0xaf:
-            case 0xb0:
-            case 0xb1:
-            case 0xb2:
-            case 0xb3:
-            case 0xb4:
-            case 0xb5:
-            case 0xb6:
-            case 0xb7:
-            {
-                basic_json result = value_t::object;
-                const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
-                for (size_t i = 0; i < len; ++i)
-                {
-                    std::string key = from_cbor_internal(v, idx);
-                    result[key] = from_cbor_internal(v, idx);
-                }
-                return result;
-            }
-
-            case 0xb8: // map (one-byte uint8_t for n follows)
-            {
-                basic_json result = value_t::object;
-                const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
-                idx += 1; // skip 1 size byte
-                for (size_t i = 0; i < len; ++i)
-                {
-                    std::string key = from_cbor_internal(v, idx);
-                    result[key] = from_cbor_internal(v, idx);
-                }
-                return result;
-            }
-
-            case 0xb9: // map (two-byte uint16_t for n follow)
-            {
-                basic_json result = value_t::object;
-                const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
-                idx += 2; // skip 2 size bytes
-                for (size_t i = 0; i < len; ++i)
-                {
-                    std::string key = from_cbor_internal(v, idx);
-                    result[key] = from_cbor_internal(v, idx);
-                }
-                return result;
-            }
-
-            case 0xba: // map (four-byte uint32_t for n follow)
-            {
-                basic_json result = value_t::object;
-                const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
-                idx += 4; // skip 4 size bytes
-                for (size_t i = 0; i < len; ++i)
-                {
-                    std::string key = from_cbor_internal(v, idx);
-                    result[key] = from_cbor_internal(v, idx);
-                }
-                return result;
-            }
-
-            case 0xbb: // map (eight-byte uint64_t for n follow)
-            {
-                basic_json result = value_t::object;
-                const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
-                idx += 8; // skip 8 size bytes
-                for (size_t i = 0; i < len; ++i)
-                {
-                    std::string key = from_cbor_internal(v, idx);
-                    result[key] = from_cbor_internal(v, idx);
-                }
-                return result;
-            }
-
-            case 0xbf: // map (indefinite length)
-            {
-                basic_json result = value_t::object;
-                while (v.at(idx) != 0xff)
-                {
-                    std::string key = from_cbor_internal(v, idx);
-                    result[key] = from_cbor_internal(v, idx);
-                }
-                // skip break byte (0xFF)
-                idx += 1;
-                return result;
-            }
-
-            case 0xf4: // false
-            {
-                return false;
-            }
-
-            case 0xf5: // true
-            {
-                return true;
-            }
-
-            case 0xf6: // null
-            {
-                return value_t::null;
-            }
-
-            case 0xf9: // Half-Precision Float (two-byte IEEE 754)
-            {
-                idx += 2; // skip two content bytes
-
-                // code from RFC 7049, Appendix D, Figure 3:
-                // As half-precision floating-point numbers were only added to
-                // IEEE 754 in 2008, today's programming platforms often still
-                // only have limited support for them. It is very easy to
-                // include at least decoding support for them even without such
-                // support. An example of a small decoder for half-precision
-                // floating-point numbers in the C language is shown in Fig. 3.
-                const int half = (v.at(current_idx + 1) << 8) + v.at(current_idx + 2);
-                const int exp = (half >> 10) & 0x1f;
-                const int mant = half & 0x3ff;
-                double val;
-                if (exp == 0)
-                {
-                    val = std::ldexp(mant, -24);
-                }
-                else if (exp != 31)
-                {
-                    val = std::ldexp(mant + 1024, exp - 25);
-                }
-                else
-                {
-                    val = mant == 0
-                          ? std::numeric_limits<double>::infinity()
-                          : std::numeric_limits<double>::quiet_NaN();
-                }
-                return (half & 0x8000) != 0 ? -val : val;
-            }
-
-            case 0xfa: // Single-Precision Float (four-byte IEEE 754)
-            {
-                // copy bytes in reverse order into the float variable
-                float res;
-                for (size_t byte = 0; byte < sizeof(float); ++byte)
-                {
-                    reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
-                }
-                idx += sizeof(float); // skip content bytes
-                return res;
-            }
-
-            case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
-            {
-                // copy bytes in reverse order into the double variable
-                double res;
-                for (size_t byte = 0; byte < sizeof(double); ++byte)
-                {
-                    reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
-                }
-                idx += sizeof(double); // skip content bytes
-                return res;
-            }
-
-            default: // anything else (0xFF is handled inside the other types)
-            {
-                JSON_THROW(std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
-            }
-        }
-    }
-
-  public:
-    /*!
-    @brief create a MessagePack serialization of a given JSON value
-
-    Serializes a given JSON value @a j to a byte vector using the MessagePack
-    serialization format. MessagePack is a binary serialization format which
-    aims to be more compact than JSON itself, yet more efficient to parse.
-
-    @param[in] j  JSON value to serialize
-    @return MessagePack serialization as byte vector
-
-    @complexity Linear in the size of the JSON value @a j.
-
-    @liveexample{The example shows the serialization of a JSON value to a byte
-    vector in MessagePack format.,to_msgpack}
-
-    @sa http://msgpack.org
-    @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
-        analogous deserialization
-    @sa @ref to_cbor(const basic_json& for the related CBOR format
-
-    @since version 2.0.9
-    */
-    static std::vector<uint8_t> to_msgpack(const basic_json& j)
-    {
-        std::vector<uint8_t> result;
-        to_msgpack_internal(j, result);
-        return result;
-    }
-
-    /*!
-    @brief create a JSON value from a byte vector in MessagePack format
-
-    Deserializes a given byte vector @a v to a JSON value using the MessagePack
-    serialization format.
-
-    @param[in] v  a byte vector in MessagePack format
-    @param[in] start_index the index to start reading from @a v (0 by default)
-    @return deserialized JSON value
-
-    @throw std::invalid_argument if unsupported features from MessagePack were
-    used in the given vector @a v or if the input is not valid MessagePack
-    @throw std::out_of_range if the given vector ends prematurely
-
-    @complexity Linear in the size of the byte vector @a v.
-
-    @liveexample{The example shows the deserialization of a byte vector in
-    MessagePack format to a JSON value.,from_msgpack}
-
-    @sa http://msgpack.org
-    @sa @ref to_msgpack(const basic_json&) for the analogous serialization
-    @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
-        related CBOR format
-
-    @since version 2.0.9, parameter @a start_index since 2.1.1
-    */
-    static basic_json from_msgpack(const std::vector<uint8_t>& v,
-                                   const size_t start_index = 0)
-    {
-        size_t i = start_index;
-        return from_msgpack_internal(v, i);
-    }
-
-    /*!
-    @brief create a MessagePack serialization of a given JSON value
-
-    Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
-    Binary Object Representation) serialization format. CBOR is a binary
-    serialization format which aims to be more compact than JSON itself, yet
-    more efficient to parse.
-
-    @param[in] j  JSON value to serialize
-    @return MessagePack serialization as byte vector
-
-    @complexity Linear in the size of the JSON value @a j.
-
-    @liveexample{The example shows the serialization of a JSON value to a byte
-    vector in CBOR format.,to_cbor}
-
-    @sa http://cbor.io
-    @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
-        analogous deserialization
-    @sa @ref to_msgpack(const basic_json& for the related MessagePack format
-
-    @since version 2.0.9
-    */
-    static std::vector<uint8_t> to_cbor(const basic_json& j)
-    {
-        std::vector<uint8_t> result;
-        to_cbor_internal(j, result);
-        return result;
-    }
-
-    /*!
-    @brief create a JSON value from a byte vector in CBOR format
-
-    Deserializes a given byte vector @a v to a JSON value using the CBOR
-    (Concise Binary Object Representation) serialization format.
-
-    @param[in] v  a byte vector in CBOR format
-    @param[in] start_index the index to start reading from @a v (0 by default)
-    @return deserialized JSON value
-
-    @throw std::invalid_argument if unsupported features from CBOR were used in
-    the given vector @a v or if the input is not valid MessagePack
-    @throw std::out_of_range if the given vector ends prematurely
-
-    @complexity Linear in the size of the byte vector @a v.
-
-    @liveexample{The example shows the deserialization of a byte vector in CBOR
-    format to a JSON value.,from_cbor}
-
-    @sa http://cbor.io
-    @sa @ref to_cbor(const basic_json&) for the analogous serialization
-    @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
-        related MessagePack format
-
-    @since version 2.0.9, parameter @a start_index since 2.1.1
-    */
-    static basic_json from_cbor(const std::vector<uint8_t>& v,
-                                const size_t start_index = 0)
-    {
-        size_t i = start_index;
-        return from_cbor_internal(v, i);
-    }
-
-    /// @}
-
     ///////////////////////////
     // convenience functions //
     ///////////////////////////
@@ -8053,16 +13050,31 @@
     Returns the type name as string to be used in error messages - usually to
     indicate that a function was called on a wrong JSON type.
 
-    @return basically a string representation of a the @a m_type member
+    @return a string representation of a the @a m_type member:
+            Value type  | return value
+            ----------- | -------------
+            null        | `"null"`
+            boolean     | `"boolean"`
+            string      | `"string"`
+            number      | `"number"` (for all number types)
+            object      | `"object"`
+            array       | `"array"`
+            discarded   | `"discarded"`
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
 
     @complexity Constant.
 
     @liveexample{The following code exemplifies `type_name()` for all JSON
     types.,type_name}
 
-    @since version 1.0.0, public since 2.1.0
+    @sa @ref type() -- return the type of the JSON value
+    @sa @ref operator value_t() -- return the type of the JSON value (implicit)
+
+    @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
+    since 3.0.0
     */
-    std::string type_name() const
+    const char* type_name() const noexcept
     {
         {
             switch (m_type)
@@ -8085,464 +13097,6 @@
         }
     }
 
-  private:
-    /*!
-    @brief calculates the extra space to escape a JSON string
-
-    @param[in] s  the string to escape
-    @return the number of characters required to escape string @a s
-
-    @complexity Linear in the length of string @a s.
-    */
-    static std::size_t extra_space(const string_t& s) noexcept
-    {
-        return std::accumulate(s.begin(), s.end(), size_t{},
-                               [](size_t res, typename string_t::value_type c)
-        {
-            switch (c)
-            {
-                case '"':
-                case '\\':
-                case '\b':
-                case '\f':
-                case '\n':
-                case '\r':
-                case '\t':
-                {
-                    // from c (1 byte) to \x (2 bytes)
-                    return res + 1;
-                }
-
-                default:
-                {
-                    if (c >= 0x00 and c <= 0x1f)
-                    {
-                        // from c (1 byte) to \uxxxx (6 bytes)
-                        return res + 5;
-                    }
-
-                    return res;
-                }
-            }
-        });
-    }
-
-    /*!
-    @brief escape a string
-
-    Escape a string by replacing certain special characters by a sequence of
-    an escape character (backslash) and another character and other control
-    characters by a sequence of "\u" followed by a four-digit hex
-    representation.
-
-    @param[in] s  the string to escape
-    @return  the escaped string
-
-    @complexity Linear in the length of string @a s.
-    */
-    static string_t escape_string(const string_t& s)
-    {
-        const auto space = extra_space(s);
-        if (space == 0)
-        {
-            return s;
-        }
-
-        // create a result string of necessary size
-        string_t result(s.size() + space, '\\');
-        std::size_t pos = 0;
-
-        for (const auto& c : s)
-        {
-            switch (c)
-            {
-                // quotation mark (0x22)
-                case '"':
-                {
-                    result[pos + 1] = '"';
-                    pos += 2;
-                    break;
-                }
-
-                // reverse solidus (0x5c)
-                case '\\':
-                {
-                    // nothing to change
-                    pos += 2;
-                    break;
-                }
-
-                // backspace (0x08)
-                case '\b':
-                {
-                    result[pos + 1] = 'b';
-                    pos += 2;
-                    break;
-                }
-
-                // formfeed (0x0c)
-                case '\f':
-                {
-                    result[pos + 1] = 'f';
-                    pos += 2;
-                    break;
-                }
-
-                // newline (0x0a)
-                case '\n':
-                {
-                    result[pos + 1] = 'n';
-                    pos += 2;
-                    break;
-                }
-
-                // carriage return (0x0d)
-                case '\r':
-                {
-                    result[pos + 1] = 'r';
-                    pos += 2;
-                    break;
-                }
-
-                // horizontal tab (0x09)
-                case '\t':
-                {
-                    result[pos + 1] = 't';
-                    pos += 2;
-                    break;
-                }
-
-                default:
-                {
-                    if (c >= 0x00 and c <= 0x1f)
-                    {
-                        // convert a number 0..15 to its hex representation
-                        // (0..f)
-                        static const char hexify[16] =
-                        {
-                            '0', '1', '2', '3', '4', '5', '6', '7',
-                            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-                        };
-
-                        // print character c as \uxxxx
-                        for (const char m :
-                    { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
-                        })
-                        {
-                            result[++pos] = m;
-                        }
-
-                        ++pos;
-                    }
-                    else
-                    {
-                        // all other characters are added as-is
-                        result[pos++] = c;
-                    }
-                    break;
-                }
-            }
-        }
-
-        return result;
-    }
-
-
-    /*!
-    @brief locale-independent serialization for built-in arithmetic types
-    */
-    struct numtostr
-    {
-      public:
-        template<typename NumberType>
-        numtostr(NumberType value)
-        {
-            x_write(value, std::is_integral<NumberType>());
-        }
-
-        const char* c_str() const
-        {
-            return m_buf.data();
-        }
-
-      private:
-        /// a (hopefully) large enough character buffer
-        std::array < char, 64 > m_buf{{}};
-
-        template<typename NumberType>
-        void x_write(NumberType x, /*is_integral=*/std::true_type)
-        {
-            // special case for "0"
-            if (x == 0)
-            {
-                m_buf[0] = '0';
-                return;
-            }
-
-            const bool is_negative = x < 0;
-            size_t i = 0;
-
-            // spare 1 byte for '\0'
-            while (x != 0 and i < m_buf.size() - 1)
-            {
-                const auto digit = std::labs(static_cast<long>(x % 10));
-                m_buf[i++] = static_cast<char>('0' + digit);
-                x /= 10;
-            }
-
-            // make sure the number has been processed completely
-            assert(x == 0);
-
-            if (is_negative)
-            {
-                // make sure there is capacity for the '-'
-                assert(i < m_buf.size() - 2);
-                m_buf[i++] = '-';
-            }
-
-            std::reverse(m_buf.begin(), m_buf.begin() + i);
-        }
-
-        template<typename NumberType>
-        void x_write(NumberType x, /*is_integral=*/std::false_type)
-        {
-            // special case for 0.0 and -0.0
-            if (x == 0)
-            {
-                size_t i = 0;
-                if (std::signbit(x))
-                {
-                    m_buf[i++] = '-';
-                }
-                m_buf[i++] = '0';
-                m_buf[i++] = '.';
-                m_buf[i] = '0';
-                return;
-            }
-
-            // get number of digits for a text -> float -> text round-trip
-            static constexpr auto d = std::numeric_limits<NumberType>::digits10;
-
-            // the actual conversion
-            const auto written_bytes = snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x);
-
-            // negative value indicates an error
-            assert(written_bytes > 0);
-            // check if buffer was large enough
-            assert(static_cast<size_t>(written_bytes) < m_buf.size());
-
-            // read information from locale
-            const auto loc = localeconv();
-            assert(loc != nullptr);
-            const char thousands_sep = !loc->thousands_sep ? '\0'
-                                       : loc->thousands_sep[0];
-
-            const char decimal_point = !loc->decimal_point ? '\0'
-                                       : loc->decimal_point[0];
-
-            // erase thousands separator
-            if (thousands_sep != '\0')
-            {
-                const auto end = std::remove(m_buf.begin(), m_buf.begin() + written_bytes, thousands_sep);
-                std::fill(end, m_buf.end(), '\0');
-            }
-
-            // convert decimal point to '.'
-            if (decimal_point != '\0' and decimal_point != '.')
-            {
-                for (auto& c : m_buf)
-                {
-                    if (c == decimal_point)
-                    {
-                        c = '.';
-                        break;
-                    }
-                }
-            }
-
-            // determine if need to append ".0"
-            size_t i = 0;
-            bool value_is_int_like = true;
-            for (i = 0; i < m_buf.size(); ++i)
-            {
-                // break when end of number is reached
-                if (m_buf[i] == '\0')
-                {
-                    break;
-                }
-
-                // check if we find non-int character
-                value_is_int_like = value_is_int_like and m_buf[i] != '.' and
-                                    m_buf[i] != 'e' and m_buf[i] != 'E';
-            }
-
-            if (value_is_int_like)
-            {
-                // there must be 2 bytes left for ".0"
-                assert((i + 2) < m_buf.size());
-                // we write to the end of the number
-                assert(m_buf[i] == '\0');
-                assert(m_buf[i - 1] != '\0');
-
-                // add ".0"
-                m_buf[i] = '.';
-                m_buf[i + 1] = '0';
-
-                // the resulting string is properly terminated
-                assert(m_buf[i + 2] == '\0');
-            }
-        }
-    };
-
-
-    /*!
-    @brief internal implementation of the serialization function
-
-    This function is called by the public member function dump and organizes
-    the serialization internally. The indentation level is propagated as
-    additional parameter. In case of arrays and objects, the function is
-    called recursively. Note that
-
-    - strings and object keys are escaped using `escape_string()`
-    - integer numbers are converted implicitly via `operator<<`
-    - floating-point numbers are converted to a string using `"%g"` format
-
-    @param[out] o              stream to write to
-    @param[in] pretty_print    whether the output shall be pretty-printed
-    @param[in] indent_step     the indent level
-    @param[in] current_indent  the current indent level (only used internally)
-    */
-    void dump(std::ostream& o,
-              const bool pretty_print,
-              const unsigned int indent_step,
-              const unsigned int current_indent = 0) const
-    {
-        // variable to hold indentation for recursive calls
-        unsigned int new_indent = current_indent;
-
-        switch (m_type)
-        {
-            case value_t::object:
-            {
-                if (m_value.object->empty())
-                {
-                    o << "{}";
-                    return;
-                }
-
-                o << "{";
-
-                // increase indentation
-                if (pretty_print)
-                {
-                    new_indent += indent_step;
-                    o << "\n";
-                }
-
-                for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
-                {
-                    if (i != m_value.object->cbegin())
-                    {
-                        o << (pretty_print ? ",\n" : ",");
-                    }
-                    o << string_t(new_indent, ' ') << "\""
-                      << escape_string(i->first) << "\":"
-                      << (pretty_print ? " " : "");
-                    i->second.dump(o, pretty_print, indent_step, new_indent);
-                }
-
-                // decrease indentation
-                if (pretty_print)
-                {
-                    new_indent -= indent_step;
-                    o << "\n";
-                }
-
-                o << string_t(new_indent, ' ') + "}";
-                return;
-            }
-
-            case value_t::array:
-            {
-                if (m_value.array->empty())
-                {
-                    o << "[]";
-                    return;
-                }
-
-                o << "[";
-
-                // increase indentation
-                if (pretty_print)
-                {
-                    new_indent += indent_step;
-                    o << "\n";
-                }
-
-                for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
-                {
-                    if (i != m_value.array->cbegin())
-                    {
-                        o << (pretty_print ? ",\n" : ",");
-                    }
-                    o << string_t(new_indent, ' ');
-                    i->dump(o, pretty_print, indent_step, new_indent);
-                }
-
-                // decrease indentation
-                if (pretty_print)
-                {
-                    new_indent -= indent_step;
-                    o << "\n";
-                }
-
-                o << string_t(new_indent, ' ') << "]";
-                return;
-            }
-
-            case value_t::string:
-            {
-                o << string_t("\"") << escape_string(*m_value.string) << "\"";
-                return;
-            }
-
-            case value_t::boolean:
-            {
-                o << (m_value.boolean ? "true" : "false");
-                return;
-            }
-
-            case value_t::number_integer:
-            {
-                o << numtostr(m_value.number_integer).c_str();
-                return;
-            }
-
-            case value_t::number_unsigned:
-            {
-                o << numtostr(m_value.number_unsigned).c_str();
-                return;
-            }
-
-            case value_t::number_float:
-            {
-                o << numtostr(m_value.number_float).c_str();
-                return;
-            }
-
-            case value_t::discarded:
-            {
-                o << "<discarded>";
-                return;
-            }
-
-            case value_t::null:
-            {
-                o << "null";
-                return;
-            }
-        }
-    }
 
   private:
     //////////////////////
@@ -8555,3691 +13109,407 @@
     /// the value of the current element
     json_value m_value = {};
 
+    //////////////////////////////////////////
+    // binary serialization/deserialization //
+    //////////////////////////////////////////
 
-  private:
-    ///////////////
-    // iterators //
-    ///////////////
-
-    /*!
-    @brief an iterator for primitive JSON types
-
-    This class models an iterator for primitive JSON types (boolean, number,
-    string). It's only purpose is to allow the iterator/const_iterator classes
-    to "iterate" over primitive values. Internally, the iterator is modeled by
-    a `difference_type` variable. Value begin_value (`0`) models the begin,
-    end_value (`1`) models past the end.
-    */
-    class primitive_iterator_t
-    {
-      public:
-
-        difference_type get_value() const noexcept
-        {
-            return m_it;
-        }
-        /// set iterator to a defined beginning
-        void set_begin() noexcept
-        {
-            m_it = begin_value;
-        }
-
-        /// set iterator to a defined past the end
-        void set_end() noexcept
-        {
-            m_it = end_value;
-        }
-
-        /// return whether the iterator can be dereferenced
-        constexpr bool is_begin() const noexcept
-        {
-            return (m_it == begin_value);
-        }
-
-        /// return whether the iterator is at end
-        constexpr bool is_end() const noexcept
-        {
-            return (m_it == end_value);
-        }
-
-        friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
-        {
-            return lhs.m_it == rhs.m_it;
-        }
-
-        friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
-        {
-            return !(lhs == rhs);
-        }
-
-        friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
-        {
-            return lhs.m_it < rhs.m_it;
-        }
-
-        friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
-        {
-            return lhs.m_it <= rhs.m_it;
-        }
-
-        friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
-        {
-            return lhs.m_it > rhs.m_it;
-        }
-
-        friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
-        {
-            return lhs.m_it >= rhs.m_it;
-        }
-
-        primitive_iterator_t operator+(difference_type i)
-        {
-            auto result = *this;
-            result += i;
-            return result;
-        }
-
-        friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
-        {
-            return lhs.m_it - rhs.m_it;
-        }
-
-        friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
-        {
-            return os << it.m_it;
-        }
-
-        primitive_iterator_t& operator++()
-        {
-            ++m_it;
-            return *this;
-        }
-
-        primitive_iterator_t operator++(int)
-        {
-            auto result = *this;
-            m_it++;
-            return result;
-        }
-
-        primitive_iterator_t& operator--()
-        {
-            --m_it;
-            return *this;
-        }
-
-        primitive_iterator_t operator--(int)
-        {
-            auto result = *this;
-            m_it--;
-            return result;
-        }
-
-        primitive_iterator_t& operator+=(difference_type n)
-        {
-            m_it += n;
-            return *this;
-        }
-
-        primitive_iterator_t& operator-=(difference_type n)
-        {
-            m_it -= n;
-            return *this;
-        }
-
-      private:
-        static constexpr difference_type begin_value = 0;
-        static constexpr difference_type end_value = begin_value + 1;
-
-        /// iterator as signed integer type
-        difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
-    };
-
-    /*!
-    @brief an iterator value
-
-    @note This structure could easily be a union, but MSVC currently does not
-    allow unions members with complex constructors, see
-    https://github.com/nlohmann/json/pull/105.
-    */
-    struct internal_iterator
-    {
-        /// iterator for JSON objects
-        typename object_t::iterator object_iterator;
-        /// iterator for JSON arrays
-        typename array_t::iterator array_iterator;
-        /// generic iterator for all other types
-        primitive_iterator_t primitive_iterator;
-
-        /// create an uninitialized internal_iterator
-        internal_iterator() noexcept
-            : object_iterator(), array_iterator(), primitive_iterator()
-        {}
-    };
-
-    /// proxy class for the iterator_wrapper functions
-    template<typename IteratorType>
-    class iteration_proxy
-    {
-      private:
-        /// helper class for iteration
-        class iteration_proxy_internal
-        {
-          private:
-            /// the iterator
-            IteratorType anchor;
-            /// an index for arrays (used to create key names)
-            size_t array_index = 0;
-
-          public:
-            explicit iteration_proxy_internal(IteratorType it) noexcept
-                : anchor(it)
-            {}
-
-            /// dereference operator (needed for range-based for)
-            iteration_proxy_internal& operator*()
-            {
-                return *this;
-            }
-
-            /// increment operator (needed for range-based for)
-            iteration_proxy_internal& operator++()
-            {
-                ++anchor;
-                ++array_index;
-
-                return *this;
-            }
-
-            /// inequality operator (needed for range-based for)
-            bool operator!= (const iteration_proxy_internal& o) const
-            {
-                return anchor != o.anchor;
-            }
-
-            /// return key of the iterator
-            typename basic_json::string_t key() const
-            {
-                assert(anchor.m_object != nullptr);
-
-                switch (anchor.m_object->type())
-                {
-                    // use integer array index as key
-                    case value_t::array:
-                    {
-                        return std::to_string(array_index);
-                    }
-
-                    // use key from the object
-                    case value_t::object:
-                    {
-                        return anchor.key();
-                    }
-
-                    // use an empty key for all primitive types
-                    default:
-                    {
-                        return "";
-                    }
-                }
-            }
-
-            /// return value of the iterator
-            typename IteratorType::reference value() const
-            {
-                return anchor.value();
-            }
-        };
-
-        /// the container to iterate
-        typename IteratorType::reference container;
-
-      public:
-        /// construct iteration proxy from a container
-        explicit iteration_proxy(typename IteratorType::reference cont)
-            : container(cont)
-        {}
-
-        /// return iterator begin (needed for range-based for)
-        iteration_proxy_internal begin() noexcept
-        {
-            return iteration_proxy_internal(container.begin());
-        }
-
-        /// return iterator end (needed for range-based for)
-        iteration_proxy_internal end() noexcept
-        {
-            return iteration_proxy_internal(container.end());
-        }
-    };
+    /// @name binary serialization/deserialization support
+    /// @{
 
   public:
     /*!
-    @brief a template for a random access iterator for the @ref basic_json class
+    @brief create a CBOR serialization of a given JSON value
 
-    This class implements a both iterators (iterator and const_iterator) for the
-    @ref basic_json class.
+    Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
+    Binary Object Representation) serialization format. CBOR is a binary
+    serialization format which aims to be more compact than JSON itself, yet
+    more efficient to parse.
 
-    @note An iterator is called *initialized* when a pointer to a JSON value
-          has been set (e.g., by a constructor or a copy assignment). If the
-          iterator is default-constructed, it is *uninitialized* and most
-          methods are undefined. **The library uses assertions to detect calls
-          on uninitialized iterators.**
+    The library uses the following mapping from JSON values types to
+    CBOR types according to the CBOR specification (RFC 7049):
 
-    @requirement The class satisfies the following concept requirements:
-    - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
-      The iterator that can be moved to point (forward and backward) to any
-      element in constant time.
+    JSON value type | value/range                                | CBOR type                          | first byte
+    --------------- | ------------------------------------------ | ---------------------------------- | ---------------
+    null            | `null`                                     | Null                               | 0xf6
+    boolean         | `true`                                     | True                               | 0xf5
+    boolean         | `false`                                    | False                              | 0xf4
+    number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3b
+    number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3a
+    number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
+    number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
+    number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
+    number_integer  | 0..23                                      | Integer                            | 0x00..0x17
+    number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
+    number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
+    number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1a
+    number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1b
+    number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
+    number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
+    number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
+    number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1a
+    number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1b
+    number_float    | *any value*                                | Double-Precision Float             | 0xfb
+    string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
+    string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
+    string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
+    string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7a
+    string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7b
+    array           | *size*: 0..23                              | array                              | 0x80..0x97
+    array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
+    array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
+    array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9a
+    array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9b
+    object          | *size*: 0..23                              | map                                | 0xa0..0xb7
+    object          | *size*: 23..255                            | map (1 byte follow)                | 0xb8
+    object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xb9
+    object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xba
+    object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xbb
 
-    @since version 1.0.0, simplified in version 2.0.9
+    @note The mapping is **complete** in the sense that any JSON value type
+          can be converted to a CBOR value.
+
+    @note If NaN or Infinity are stored inside a JSON number, they are
+          serialized properly. This behavior differs from the @ref dump()
+          function which serializes NaN or Infinity to `null`.
+
+    @note The following CBOR types are not used in the conversion:
+          - byte strings (0x40..0x5f)
+          - UTF-8 strings terminated by "break" (0x7f)
+          - arrays terminated by "break" (0x9f)
+          - maps terminated by "break" (0xbf)
+          - date/time (0xc0..0xc1)
+          - bignum (0xc2..0xc3)
+          - decimal fraction (0xc4)
+          - bigfloat (0xc5)
+          - tagged items (0xc6..0xd4, 0xd8..0xdb)
+          - expected conversions (0xd5..0xd7)
+          - simple values (0xe0..0xf3, 0xf8)
+          - undefined (0xf7)
+          - half and single-precision floats (0xf9-0xfa)
+          - break (0xff)
+
+    @param[in] j  JSON value to serialize
+    @return MessagePack serialization as byte vector
+
+    @complexity Linear in the size of the JSON value @a j.
+
+    @liveexample{The example shows the serialization of a JSON value to a byte
+    vector in CBOR format.,to_cbor}
+
+    @sa http://cbor.io
+    @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
+        analogous deserialization
+    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
+
+    @since version 2.0.9
     */
-    template<typename U>
-    class iter_impl : public std::iterator<std::random_access_iterator_tag, U>
+    static std::vector<uint8_t> to_cbor(const basic_json& j)
     {
-        /// allow basic_json to access private members
-        friend class basic_json;
+        std::vector<uint8_t> result;
+        to_cbor(j, result);
+        return result;
+    }
 
-        // make sure U is basic_json or const basic_json
-        static_assert(std::is_same<U, basic_json>::value
-                      or std::is_same<U, const basic_json>::value,
-                      "iter_impl only accepts (const) basic_json");
+    static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
+    {
+        binary_writer<uint8_t>(o).write_cbor(j);
+    }
 
-      public:
-        /// the type of the values when the iterator is dereferenced
-        using value_type = typename basic_json::value_type;
-        /// a type to represent differences between iterators
-        using difference_type = typename basic_json::difference_type;
-        /// defines a pointer to the type iterated over (value_type)
-        using pointer = typename std::conditional<std::is_const<U>::value,
-              typename basic_json::const_pointer,
-              typename basic_json::pointer>::type;
-        /// defines a reference to the type iterated over (value_type)
-        using reference = typename std::conditional<std::is_const<U>::value,
-              typename basic_json::const_reference,
-              typename basic_json::reference>::type;
-        /// the category of the iterator
-        using iterator_category = std::bidirectional_iterator_tag;
-
-        /// default constructor
-        iter_impl() = default;
-
-        /*!
-        @brief constructor for a given JSON instance
-        @param[in] object  pointer to a JSON object for this iterator
-        @pre object != nullptr
-        @post The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        explicit iter_impl(pointer object) noexcept
-            : m_object(object)
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    m_it.object_iterator = typename object_t::iterator();
-                    break;
-                }
-
-                case basic_json::value_t::array:
-                {
-                    m_it.array_iterator = typename array_t::iterator();
-                    break;
-                }
-
-                default:
-                {
-                    m_it.primitive_iterator = primitive_iterator_t();
-                    break;
-                }
-            }
-        }
-
-        /*
-        Use operator `const_iterator` instead of `const_iterator(const iterator&
-        other) noexcept` to avoid two class definitions for @ref iterator and
-        @ref const_iterator.
-
-        This function is only called if this class is an @ref iterator. If this
-        class is a @ref const_iterator this function is not called.
-        */
-        operator const_iterator() const
-        {
-            const_iterator ret;
-
-            if (m_object)
-            {
-                ret.m_object = m_object;
-                ret.m_it = m_it;
-            }
-
-            return ret;
-        }
-
-        /*!
-        @brief copy constructor
-        @param[in] other  iterator to copy from
-        @note It is not checked whether @a other is initialized.
-        */
-        iter_impl(const iter_impl& other) noexcept
-            : m_object(other.m_object), m_it(other.m_it)
-        {}
-
-        /*!
-        @brief copy assignment
-        @param[in,out] other  iterator to copy from
-        @note It is not checked whether @a other is initialized.
-        */
-        iter_impl& operator=(iter_impl other) noexcept(
-            std::is_nothrow_move_constructible<pointer>::value and
-            std::is_nothrow_move_assignable<pointer>::value and
-            std::is_nothrow_move_constructible<internal_iterator>::value and
-            std::is_nothrow_move_assignable<internal_iterator>::value
-        )
-        {
-            std::swap(m_object, other.m_object);
-            std::swap(m_it, other.m_it);
-            return *this;
-        }
-
-      private:
-        /*!
-        @brief set the iterator to the first value
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        void set_begin() noexcept
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    m_it.object_iterator = m_object->m_value.object->begin();
-                    break;
-                }
-
-                case basic_json::value_t::array:
-                {
-                    m_it.array_iterator = m_object->m_value.array->begin();
-                    break;
-                }
-
-                case basic_json::value_t::null:
-                {
-                    // set to end so begin()==end() is true: null is empty
-                    m_it.primitive_iterator.set_end();
-                    break;
-                }
-
-                default:
-                {
-                    m_it.primitive_iterator.set_begin();
-                    break;
-                }
-            }
-        }
-
-        /*!
-        @brief set the iterator past the last value
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        void set_end() noexcept
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    m_it.object_iterator = m_object->m_value.object->end();
-                    break;
-                }
-
-                case basic_json::value_t::array:
-                {
-                    m_it.array_iterator = m_object->m_value.array->end();
-                    break;
-                }
-
-                default:
-                {
-                    m_it.primitive_iterator.set_end();
-                    break;
-                }
-            }
-        }
-
-      public:
-        /*!
-        @brief return a reference to the value pointed to by the iterator
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        reference operator*() const
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    assert(m_it.object_iterator != m_object->m_value.object->end());
-                    return m_it.object_iterator->second;
-                }
-
-                case basic_json::value_t::array:
-                {
-                    assert(m_it.array_iterator != m_object->m_value.array->end());
-                    return *m_it.array_iterator;
-                }
-
-                case basic_json::value_t::null:
-                {
-                    JSON_THROW(std::out_of_range("cannot get value"));
-                }
-
-                default:
-                {
-                    if (m_it.primitive_iterator.is_begin())
-                    {
-                        return *m_object;
-                    }
-
-                    JSON_THROW(std::out_of_range("cannot get value"));
-                }
-            }
-        }
-
-        /*!
-        @brief dereference the iterator
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        pointer operator->() const
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    assert(m_it.object_iterator != m_object->m_value.object->end());
-                    return &(m_it.object_iterator->second);
-                }
-
-                case basic_json::value_t::array:
-                {
-                    assert(m_it.array_iterator != m_object->m_value.array->end());
-                    return &*m_it.array_iterator;
-                }
-
-                default:
-                {
-                    if (m_it.primitive_iterator.is_begin())
-                    {
-                        return m_object;
-                    }
-
-                    JSON_THROW(std::out_of_range("cannot get value"));
-                }
-            }
-        }
-
-        /*!
-        @brief post-increment (it++)
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        iter_impl operator++(int)
-        {
-            auto result = *this;
-            ++(*this);
-            return result;
-        }
-
-        /*!
-        @brief pre-increment (++it)
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        iter_impl& operator++()
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    std::advance(m_it.object_iterator, 1);
-                    break;
-                }
-
-                case basic_json::value_t::array:
-                {
-                    std::advance(m_it.array_iterator, 1);
-                    break;
-                }
-
-                default:
-                {
-                    ++m_it.primitive_iterator;
-                    break;
-                }
-            }
-
-            return *this;
-        }
-
-        /*!
-        @brief post-decrement (it--)
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        iter_impl operator--(int)
-        {
-            auto result = *this;
-            --(*this);
-            return result;
-        }
-
-        /*!
-        @brief pre-decrement (--it)
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        iter_impl& operator--()
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    std::advance(m_it.object_iterator, -1);
-                    break;
-                }
-
-                case basic_json::value_t::array:
-                {
-                    std::advance(m_it.array_iterator, -1);
-                    break;
-                }
-
-                default:
-                {
-                    --m_it.primitive_iterator;
-                    break;
-                }
-            }
-
-            return *this;
-        }
-
-        /*!
-        @brief  comparison: equal
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        bool operator==(const iter_impl& other) const
-        {
-            // if objects are not the same, the comparison is undefined
-            if (m_object != other.m_object)
-            {
-                JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
-            }
-
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    return (m_it.object_iterator == other.m_it.object_iterator);
-                }
-
-                case basic_json::value_t::array:
-                {
-                    return (m_it.array_iterator == other.m_it.array_iterator);
-                }
-
-                default:
-                {
-                    return (m_it.primitive_iterator == other.m_it.primitive_iterator);
-                }
-            }
-        }
-
-        /*!
-        @brief  comparison: not equal
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        bool operator!=(const iter_impl& other) const
-        {
-            return not operator==(other);
-        }
-
-        /*!
-        @brief  comparison: smaller
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        bool operator<(const iter_impl& other) const
-        {
-            // if objects are not the same, the comparison is undefined
-            if (m_object != other.m_object)
-            {
-                JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
-            }
-
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    JSON_THROW(std::domain_error("cannot compare order of object iterators"));
-                }
-
-                case basic_json::value_t::array:
-                {
-                    return (m_it.array_iterator < other.m_it.array_iterator);
-                }
-
-                default:
-                {
-                    return (m_it.primitive_iterator < other.m_it.primitive_iterator);
-                }
-            }
-        }
-
-        /*!
-        @brief  comparison: less than or equal
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        bool operator<=(const iter_impl& other) const
-        {
-            return not other.operator < (*this);
-        }
-
-        /*!
-        @brief  comparison: greater than
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        bool operator>(const iter_impl& other) const
-        {
-            return not operator<=(other);
-        }
-
-        /*!
-        @brief  comparison: greater than or equal
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        bool operator>=(const iter_impl& other) const
-        {
-            return not operator<(other);
-        }
-
-        /*!
-        @brief  add to iterator
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        iter_impl& operator+=(difference_type i)
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
-                }
-
-                case basic_json::value_t::array:
-                {
-                    std::advance(m_it.array_iterator, i);
-                    break;
-                }
-
-                default:
-                {
-                    m_it.primitive_iterator += i;
-                    break;
-                }
-            }
-
-            return *this;
-        }
-
-        /*!
-        @brief  subtract from iterator
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        iter_impl& operator-=(difference_type i)
-        {
-            return operator+=(-i);
-        }
-
-        /*!
-        @brief  add to iterator
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        iter_impl operator+(difference_type i)
-        {
-            auto result = *this;
-            result += i;
-            return result;
-        }
-
-        /*!
-        @brief  subtract from iterator
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        iter_impl operator-(difference_type i)
-        {
-            auto result = *this;
-            result -= i;
-            return result;
-        }
-
-        /*!
-        @brief  return difference
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        difference_type operator-(const iter_impl& other) const
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
-                }
-
-                case basic_json::value_t::array:
-                {
-                    return m_it.array_iterator - other.m_it.array_iterator;
-                }
-
-                default:
-                {
-                    return m_it.primitive_iterator - other.m_it.primitive_iterator;
-                }
-            }
-        }
-
-        /*!
-        @brief  access to successor
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        reference operator[](difference_type n) const
-        {
-            assert(m_object != nullptr);
-
-            switch (m_object->m_type)
-            {
-                case basic_json::value_t::object:
-                {
-                    JSON_THROW(std::domain_error("cannot use operator[] for object iterators"));
-                }
-
-                case basic_json::value_t::array:
-                {
-                    return *std::next(m_it.array_iterator, n);
-                }
-
-                case basic_json::value_t::null:
-                {
-                    JSON_THROW(std::out_of_range("cannot get value"));
-                }
-
-                default:
-                {
-                    if (m_it.primitive_iterator.get_value() == -n)
-                    {
-                        return *m_object;
-                    }
-
-                    JSON_THROW(std::out_of_range("cannot get value"));
-                }
-            }
-        }
-
-        /*!
-        @brief  return the key of an object iterator
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        typename object_t::key_type key() const
-        {
-            assert(m_object != nullptr);
-
-            if (m_object->is_object())
-            {
-                return m_it.object_iterator->first;
-            }
-
-            JSON_THROW(std::domain_error("cannot use key() for non-object iterators"));
-        }
-
-        /*!
-        @brief  return the value of an iterator
-        @pre The iterator is initialized; i.e. `m_object != nullptr`.
-        */
-        reference value() const
-        {
-            return operator*();
-        }
-
-      private:
-        /// associated JSON instance
-        pointer m_object = nullptr;
-        /// the actual iterator of the associated instance
-        internal_iterator m_it = internal_iterator();
-    };
+    static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
+    {
+        binary_writer<char>(o).write_cbor(j);
+    }
 
     /*!
-    @brief a template for a reverse iterator class
+    @brief create a MessagePack serialization of a given JSON value
 
-    @tparam Base the base iterator type to reverse. Valid types are @ref
-    iterator (to create @ref reverse_iterator) and @ref const_iterator (to
-    create @ref const_reverse_iterator).
+    Serializes a given JSON value @a j to a byte vector using the MessagePack
+    serialization format. MessagePack is a binary serialization format which
+    aims to be more compact than JSON itself, yet more efficient to parse.
 
-    @requirement The class satisfies the following concept requirements:
-    - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
-      The iterator that can be moved to point (forward and backward) to any
-      element in constant time.
-    - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
-      It is possible to write to the pointed-to element (only if @a Base is
-      @ref iterator).
+    The library uses the following mapping from JSON values types to
+    MessagePack types according to the MessagePack specification:
 
-    @since version 1.0.0
+    JSON value type | value/range                       | MessagePack type | first byte
+    --------------- | --------------------------------- | ---------------- | ----------
+    null            | `null`                            | nil              | 0xc0
+    boolean         | `true`                            | true             | 0xc3
+    boolean         | `false`                           | false            | 0xc2
+    number_integer  | -9223372036854775808..-2147483649 | int64            | 0xd3
+    number_integer  | -2147483648..-32769               | int32            | 0xd2
+    number_integer  | -32768..-129                      | int16            | 0xd1
+    number_integer  | -128..-33                         | int8             | 0xd0
+    number_integer  | -32..-1                           | negative fixint  | 0xe0..0xff
+    number_integer  | 0..127                            | positive fixint  | 0x00..0x7f
+    number_integer  | 128..255                          | uint 8           | 0xcc
+    number_integer  | 256..65535                        | uint 16          | 0xcd
+    number_integer  | 65536..4294967295                 | uint 32          | 0xce
+    number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xcf
+    number_unsigned | 0..127                            | positive fixint  | 0x00..0x7f
+    number_unsigned | 128..255                          | uint 8           | 0xcc
+    number_unsigned | 256..65535                        | uint 16          | 0xcd
+    number_unsigned | 65536..4294967295                 | uint 32          | 0xce
+    number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xcf
+    number_float    | *any value*                       | float 64         | 0xcb
+    string          | *length*: 0..31                   | fixstr           | 0xa0..0xbf
+    string          | *length*: 32..255                 | str 8            | 0xd9
+    string          | *length*: 256..65535              | str 16           | 0xda
+    string          | *length*: 65536..4294967295       | str 32           | 0xdb
+    array           | *size*: 0..15                     | fixarray         | 0x90..0x9f
+    array           | *size*: 16..65535                 | array 16         | 0xdc
+    array           | *size*: 65536..4294967295         | array 32         | 0xdd
+    object          | *size*: 0..15                     | fix map          | 0x80..0x8f
+    object          | *size*: 16..65535                 | map 16           | 0xde
+    object          | *size*: 65536..4294967295         | map 32           | 0xdf
+
+    @note The mapping is **complete** in the sense that any JSON value type
+          can be converted to a MessagePack value.
+
+    @note The following values can **not** be converted to a MessagePack value:
+          - strings with more than 4294967295 bytes
+          - arrays with more than 4294967295 elements
+          - objects with more than 4294967295 elements
+
+    @note The following MessagePack types are not used in the conversion:
+          - bin 8 - bin 32 (0xc4..0xc6)
+          - ext 8 - ext 32 (0xc7..0xc9)
+          - float 32 (0xca)
+          - fixext 1 - fixext 16 (0xd4..0xd8)
+
+    @note Any MessagePack output created @ref to_msgpack can be successfully
+          parsed by @ref from_msgpack.
+
+    @note If NaN or Infinity are stored inside a JSON number, they are
+          serialized properly. This behavior differs from the @ref dump()
+          function which serializes NaN or Infinity to `null`.
+
+    @param[in] j  JSON value to serialize
+    @return MessagePack serialization as byte vector
+
+    @complexity Linear in the size of the JSON value @a j.
+
+    @liveexample{The example shows the serialization of a JSON value to a byte
+    vector in MessagePack format.,to_msgpack}
+
+    @sa http://msgpack.org
+    @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
+        analogous deserialization
+    @sa @ref to_cbor(const basic_json& for the related CBOR format
+
+    @since version 2.0.9
     */
-    template<typename Base>
-    class json_reverse_iterator : public std::reverse_iterator<Base>
+    static std::vector<uint8_t> to_msgpack(const basic_json& j)
     {
-      public:
-        /// shortcut to the reverse iterator adaptor
-        using base_iterator = std::reverse_iterator<Base>;
-        /// the reference type for the pointed-to element
-        using reference = typename Base::reference;
+        std::vector<uint8_t> result;
+        to_msgpack(j, result);
+        return result;
+    }
 
-        /// create reverse iterator from iterator
-        json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
-            : base_iterator(it)
-        {}
+    static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
+    {
+        binary_writer<uint8_t>(o).write_msgpack(j);
+    }
 
-        /// create reverse iterator from base class
-        json_reverse_iterator(const base_iterator& it) noexcept
-            : base_iterator(it)
-        {}
-
-        /// post-increment (it++)
-        json_reverse_iterator operator++(int)
-        {
-            return base_iterator::operator++(1);
-        }
-
-        /// pre-increment (++it)
-        json_reverse_iterator& operator++()
-        {
-            base_iterator::operator++();
-            return *this;
-        }
-
-        /// post-decrement (it--)
-        json_reverse_iterator operator--(int)
-        {
-            return base_iterator::operator--(1);
-        }
-
-        /// pre-decrement (--it)
-        json_reverse_iterator& operator--()
-        {
-            base_iterator::operator--();
-            return *this;
-        }
-
-        /// add to iterator
-        json_reverse_iterator& operator+=(difference_type i)
-        {
-            base_iterator::operator+=(i);
-            return *this;
-        }
-
-        /// add to iterator
-        json_reverse_iterator operator+(difference_type i) const
-        {
-            auto result = *this;
-            result += i;
-            return result;
-        }
-
-        /// subtract from iterator
-        json_reverse_iterator operator-(difference_type i) const
-        {
-            auto result = *this;
-            result -= i;
-            return result;
-        }
-
-        /// return difference
-        difference_type operator-(const json_reverse_iterator& other) const
-        {
-            return this->base() - other.base();
-        }
-
-        /// access to successor
-        reference operator[](difference_type n) const
-        {
-            return *(this->operator+(n));
-        }
-
-        /// return the key of an object iterator
-        typename object_t::key_type key() const
-        {
-            auto it = --this->base();
-            return it.key();
-        }
-
-        /// return the value of an iterator
-        reference value() const
-        {
-            auto it = --this->base();
-            return it.operator * ();
-        }
-    };
-
-
-  private:
-    //////////////////////
-    // lexer and parser //
-    //////////////////////
+    static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
+    {
+        binary_writer<char>(o).write_msgpack(j);
+    }
 
     /*!
-    @brief lexical analysis
+    @brief create a JSON value from an input in CBOR format
 
-    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.
+    Deserializes a given input @a i to a JSON value using the CBOR (Concise
+    Binary Object Representation) serialization format.
+
+    The library maps CBOR types to JSON value types as follows:
+
+    CBOR type              | JSON value type | first byte
+    ---------------------- | --------------- | ----------
+    Integer                | number_unsigned | 0x00..0x17
+    Unsigned integer       | number_unsigned | 0x18
+    Unsigned integer       | number_unsigned | 0x19
+    Unsigned integer       | number_unsigned | 0x1a
+    Unsigned integer       | number_unsigned | 0x1b
+    Negative integer       | number_integer  | 0x20..0x37
+    Negative integer       | number_integer  | 0x38
+    Negative integer       | number_integer  | 0x39
+    Negative integer       | number_integer  | 0x3a
+    Negative integer       | number_integer  | 0x3b
+    Negative integer       | number_integer  | 0x40..0x57
+    UTF-8 string           | string          | 0x60..0x77
+    UTF-8 string           | string          | 0x78
+    UTF-8 string           | string          | 0x79
+    UTF-8 string           | string          | 0x7a
+    UTF-8 string           | string          | 0x7b
+    UTF-8 string           | string          | 0x7f
+    array                  | array           | 0x80..0x97
+    array                  | array           | 0x98
+    array                  | array           | 0x99
+    array                  | array           | 0x9a
+    array                  | array           | 0x9b
+    array                  | array           | 0x9f
+    map                    | object          | 0xa0..0xb7
+    map                    | object          | 0xb8
+    map                    | object          | 0xb9
+    map                    | object          | 0xba
+    map                    | object          | 0xbb
+    map                    | object          | 0xbf
+    False                  | `false`         | 0xf4
+    True                   | `true`          | 0xf5
+    Nill                   | `null`          | 0xf6
+    Half-Precision Float   | number_float    | 0xf9
+    Single-Precision Float | number_float    | 0xfa
+    Double-Precision Float | number_float    | 0xfb
+
+    @warning The mapping is **incomplete** in the sense that not all CBOR
+             types can be converted to a JSON value. The following CBOR types
+             are not supported and will yield parse errors (parse_error.112):
+             - byte strings (0x40..0x5f)
+             - date/time (0xc0..0xc1)
+             - bignum (0xc2..0xc3)
+             - decimal fraction (0xc4)
+             - bigfloat (0xc5)
+             - tagged items (0xc6..0xd4, 0xd8..0xdb)
+             - expected conversions (0xd5..0xd7)
+             - simple values (0xe0..0xf3, 0xf8)
+             - undefined (0xf7)
+
+    @warning CBOR allows map keys of any type, whereas JSON only allows
+             strings as keys in object values. Therefore, CBOR maps with keys
+             other than UTF-8 strings are rejected (parse_error.113).
+
+    @note Any CBOR output created @ref to_cbor can be successfully parsed by
+          @ref from_cbor.
+
+    @param[in] i  an input in CBOR format convertible to an input adapter
+    @param[in] strict  whether to expect the input to be consumed until EOF
+                       (true by default)
+    @return deserialized JSON value
+
+    @throw parse_error.110 if the given input ends prematurely or the end of
+    file was not reached when @a strict was set to true
+    @throw parse_error.112 if unsupported features from CBOR were
+    used in the given input @a v or if the input is not valid CBOR
+    @throw parse_error.113 if a string was expected as map key, but not found
+
+    @complexity Linear in the size of the input @a i.
+
+    @liveexample{The example shows the deserialization of a byte vector in CBOR
+    format to a JSON value.,from_cbor}
+
+    @sa http://cbor.io
+    @sa @ref to_cbor(const basic_json&) for the analogous serialization
+    @sa @ref from_msgpack(detail::input_adapter, const bool) for the
+        related MessagePack format
+
+    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
+           consume input adapters, removed start_index parameter, and added
+           @a strict parameter since 3.0.0
     */
-    class lexer
+    static basic_json from_cbor(detail::input_adapter i,
+                                const bool strict = true)
     {
-      public:
-        /// token types for the parser
-        enum class token_type
-        {
-            uninitialized,   ///< indicating the scanner is uninitialized
-            literal_true,    ///< the `true` literal
-            literal_false,   ///< the `false` literal
-            literal_null,    ///< the `null` literal
-            value_string,    ///< a string -- use get_string() for actual value
-            value_unsigned,  ///< an unsigned integer -- use get_number() for actual value
-            value_integer,   ///< a signed integer -- use get_number() for actual value
-            value_float,     ///< an floating point number -- use get_number() for actual value
-            begin_array,     ///< the character for array begin `[`
-            begin_object,    ///< the character for object begin `{`
-            end_array,       ///< the character for array end `]`
-            end_object,      ///< the character for object end `}`
-            name_separator,  ///< the name separator `:`
-            value_separator, ///< the value separator `,`
-            parse_error,     ///< indicating a parse error
-            end_of_input     ///< indicating the end of the input buffer
-        };
-
-        /// the char type to use in the lexer
-        using lexer_char_t = unsigned char;
-
-        /// a lexer from a buffer with given length
-        lexer(const lexer_char_t* buff, const size_t len) noexcept
-            : m_content(buff)
-        {
-            assert(m_content != nullptr);
-            m_start = m_cursor = m_content;
-            m_limit = m_content + len;
-        }
-
-        /// a lexer from an input stream
-        explicit lexer(std::istream& s)
-            : m_stream(&s), m_line_buffer()
-        {
-            // immediately abort if stream is erroneous
-            if (s.fail())
-            {
-                JSON_THROW(std::invalid_argument("stream error"));
-            }
-
-            // fill buffer
-            fill_line_buffer();
-
-            // skip UTF-8 byte-order mark
-            if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) == "\xEF\xBB\xBF")
-            {
-                m_line_buffer[0] = ' ';
-                m_line_buffer[1] = ' ';
-                m_line_buffer[2] = ' ';
-            }
-        }
-
-        // switch off unwanted functions (due to pointer members)
-        lexer() = delete;
-        lexer(const lexer&) = delete;
-        lexer operator=(const lexer&) = delete;
-
-        /*!
-        @brief create a string from one or two Unicode code points
-
-        There are two cases: (1) @a codepoint1 is in the Basic Multilingual
-        Plane (U+0000 through U+FFFF) and @a codepoint2 is 0, or (2)
-        @a codepoint1 and @a codepoint2 are a UTF-16 surrogate pair to
-        represent a code point above U+FFFF.
-
-        @param[in] codepoint1  the code point (can be high surrogate)
-        @param[in] codepoint2  the code point (can be low surrogate or 0)
-
-        @return string representation of the code point; the length of the
-        result string is between 1 and 4 characters.
-
-        @throw std::out_of_range if code point is > 0x10ffff; example: `"code
-        points above 0x10FFFF are invalid"`
-        @throw std::invalid_argument if the low surrogate is invalid; example:
-        `""missing or wrong low surrogate""`
-
-        @complexity Constant.
-
-        @see <http://en.wikipedia.org/wiki/UTF-8#Sample_code>
-        */
-        static string_t to_unicode(const std::size_t codepoint1,
-                                   const std::size_t codepoint2 = 0)
-        {
-            // calculate the code point from the given code points
-            std::size_t codepoint = codepoint1;
-
-            // check if codepoint1 is a high surrogate
-            if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
-            {
-                // check if codepoint2 is a low surrogate
-                if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
-                {
-                    codepoint =
-                        // high surrogate occupies the most significant 22 bits
-                        (codepoint1 << 10)
-                        // low surrogate occupies the least significant 15 bits
-                        + codepoint2
-                        // there is still the 0xD800, 0xDC00 and 0x10000 noise
-                        // in the result so we have to subtract with:
-                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
-                        - 0x35FDC00;
-                }
-                else
-                {
-                    JSON_THROW(std::invalid_argument("missing or wrong low surrogate"));
-                }
-            }
-
-            string_t result;
-
-            if (codepoint < 0x80)
-            {
-                // 1-byte characters: 0xxxxxxx (ASCII)
-                result.append(1, static_cast<typename string_t::value_type>(codepoint));
-            }
-            else if (codepoint <= 0x7ff)
-            {
-                // 2-byte characters: 110xxxxx 10xxxxxx
-                result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
-                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
-            }
-            else if (codepoint <= 0xffff)
-            {
-                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
-                result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
-                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
-                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
-            }
-            else if (codepoint <= 0x10ffff)
-            {
-                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-                result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
-                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
-                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
-                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
-            }
-            else
-            {
-                JSON_THROW(std::out_of_range("code points above 0x10FFFF are invalid"));
-            }
-
-            return result;
-        }
-
-        /// return name of values of type token_type (only used for errors)
-        static std::string token_type_name(const token_type t)
-        {
-            switch (t)
-            {
-                case token_type::uninitialized:
-                    return "<uninitialized>";
-                case token_type::literal_true:
-                    return "true literal";
-                case token_type::literal_false:
-                    return "false literal";
-                case token_type::literal_null:
-                    return "null literal";
-                case token_type::value_string:
-                    return "string literal";
-                case lexer::token_type::value_unsigned:
-                case lexer::token_type::value_integer:
-                case lexer::token_type::value_float:
-                    return "number literal";
-                case token_type::begin_array:
-                    return "'['";
-                case token_type::begin_object:
-                    return "'{'";
-                case token_type::end_array:
-                    return "']'";
-                case token_type::end_object:
-                    return "'}'";
-                case token_type::name_separator:
-                    return "':'";
-                case token_type::value_separator:
-                    return "','";
-                case token_type::parse_error:
-                    return "<parse error>";
-                case token_type::end_of_input:
-                    return "end of input";
-                default:
-                {
-                    // catch non-enum values
-                    return "unknown token"; // LCOV_EXCL_LINE
-                }
-            }
-        }
-
-        /*!
-        This function implements a scanner for JSON. It is specified using
-        regular expressions that try to follow RFC 7159 as close as possible.
-        These regular expressions are then translated into a minimized
-        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
-
-        @complexity Linear in the length of the input.\n
-
-        Proposition: The loop below will always terminate for finite input.\n
-
-        Proof (by contradiction): Assume a finite input. To loop forever, the
-        loop must never hit code with a `break` statement. The only code
-        snippets without a `break` statement are the continue statements for
-        whitespace and byte-order-marks. To loop forever, the input must be an
-        infinite sequence of whitespace or byte-order-marks. This contradicts
-        the assumption of finite input, q.e.d.
-        */
-        token_type scan()
-        {
-            while (true)
-            {
-                // pointer for backtracking information
-                m_marker = nullptr;
-
-                // remember the begin of the token
-                m_start = m_cursor;
-                assert(m_start != nullptr);
-
-
-                {
-                    lexer_char_t yych;
-                    unsigned int yyaccept = 0;
-                    static const unsigned char yybm[] =
-                    {
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,  32,  32,   0,   0,  32,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        160, 128,   0, 128, 128, 128, 128, 128,
-                        128, 128, 128, 128, 128, 128, 128, 128,
-                        192, 192, 192, 192, 192, 192, 192, 192,
-                        192, 192, 128, 128, 128, 128, 128, 128,
-                        128, 128, 128, 128, 128, 128, 128, 128,
-                        128, 128, 128, 128, 128, 128, 128, 128,
-                        128, 128, 128, 128, 128, 128, 128, 128,
-                        128, 128, 128, 128,   0, 128, 128, 128,
-                        128, 128, 128, 128, 128, 128, 128, 128,
-                        128, 128, 128, 128, 128, 128, 128, 128,
-                        128, 128, 128, 128, 128, 128, 128, 128,
-                        128, 128, 128, 128, 128, 128, 128, 128,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                        0,   0,   0,   0,   0,   0,   0,   0,
-                    };
-                    if ((m_limit - m_cursor) < 5)
-                    {
-                        fill_line_buffer(5);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yybm[0 + yych] & 32)
-                    {
-                        goto basic_json_parser_6;
-                    }
-                    if (yych <= '[')
-                    {
-                        if (yych <= '-')
-                        {
-                            if (yych <= '"')
-                            {
-                                if (yych <= 0x00)
-                                {
-                                    goto basic_json_parser_2;
-                                }
-                                if (yych <= '!')
-                                {
-                                    goto basic_json_parser_4;
-                                }
-                                goto basic_json_parser_9;
-                            }
-                            else
-                            {
-                                if (yych <= '+')
-                                {
-                                    goto basic_json_parser_4;
-                                }
-                                if (yych <= ',')
-                                {
-                                    goto basic_json_parser_10;
-                                }
-                                goto basic_json_parser_12;
-                            }
-                        }
-                        else
-                        {
-                            if (yych <= '9')
-                            {
-                                if (yych <= '/')
-                                {
-                                    goto basic_json_parser_4;
-                                }
-                                if (yych <= '0')
-                                {
-                                    goto basic_json_parser_13;
-                                }
-                                goto basic_json_parser_15;
-                            }
-                            else
-                            {
-                                if (yych <= ':')
-                                {
-                                    goto basic_json_parser_17;
-                                }
-                                if (yych <= 'Z')
-                                {
-                                    goto basic_json_parser_4;
-                                }
-                                goto basic_json_parser_19;
-                            }
-                        }
-                    }
-                    else
-                    {
-                        if (yych <= 'n')
-                        {
-                            if (yych <= 'e')
-                            {
-                                if (yych == ']')
-                                {
-                                    goto basic_json_parser_21;
-                                }
-                                goto basic_json_parser_4;
-                            }
-                            else
-                            {
-                                if (yych <= 'f')
-                                {
-                                    goto basic_json_parser_23;
-                                }
-                                if (yych <= 'm')
-                                {
-                                    goto basic_json_parser_4;
-                                }
-                                goto basic_json_parser_24;
-                            }
-                        }
-                        else
-                        {
-                            if (yych <= 'z')
-                            {
-                                if (yych == 't')
-                                {
-                                    goto basic_json_parser_25;
-                                }
-                                goto basic_json_parser_4;
-                            }
-                            else
-                            {
-                                if (yych <= '{')
-                                {
-                                    goto basic_json_parser_26;
-                                }
-                                if (yych == '}')
-                                {
-                                    goto basic_json_parser_28;
-                                }
-                                goto basic_json_parser_4;
-                            }
-                        }
-                    }
-basic_json_parser_2:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::end_of_input;
-                        break;
-                    }
-basic_json_parser_4:
-                    ++m_cursor;
-basic_json_parser_5:
-                    {
-                        last_token_type = token_type::parse_error;
-                        break;
-                    }
-basic_json_parser_6:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yybm[0 + yych] & 32)
-                    {
-                        goto basic_json_parser_6;
-                    }
-                    {
-                        continue;
-                    }
-basic_json_parser_9:
-                    yyaccept = 0;
-                    yych = *(m_marker = ++m_cursor);
-                    if (yych <= 0x1F)
-                    {
-                        goto basic_json_parser_5;
-                    }
-                    if (yych <= 0x7F)
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    if (yych <= 0xC1)
-                    {
-                        goto basic_json_parser_5;
-                    }
-                    if (yych <= 0xF4)
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    goto basic_json_parser_5;
-basic_json_parser_10:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::value_separator;
-                        break;
-                    }
-basic_json_parser_12:
-                    yych = *++m_cursor;
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_5;
-                    }
-                    if (yych <= '0')
-                    {
-                        goto basic_json_parser_43;
-                    }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_45;
-                    }
-                    goto basic_json_parser_5;
-basic_json_parser_13:
-                    yyaccept = 1;
-                    yych = *(m_marker = ++m_cursor);
-                    if (yych <= '9')
-                    {
-                        if (yych == '.')
-                        {
-                            goto basic_json_parser_47;
-                        }
-                        if (yych >= '0')
-                        {
-                            goto basic_json_parser_48;
-                        }
-                    }
-                    else
-                    {
-                        if (yych <= 'E')
-                        {
-                            if (yych >= 'E')
-                            {
-                                goto basic_json_parser_51;
-                            }
-                        }
-                        else
-                        {
-                            if (yych == 'e')
-                            {
-                                goto basic_json_parser_51;
-                            }
-                        }
-                    }
-basic_json_parser_14:
-                    {
-                        last_token_type = token_type::value_unsigned;
-                        break;
-                    }
-basic_json_parser_15:
-                    yyaccept = 1;
-                    m_marker = ++m_cursor;
-                    if ((m_limit - m_cursor) < 3)
-                    {
-                        fill_line_buffer(3);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yybm[0 + yych] & 64)
-                    {
-                        goto basic_json_parser_15;
-                    }
-                    if (yych <= 'D')
-                    {
-                        if (yych == '.')
-                        {
-                            goto basic_json_parser_47;
-                        }
-                        goto basic_json_parser_14;
-                    }
-                    else
-                    {
-                        if (yych <= 'E')
-                        {
-                            goto basic_json_parser_51;
-                        }
-                        if (yych == 'e')
-                        {
-                            goto basic_json_parser_51;
-                        }
-                        goto basic_json_parser_14;
-                    }
-basic_json_parser_17:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::name_separator;
-                        break;
-                    }
-basic_json_parser_19:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::begin_array;
-                        break;
-                    }
-basic_json_parser_21:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::end_array;
-                        break;
-                    }
-basic_json_parser_23:
-                    yyaccept = 0;
-                    yych = *(m_marker = ++m_cursor);
-                    if (yych == 'a')
-                    {
-                        goto basic_json_parser_52;
-                    }
-                    goto basic_json_parser_5;
-basic_json_parser_24:
-                    yyaccept = 0;
-                    yych = *(m_marker = ++m_cursor);
-                    if (yych == 'u')
-                    {
-                        goto basic_json_parser_53;
-                    }
-                    goto basic_json_parser_5;
-basic_json_parser_25:
-                    yyaccept = 0;
-                    yych = *(m_marker = ++m_cursor);
-                    if (yych == 'r')
-                    {
-                        goto basic_json_parser_54;
-                    }
-                    goto basic_json_parser_5;
-basic_json_parser_26:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::begin_object;
-                        break;
-                    }
-basic_json_parser_28:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::end_object;
-                        break;
-                    }
-basic_json_parser_30:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-basic_json_parser_31:
-                    if (yybm[0 + yych] & 128)
-                    {
-                        goto basic_json_parser_30;
-                    }
-                    if (yych <= 0xE0)
-                    {
-                        if (yych <= '\\')
-                        {
-                            if (yych <= 0x1F)
-                            {
-                                goto basic_json_parser_32;
-                            }
-                            if (yych <= '"')
-                            {
-                                goto basic_json_parser_33;
-                            }
-                            goto basic_json_parser_35;
-                        }
-                        else
-                        {
-                            if (yych <= 0xC1)
-                            {
-                                goto basic_json_parser_32;
-                            }
-                            if (yych <= 0xDF)
-                            {
-                                goto basic_json_parser_36;
-                            }
-                            goto basic_json_parser_37;
-                        }
-                    }
-                    else
-                    {
-                        if (yych <= 0xEF)
-                        {
-                            if (yych == 0xED)
-                            {
-                                goto basic_json_parser_39;
-                            }
-                            goto basic_json_parser_38;
-                        }
-                        else
-                        {
-                            if (yych <= 0xF0)
-                            {
-                                goto basic_json_parser_40;
-                            }
-                            if (yych <= 0xF3)
-                            {
-                                goto basic_json_parser_41;
-                            }
-                            if (yych <= 0xF4)
-                            {
-                                goto basic_json_parser_42;
-                            }
-                        }
-                    }
-basic_json_parser_32:
-                    m_cursor = m_marker;
-                    if (yyaccept <= 1)
-                    {
-                        if (yyaccept == 0)
-                        {
-                            goto basic_json_parser_5;
-                        }
-                        else
-                        {
-                            goto basic_json_parser_14;
-                        }
-                    }
-                    else
-                    {
-                        if (yyaccept == 2)
-                        {
-                            goto basic_json_parser_44;
-                        }
-                        else
-                        {
-                            goto basic_json_parser_58;
-                        }
-                    }
-basic_json_parser_33:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::value_string;
-                        break;
-                    }
-basic_json_parser_35:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 'e')
-                    {
-                        if (yych <= '/')
-                        {
-                            if (yych == '"')
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            if (yych <= '.')
-                            {
-                                goto basic_json_parser_32;
-                            }
-                            goto basic_json_parser_30;
-                        }
-                        else
-                        {
-                            if (yych <= '\\')
-                            {
-                                if (yych <= '[')
-                                {
-                                    goto basic_json_parser_32;
-                                }
-                                goto basic_json_parser_30;
-                            }
-                            else
-                            {
-                                if (yych == 'b')
-                                {
-                                    goto basic_json_parser_30;
-                                }
-                                goto basic_json_parser_32;
-                            }
-                        }
-                    }
-                    else
-                    {
-                        if (yych <= 'q')
-                        {
-                            if (yych <= 'f')
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            if (yych == 'n')
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            goto basic_json_parser_32;
-                        }
-                        else
-                        {
-                            if (yych <= 's')
-                            {
-                                if (yych <= 'r')
-                                {
-                                    goto basic_json_parser_30;
-                                }
-                                goto basic_json_parser_32;
-                            }
-                            else
-                            {
-                                if (yych <= 't')
-                                {
-                                    goto basic_json_parser_30;
-                                }
-                                if (yych <= 'u')
-                                {
-                                    goto basic_json_parser_55;
-                                }
-                                goto basic_json_parser_32;
-                            }
-                        }
-                    }
-basic_json_parser_36:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 0x7F)
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych <= 0xBF)
-                    {
-                        goto basic_json_parser_30;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_37:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 0x9F)
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych <= 0xBF)
-                    {
-                        goto basic_json_parser_36;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_38:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 0x7F)
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych <= 0xBF)
-                    {
-                        goto basic_json_parser_36;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_39:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 0x7F)
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych <= 0x9F)
-                    {
-                        goto basic_json_parser_36;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_40:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 0x8F)
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych <= 0xBF)
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_41:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 0x7F)
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych <= 0xBF)
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_42:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 0x7F)
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych <= 0x8F)
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_43:
-                    yyaccept = 2;
-                    yych = *(m_marker = ++m_cursor);
-                    if (yych <= '9')
-                    {
-                        if (yych == '.')
-                        {
-                            goto basic_json_parser_47;
-                        }
-                        if (yych >= '0')
-                        {
-                            goto basic_json_parser_48;
-                        }
-                    }
-                    else
-                    {
-                        if (yych <= 'E')
-                        {
-                            if (yych >= 'E')
-                            {
-                                goto basic_json_parser_51;
-                            }
-                        }
-                        else
-                        {
-                            if (yych == 'e')
-                            {
-                                goto basic_json_parser_51;
-                            }
-                        }
-                    }
-basic_json_parser_44:
-                    {
-                        last_token_type = token_type::value_integer;
-                        break;
-                    }
-basic_json_parser_45:
-                    yyaccept = 2;
-                    m_marker = ++m_cursor;
-                    if ((m_limit - m_cursor) < 3)
-                    {
-                        fill_line_buffer(3);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= '9')
-                    {
-                        if (yych == '.')
-                        {
-                            goto basic_json_parser_47;
-                        }
-                        if (yych <= '/')
-                        {
-                            goto basic_json_parser_44;
-                        }
-                        goto basic_json_parser_45;
-                    }
-                    else
-                    {
-                        if (yych <= 'E')
-                        {
-                            if (yych <= 'D')
-                            {
-                                goto basic_json_parser_44;
-                            }
-                            goto basic_json_parser_51;
-                        }
-                        else
-                        {
-                            if (yych == 'e')
-                            {
-                                goto basic_json_parser_51;
-                            }
-                            goto basic_json_parser_44;
-                        }
-                    }
-basic_json_parser_47:
-                    yych = *++m_cursor;
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_56;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_48:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_50;
-                    }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_48;
-                    }
-basic_json_parser_50:
-                    {
-                        last_token_type = token_type::parse_error;
-                        break;
-                    }
-basic_json_parser_51:
-                    yych = *++m_cursor;
-                    if (yych <= ',')
-                    {
-                        if (yych == '+')
-                        {
-                            goto basic_json_parser_59;
-                        }
-                        goto basic_json_parser_32;
-                    }
-                    else
-                    {
-                        if (yych <= '-')
-                        {
-                            goto basic_json_parser_59;
-                        }
-                        if (yych <= '/')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= '9')
-                        {
-                            goto basic_json_parser_60;
-                        }
-                        goto basic_json_parser_32;
-                    }
-basic_json_parser_52:
-                    yych = *++m_cursor;
-                    if (yych == 'l')
-                    {
-                        goto basic_json_parser_62;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_53:
-                    yych = *++m_cursor;
-                    if (yych == 'l')
-                    {
-                        goto basic_json_parser_63;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_54:
-                    yych = *++m_cursor;
-                    if (yych == 'u')
-                    {
-                        goto basic_json_parser_64;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_55:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= '@')
-                    {
-                        if (yych <= '/')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= '9')
-                        {
-                            goto basic_json_parser_65;
-                        }
-                        goto basic_json_parser_32;
-                    }
-                    else
-                    {
-                        if (yych <= 'F')
-                        {
-                            goto basic_json_parser_65;
-                        }
-                        if (yych <= '`')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= 'f')
-                        {
-                            goto basic_json_parser_65;
-                        }
-                        goto basic_json_parser_32;
-                    }
-basic_json_parser_56:
-                    yyaccept = 3;
-                    m_marker = ++m_cursor;
-                    if ((m_limit - m_cursor) < 3)
-                    {
-                        fill_line_buffer(3);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= 'D')
-                    {
-                        if (yych <= '/')
-                        {
-                            goto basic_json_parser_58;
-                        }
-                        if (yych <= '9')
-                        {
-                            goto basic_json_parser_56;
-                        }
-                    }
-                    else
-                    {
-                        if (yych <= 'E')
-                        {
-                            goto basic_json_parser_51;
-                        }
-                        if (yych == 'e')
-                        {
-                            goto basic_json_parser_51;
-                        }
-                    }
-basic_json_parser_58:
-                    {
-                        last_token_type = token_type::value_float;
-                        break;
-                    }
-basic_json_parser_59:
-                    yych = *++m_cursor;
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_32;
-                    }
-                    if (yych >= ':')
-                    {
-                        goto basic_json_parser_32;
-                    }
-basic_json_parser_60:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= '/')
-                    {
-                        goto basic_json_parser_58;
-                    }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_60;
-                    }
-                    goto basic_json_parser_58;
-basic_json_parser_62:
-                    yych = *++m_cursor;
-                    if (yych == 's')
-                    {
-                        goto basic_json_parser_66;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_63:
-                    yych = *++m_cursor;
-                    if (yych == 'l')
-                    {
-                        goto basic_json_parser_67;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_64:
-                    yych = *++m_cursor;
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_69;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_65:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= '@')
-                    {
-                        if (yych <= '/')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= '9')
-                        {
-                            goto basic_json_parser_71;
-                        }
-                        goto basic_json_parser_32;
-                    }
-                    else
-                    {
-                        if (yych <= 'F')
-                        {
-                            goto basic_json_parser_71;
-                        }
-                        if (yych <= '`')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= 'f')
-                        {
-                            goto basic_json_parser_71;
-                        }
-                        goto basic_json_parser_32;
-                    }
-basic_json_parser_66:
-                    yych = *++m_cursor;
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_72;
-                    }
-                    goto basic_json_parser_32;
-basic_json_parser_67:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::literal_null;
-                        break;
-                    }
-basic_json_parser_69:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::literal_true;
-                        break;
-                    }
-basic_json_parser_71:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= '@')
-                    {
-                        if (yych <= '/')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= '9')
-                        {
-                            goto basic_json_parser_74;
-                        }
-                        goto basic_json_parser_32;
-                    }
-                    else
-                    {
-                        if (yych <= 'F')
-                        {
-                            goto basic_json_parser_74;
-                        }
-                        if (yych <= '`')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= 'f')
-                        {
-                            goto basic_json_parser_74;
-                        }
-                        goto basic_json_parser_32;
-                    }
-basic_json_parser_72:
-                    ++m_cursor;
-                    {
-                        last_token_type = token_type::literal_false;
-                        break;
-                    }
-basic_json_parser_74:
-                    ++m_cursor;
-                    if (m_limit <= m_cursor)
-                    {
-                        fill_line_buffer(1);    // LCOV_EXCL_LINE
-                    }
-                    yych = *m_cursor;
-                    if (yych <= '@')
-                    {
-                        if (yych <= '/')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= '9')
-                        {
-                            goto basic_json_parser_30;
-                        }
-                        goto basic_json_parser_32;
-                    }
-                    else
-                    {
-                        if (yych <= 'F')
-                        {
-                            goto basic_json_parser_30;
-                        }
-                        if (yych <= '`')
-                        {
-                            goto basic_json_parser_32;
-                        }
-                        if (yych <= 'f')
-                        {
-                            goto basic_json_parser_30;
-                        }
-                        goto basic_json_parser_32;
-                    }
-                }
-
-            }
-
-            return last_token_type;
-        }
-
-        /*!
-        @brief append data from the stream to the line buffer
-
-        This function is called by the scan() function when the end of the
-        buffer (`m_limit`) is reached and the `m_cursor` pointer cannot be
-        incremented without leaving the limits of the line buffer. Note re2c
-        decides when to call this function.
-
-        If the lexer reads from contiguous storage, there is no trailing null
-        byte. Therefore, this function must make sure to add these padding
-        null bytes.
-
-        If the lexer reads from an input stream, this function reads the next
-        line of the input.
-
-        @pre
-            p p p p p p u u u u u x . . . . . .
-            ^           ^       ^   ^
-            m_content   m_start |   m_limit
-                                m_cursor
-
-        @post
-            u u u u u x x x x x x x . . . . . .
-            ^       ^               ^
-            |       m_cursor        m_limit
-            m_start
-            m_content
-        */
-        void fill_line_buffer(size_t n = 0)
-        {
-            // if line buffer is used, m_content points to its data
-            assert(m_line_buffer.empty()
-                   or m_content == reinterpret_cast<const lexer_char_t*>(m_line_buffer.data()));
-
-            // if line buffer is used, m_limit is set past the end of its data
-            assert(m_line_buffer.empty()
-                   or m_limit == m_content + m_line_buffer.size());
-
-            // pointer relationships
-            assert(m_content <= m_start);
-            assert(m_start <= m_cursor);
-            assert(m_cursor <= m_limit);
-            assert(m_marker == nullptr or m_marker  <= m_limit);
-
-            // number of processed characters (p)
-            const auto num_processed_chars = static_cast<size_t>(m_start - m_content);
-            // offset for m_marker wrt. to m_start
-            const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start;
-            // number of unprocessed characters (u)
-            const auto offset_cursor = m_cursor - m_start;
-
-            // no stream is used or end of file is reached
-            if (m_stream == nullptr or m_stream->eof())
-            {
-                // m_start may or may not be pointing into m_line_buffer at
-                // this point. We trust the standard library to do the right
-                // thing. See http://stackoverflow.com/q/28142011/266378
-                m_line_buffer.assign(m_start, m_limit);
-
-                // append n characters to make sure that there is sufficient
-                // space between m_cursor and m_limit
-                m_line_buffer.append(1, '\x00');
-                if (n > 0)
-                {
-                    m_line_buffer.append(n - 1, '\x01');
-                }
-            }
-            else
-            {
-                // delete processed characters from line buffer
-                m_line_buffer.erase(0, num_processed_chars);
-                // read next line from input stream
-                m_line_buffer_tmp.clear();
-                std::getline(*m_stream, m_line_buffer_tmp, '\n');
-
-                // add line with newline symbol to the line buffer
-                m_line_buffer += m_line_buffer_tmp;
-                m_line_buffer.push_back('\n');
-            }
-
-            // set pointers
-            m_content = reinterpret_cast<const lexer_char_t*>(m_line_buffer.data());
-            assert(m_content != nullptr);
-            m_start  = m_content;
-            m_marker = m_start + offset_marker;
-            m_cursor = m_start + offset_cursor;
-            m_limit  = m_start + m_line_buffer.size();
-        }
-
-        /// return string representation of last read token
-        string_t get_token_string() const
-        {
-            assert(m_start != nullptr);
-            return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
-                            static_cast<size_t>(m_cursor - m_start));
-        }
-
-        /*!
-        @brief return string value for string tokens
-
-        The function iterates the characters between the opening and closing
-        quotes of the string value. The complete string is the range
-        [m_start,m_cursor). Consequently, we iterate from m_start+1 to
-        m_cursor-1.
-
-        We differentiate two cases:
-
-        1. Escaped characters. In this case, a new character is constructed
-           according to the nature of the escape. Some escapes create new
-           characters (e.g., `"\\n"` is replaced by `"\n"`), some are copied
-           as is (e.g., `"\\\\"`). Furthermore, Unicode escapes of the shape
-           `"\\uxxxx"` need special care. In this case, to_unicode takes care
-           of the construction of the values.
-        2. Unescaped characters are copied as is.
-
-        @pre `m_cursor - m_start >= 2`, meaning the length of the last token
-        is at least 2 bytes which is trivially true for any string (which
-        consists of at least two quotes).
-
-            " c1 c2 c3 ... "
-            ^                ^
-            m_start          m_cursor
-
-        @complexity Linear in the length of the string.\n
-
-        Lemma: The loop body will always terminate.\n
-
-        Proof (by contradiction): Assume the loop body does not terminate. As
-        the loop body does not contain another loop, one of the called
-        functions must never return. The called functions are `std::strtoul`
-        and to_unicode. Neither function can loop forever, so the loop body
-        will never loop forever which contradicts the assumption that the loop
-        body does not terminate, q.e.d.\n
-
-        Lemma: The loop condition for the for loop is eventually false.\n
-
-        Proof (by contradiction): Assume the loop does not terminate. Due to
-        the above lemma, this can only be due to a tautological loop
-        condition; that is, the loop condition i < m_cursor - 1 must always be
-        true. Let x be the change of i for any loop iteration. Then
-        m_start + 1 + x < m_cursor - 1 must hold to loop indefinitely. This
-        can be rephrased to m_cursor - m_start - 2 > x. With the
-        precondition, we x <= 0, meaning that the loop condition holds
-        indefinitely if i is always decreased. However, observe that the value
-        of i is strictly increasing with each iteration, as it is incremented
-        by 1 in the iteration expression and never decremented inside the loop
-        body. Hence, the loop condition will eventually be false which
-        contradicts the assumption that the loop condition is a tautology,
-        q.e.d.
-
-        @return string value of current token without opening and closing
-        quotes
-        @throw std::out_of_range if to_unicode fails
-        */
-        string_t get_string() const
-        {
-            assert(m_cursor - m_start >= 2);
-
-            string_t result;
-            result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
-
-            // iterate the result between the quotes
-            for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
-            {
-                // find next escape character
-                auto e = std::find(i, m_cursor - 1, '\\');
-                if (e != i)
-                {
-                    // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705
-                    for (auto k = i; k < e; k++)
-                    {
-                        result.push_back(static_cast<typename string_t::value_type>(*k));
-                    }
-                    i = e - 1; // -1 because of ++i
-                }
-                else
-                {
-                    // processing escaped character
-                    // read next character
-                    ++i;
-
-                    switch (*i)
-                    {
-                        // the default escapes
-                        case 't':
-                        {
-                            result += "\t";
-                            break;
-                        }
-                        case 'b':
-                        {
-                            result += "\b";
-                            break;
-                        }
-                        case 'f':
-                        {
-                            result += "\f";
-                            break;
-                        }
-                        case 'n':
-                        {
-                            result += "\n";
-                            break;
-                        }
-                        case 'r':
-                        {
-                            result += "\r";
-                            break;
-                        }
-                        case '\\':
-                        {
-                            result += "\\";
-                            break;
-                        }
-                        case '/':
-                        {
-                            result += "/";
-                            break;
-                        }
-                        case '"':
-                        {
-                            result += "\"";
-                            break;
-                        }
-
-                        // unicode
-                        case 'u':
-                        {
-                            // get code xxxx from uxxxx
-                            auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
-                                                          4).c_str(), nullptr, 16);
-
-                            // check if codepoint is a high surrogate
-                            if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
-                            {
-                                // make sure there is a subsequent unicode
-                                if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
-                                {
-                                    JSON_THROW(std::invalid_argument("missing low surrogate"));
-                                }
-
-                                // get code yyyy from uxxxx\uyyyy
-                                auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
-                                                               (i + 7), 4).c_str(), nullptr, 16);
-                                result += to_unicode(codepoint, codepoint2);
-                                // skip the next 10 characters (xxxx\uyyyy)
-                                i += 10;
-                            }
-                            else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
-                            {
-                                // we found a lone low surrogate
-                                JSON_THROW(std::invalid_argument("missing high surrogate"));
-                            }
-                            else
-                            {
-                                // add unicode character(s)
-                                result += to_unicode(codepoint);
-                                // skip the next four characters (xxxx)
-                                i += 4;
-                            }
-                            break;
-                        }
-                    }
-                }
-            }
-
-            return result;
-        }
-
-
-        /*!
-        @brief parse string into a built-in arithmetic type as if the current
-               locale is POSIX.
-
-        @note in floating-point case strtod may parse past the token's end -
-              this is not an error
-
-        @note any leading blanks are not handled
-        */
-        struct strtonum
-        {
-          public:
-            strtonum(const char* start, const char* end)
-                : m_start(start), m_end(end)
-            {}
-
-            /*!
-            @return true iff parsed successfully as number of type T
-
-            @param[in,out] val shall contain parsed value, or undefined value
-            if could not parse
-            */
-            template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
-            bool to(T& val) const
-            {
-                return parse(val, std::is_integral<T>());
-            }
-
-          private:
-            const char* const m_start = nullptr;
-            const char* const m_end = nullptr;
-
-            // floating-point conversion
-
-            // overloaded wrappers for strtod/strtof/strtold
-            // that will be called from parse<floating_point_t>
-            static void strtof(float& f, const char* str, char** endptr)
-            {
-                f = std::strtof(str, endptr);
-            }
-
-            static void strtof(double& f, const char* str, char** endptr)
-            {
-                f = std::strtod(str, endptr);
-            }
-
-            static void strtof(long double& f, const char* str, char** endptr)
-            {
-                f = std::strtold(str, endptr);
-            }
-
-            template<typename T>
-            bool parse(T& value, /*is_integral=*/std::false_type) const
-            {
-                // replace decimal separator with locale-specific version,
-                // when necessary; data will point to either the original
-                // string, or buf, or tempstr containing the fixed string.
-                std::string tempstr;
-                std::array<char, 64> buf;
-                const size_t len = static_cast<size_t>(m_end - m_start);
-
-                // lexer will reject empty numbers
-                assert(len > 0);
-
-                // since dealing with strtod family of functions, we're
-                // getting the decimal point char from the C locale facilities
-                // instead of C++'s numpunct facet of the current std::locale
-                const auto loc = localeconv();
-                assert(loc != nullptr);
-                const char decimal_point_char = (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
-
-                const char* data = m_start;
-
-                if (decimal_point_char != '.')
-                {
-                    const size_t ds_pos = static_cast<size_t>(std::find(m_start, m_end, '.') - m_start);
-
-                    if (ds_pos != len)
-                    {
-                        // copy the data into the local buffer or tempstr, if
-                        // buffer is too small; replace decimal separator, and
-                        // update data to point to the modified bytes
-                        if ((len + 1) < buf.size())
-                        {
-                            std::copy(m_start, m_end, buf.begin());
-                            buf[len] = 0;
-                            buf[ds_pos] = decimal_point_char;
-                            data = buf.data();
-                        }
-                        else
-                        {
-                            tempstr.assign(m_start, m_end);
-                            tempstr[ds_pos] = decimal_point_char;
-                            data = tempstr.c_str();
-                        }
-                    }
-                }
-
-                char* endptr = nullptr;
-                value = 0;
-                // this calls appropriate overload depending on T
-                strtof(value, data, &endptr);
-
-                // parsing was successful iff strtof parsed exactly the number
-                // of characters determined by the lexer (len)
-                const bool ok = (endptr == (data + len));
-
-                if (ok and (value == static_cast<T>(0.0)) and (*data == '-'))
-                {
-                    // some implementations forget to negate the zero
-                    value = -0.0;
-                }
-
-                return ok;
-            }
-
-            // integral conversion
-
-            signed long long parse_integral(char** endptr, /*is_signed*/std::true_type) const
-            {
-                return std::strtoll(m_start, endptr, 10);
-            }
-
-            unsigned long long parse_integral(char** endptr, /*is_signed*/std::false_type) const
-            {
-                return std::strtoull(m_start, endptr, 10);
-            }
-
-            template<typename T>
-            bool parse(T& value, /*is_integral=*/std::true_type) const
-            {
-                char* endptr = nullptr;
-                errno = 0; // these are thread-local
-                const auto x = parse_integral(&endptr, std::is_signed<T>());
-
-                // called right overload?
-                static_assert(std::is_signed<T>() == std::is_signed<decltype(x)>(), "");
-
-                value = static_cast<T>(x);
-
-                return (x == static_cast<decltype(x)>(value)) // x fits into destination T
-                       and (x < 0) == (value < 0)             // preserved sign
-                       //and ((x != 0) or is_integral())        // strto[u]ll did nto fail
-                       and (errno == 0)                       // strto[u]ll did not overflow
-                       and (m_start < m_end)                  // token was not empty
-                       and (endptr == m_end);                 // parsed entire token exactly
-            }
-        };
-
-        /*!
-        @brief return number value for number tokens
-
-        This function translates the last token into the most appropriate
-        number type (either integer, unsigned integer or floating point),
-        which is passed back to the caller via the result parameter.
-
-        integral numbers that don't fit into the the range of the respective
-        type are parsed as number_float_t
-
-        floating-point values do not satisfy std::isfinite predicate
-        are converted to value_t::null
-
-        throws if the entire string [m_start .. m_cursor) cannot be
-        interpreted as a number
-
-        @param[out] result  @ref basic_json object to receive the number.
-        @param[in]  token   the type of the number token
-        */
-        bool get_number(basic_json& result, const token_type token) const
-        {
-            assert(m_start != nullptr);
-            assert(m_start < m_cursor);
-            assert((token == token_type::value_unsigned) or
-                   (token == token_type::value_integer) or
-                   (token == token_type::value_float));
-
-            strtonum num_converter(reinterpret_cast<const char*>(m_start),
-                                   reinterpret_cast<const char*>(m_cursor));
-
-            switch (token)
-            {
-                case lexer::token_type::value_unsigned:
-                {
-                    number_unsigned_t val;
-                    if (num_converter.to(val))
-                    {
-                        // parsing successful
-                        result.m_type = value_t::number_unsigned;
-                        result.m_value = val;
-                        return true;
-                    }
-                    break;
-                }
-
-                case lexer::token_type::value_integer:
-                {
-                    number_integer_t val;
-                    if (num_converter.to(val))
-                    {
-                        // parsing successful
-                        result.m_type = value_t::number_integer;
-                        result.m_value = val;
-                        return true;
-                    }
-                    break;
-                }
-
-                default:
-                {
-                    break;
-                }
-            }
-
-            // parse float (either explicitly or because a previous conversion
-            // failed)
-            number_float_t val;
-            if (num_converter.to(val))
-            {
-                // parsing successful
-                result.m_type = value_t::number_float;
-                result.m_value = val;
-
-                // replace infinity and NAN by null
-                if (not std::isfinite(result.m_value.number_float))
-                {
-                    result.m_type  = value_t::null;
-                    result.m_value = basic_json::json_value();
-                }
-
-                return true;
-            }
-
-            // couldn't parse number in any format
-            return false;
-        }
-
-      private:
-        /// optional input stream
-        std::istream* m_stream = nullptr;
-        /// line buffer buffer for m_stream
-        string_t m_line_buffer {};
-        /// used for filling m_line_buffer
-        string_t m_line_buffer_tmp {};
-        /// the buffer pointer
-        const lexer_char_t* m_content = nullptr;
-        /// pointer to the beginning of the current symbol
-        const lexer_char_t* m_start = nullptr;
-        /// pointer for backtracking information
-        const lexer_char_t* m_marker = nullptr;
-        /// pointer to the current symbol
-        const lexer_char_t* m_cursor = nullptr;
-        /// pointer to the end of the buffer
-        const lexer_char_t* m_limit = nullptr;
-        /// the last token type
-        token_type last_token_type = token_type::end_of_input;
-    };
+        return binary_reader(i).parse_cbor(strict);
+    }
 
     /*!
-    @brief syntax analysis
-
-    This class implements a recursive decent parser.
+    @copydoc from_cbor(detail::input_adapter, const bool)
     */
-    class parser
+    template<typename A1, typename A2,
+             detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+    static basic_json from_cbor(A1 && a1, A2 && a2, const bool strict = true)
     {
-      public:
-        /// a parser reading from a string literal
-        parser(const char* buff, const parser_callback_t cb = nullptr)
-            : callback(cb),
-              m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), std::strlen(buff))
-        {}
+        return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
+    }
 
-        /// a parser reading from an input stream
-        parser(std::istream& is, const parser_callback_t cb = nullptr)
-            : callback(cb), m_lexer(is)
-        {}
-
-        /// a parser reading from an iterator range with contiguous storage
-        template<class IteratorType, typename std::enable_if<
-                     std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
-                     , int>::type
-                 = 0>
-        parser(IteratorType first, IteratorType last, const parser_callback_t cb = nullptr)
-            : callback(cb),
-              m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(&(*first)),
-                      static_cast<size_t>(std::distance(first, last)))
-        {}
-
-        /// public parser interface
-        basic_json parse()
-        {
-            // read first token
-            get_token();
-
-            basic_json result = parse_internal(true);
-            result.assert_invariant();
-
-            expect(lexer::token_type::end_of_input);
-
-            // return parser result and replace it with null in case the
-            // top-level value was discarded by the callback function
-            return result.is_discarded() ? basic_json() : std::move(result);
-        }
-
-      private:
-        /// the actual parser
-        basic_json parse_internal(bool keep)
-        {
-            auto result = basic_json(value_t::discarded);
-
-            switch (last_token)
-            {
-                case lexer::token_type::begin_object:
-                {
-                    if (keep and (not callback
-                                  or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
-                    {
-                        // explicitly set result to object to cope with {}
-                        result.m_type = value_t::object;
-                        result.m_value = value_t::object;
-                    }
-
-                    // read next token
-                    get_token();
-
-                    // closing } -> we are done
-                    if (last_token == lexer::token_type::end_object)
-                    {
-                        get_token();
-                        if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
-                        {
-                            result = basic_json(value_t::discarded);
-                        }
-                        return result;
-                    }
-
-                    // no comma is expected here
-                    unexpect(lexer::token_type::value_separator);
-
-                    // otherwise: parse key-value pairs
-                    do
-                    {
-                        // ugly, but could be fixed with loop reorganization
-                        if (last_token == lexer::token_type::value_separator)
-                        {
-                            get_token();
-                        }
-
-                        // store key
-                        expect(lexer::token_type::value_string);
-                        const auto key = m_lexer.get_string();
-
-                        bool keep_tag = false;
-                        if (keep)
-                        {
-                            if (callback)
-                            {
-                                basic_json k(key);
-                                keep_tag = callback(depth, parse_event_t::key, k);
-                            }
-                            else
-                            {
-                                keep_tag = true;
-                            }
-                        }
-
-                        // parse separator (:)
-                        get_token();
-                        expect(lexer::token_type::name_separator);
-
-                        // parse and add value
-                        get_token();
-                        auto value = parse_internal(keep);
-                        if (keep and keep_tag and not value.is_discarded())
-                        {
-                            result[key] = std::move(value);
-                        }
-                    }
-                    while (last_token == lexer::token_type::value_separator);
-
-                    // closing }
-                    expect(lexer::token_type::end_object);
-                    get_token();
-                    if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
-                    {
-                        result = basic_json(value_t::discarded);
-                    }
-
-                    return result;
-                }
-
-                case lexer::token_type::begin_array:
-                {
-                    if (keep and (not callback
-                                  or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
-                    {
-                        // explicitly set result to object to cope with []
-                        result.m_type = value_t::array;
-                        result.m_value = value_t::array;
-                    }
-
-                    // read next token
-                    get_token();
-
-                    // closing ] -> we are done
-                    if (last_token == lexer::token_type::end_array)
-                    {
-                        get_token();
-                        if (callback and not callback(--depth, parse_event_t::array_end, result))
-                        {
-                            result = basic_json(value_t::discarded);
-                        }
-                        return result;
-                    }
-
-                    // no comma is expected here
-                    unexpect(lexer::token_type::value_separator);
-
-                    // otherwise: parse values
-                    do
-                    {
-                        // ugly, but could be fixed with loop reorganization
-                        if (last_token == lexer::token_type::value_separator)
-                        {
-                            get_token();
-                        }
-
-                        // parse value
-                        auto value = parse_internal(keep);
-                        if (keep and not value.is_discarded())
-                        {
-                            result.push_back(std::move(value));
-                        }
-                    }
-                    while (last_token == lexer::token_type::value_separator);
-
-                    // closing ]
-                    expect(lexer::token_type::end_array);
-                    get_token();
-                    if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
-                    {
-                        result = basic_json(value_t::discarded);
-                    }
-
-                    return result;
-                }
-
-                case lexer::token_type::literal_null:
-                {
-                    get_token();
-                    result.m_type = value_t::null;
-                    break;
-                }
-
-                case lexer::token_type::value_string:
-                {
-                    const auto s = m_lexer.get_string();
-                    get_token();
-                    result = basic_json(s);
-                    break;
-                }
-
-                case lexer::token_type::literal_true:
-                {
-                    get_token();
-                    result.m_type = value_t::boolean;
-                    result.m_value = true;
-                    break;
-                }
-
-                case lexer::token_type::literal_false:
-                {
-                    get_token();
-                    result.m_type = value_t::boolean;
-                    result.m_value = false;
-                    break;
-                }
-
-                case lexer::token_type::value_unsigned:
-                case lexer::token_type::value_integer:
-                case lexer::token_type::value_float:
-                {
-                    m_lexer.get_number(result, last_token);
-                    get_token();
-                    break;
-                }
-
-                default:
-                {
-                    // the last token was unexpected
-                    unexpect(last_token);
-                }
-            }
-
-            if (keep and callback and not callback(depth, parse_event_t::value, result))
-            {
-                result = basic_json(value_t::discarded);
-            }
-            return result;
-        }
-
-        /// get next token from lexer
-        typename lexer::token_type get_token()
-        {
-            last_token = m_lexer.scan();
-            return last_token;
-        }
-
-        void expect(typename lexer::token_type t) const
-        {
-            if (t != last_token)
-            {
-                std::string error_msg = "parse error - unexpected ";
-                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token_string() +
-                              "'") :
-                              lexer::token_type_name(last_token));
-                error_msg += "; expected " + lexer::token_type_name(t);
-                JSON_THROW(std::invalid_argument(error_msg));
-            }
-        }
-
-        void unexpect(typename lexer::token_type t) const
-        {
-            if (t == last_token)
-            {
-                std::string error_msg = "parse error - unexpected ";
-                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token_string() +
-                              "'") :
-                              lexer::token_type_name(last_token));
-                JSON_THROW(std::invalid_argument(error_msg));
-            }
-        }
-
-      private:
-        /// current level of recursion
-        int depth = 0;
-        /// callback function
-        const parser_callback_t callback = nullptr;
-        /// the type of the last read token
-        typename lexer::token_type last_token = lexer::token_type::uninitialized;
-        /// the lexer
-        lexer m_lexer;
-    };
-
-  public:
     /*!
-    @brief JSON Pointer
+    @brief create a JSON value from an input in MessagePack format
 
-    A JSON pointer defines a string syntax for identifying a specific value
-    within a JSON document. It can be used with functions `at` and
-    `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
+    Deserializes a given input @a i to a JSON value using the MessagePack
+    serialization format.
 
-    @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
+    The library maps MessagePack types to JSON value types as follows:
 
-    @since version 2.0.0
+    MessagePack type | JSON value type | first byte
+    ---------------- | --------------- | ----------
+    positive fixint  | number_unsigned | 0x00..0x7f
+    fixmap           | object          | 0x80..0x8f
+    fixarray         | array           | 0x90..0x9f
+    fixstr           | string          | 0xa0..0xbf
+    nil              | `null`          | 0xc0
+    false            | `false`         | 0xc2
+    true             | `true`          | 0xc3
+    float 32         | number_float    | 0xca
+    float 64         | number_float    | 0xcb
+    uint 8           | number_unsigned | 0xcc
+    uint 16          | number_unsigned | 0xcd
+    uint 32          | number_unsigned | 0xce
+    uint 64          | number_unsigned | 0xcf
+    int 8            | number_integer  | 0xd0
+    int 16           | number_integer  | 0xd1
+    int 32           | number_integer  | 0xd2
+    int 64           | number_integer  | 0xd3
+    str 8            | string          | 0xd9
+    str 16           | string          | 0xda
+    str 32           | string          | 0xdb
+    array 16         | array           | 0xdc
+    array 32         | array           | 0xdd
+    map 16           | object          | 0xde
+    map 32           | object          | 0xdf
+    negative fixint  | number_integer  | 0xe0-0xff
+
+    @warning The mapping is **incomplete** in the sense that not all
+             MessagePack types can be converted to a JSON value. The following
+             MessagePack types are not supported and will yield parse errors:
+              - bin 8 - bin 32 (0xc4..0xc6)
+              - ext 8 - ext 32 (0xc7..0xc9)
+              - fixext 1 - fixext 16 (0xd4..0xd8)
+
+    @note Any MessagePack output created @ref to_msgpack can be successfully
+          parsed by @ref from_msgpack.
+
+    @param[in] i  an input in MessagePack format convertible to an input
+                  adapter
+    @param[in] strict  whether to expect the input to be consumed until EOF
+                       (true by default)
+
+    @throw parse_error.110 if the given input ends prematurely or the end of
+    file was not reached when @a strict was set to true
+    @throw parse_error.112 if unsupported features from MessagePack were
+    used in the given input @a i or if the input is not valid MessagePack
+    @throw parse_error.113 if a string was expected as map key, but not found
+
+    @complexity Linear in the size of the input @a i.
+
+    @liveexample{The example shows the deserialization of a byte vector in
+    MessagePack format to a JSON value.,from_msgpack}
+
+    @sa http://msgpack.org
+    @sa @ref to_msgpack(const basic_json&) for the analogous serialization
+    @sa @ref from_cbor(detail::input_adapter, const bool) for the related CBOR
+        format
+
+    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
+           consume input adapters, removed start_index parameter, and added
+           @a strict parameter since 3.0.0
     */
-    class json_pointer
+    static basic_json from_msgpack(detail::input_adapter i,
+                                   const bool strict = true)
     {
-        /// allow basic_json to access private members
-        friend class basic_json;
+        return binary_reader(i).parse_msgpack(strict);
+    }
 
-      public:
-        /*!
-        @brief create JSON pointer
+    /*!
+    @copydoc from_msgpack(detail::input_adapter, const bool)
+    */
+    template<typename A1, typename A2,
+             detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+    static basic_json from_msgpack(A1 && a1, A2 && a2, const bool strict = true)
+    {
+        return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
+    }
 
-        Create a JSON pointer according to the syntax described in
-        [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
-
-        @param[in] s  string representing the JSON pointer; if omitted, the
-                      empty string is assumed which references the whole JSON
-                      value
-
-        @throw std::domain_error if reference token is nonempty and does not
-        begin with a slash (`/`); example: `"JSON pointer must be empty or
-        begin with /"`
-        @throw std::domain_error if a tilde (`~`) is not followed by `0`
-        (representing `~`) or `1` (representing `/`); example: `"escape error:
-        ~ must be followed with 0 or 1"`
-
-        @liveexample{The example shows the construction several valid JSON
-        pointers as well as the exceptional behavior.,json_pointer}
-
-        @since version 2.0.0
-        */
-        explicit json_pointer(const std::string& s = "")
-            : reference_tokens(split(s))
-        {}
-
-        /*!
-        @brief return a string representation of the JSON pointer
-
-        @invariant For each JSON pointer `ptr`, it holds:
-        @code {.cpp}
-        ptr == json_pointer(ptr.to_string());
-        @endcode
-
-        @return a string representation of the JSON pointer
-
-        @liveexample{The example shows the result of `to_string`.,
-        json_pointer__to_string}
-
-        @since version 2.0.0
-        */
-        std::string to_string() const noexcept
-        {
-            return std::accumulate(reference_tokens.begin(),
-                                   reference_tokens.end(), std::string{},
-                                   [](const std::string & a, const std::string & b)
-            {
-                return a + "/" + escape(b);
-            });
-        }
-
-        /// @copydoc to_string()
-        operator std::string() const
-        {
-            return to_string();
-        }
-
-      private:
-        /// remove and return last reference pointer
-        std::string pop_back()
-        {
-            if (is_root())
-            {
-                JSON_THROW(std::domain_error("JSON pointer has no parent"));
-            }
-
-            auto last = reference_tokens.back();
-            reference_tokens.pop_back();
-            return last;
-        }
-
-        /// return whether pointer points to the root document
-        bool is_root() const
-        {
-            return reference_tokens.empty();
-        }
-
-        json_pointer top() const
-        {
-            if (is_root())
-            {
-                JSON_THROW(std::domain_error("JSON pointer has no parent"));
-            }
-
-            json_pointer result = *this;
-            result.reference_tokens = {reference_tokens[0]};
-            return result;
-        }
-
-        /*!
-        @brief create and return a reference to the pointed to value
-
-        @complexity Linear in the number of reference tokens.
-        */
-        reference get_and_create(reference j) const
-        {
-            pointer result = &j;
-
-            // in case no reference tokens exist, return a reference to the
-            // JSON value j which will be overwritten by a primitive value
-            for (const auto& reference_token : reference_tokens)
-            {
-                switch (result->m_type)
-                {
-                    case value_t::null:
-                    {
-                        if (reference_token == "0")
-                        {
-                            // start a new array if reference token is 0
-                            result = &result->operator[](0);
-                        }
-                        else
-                        {
-                            // start a new object otherwise
-                            result = &result->operator[](reference_token);
-                        }
-                        break;
-                    }
-
-                    case value_t::object:
-                    {
-                        // create an entry in the object
-                        result = &result->operator[](reference_token);
-                        break;
-                    }
-
-                    case value_t::array:
-                    {
-                        // create an entry in the array
-                        result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
-                        break;
-                    }
-
-                    /*
-                    The following code is only reached if there exists a
-                    reference token _and_ the current value is primitive. In
-                    this case, we have an error situation, because primitive
-                    values may only occur as single value; that is, with an
-                    empty list of reference tokens.
-                    */
-                    default:
-                    {
-                        JSON_THROW(std::domain_error("invalid value to unflatten"));
-                    }
-                }
-            }
-
-            return *result;
-        }
-
-        /*!
-        @brief return a reference to the pointed to value
-
-        @note This version does not throw if a value is not present, but tries
-        to create nested values instead. For instance, calling this function
-        with pointer `"/this/that"` on a null value is equivalent to calling
-        `operator[]("this").operator[]("that")` on that value, effectively
-        changing the null value to an object.
-
-        @param[in] ptr  a JSON value
-
-        @return reference to the JSON value pointed to by the JSON pointer
-
-        @complexity Linear in the length of the JSON pointer.
-
-        @throw std::out_of_range      if the JSON pointer can not be resolved
-        @throw std::domain_error      if an array index begins with '0'
-        @throw std::invalid_argument  if an array index was not a number
-        */
-        reference get_unchecked(pointer ptr) const
-        {
-            for (const auto& reference_token : reference_tokens)
-            {
-                // convert null values to arrays or objects before continuing
-                if (ptr->m_type == value_t::null)
-                {
-                    // check if reference token is a number
-                    const bool nums = std::all_of(reference_token.begin(),
-                                                  reference_token.end(),
-                                                  [](const char x)
-                    {
-                        return std::isdigit(x);
-                    });
-
-                    // change value to array for numbers or "-" or to object
-                    // otherwise
-                    if (nums or reference_token == "-")
-                    {
-                        *ptr = value_t::array;
-                    }
-                    else
-                    {
-                        *ptr = value_t::object;
-                    }
-                }
-
-                switch (ptr->m_type)
-                {
-                    case value_t::object:
-                    {
-                        // use unchecked object access
-                        ptr = &ptr->operator[](reference_token);
-                        break;
-                    }
-
-                    case value_t::array:
-                    {
-                        // error condition (cf. RFC 6901, Sect. 4)
-                        if (reference_token.size() > 1 and reference_token[0] == '0')
-                        {
-                            JSON_THROW(std::domain_error("array index must not begin with '0'"));
-                        }
-
-                        if (reference_token == "-")
-                        {
-                            // explicitly treat "-" as index beyond the end
-                            ptr = &ptr->operator[](ptr->m_value.array->size());
-                        }
-                        else
-                        {
-                            // convert array index to number; unchecked access
-                            ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
-                        }
-                        break;
-                    }
-
-                    default:
-                    {
-                        JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
-                    }
-                }
-            }
-
-            return *ptr;
-        }
-
-        reference get_checked(pointer ptr) const
-        {
-            for (const auto& reference_token : reference_tokens)
-            {
-                switch (ptr->m_type)
-                {
-                    case value_t::object:
-                    {
-                        // note: at performs range check
-                        ptr = &ptr->at(reference_token);
-                        break;
-                    }
-
-                    case value_t::array:
-                    {
-                        if (reference_token == "-")
-                        {
-                            // "-" always fails the range check
-                            JSON_THROW(std::out_of_range("array index '-' (" +
-                                                         std::to_string(ptr->m_value.array->size()) +
-                                                         ") is out of range"));
-                        }
-
-                        // error condition (cf. RFC 6901, Sect. 4)
-                        if (reference_token.size() > 1 and reference_token[0] == '0')
-                        {
-                            JSON_THROW(std::domain_error("array index must not begin with '0'"));
-                        }
-
-                        // note: at performs range check
-                        ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
-                        break;
-                    }
-
-                    default:
-                    {
-                        JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
-                    }
-                }
-            }
-
-            return *ptr;
-        }
-
-        /*!
-        @brief return a const reference to the pointed to value
-
-        @param[in] ptr  a JSON value
-
-        @return const reference to the JSON value pointed to by the JSON
-                pointer
-        */
-        const_reference get_unchecked(const_pointer ptr) const
-        {
-            for (const auto& reference_token : reference_tokens)
-            {
-                switch (ptr->m_type)
-                {
-                    case value_t::object:
-                    {
-                        // use unchecked object access
-                        ptr = &ptr->operator[](reference_token);
-                        break;
-                    }
-
-                    case value_t::array:
-                    {
-                        if (reference_token == "-")
-                        {
-                            // "-" cannot be used for const access
-                            JSON_THROW(std::out_of_range("array index '-' (" +
-                                                         std::to_string(ptr->m_value.array->size()) +
-                                                         ") is out of range"));
-                        }
-
-                        // error condition (cf. RFC 6901, Sect. 4)
-                        if (reference_token.size() > 1 and reference_token[0] == '0')
-                        {
-                            JSON_THROW(std::domain_error("array index must not begin with '0'"));
-                        }
-
-                        // use unchecked array access
-                        ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
-                        break;
-                    }
-
-                    default:
-                    {
-                        JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
-                    }
-                }
-            }
-
-            return *ptr;
-        }
-
-        const_reference get_checked(const_pointer ptr) const
-        {
-            for (const auto& reference_token : reference_tokens)
-            {
-                switch (ptr->m_type)
-                {
-                    case value_t::object:
-                    {
-                        // note: at performs range check
-                        ptr = &ptr->at(reference_token);
-                        break;
-                    }
-
-                    case value_t::array:
-                    {
-                        if (reference_token == "-")
-                        {
-                            // "-" always fails the range check
-                            JSON_THROW(std::out_of_range("array index '-' (" +
-                                                         std::to_string(ptr->m_value.array->size()) +
-                                                         ") is out of range"));
-                        }
-
-                        // error condition (cf. RFC 6901, Sect. 4)
-                        if (reference_token.size() > 1 and reference_token[0] == '0')
-                        {
-                            JSON_THROW(std::domain_error("array index must not begin with '0'"));
-                        }
-
-                        // note: at performs range check
-                        ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
-                        break;
-                    }
-
-                    default:
-                    {
-                        JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
-                    }
-                }
-            }
-
-            return *ptr;
-        }
-
-        /// split the string input to reference tokens
-        static std::vector<std::string> split(const std::string& reference_string)
-        {
-            std::vector<std::string> result;
-
-            // special case: empty reference string -> no reference tokens
-            if (reference_string.empty())
-            {
-                return result;
-            }
-
-            // check if nonempty reference string begins with slash
-            if (reference_string[0] != '/')
-            {
-                JSON_THROW(std::domain_error("JSON pointer must be empty or begin with '/'"));
-            }
-
-            // extract the reference tokens:
-            // - slash: position of the last read slash (or end of string)
-            // - start: position after the previous slash
-            for (
-                // search for the first slash after the first character
-                size_t slash = reference_string.find_first_of('/', 1),
-                // set the beginning of the first reference token
-                start = 1;
-                // we can stop if start == string::npos+1 = 0
-                start != 0;
-                // set the beginning of the next reference token
-                // (will eventually be 0 if slash == std::string::npos)
-                start = slash + 1,
-                // find next slash
-                slash = reference_string.find_first_of('/', start))
-            {
-                // use the text between the beginning of the reference token
-                // (start) and the last slash (slash).
-                auto reference_token = reference_string.substr(start, slash - start);
-
-                // check reference tokens are properly escaped
-                for (size_t pos = reference_token.find_first_of('~');
-                        pos != std::string::npos;
-                        pos = reference_token.find_first_of('~', pos + 1))
-                {
-                    assert(reference_token[pos] == '~');
-
-                    // ~ must be followed by 0 or 1
-                    if (pos == reference_token.size() - 1 or
-                            (reference_token[pos + 1] != '0' and
-                             reference_token[pos + 1] != '1'))
-                    {
-                        JSON_THROW(std::domain_error("escape error: '~' must be followed with '0' or '1'"));
-                    }
-                }
-
-                // finally, store the reference token
-                unescape(reference_token);
-                result.push_back(reference_token);
-            }
-
-            return result;
-        }
-
-      private:
-        /*!
-        @brief replace all occurrences of a substring by another string
-
-        @param[in,out] s  the string to manipulate; changed so that all
-                          occurrences of @a f are replaced with @a t
-        @param[in]     f  the substring to replace with @a t
-        @param[in]     t  the string to replace @a f
-
-        @pre The search string @a f must not be empty.
-
-        @since version 2.0.0
-        */
-        static void replace_substring(std::string& s,
-                                      const std::string& f,
-                                      const std::string& t)
-        {
-            assert(not f.empty());
-
-            for (
-                size_t pos = s.find(f);         // find first occurrence of f
-                pos != std::string::npos;       // make sure f was found
-                s.replace(pos, f.size(), t),    // replace with t
-                pos = s.find(f, pos + t.size()) // find next occurrence of f
-            );
-        }
-
-        /// escape tilde and slash
-        static std::string escape(std::string s)
-        {
-            // escape "~"" to "~0" and "/" to "~1"
-            replace_substring(s, "~", "~0");
-            replace_substring(s, "/", "~1");
-            return s;
-        }
-
-        /// unescape tilde and slash
-        static void unescape(std::string& s)
-        {
-            // first transform any occurrence of the sequence '~1' to '/'
-            replace_substring(s, "~1", "/");
-            // then transform any occurrence of the sequence '~0' to '~'
-            replace_substring(s, "~0", "~");
-        }
-
-        /*!
-        @param[in] reference_string  the reference string to the current value
-        @param[in] value             the value to consider
-        @param[in,out] result        the result object to insert values to
-
-        @note Empty objects or arrays are flattened to `null`.
-        */
-        static void flatten(const std::string& reference_string,
-                            const basic_json& value,
-                            basic_json& result)
-        {
-            switch (value.m_type)
-            {
-                case value_t::array:
-                {
-                    if (value.m_value.array->empty())
-                    {
-                        // flatten empty array as null
-                        result[reference_string] = nullptr;
-                    }
-                    else
-                    {
-                        // iterate array and use index as reference string
-                        for (size_t i = 0; i < value.m_value.array->size(); ++i)
-                        {
-                            flatten(reference_string + "/" + std::to_string(i),
-                                    value.m_value.array->operator[](i), result);
-                        }
-                    }
-                    break;
-                }
-
-                case value_t::object:
-                {
-                    if (value.m_value.object->empty())
-                    {
-                        // flatten empty object as null
-                        result[reference_string] = nullptr;
-                    }
-                    else
-                    {
-                        // iterate object and use keys as reference string
-                        for (const auto& element : *value.m_value.object)
-                        {
-                            flatten(reference_string + "/" + escape(element.first),
-                                    element.second, result);
-                        }
-                    }
-                    break;
-                }
-
-                default:
-                {
-                    // add primitive value with its reference string
-                    result[reference_string] = value;
-                    break;
-                }
-            }
-        }
-
-        /*!
-        @param[in] value  flattened JSON
-
-        @return unflattened JSON
-        */
-        static basic_json unflatten(const basic_json& value)
-        {
-            if (not value.is_object())
-            {
-                JSON_THROW(std::domain_error("only objects can be unflattened"));
-            }
-
-            basic_json result;
-
-            // iterate the JSON object values
-            for (const auto& element : *value.m_value.object)
-            {
-                if (not element.second.is_primitive())
-                {
-                    JSON_THROW(std::domain_error("values in object must be primitive"));
-                }
-
-                // assign value to reference pointed to by JSON pointer; Note
-                // that if the JSON pointer is "" (i.e., points to the whole
-                // value), function get_and_create returns a reference to
-                // result itself. An assignment will then create a primitive
-                // value.
-                json_pointer(element.first).get_and_create(result) = element.second;
-            }
-
-            return result;
-        }
-
-      private:
-        friend bool operator==(json_pointer const& lhs,
-                               json_pointer const& rhs) noexcept
-        {
-            return lhs.reference_tokens == rhs.reference_tokens;
-        }
-
-        friend bool operator!=(json_pointer const& lhs,
-                               json_pointer const& rhs) noexcept
-        {
-            return !(lhs == rhs);
-        }
-
-        /// the reference tokens
-        std::vector<std::string> reference_tokens {};
-    };
+    /// @}
 
     //////////////////////////
     // JSON Pointer support //
@@ -12273,9 +13543,9 @@
 
     @complexity Constant.
 
-    @throw std::out_of_range      if the JSON pointer can not be resolved
-    @throw std::domain_error      if an array index begins with '0'
-    @throw std::invalid_argument  if an array index was not a number
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.404  if the JSON pointer can not be resolved
 
     @liveexample{The behavior is shown in the example.,operatorjson_pointer}
 
@@ -12300,9 +13570,10 @@
 
     @complexity Constant.
 
-    @throw std::out_of_range      if the JSON pointer can not be resolved
-    @throw std::domain_error      if an array index begins with '0'
-    @throw std::invalid_argument  if an array index was not a number
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.402  if the array index '-' is used
+    @throw out_of_range.404  if the JSON pointer can not be resolved
 
     @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
 
@@ -12323,15 +13594,30 @@
 
     @return reference to the element pointed to by @a ptr
 
+    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
+    begins with '0'. See example below.
+
+    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
+    is not a number. See example below.
+
+    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
+    is out of range. See example below.
+
+    @throw out_of_range.402 if the array index '-' is used in the passed JSON
+    pointer @a ptr. As `at` provides checked access (and no elements are
+    implicitly inserted), the index '-' is always invalid. See example below.
+
+    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
+    See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
     @complexity Constant.
 
-    @throw std::out_of_range      if the JSON pointer can not be resolved
-    @throw std::domain_error      if an array index begins with '0'
-    @throw std::invalid_argument  if an array index was not a number
+    @since version 2.0.0
 
     @liveexample{The behavior is shown in the example.,at_json_pointer}
-
-    @since version 2.0.0
     */
     reference at(const json_pointer& ptr)
     {
@@ -12348,15 +13634,30 @@
 
     @return reference to the element pointed to by @a ptr
 
+    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
+    begins with '0'. See example below.
+
+    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
+    is not a number. See example below.
+
+    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
+    is out of range. See example below.
+
+    @throw out_of_range.402 if the array index '-' is used in the passed JSON
+    pointer @a ptr. As `at` provides checked access (and no elements are
+    implicitly inserted), the index '-' is always invalid. See example below.
+
+    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
+    See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
     @complexity Constant.
 
-    @throw std::out_of_range      if the JSON pointer can not be resolved
-    @throw std::domain_error      if an array index begins with '0'
-    @throw std::invalid_argument  if an array index was not a number
+    @since version 2.0.0
 
     @liveexample{The behavior is shown in the example.,at_json_pointer_const}
-
-    @since version 2.0.0
     */
     const_reference at(const json_pointer& ptr) const
     {
@@ -12412,6 +13713,9 @@
 
     @complexity Linear in the size the JSON value.
 
+    @throw type_error.314  if value is not an object
+    @throw type_error.315  if object values are not primitive
+
     @liveexample{The following code shows how a flattened JSON object is
     unflattened into the original nested JSON object.,unflatten}
 
@@ -12449,12 +13753,23 @@
           any case, the original value is not changed: the patch is applied
           to a copy of the value.
 
-    @throw std::out_of_range if a JSON pointer inside the patch could not
-    be resolved successfully in the current JSON value; example: `"key baz
-    not found"`
-    @throw invalid_argument if the JSON patch is malformed (e.g., mandatory
+    @throw parse_error.104 if the JSON patch does not consist of an array of
+    objects
+
+    @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
     attributes are missing); example: `"operation add must have member path"`
 
+    @throw out_of_range.401 if an array index is out of range.
+
+    @throw out_of_range.403 if a JSON pointer inside the patch could not be
+    resolved successfully in the current JSON value; example: `"key baz not
+    found"`
+
+    @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
+    "move")
+
+    @throw other_error.501 if "test" operation was unsuccessful
+
     @complexity Linear in the size of the JSON value and the length of the
     JSON patch. As usually only a fraction of the JSON value is affected by
     the patch, the complexity can usually be neglected.
@@ -12477,7 +13792,7 @@
         // the valid JSON Patch operations
         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
 
-        const auto get_op = [](const std::string op)
+        const auto get_op = [](const std::string & op)
         {
             if (op == "add")
             {
@@ -12548,10 +13863,10 @@
                         else
                         {
                             const auto idx = std::stoi(last_path);
-                            if (static_cast<size_type>(idx) > parent.size())
+                            if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
                             {
                                 // avoid undefined behavior
-                                JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
+                                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
                             }
                             else
                             {
@@ -12583,13 +13898,13 @@
             {
                 // perform range check
                 auto it = parent.find(last_path);
-                if (it != parent.end())
+                if (JSON_LIKELY(it != parent.end()))
                 {
                     parent.erase(it);
                 }
                 else
                 {
-                    JSON_THROW(std::out_of_range("key '" + last_path + "' not found"));
+                    JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
                 }
             }
             else if (parent.is_array())
@@ -12599,11 +13914,10 @@
             }
         };
 
-        // type check
-        if (not json_patch.is_array())
+        // type check: top level value must be an array
+        if (JSON_UNLIKELY(not json_patch.is_array()))
         {
-            // a JSON patch must be an array of objects
-            JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
+            JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
         }
 
         // iterate and apply the operations
@@ -12621,25 +13935,25 @@
                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
 
                 // check if desired value is present
-                if (it == val.m_value.object->end())
+                if (JSON_UNLIKELY(it == val.m_value.object->end()))
                 {
-                    JSON_THROW(std::invalid_argument(error_msg + " must have member '" + member + "'"));
+                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
                 }
 
                 // check if result is of type string
-                if (string_type and not it->second.is_string())
+                if (JSON_UNLIKELY(string_type and not it->second.is_string()))
                 {
-                    JSON_THROW(std::invalid_argument(error_msg + " must have string member '" + member + "'"));
+                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
                 }
 
                 // no error: return value
                 return it->second;
             };
 
-            // type check
-            if (not val.is_object())
+            // type check: every element of the array must be an object
+            if (JSON_UNLIKELY(not val.is_object()))
             {
-                JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
+                JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
             }
 
             // collect mandatory members
@@ -12687,7 +14001,7 @@
 
                 case patch_operations::copy:
                 {
-                    const std::string from_path = get_value("copy", "from", true);;
+                    const std::string from_path = get_value("copy", "from", true);
                     const json_pointer from_ptr(from_path);
 
                     // the "from" location must exist - use at()
@@ -12704,15 +14018,15 @@
                         // the "path" location must exist - use at()
                         success = (result.at(ptr) == get_value("test", "value", false));
                     }
-                    JSON_CATCH (std::out_of_range&)
+                    JSON_CATCH (out_of_range&)
                     {
                         // ignore out of range errors: success remains false
                     }
 
                     // throw an exception if test fails
-                    if (not success)
+                    if (JSON_UNLIKELY(not success))
                     {
-                        JSON_THROW(std::domain_error("unsuccessful: " + val.dump()));
+                        JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
                     }
 
                     break;
@@ -12722,7 +14036,7 @@
                 {
                     // op must be "add", "remove", "replace", "move", "copy", or
                     // "test"
-                    JSON_THROW(std::invalid_argument("operation value '" + op + "' is invalid"));
+                    JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
                 }
             }
         }
@@ -12762,8 +14076,7 @@
 
     @since version 2.0.0
     */
-    static basic_json diff(const basic_json& source,
-                           const basic_json& target,
+    static basic_json diff(const basic_json& source, const basic_json& target,
                            const std::string& path = "")
     {
         // the patch
@@ -12780,9 +14093,7 @@
             // different types: replace value
             result.push_back(
             {
-                {"op", "replace"},
-                {"path", path},
-                {"value", target}
+                {"op", "replace"}, {"path", path}, {"value", target}
             });
         }
         else
@@ -12792,7 +14103,7 @@
                 case value_t::array:
                 {
                     // first pass: traverse common elements
-                    size_t i = 0;
+                    std::size_t i = 0;
                     while (i < source.size() and i < target.size())
                     {
                         // recursive call to compare array values at index i
@@ -12852,8 +14163,7 @@
                             // found a key that is not in o -> remove it
                             result.push_back(object(
                             {
-                                {"op", "remove"},
-                                {"path", path + "/" + key}
+                                {"op", "remove"}, {"path", path + "/" + key}
                             }));
                         }
                     }
@@ -12867,8 +14177,7 @@
                             const auto key = json_pointer::escape(it.key());
                             result.push_back(
                             {
-                                {"op", "add"},
-                                {"path", path + "/" + key},
+                                {"op", "add"}, {"path", path + "/" + key},
                                 {"value", it.value()}
                             });
                         }
@@ -12882,9 +14191,7 @@
                     // both primitive type: replace value
                     result.push_back(
                     {
-                        {"op", "replace"},
-                        {"path", path},
-                        {"value", target}
+                        {"op", "replace"}, {"path", path}, {"value", target}
                     });
                     break;
                 }
@@ -12910,6 +14217,400 @@
 @since version 1.0.0
 */
 using json = basic_json<>;
+
+//////////////////
+// json_pointer //
+//////////////////
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+NLOHMANN_BASIC_JSON_TPL&
+json_pointer::get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const
+{
+    using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
+    auto result = &j;
+
+    // in case no reference tokens exist, return a reference to the JSON value
+    // j which will be overwritten by a primitive value
+    for (const auto& reference_token : reference_tokens)
+    {
+        switch (result->m_type)
+        {
+            case detail::value_t::null:
+            {
+                if (reference_token == "0")
+                {
+                    // start a new array if reference token is 0
+                    result = &result->operator[](0);
+                }
+                else
+                {
+                    // start a new object otherwise
+                    result = &result->operator[](reference_token);
+                }
+                break;
+            }
+
+            case detail::value_t::object:
+            {
+                // create an entry in the object
+                result = &result->operator[](reference_token);
+                break;
+            }
+
+            case detail::value_t::array:
+            {
+                // create an entry in the array
+                JSON_TRY
+                {
+                    result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
+                }
+                JSON_CATCH(std::invalid_argument&)
+                {
+                    JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+                }
+                break;
+            }
+
+            /*
+            The following code is only reached if there exists a reference
+            token _and_ the current value is primitive. In this case, we have
+            an error situation, because primitive values may only occur as
+            single value; that is, with an empty list of reference tokens.
+            */
+            default:
+                JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
+        }
+    }
+
+    return *result;
+}
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+NLOHMANN_BASIC_JSON_TPL&
+json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
+{
+    using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
+    for (const auto& reference_token : reference_tokens)
+    {
+        // convert null values to arrays or objects before continuing
+        if (ptr->m_type == detail::value_t::null)
+        {
+            // check if reference token is a number
+            const bool nums =
+                std::all_of(reference_token.begin(), reference_token.end(),
+                            [](const char x)
+            {
+                return (x >= '0' and x <= '9');
+            });
+
+            // change value to array for numbers or "-" or to object otherwise
+            *ptr = (nums or reference_token == "-")
+                   ? detail::value_t::array
+                   : detail::value_t::object;
+        }
+
+        switch (ptr->m_type)
+        {
+            case detail::value_t::object:
+            {
+                // use unchecked object access
+                ptr = &ptr->operator[](reference_token);
+                break;
+            }
+
+            case detail::value_t::array:
+            {
+                // error condition (cf. RFC 6901, Sect. 4)
+                if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
+                {
+                    JSON_THROW(detail::parse_error::create(106, 0,
+                                                           "array index '" + reference_token +
+                                                           "' must not begin with '0'"));
+                }
+
+                if (reference_token == "-")
+                {
+                    // explicitly treat "-" as index beyond the end
+                    ptr = &ptr->operator[](ptr->m_value.array->size());
+                }
+                else
+                {
+                    // convert array index to number; unchecked access
+                    JSON_TRY
+                    {
+                        ptr = &ptr->operator[](
+                            static_cast<size_type>(std::stoi(reference_token)));
+                    }
+                    JSON_CATCH(std::invalid_argument&)
+                    {
+                        JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+                    }
+                }
+                break;
+            }
+
+            default:
+                JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+        }
+    }
+
+    return *ptr;
+}
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+NLOHMANN_BASIC_JSON_TPL&
+json_pointer::get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const
+{
+    using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
+    for (const auto& reference_token : reference_tokens)
+    {
+        switch (ptr->m_type)
+        {
+            case detail::value_t::object:
+            {
+                // note: at performs range check
+                ptr = &ptr->at(reference_token);
+                break;
+            }
+
+            case detail::value_t::array:
+            {
+                if (JSON_UNLIKELY(reference_token == "-"))
+                {
+                    // "-" always fails the range check
+                    JSON_THROW(detail::out_of_range::create(402,
+                                                            "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+                                                            ") is out of range"));
+                }
+
+                // error condition (cf. RFC 6901, Sect. 4)
+                if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
+                {
+                    JSON_THROW(detail::parse_error::create(106, 0,
+                                                           "array index '" + reference_token +
+                                                           "' must not begin with '0'"));
+                }
+
+                // note: at performs range check
+                JSON_TRY
+                {
+                    ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
+                }
+                JSON_CATCH(std::invalid_argument&)
+                {
+                    JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+                }
+                break;
+            }
+
+            default:
+                JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+        }
+    }
+
+    return *ptr;
+}
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+const NLOHMANN_BASIC_JSON_TPL&
+json_pointer::get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
+{
+    using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
+    for (const auto& reference_token : reference_tokens)
+    {
+        switch (ptr->m_type)
+        {
+            case detail::value_t::object:
+            {
+                // use unchecked object access
+                ptr = &ptr->operator[](reference_token);
+                break;
+            }
+
+            case detail::value_t::array:
+            {
+                if (JSON_UNLIKELY(reference_token == "-"))
+                {
+                    // "-" cannot be used for const access
+                    JSON_THROW(detail::out_of_range::create(402,
+                                                            "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+                                                            ") is out of range"));
+                }
+
+                // error condition (cf. RFC 6901, Sect. 4)
+                if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
+                {
+                    JSON_THROW(detail::parse_error::create(106, 0,
+                                                           "array index '" + reference_token +
+                                                           "' must not begin with '0'"));
+                }
+
+                // use unchecked array access
+                JSON_TRY
+                {
+                    ptr = &ptr->operator[](
+                        static_cast<size_type>(std::stoi(reference_token)));
+                }
+                JSON_CATCH(std::invalid_argument&)
+                {
+                    JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+                }
+                break;
+            }
+
+            default:
+                JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+        }
+    }
+
+    return *ptr;
+}
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+const NLOHMANN_BASIC_JSON_TPL&
+json_pointer::get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
+{
+    using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
+    for (const auto& reference_token : reference_tokens)
+    {
+        switch (ptr->m_type)
+        {
+            case detail::value_t::object:
+            {
+                // note: at performs range check
+                ptr = &ptr->at(reference_token);
+                break;
+            }
+
+            case detail::value_t::array:
+            {
+                if (JSON_UNLIKELY(reference_token == "-"))
+                {
+                    // "-" always fails the range check
+                    JSON_THROW(detail::out_of_range::create(402,
+                                                            "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+                                                            ") is out of range"));
+                }
+
+                // error condition (cf. RFC 6901, Sect. 4)
+                if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
+                {
+                    JSON_THROW(detail::parse_error::create(106, 0,
+                                                           "array index '" + reference_token +
+                                                           "' must not begin with '0'"));
+                }
+
+                // note: at performs range check
+                JSON_TRY
+                {
+                    ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
+                }
+                JSON_CATCH(std::invalid_argument&)
+                {
+                    JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+                }
+                break;
+            }
+
+            default:
+                JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+        }
+    }
+
+    return *ptr;
+}
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+void json_pointer::flatten(const std::string& reference_string,
+                           const NLOHMANN_BASIC_JSON_TPL& value,
+                           NLOHMANN_BASIC_JSON_TPL& result)
+{
+    switch (value.m_type)
+    {
+        case detail::value_t::array:
+        {
+            if (value.m_value.array->empty())
+            {
+                // flatten empty array as null
+                result[reference_string] = nullptr;
+            }
+            else
+            {
+                // iterate array and use index as reference string
+                for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
+                {
+                    flatten(reference_string + "/" + std::to_string(i),
+                            value.m_value.array->operator[](i), result);
+                }
+            }
+            break;
+        }
+
+        case detail::value_t::object:
+        {
+            if (value.m_value.object->empty())
+            {
+                // flatten empty object as null
+                result[reference_string] = nullptr;
+            }
+            else
+            {
+                // iterate object and use keys as reference string
+                for (const auto& element : *value.m_value.object)
+                {
+                    flatten(reference_string + "/" + escape(element.first), element.second, result);
+                }
+            }
+            break;
+        }
+
+        default:
+        {
+            // add primitive value with its reference string
+            result[reference_string] = value;
+            break;
+        }
+    }
+}
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+NLOHMANN_BASIC_JSON_TPL
+json_pointer::unflatten(const NLOHMANN_BASIC_JSON_TPL& value)
+{
+    if (JSON_UNLIKELY(not value.is_object()))
+    {
+        JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
+    }
+
+    NLOHMANN_BASIC_JSON_TPL result;
+
+    // iterate the JSON object values
+    for (const auto& element : *value.m_value.object)
+    {
+        if (JSON_UNLIKELY(not element.second.is_primitive()))
+        {
+            JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
+        }
+
+        // assign value to reference pointed to by JSON pointer; Note that if
+        // the JSON pointer is "" (i.e., points to the whole value), function
+        // get_and_create returns a reference to result itself. An assignment
+        // will then create a primitive value.
+        json_pointer(element.first).get_and_create(result) = element.second;
+    }
+
+    return result;
+}
+
+inline bool operator==(json_pointer const& lhs, json_pointer const& rhs) noexcept
+{
+    return (lhs.reference_tokens == rhs.reference_tokens);
+}
+
+inline bool operator!=(json_pointer const& lhs, json_pointer const& rhs) noexcept
+{
+    return not (lhs == rhs);
+}
 } // namespace nlohmann
 
 
@@ -12951,6 +14652,24 @@
         return h(j.dump());
     }
 };
+
+/// specialization for std::less<value_t>
+/// @note: do not remove the space after '<',
+///        see https://github.com/nlohmann/json/pull/679
+template<>
+struct less< ::nlohmann::detail::value_t>
+{
+    /*!
+    @brief compare two value_t enum values
+    @since version 3.0.0
+    */
+    bool operator()(nlohmann::detail::value_t lhs,
+                    nlohmann::detail::value_t rhs) const noexcept
+    {
+        return nlohmann::detail::operator<(lhs, rhs);
+    }
+};
+
 } // namespace std
 
 /*!
@@ -12993,11 +14712,18 @@
 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
     #pragma GCC diagnostic pop
 #endif
+#if defined(__clang__)
+    #pragma GCC diagnostic pop
+#endif
 
 // clean up
 #undef JSON_CATCH
-#undef JSON_DEPRECATED
 #undef JSON_THROW
 #undef JSON_TRY
+#undef JSON_LIKELY
+#undef JSON_UNLIKELY
+#undef JSON_DEPRECATED
+#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
+#undef NLOHMANN_BASIC_JSON_TPL
 
-#endif
+#endif
\ No newline at end of file
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index 9348808..4e29805 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -10,6 +10,11 @@
 
 namespace crow {
 namespace openbmc_mapper {
+
+// TODO(ed) having these as scope globals, and as simple as they are limits the
+// ability to queue multiple async operations at once.  Being able to register
+// "done" callbacks to a queue here that also had a count attached would allow
+// multiple requests to be running at once
 std::atomic<std::size_t> outstanding_async_calls(0);
 nlohmann::json object_paths;
 
@@ -101,19 +106,104 @@
 
       });
 
+  CROW_ROUTE(app, "/list/")
+      .methods("GET"_method)([](const crow::request &req, crow::response &res) {
+        crow::connections::system_bus->async_method_call(
+            [&](const boost::system::error_code ec,
+                const std::vector<std::string> &object_paths) {
+
+              if (ec) {
+                res.code = 500;
+              } else {
+                nlohmann::json j{{"status", "ok"},
+                                 {"message", "200 OK"},
+                                 {"data", object_paths}};
+                res.body = j.dump();
+              }
+              res.end();
+            },
+            {"xyz.openbmc_project.ObjectMapper",
+             "/xyz/openbmc_project/object_mapper",
+             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths"},
+            "", static_cast<int32_t>(99), std::array<std::string, 0>());
+      });
+
+  CROW_ROUTE(app, "/xyz/<path>")
+      .methods("GET"_method)([](const crow::request &req, crow::response &res,
+                                const std::string &path) {
+        if (outstanding_async_calls != 0) {
+          res.code = 500;
+          res.body = "request in progress";
+          res.end();
+          return;
+        }
+        using GetObjectType =
+            std::vector<std::pair<std::string, std::vector<std::string>>>;
+
+        std::string object_path = "/xyz/" + path;
+        crow::connections::system_bus->async_method_call(
+            // object_path intentially captured by value
+            [&, object_path](const boost::system::error_code ec,
+                             const GetObjectType &object_names) {
+
+              if (ec) {
+                res.code = 500;
+                res.end();
+                return;
+              }
+              if (object_names.size() != 1) {
+                res.code = 404;
+                res.end();
+                return;
+              }
+
+              for (auto &interface : object_names[0].second) {
+                outstanding_async_calls++;
+                crow::connections::system_bus->async_method_call(
+                    [&](const boost::system::error_code ec,
+                        const std::vector<std::pair<
+                            std::string, dbus::dbus_variant>> &properties) {
+                      outstanding_async_calls--;
+                      if (ec) {
+                        std::cerr << "Bad dbus request error: " << ec;
+                      } else {
+                        for (auto &property : properties) {
+                          boost::apply_visitor(
+                              [&](auto val) {
+                                object_paths[property.first] = val;
+                              },
+                              property.second);
+                        }
+                      }
+                      if (outstanding_async_calls == 0) {
+                        nlohmann::json j{{"status", "ok"},
+                                         {"message", "200 OK"},
+                                         {"data", object_paths}};
+                        res.body = j.dump();
+                        res.end();
+                        object_paths.clear();
+                      }
+                    },
+                    {object_names[0].first, object_path,
+                     "org.freedesktop.DBus.Properties", "GetAll"},
+                    interface);
+              }
+            },
+            {"xyz.openbmc_project.ObjectMapper",
+             "/xyz/openbmc_project/object_mapper",
+             "xyz.openbmc_project.ObjectMapper", "GetObject"},
+            object_path, std::array<std::string, 0>());
+      });
   CROW_ROUTE(app, "/bus/system/<str>/")
       .methods("GET"_method)([](const crow::request &req, crow::response &res,
                                 const std::string &connection) {
-        // Can only do one call at a time (for now)
-        if (outstanding_async_calls == 0) {
-          // TODO(ed) sanitize paths
-          introspect_objects(res, connection, "/");
-        } else {
-          nlohmann::json j{{"status", "failed"}};
+        if (outstanding_async_calls != 0) {
           res.code = 500;
-          res.write(j.dump());
+          res.body = "request in progress";
           res.end();
+          return;
         }
+        introspect_objects(res, connection, "/");
       });
 
   CROW_ROUTE(app, "/bus/system/<str>/<path>")
@@ -135,7 +225,8 @@
           // interface
           if ((*it).find(".") != std::string::npos) {
             break;
-            // THis check is neccesary as the trailing slash gets parsed as part
+            // THis check is neccesary as the trailing slash gets parsed as
+            // part
             // of our <path> specifier above, which causes the normal trailing
             // backslash redirector to fail.
           } else if (!it->empty()) {
@@ -260,9 +351,10 @@
                           }
                           methods_array.push_back(
                               {{"name", methods->Attribute("name")},
-                               {"uri", "/bus/system/" + process_name +
-                                           object_path + "/" + interface_name +
-                                           "/" + methods->Attribute("name")},
+                               {"uri",
+                                "/bus/system/" + process_name + object_path +
+                                    "/" + interface_name + "/" +
+                                    methods->Attribute("name")},
                                {"args", args_array}});
                           methods = methods->NextSiblingElement("method");
                         }
diff --git a/include/pam_authenticate.hpp b/include/pam_authenticate.hpp
index 0825dd6..d0ca1b0 100644
--- a/include/pam_authenticate.hpp
+++ b/include/pam_authenticate.hpp
@@ -37,7 +37,7 @@
       pam_function_conversation, const_cast<char*>(password.c_str())};
   pam_handle_t* local_auth_handle = NULL;  // this gets set by pam_start
 
-  if (pam_start("su", username.c_str(), &local_conversation,
+  if (pam_start("dropbear", username.c_str(), &local_conversation,
                 &local_auth_handle) != PAM_SUCCESS) {
     return false;
   }
diff --git a/include/persistent_data_middleware.hpp b/include/persistent_data_middleware.hpp
new file mode 100644
index 0000000..2ea65a7
--- /dev/null
+++ b/include/persistent_data_middleware.hpp
@@ -0,0 +1,143 @@
+#pragma once
+
+#include <base64.hpp>
+#include <nlohmann/json.hpp>
+#include <pam_authenticate.hpp>
+#include <webassets.hpp>
+#include <random>
+#include <crow/app.h>
+#include <crow/http_request.h>
+#include <crow/http_response.h>
+#include <boost/container/flat_map.hpp>
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/uuid/uuid_io.hpp>
+
+namespace crow {
+
+namespace PersistentData {
+struct UserSession {
+  std::string unique_id;
+  std::string session_token;
+  std::string username;
+  std::string csrf_token;
+};
+
+void to_json(nlohmann::json& j, const UserSession& p) {
+  j = nlohmann::json{{"unique_id", p.unique_id},
+                     {"session_token", p.session_token},
+                     {"username", p.username},
+                     {"csrf_token", p.csrf_token}};
+}
+
+void from_json(const nlohmann::json& j, UserSession& p) {
+  try {
+    p.unique_id = j.at("unique_id").get<std::string>();
+    p.session_token = j.at("session_token").get<std::string>();
+    p.username = j.at("username").get<std::string>();
+    p.csrf_token = j.at("csrf_token").get<std::string>();
+  } catch (std::out_of_range) {
+    // do nothing.  Session API incompatibility, leave sessions empty
+  }
+}
+
+class Middleware {
+  using SessionStore = boost::container::flat_map<std::string, UserSession>;
+  // todo(ed) should read this from a fixed location somewhere, not CWD
+  static constexpr const char* filename = "bmcweb_persistent_data.json";
+  int json_revision = 1;
+
+ public:
+  struct context {
+    SessionStore* auth_tokens;
+  };
+
+  Middleware() { read_data(); }
+
+  void before_handle(crow::request& req, response& res, context& ctx) {
+    ctx.auth_tokens = &auth_tokens;
+  }
+
+  void after_handle(request& req, response& res, context& ctx) {}
+
+  // TODO(ed) this should really use protobuf, or some other serialization
+  // library, but adding another dependency is somewhat outside the scope of
+  // this application for the moment
+  void read_data() {
+    std::ifstream persistent_file(filename);
+    int file_revision = 0;
+    if (persistent_file.is_open()) {
+      // call with exceptions disabled
+      auto data = nlohmann::json::parse(persistent_file, nullptr, false);
+      if (!data.is_discarded()) {
+        file_revision = data["revision"].get<int>();
+        auth_tokens = data["sessions"].get<SessionStore>();
+        system_uuid = data["system_uuid"].get<std::string>();
+      }
+    }
+    bool need_write = false;
+
+    if (system_uuid.empty()) {
+      system_uuid = boost::uuids::to_string(boost::uuids::random_generator()());
+      need_write = true;
+    }
+    if (file_revision < json_revision) {
+      need_write = true;
+    }
+
+    if (need_write) {
+      write_data();
+    }
+  }
+
+  void write_data() {
+    std::ofstream persistent_file(filename);
+    nlohmann::json data;
+    data["sessions"] = auth_tokens;
+    data["system_uuid"] = system_uuid;
+    data["revision"] = json_revision;
+    persistent_file << data;
+  }
+
+  UserSession generate_user_session(const std::string& username) {
+    static constexpr std::array<char, 62> alphanum = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
+        'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
+        'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+        'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
+
+    // entropy: 30 characters, 62 possibilies.  log2(62^30) = 178 bits of
+    // entropy.  OWASP recommends at least 60
+    // https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Session_ID_Entropy
+    std::string session_token;
+    session_token.resize(20, '0');
+    std::uniform_int_distribution<int> dist(0, alphanum.size() - 1);
+    for (int i = 0; i < session_token.size(); ++i) {
+      session_token[i] = alphanum[dist(rd)];
+    }
+    // Only need csrf tokens for cookie based auth, token doesn't matter
+    std::string csrf_token;
+    csrf_token.resize(20, '0');
+    for (int i = 0; i < csrf_token.size(); ++i) {
+      csrf_token[i] = alphanum[dist(rd)];
+    }
+
+    std::string unique_id;
+    unique_id.resize(10, '0');
+    for (int i = 0; i < unique_id.size(); ++i) {
+      unique_id[i] = alphanum[dist(rd)];
+    }
+    UserSession session{unique_id, session_token, username, csrf_token};
+    auth_tokens.emplace(session_token, session);
+    write_data();
+    return session;
+  }
+
+  SessionStore auth_tokens;
+  std::string system_uuid;
+  std::random_device rd;
+};
+
+}  // namespaec PersistentData
+}  // namespace crow
diff --git a/include/redfish_v1.hpp b/include/redfish_v1.hpp
index 73ed84e..d13eb13 100644
--- a/include/redfish_v1.hpp
+++ b/include/redfish_v1.hpp
@@ -7,86 +7,403 @@
 #include <dbus/filter.hpp>
 #include <dbus/match.hpp>
 #include <dbus/message.hpp>
+#include <persistent_data_middleware.hpp>
+#include <token_authorization_middleware.hpp>
 #include <fstream>
+#include <streambuf>
+#include <string>
 
 namespace crow {
 namespace redfish {
 
 template <typename... Middlewares>
-void request_routes(Crow<Middlewares...>& app) {
-  
-  // noop for now
-  return;
-
-
-  CROW_ROUTE(app, "/redfish/").methods("GET"_method)([]() {
-    return nlohmann::json{{"v1", "/redfish/v1/"}};
-  });
-  CROW_ROUTE(app, "/redfish/v1/").methods("GET"_method)([]() {
-    return nlohmann::json{
-        {"@odata.context", "/redfish/v1/$metadata#ServiceRoot.ServiceRoot"},
-        {"@odata.id", "/redfish/v1/"},
-        {"@odata.type", "#ServiceRoot.v1_1_1.ServiceRoot"},
-        {"Id", "RootService"},
-        {"Name", "Root Service"},
-        {"RedfishVersion", "1.1.0"},
-        {"UUID", "bdfc5c6d-07a9-4e67-972f-bd2b30c6a0e8"},
-        //{"Systems", {{"@odata.id", "/redfish/v1/Systems"}}},
-        //{"Chassis", {{"@odata.id", "/redfish/v1/Chassis"}}},
-        //{"Managers", {{"@odata.id", "/redfish/v1/Managers"}}},
-        //{"SessionService", {{"@odata.id", "/redfish/v1/SessionService"}}},
-        {"AccountService", {{"@odata.id", "/redfish/v1/AccountService"}}},
-        //{"UpdateService", {{"@odata.id", "/redfish/v1/UpdateService"}}},
-        /*{"Links",
-         {{"Sessions",
-           {{"@odata.id", "/redfish/v1/SessionService/Sessions"}}}}}*/
-    };
-  });
-
-  CROW_ROUTE(app, "/redfish/v1/Chassis").methods("GET"_method)([]() {
-    std::vector<std::string> entities;
-    std::ifstream f("~/system.json");
-    nlohmann::json input;
-    input << f;
-    for (auto it = input.begin(); it != input.end(); it++) {
-      auto value = it.value();
-      if (value["type"] == "Chassis") {
-         std::string str = value["name"];
-         entities.emplace_back(str);
-      }
+void get_redfish_sub_routes(Crow<Middlewares...>& app, const std::string& url,
+                            nlohmann::json& j) {
+  auto routes = app.get_routes(url);
+  for (auto& route : routes) {
+    auto redfish_sub_route =
+        route.substr(url.size(), route.size() - url.size() - 1);
+    // check if the route is at this level, and we didn't find and exact match
+    // also, filter out resources that start with $ to remove $metadata
+    if (!redfish_sub_route.empty() && redfish_sub_route[0] != '$' &&
+        redfish_sub_route.find('/') == std::string::npos) {
+      j[redfish_sub_route] = nlohmann::json{{"@odata.id", route}};
     }
-    auto ret = nlohmann::json{
-        {"@odata.context",
-         "/redfish/v1/$metadata#ChassisCollection.ChassisCollection"},
-        {"@odata.id", "/redfish/v1/Chassis"},
-        {"@odata.type", "#ChassisCollection.ChassisCollection"},
-        {"Name", "Chassis Collection"},
-        {"Members@odata.count", entities.size()}};
-    return ret;
-  });
+  }
+}
 
-  CROW_ROUTE(app, "/redfish/v1/AccountService").methods("GET"_method)([]() {
-    return nlohmann::json{
-        {"@odata.context",
-         "/redfish/v1/$metadata#AccountService.AccountService"},
-        {"@odata.id", "/redfish/v1/AccountService"},
-        {"@odata.type", "#AccountService.v1_1_0.AccountService"},
-        {"Id", "AccountService"},
-        {"Name", "Account Service"},
-        {"Description", "BMC User Accounts"},
-        {"Status",
-         // TODO(ed) health rollup
-         {{"State", "Enabled"}, {"Health", "OK"}, {"HealthRollup", "OK"}}},
-        {"ServiceEnabled", true},
-        {"MinPasswordLength", 1},
-        {"MaxPasswordLength", 20},
-        {"Accounts", {{"@odata.id", "/redfish/v1/AccountService/Accounts"}}},
-        //{"Roles", {{"@odata.id", "/redfish/v1/AccountService/Roles"}}}
-    };
-  });
-
-  CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts")
+template <typename... Middlewares>
+void request_routes(Crow<Middlewares...>& app) {
+  CROW_ROUTE(app, "/redfish/")
       .methods("GET"_method)([](const crow::request& req, crow::response& res) {
+        res.json_value = {{"v1", "/redfish/v1/"}};
+        res.end();
+      });
+
+  CROW_ROUTE(app, "/redfish/v1/")
+      .methods(
+          "GET"_method)([&](const crow::request& req, crow::response& res) {
+        res.json_value = {
+            {"@odata.context", "/redfish/v1/$metadata#ServiceRoot.ServiceRoot"},
+            {"@odata.id", "/redfish/v1/"},
+            {"@odata.type", "#ServiceRoot.v1_1_1.ServiceRoot"},
+            {"Id", "RootService"},
+            {"Name", "Root Service"},
+            {"RedfishVersion", "1.1.0"},
+            {"Links",
+             {{"Sessions",
+               {{"@odata.id", "/redfish/v1/SessionService/Sessions/"}}}}}};
+
+        res.json_value["UUID"] =
+            app.template get_middleware<PersistentData::Middleware>()
+                .system_uuid;
+        get_redfish_sub_routes(app, "/redfish/v1/", res.json_value);
+        res.end();
+      });
+
+  CROW_ROUTE(app, "/redfish/v1/$metadata/")
+      .methods(
+          "GET"_method)([&](const crow::request& req, crow::response& res) {
+        const char* response_text = R"(<?xml version="1.0" encoding="UTF-8"?>
+        <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
+            <edmx:Reference Uri="/redfish/v1/schema/ServiceRoot_v1.xml">
+                <edmx:Include Namespace="ServiceRoot"/>
+                <edmx:Include Namespace="ServiceRoot.v1_0_4"/>
+                <edmx:Include Namespace="ServiceRoot.v1_1_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/AccountService_v1.xml">
+                <edmx:Include Namespace="AccountService"/>
+                <edmx:Include Namespace="AccountService.v1_0_3"/>
+                <edmx:Include Namespace="AccountService.v1_1_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Chassis_v1.xml">
+                <edmx:Include Namespace="Chassis"/>
+                <edmx:Include Namespace="Chassis.v1_0_3"/>
+                <edmx:Include Namespace="Chassis.v1_1_3"/>
+                <edmx:Include Namespace="Chassis.v1_2_1"/>
+                <edmx:Include Namespace="Chassis.v1_3_1"/>
+                <edmx:Include Namespace="Chassis.v1_4_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/ChassisCollection_v1.xml">
+                <edmx:Include Namespace="ChassisCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/ComputerSystem_v1.xml">
+                <edmx:Include Namespace="ComputerSystem"/>
+                <edmx:Include Namespace="ComputerSystem.v1_0_4"/>
+                <edmx:Include Namespace="ComputerSystem.v1_1_2"/>
+                <edmx:Include Namespace="ComputerSystem.v1_2_1"/>
+                <edmx:Include Namespace="ComputerSystem.v1_3_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/ComputerSystemCollection_v1.xml">
+                <edmx:Include Namespace="ComputerSystemCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/EthernetInterface_v1.xml">
+                <edmx:Include Namespace="EthernetInterface"/>
+                <edmx:Include Namespace="EthernetInterface.v1_0_3"/>
+                <edmx:Include Namespace="EthernetInterface.v1_1_1"/>
+                <edmx:Include Namespace="EthernetInterface.v1_2_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/EthernetInterfaceCollection_v1.xml">
+                <edmx:Include Namespace="EthernetInterfaceCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/LogEntry_v1.xml">
+                <edmx:Include Namespace="LogEntry"/>
+                <edmx:Include Namespace="LogEntry.v1_0_3"/>
+                <edmx:Include Namespace="LogEntry.v1_1_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/LogEntryCollection_v1.xml">
+                <edmx:Include Namespace="LogEntryCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/LogService_v1.xml">
+                <edmx:Include Namespace="LogService"/>
+                <edmx:Include Namespace="LogService.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/LogServiceCollection_v1.xml">
+                <edmx:Include Namespace="LogServiceCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Manager_v1.xml">
+                <edmx:Include Namespace="Manager"/>
+                <edmx:Include Namespace="Manager.v1_0_3"/>
+                <edmx:Include Namespace="Manager.v1_1_1"/>
+                <edmx:Include Namespace="Manager.v1_2_1"/>
+                <edmx:Include Namespace="Manager.v1_3_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/ManagerAccount_v1.xml">
+                <edmx:Include Namespace="ManagerAccount"/>
+                <edmx:Include Namespace="ManagerAccount.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/ManagerNetworkProtocol_v1.xml">
+                <edmx:Include Namespace="ManagerNetworkProtocol"/>
+                <edmx:Include Namespace="ManagerNetworkProtocol.v1_0_3"/>
+                <edmx:Include Namespace="ManagerNetworkProtocol.v1_1_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/ManagerAccountCollection_v1.xml">
+                <edmx:Include Namespace="ManagerAccountCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/ManagerCollection_v1.xml">
+                <edmx:Include Namespace="ManagerCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Power_v1.xml">
+                <edmx:Include Namespace="Power"/>
+                <edmx:Include Namespace="Power.v1_0_3"/>
+                <edmx:Include Namespace="Power.v1_1_1"/>
+                <edmx:Include Namespace="Power.v1_2_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Processor_v1.xml">
+                <edmx:Include Namespace="Processor"/>
+                <edmx:Include Namespace="Processor.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/ProcessorCollection_v1.xml">
+                <edmx:Include Namespace="ProcessorCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Role_v1.xml">
+                <edmx:Include Namespace="Role"/>
+                <edmx:Include Namespace="Role.v1_0_2"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/RoleCollection_v1.xml">
+                <edmx:Include Namespace="RoleCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Session_v1.xml">
+                <edmx:Include Namespace="Session"/>
+                <edmx:Include Namespace="Session.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/SessionCollection_v1.xml">
+                <edmx:Include Namespace="SessionCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/SessionService_v1.xml">
+                <edmx:Include Namespace="SessionService"/>
+                <edmx:Include Namespace="SessionService.v1_0_3"/>
+                <edmx:Include Namespace="SessionService.v1_1_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Thermal_v1.xml">
+                <edmx:Include Namespace="Thermal"/>
+                <edmx:Include Namespace="Thermal.v1_0_3"/>
+                <edmx:Include Namespace="Thermal.v1_1_1"/>
+                <edmx:Include Namespace="Thermal.v1_2_0"/>
+            </edmx:Reference>
+          <edmx:Reference Uri="/redfish/v1/schema/RedfishExtensions_v1.xml">
+                <edmx:Include Namespace="RedfishExtensions.v1_0_0" Alias="Redfish"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/IPAddresses_v1.xml">
+                <edmx:Include Namespace="IPAddresses"/>
+                <edmx:Include Namespace="IPAddresses.v1_0_4"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/MemoryCollection_v1.xml">
+                <edmx:Include Namespace="MemoryCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/MemoryMetrics_v1.xml">
+                <edmx:Include Namespace="MemoryMetrics"/>
+                <edmx:Include Namespace="MemoryMetrics.v1_0_1"/>
+                <edmx:Include Namespace="MemoryMetrics.v1_1_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Memory_v1.xml">
+                <edmx:Include Namespace="Memory"/>
+                <edmx:Include Namespace="Memory.v1_0_1"/>
+                <edmx:Include Namespace="Memory.v1_1_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/PhysicalContext_v1.xml">
+                <edmx:Include Namespace="PhysicalContext"/>
+                <edmx:Include Namespace="PhysicalContext.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Privileges_v1.xml">
+                <edmx:Include Namespace="Privileges"/>
+                <edmx:Include Namespace="Privileges.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Redundancy_v1.xml">
+                <edmx:Include Namespace="Redundancy"/>
+                <edmx:Include Namespace="Redundancy.v1_0_3"/>
+                <edmx:Include Namespace="Redundancy.v1_1_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Resource_v1.xml">
+                <edmx:Include Namespace="Resource"/>
+                <edmx:Include Namespace="Resource.v1_0_3"/>
+                <edmx:Include Namespace="Resource.v1_1_2"/>
+                <edmx:Include Namespace="Resource.v1_2_1"/>
+                <edmx:Include Namespace="Resource.v1_3_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/VirtualMediaCollection_v1.xml">
+                <edmx:Include Namespace="VirtualMediaCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/VirtualMedia_v1.xml">
+                <edmx:Include Namespace="VirtualMedia"/>
+                <edmx:Include Namespace="VirtualMedia.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/VLanNetworkInterfaceCollection_v1.xml">
+                <edmx:Include Namespace="VLanNetworkInterfaceCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/VLanNetworkInterface_v1.xml">
+                <edmx:Include Namespace="VLanNetworkInterface"/>
+                <edmx:Include Namespace="VLanNetworkInterface.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/StorageCollection_v1.xml">
+                <edmx:Include Namespace="StorageCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Storage_v1.xml">
+                <edmx:Include Namespace="Storage"/>
+                <edmx:Include Namespace="Storage.v1_0_2"/>
+                <edmx:Include Namespace="Storage.v1_1_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Drive_v1.xml">
+                <edmx:Include Namespace="Drive"/>
+                <edmx:Include Namespace="Drive.v1_0_2"/>
+                <edmx:Include Namespace="Drive.v1_1_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/SoftwareInventoryCollection_v1.xml">
+                <edmx:Include Namespace="SoftwareInventoryCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/SoftwareInventory_v1.xml">
+                <edmx:Include Namespace="SoftwareInventory"/>
+                <edmx:Include Namespace="SoftwareInventory.v1_0_1"/>
+                <edmx:Include Namespace="SoftwareInventory.v1_1_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/UpdateService_v1.xml">
+                <edmx:Include Namespace="UpdateService"/>
+                <edmx:Include Namespace="UpdateService.v1_0_1"/>
+                <edmx:Include Namespace="UpdateService.v1_1_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Message_v1.xml">
+                <edmx:Include Namespace="Message"/>
+                <edmx:Include Namespace="Message.v1_0_4"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/EndpointCollection_v1.xml">
+                <edmx:Include Namespace="EndpointCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/Endpoint_v1.xml">
+                <edmx:Include Namespace="Endpoint"/>
+                <edmx:Include Namespace="Endpoint.v1_0_1"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/HostInterfaceCollection_v1.xml">
+                <edmx:Include Namespace="HostInterfaceCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/HostInterface_v1.xml">
+                <edmx:Include Namespace="HostInterface"/>
+                <edmx:Include Namespace="HostInterface.v1_0_0"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/MessageRegistryFileCollection_v1.xml">
+                <edmx:Include Namespace="MessageRegistryFileCollection"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/MessageRegistryFile_v1.xml">
+                <edmx:Include Namespace="MessageRegistryFile"/>
+                <edmx:Include Namespace="MessageRegistryFile.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/EventService_v1.xml">
+                <edmx:Include Namespace="EventService"/>
+                <edmx:Include Namespace="EventService.v1_0_3"/>
+            </edmx:Reference>
+            <edmx:Reference Uri="/redfish/v1/schema/EventDestinationCollection_v1.xml">
+                <edmx:Include Namespace="EventDestinationCollection"/>
+            </edmx:Reference> 
+            <edmx:Reference Uri="/redfish/v1/schema/EventDestination_v1.xml">
+                <edmx:Include Namespace="EventDestination"/>
+                <edmx:Include Namespace="EventDestination.v1_0_3"/>
+                <edmx:Include Namespace="EventDestination.v1_1_1"/>
+            </edmx:Reference> 
+            <edmx:Reference Uri="/redfish/v1/schema/Event_v1.xml">
+                <edmx:Include Namespace="Event"/>
+                <edmx:Include Namespace="Event.v1_0_4"/>
+                <edmx:Include Namespace="Event.v1_1_2"/>
+            </edmx:Reference> 
+            <edmx:DataServices>
+                <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Service">
+                    <EntityContainer Name="Service" Extends="ServiceRoot.v1_0_0.ServiceContainer"/>
+                </Schema>
+            </edmx:DataServices>
+        </edmx:Edmx>)";
+
+        res.body = response_text;
+        res.add_header("Content-Type", "application/xml");
+        res.end();
+      });
+
+  CROW_ROUTE(app, "/redfish/v1/Chassis/")
+      .methods("GET"_method)(
+          [&](const crow::request& req, crow::response& res) {
+            std::vector<std::string> entities;
+            /*std::ifstream f("~/system.json");
+
+            nlohmann::json input = nlohmann::json::parse(f);
+            for (auto it = input.begin(); it != input.end(); it++) {
+              auto value = it.value();
+              if (value["type"] == "Chassis") {
+                std::string str = value["name"];
+                entities.emplace_back(str);
+              }
+            }
+            */
+            res.json_value = {
+                {"@odata.context",
+                 "/redfish/v1/$metadata#ChassisCollection.ChassisCollection"},
+                {"@odata.id", "/redfish/v1/Chassis"},
+                {"@odata.type", "#ChassisCollection.ChassisCollection"},
+                {"Name", "Chassis Collection"},
+                {"Members@odata.count", entities.size()}};
+
+            get_redfish_sub_routes(app, "/redfish/v1/Chassis", res.json_value);
+            res.end();
+          });
+
+  CROW_ROUTE(app, "/redfish/v1/AccountService/")
+      .methods(
+          "GET"_method)([&](const crow::request& req, crow::response& res) {
+        res.json_value = {
+            {"@odata.context",
+             "/redfish/v1/$metadata#AccountService.AccountService"},
+            {"@odata.id", "/redfish/v1/AccountService"},
+            {"@odata.type", "#AccountService.v1_1_0.AccountService"},
+            {"Id", "AccountService"},
+            {"Name", "Account Service"},
+            {"Description", "BMC User Accounts"},
+            {"Status",
+             // TODO(ed) health rollup
+             {{"State", "Enabled"}, {"Health", "OK"}, {"HealthRollup", "OK"}}},
+            {"ServiceEnabled", true},
+            {"MinPasswordLength", 1},
+            {"MaxPasswordLength", 20},
+        };
+        get_redfish_sub_routes(app, "/redfish/v1/AccountService",
+                               res.json_value);
+        res.end();
+      });
+
+  CROW_ROUTE(app, "/redfish/v1/AccountService/Roles/")
+      .methods("GET"_method)(
+          [&](const crow::request& req, crow::response& res) {
+            res.json_value = {
+                {"@odata.context",
+                 "/redfish/v1/$metadata#RoleCollection.RoleCollection"},
+                {"@odata.id", "/redfish/v1/AccountService/Roles"},
+                {"@odata.type", "#RoleCollection.RoleCollection"},
+                {"Name", "Account Service"},
+                {"Description", "BMC User Roles"},
+                {"Members@odata.count", 1},
+                {"Members",
+                 {{"@odata.id",
+                   "/redfish/v1/AccountService/Roles/Administrator"}}}};
+            get_redfish_sub_routes(app, "/redfish/v1/AccountService",
+                                   res.json_value);
+            res.end();
+          });
+
+  CROW_ROUTE(app, "/redfish/v1/AccountService/Roles/Administrator/")
+      .methods("GET"_method)(
+          [&](const crow::request& req, crow::response& res) {
+            res.json_value = {
+                {"@odata.context", "/redfish/v1/$metadata#Role.Role"},
+                {"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"},
+                {"@odata.type", "#Role.v1_0_2.Role"},
+                {"Id", "Administrator"},
+                {"Name", "User Role"},
+                {"Description", "Administrator User Role"},
+                {"IsPredefined", true},
+                {"AssignedPrivileges",
+                 {"Login", "ConfigureManager", "ConfigureUsers",
+                  "ConfigureSelf", "ConfigureComponents"}}};
+            res.end();
+          });
+
+  CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
+      .methods(
+          "GET"_method)([&](const crow::request& req, crow::response& res) {
         boost::asio::io_service io;
         auto bus = std::make_shared<dbus::connection>(io, dbus::bus::session);
         dbus::endpoint user_list("org.openbmc.UserManager",
@@ -94,11 +411,11 @@
                                  "org.openbmc.Enrol", "UserList");
         bus->async_method_call(
             [&](const boost::system::error_code ec,
-                           const std::vector<std::string>& users) {
+                const std::vector<std::string>& users) {
               if (ec) {
                 res.code = 500;
               } else {
-                nlohmann::json return_json{
+                res.json_value = {
                     {"@odata.context",
                      "/redfish/v1/"
                      "$metadata#ManagerAccountCollection."
@@ -109,22 +426,25 @@
                     {"Name", "Accounts Collection"},
                     {"Description", "BMC User Accounts"},
                     {"Members@odata.count", users.size()}};
-                nlohmann::json member_array;
+                nlohmann::json member_array = nlohmann::json::array();
                 int user_index = 0;
                 for (auto& user : users) {
                   member_array.push_back(
-                      {{"@odata.id", "/redfish/v1/AccountService/Accounts/" +
-                                         std::to_string(++user_index)}});
+                      {{"@odata.id",
+                        "/redfish/v1/AccountService/Accounts/" +
+                            std::to_string(++user_index)}});
                 }
-                return_json["Members"] = member_array;
+                res.json_value["Members"] = member_array;
               }
               res.end();
-            }, user_list);
+            },
+            user_list);
       });
 
   CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/<int>/")
-      .methods("GET"_method)([](int account_index) {
-        return nlohmann::json{
+      .methods("GET"_method)([](const crow::request& req, crow::response& res,
+                                int account_index) {
+        res.json_value = {
             {"@odata.context",
              "/redfish/v1/$metadata#ManagerAccount.ManagerAccount"},
             {"@odata.id", "/redfish/v1/AccountService/Accounts/1"},
@@ -139,6 +459,128 @@
             {"Links",
              {{"Role",
                {{"@odata.id", "/redfish/v1/AccountService/Roles/NoAccess"}}}}}};
+        res.end();
+      });
+
+  CROW_ROUTE(app, "/redfish/v1/SessionService/")
+      .methods(
+          "GET"_method)([&](const crow::request& req, crow::response& res) {
+        res.json_value = {
+            {"@odata.context",
+             "/redfish/v1/$metadata#SessionService.SessionService"},
+            {"@odata.id", "/redfish/v1/SessionService"},
+            {"@odata.type", "#SessionService.v1_1_1.SessionService"},
+            {"Id", "SessionService"},
+            {"Name", "SessionService"},
+            {"Description", "SessionService"},
+            {"Status",
+             {{"State", "Enabled"}, {"Health", "OK"}, {"HealthRollup", "OK"}}},
+            {"ServiceEnabled", true},
+            // TODO(ed) converge with session timeouts once they exist
+            // Bogus number for now
+            {"SessionTimeout", 1800}};
+        get_redfish_sub_routes(app, "/redfish/v1/AccountService",
+                               res.json_value);
+        res.end();
+      });
+
+  CROW_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
+      .methods("POST"_method, "GET"_method)([&](const crow::request& req,
+                                                crow::response& res) {
+        auto& data_middleware =
+            app.template get_middleware<PersistentData::Middleware>();
+        if (req.method == "POST"_method) {
+          // call with exceptions disabled
+          auto login_credentials =
+              nlohmann::json::parse(req.body, nullptr, false);
+          if (login_credentials.is_discarded()) {
+            res.code = 400;
+            res.end();
+            return;
+          }
+          // check for username/password in the root object
+          auto user_it = login_credentials.find("UserName");
+          auto pass_it = login_credentials.find("Password");
+          if (user_it == login_credentials.end() ||
+              pass_it == login_credentials.end()) {
+            res.code = 400;
+            res.end();
+            return;
+          }
+
+          std::string username = user_it->get<const std::string>();
+          std::string password = pass_it->get<const std::string>();
+          if (username.empty() || password.empty()) {
+            res.code = 400;
+            res.end();
+            return;
+          }
+
+          if (!pam_authenticate_user(username, password)) {
+            res.code = 401;
+            res.end();
+            return;
+          }
+          auto session = data_middleware.generate_user_session(username);
+          res.code = 200;
+          res.add_header("X-Auth-Token", session.session_token);
+          res.json_value = {
+              {"@odata.context", "/redfish/v1/$metadata#Session"},
+              {"@odata.id",
+               "/redfish/v1/SessionService/Sessions/" + session.unique_id},
+              {"@odata.type", "#Session.v1_0_3.Session"},
+              {"Id", session.unique_id},
+              {"Name", "User Session"},
+              {"Description", "Manager User Session"},
+              {"UserName", username}};
+        } else {  // assume get
+          res.json_value = {
+              {"@odata.context",
+               "/redfish/v1/$metadata#SessionCollection.SessionCollection"},
+              {"@odata.id", "/redfish/v1/SessionService/Sessions"},
+              {"@odata.type", "#SessionCollection.SessionCollection"},
+              {"Name", "Session Collection"},
+              {"Description", "Session Collection"},
+              {"Members@odata.count", data_middleware.auth_tokens.size()}
+
+          };
+          nlohmann::json member_array = nlohmann::json::array();
+          for (auto& session : data_middleware.auth_tokens) {
+            member_array.push_back({{"@odata.id",
+                                     "/redfish/v1/SessionService/Sessions/" +
+                                         session.second.unique_id}});
+          }
+          res.json_value["Members"] = member_array;
+        }
+        res.end();
+      });
+
+  CROW_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
+      .methods("GET"_method, "DELETE"_method)([&](const crow::request& req,
+                                                  crow::response& res,
+                                                  const std::string& session) {
+        auto& data_middleware =
+            app.template get_middleware<PersistentData::Middleware>();
+        auto session_it = data_middleware.auth_tokens.find(session);
+        if (session_it == data_middleware.auth_tokens.end()) {
+          res.code = 404;
+          res.end();
+          return;
+        }
+        if (req.method == "DELETE"_method) {
+          data_middleware.auth_tokens.erase(session_it);
+          res.code = 200;
+        } else {  // assume get
+          res.json_value = {
+              {"@odata.context", "/redfish/v1/$metadata#Session.Session"},
+              {"@odata.id", "/redfish/v1/SessionService/Sessions/" + session},
+              {"@odata.type", "#Session.v1_0_3.Session"},
+              {"Id", session_it->second.unique_id},
+              {"Name", "User Session"},
+              {"Description", "Manager User Session"},
+              {"UserName", session_it->second.username}};
+        }
+        res.end();
       });
 }
 }  // namespace redfish
diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp
index eebd4f0..9642282 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/token_authorization_middleware.hpp
@@ -2,49 +2,48 @@
 
 #include <base64.hpp>
 #include <pam_authenticate.hpp>
+#include <persistent_data_middleware.hpp>
 #include <webassets.hpp>
 #include <random>
 #include <crow/app.h>
 #include <crow/http_request.h>
 #include <crow/http_response.h>
+#include <boost/bimap.hpp>
 #include <boost/container/flat_set.hpp>
-
 namespace crow {
 
 namespace TokenAuthorization {
 struct User {};
 
-using random_bytes_engine =
-    std::independent_bits_engine<std::random_device, CHAR_BIT, unsigned char>;
-
 class Middleware {
  public:
-  Middleware() {
-    for (auto& route : crow::webassets::routes) {
-      allowed_routes.emplace(route);
-    }
-    allowed_routes.emplace("/login");
-  };
-
   struct context {};
-
-  void before_handle(crow::request& req, response& res, context& ctx) {
+  template <typename AllContext>
+  void before_handle(crow::request& req, response& res, context& ctx,
+                     AllContext& allctx) {
     auto return_unauthorized = [&req, &res]() {
       res.code = 401;
       res.end();
     };
 
-    if (allowed_routes.find(req.url.c_str()) != allowed_routes.end()) {
+    if (crow::webassets::routes.find(req.url) !=
+        crow::webassets::routes.end()) {
       // TODO this is total hackery to allow the login page to work before the
       // user is authenticated.  Also, it will be quite slow for all pages
       // instead of a one time hit for the whitelist entries.  Ideally, this
       // should be done in the url router handler, with tagged routes for the
       // whitelist entries. Another option would be to whitelist a minimal form
       // based page that didn't load the full angular UI until after login
+    } else if (req.url == "/login" || req.url == "/redfish/v1" ||
+               req.url == "/redfish/v1/" ||
+               req.url == "/redfish/v1/$metadata" ||
+               (req.url == "/redfish/v1/SessionService/Sessions/" &&
+                req.method == "POST"_method)) {
     } else {
       // Normal, non login, non static file request
       // Check for an authorization header, reject if not present
       std::string auth_key;
+      bool require_csrf = true;
       if (req.headers.count("Authorization") == 1) {
         std::string auth_header = req.get_header_value("Authorization");
         // If the user is attempting any kind of auth other than token, reject
@@ -53,6 +52,10 @@
           return;
         }
         auth_key = auth_header.substr(6);
+        require_csrf = false;
+      } else if (req.headers.count("X-Auth-Token") == 1) {
+        auth_key = req.get_header_value("X-Auth-Token");
+        require_csrf = false;
       } else {
         int count = req.headers.count("Cookie");
         if (count == 1) {
@@ -62,36 +65,50 @@
             start_index += 8;
             auto end_index = cookie_value.find(";", start_index);
             if (end_index == std::string::npos) {
-              end_index = cookie_value.size() - 1;
+              end_index = cookie_value.size();
             }
             auth_key =
-                cookie_value.substr(start_index, end_index - start_index + 1);
+                cookie_value.substr(start_index, end_index - start_index);
           }
         }
+        require_csrf = true;  // Cookies require CSRF
       }
       if (auth_key.empty()) {
         res.code = 400;
         res.end();
         return;
       }
-      std::cout << "auth_key=" << auth_key << "\n";
-
-      for (auto& token : this->auth_tokens) {
-        std::cout << "token=" << token << "\n";
-      }
-
-      // TODO(ed), use span here instead of constructing a new string
-      if (this->auth_tokens.find(auth_key) == this->auth_tokens.end()) {
+      auto& data_mw = allctx.template get<PersistentData::Middleware>();
+      auto session_it = data_mw.auth_tokens->find(auth_key);
+      if (session_it == data_mw.auth_tokens->end()) {
         return_unauthorized();
         return;
       }
 
-      if (req.url == "/logout") {
-        this->auth_tokens.erase(auth_key);
+      if (require_csrf) {
+        // RFC7231 defines methods that need csrf protection
+        if (req.method != "GET"_method) {
+          const std::string& csrf = req.get_header_value("X-XSRF-TOKEN");
+          // Make sure both tokens are filled
+          if (csrf.empty() || session_it->second.csrf_token.empty()) {
+            return_unauthorized();
+            return;
+          }
+          // Reject if csrf token not available
+          if (csrf != session_it->second.csrf_token) {
+            return_unauthorized();
+            return;
+          }
+        }
+      }
+
+      if (req.url == "/logout" && req.method == "POST"_method) {
+        data_mw.auth_tokens->erase(auth_key);
         res.code = 200;
         res.end();
         return;
       }
+
       // else let the request continue unharmed
     }
   }
@@ -100,19 +117,18 @@
     // Do nothing
   }
 
-  boost::container::flat_set<std::string> auth_tokens;
   boost::container::flat_set<std::string> allowed_routes;
-  random_bytes_engine rbe;
 };
 
-// TODO(ed) see if there is a better way to allow middlewares to request routes.
+// TODO(ed) see if there is a better way to allow middlewares to request
+// routes.
 // Possibly an init function on first construction?
 template <typename... Middlewares>
 void request_routes(Crow<Middlewares...>& app) {
-  static_assert(black_magic::contains<TokenAuthorization::Middleware,
-                                      Middlewares...>::value,
-                "TokenAuthorization middleware must be enabled in app to use "
-                "auth routes");
+  static_assert(
+      black_magic::contains<PersistentData::Middleware, Middlewares...>::value,
+      "TokenAuthorization middleware must be enabled in app to use "
+      "auth routes");
   CROW_ROUTE(app, "/login")
       .methods(
           "POST"_method)([&](const crow::request& req, crow::response& res) {
@@ -127,44 +143,44 @@
         bool looks_like_ibm = false;
         // Check if auth was provided by a payload
         if (content_type == "application/json") {
-          try {
-            auto login_credentials = nlohmann::json::parse(req.body);
-            // check for username/password in the root object
-            // THis method is how intel APIs authenticate
-            auto user_it = login_credentials.find("username");
-            auto pass_it = login_credentials.find("password");
-            if (user_it != login_credentials.end() &&
-                pass_it != login_credentials.end()) {
-              username = user_it->get<const std::string>();
-              password = pass_it->get<const std::string>();
-            } else {
-              // Openbmc appears to push a data object that contains the same
-              // keys (username and password), attempt to use that
-              auto data_it = login_credentials.find("data");
-              if (data_it != login_credentials.end()) {
-                // Some apis produce an array of value ["username", "password"]
-                if (data_it->is_array()) {
-                  if (data_it->size() == 2) {
-                    username = (*data_it)[0].get<const std::string>();
-                    password = (*data_it)[1].get<const std::string>();
-                    looks_like_ibm = true;
-                  }
-                } else if (data_it->is_object()) {
-                  auto user_it = data_it->find("username");
-                  auto pass_it = data_it->find("password");
-                  if (user_it != data_it->end() && pass_it != data_it->end()) {
-                    username = user_it->get<const std::string>();
-                    password = pass_it->get<const std::string>();
-                  }
-                }
-              }
-            }
-          } catch (...) {
-            // TODO(ed) figure out how to not throw on a bad json parse
+          auto login_credentials =
+              nlohmann::json::parse(req.body, nullptr, false);
+          if (login_credentials.is_discarded()) {
             res.code = 400;
             res.end();
             return;
           }
+          // check for username/password in the root object
+          // THis method is how intel APIs authenticate
+          auto user_it = login_credentials.find("username");
+          auto pass_it = login_credentials.find("password");
+          if (user_it != login_credentials.end() &&
+              pass_it != login_credentials.end()) {
+            username = user_it->get<const std::string>();
+            password = pass_it->get<const std::string>();
+          } else {
+            // Openbmc appears to push a data object that contains the same
+            // keys (username and password), attempt to use that
+            auto data_it = login_credentials.find("data");
+            if (data_it != login_credentials.end()) {
+              // Some apis produce an array of value ["username",
+              // "password"]
+              if (data_it->is_array()) {
+                if (data_it->size() == 2) {
+                  username = (*data_it)[0].get<const std::string>();
+                  password = (*data_it)[1].get<const std::string>();
+                  looks_like_ibm = true;
+                }
+              } else if (data_it->is_object()) {
+                auto user_it = data_it->find("username");
+                auto pass_it = data_it->find("password");
+                if (user_it != data_it->end() && pass_it != data_it->end()) {
+                  username = user_it->get<const std::string>();
+                  password = pass_it->get<const std::string>();
+                }
+              }
+            }
+          }
         } else {
           // check if auth was provided as a query string
           auto user_it = req.headers.find("username");
@@ -179,41 +195,28 @@
           if (!pam_authenticate_user(username, password)) {
             res.code = 401;
           } else {
-            // THis should be a multiple of 3 to make sure that base64 doesn't
-            // end with an equals sign at the end.  we could strip it off
-            // afterward
-            std::string token(30, 'a');
-            // TODO(ed) for some reason clang-tidy finds a divide by zero
-            // error in cstdlibc here commented out for now.
-            // Needs investigation
-            auto& m = app.template get_middleware<Middleware>();
-            std::generate(std::begin(token), std::end(token),
-                          std::ref(m.rbe));  // NOLINT
-            std::string encoded_token;
-            if (!base64::base64_encode(token, encoded_token)) {
-              res.code = 500;
-            } else {
-              
-              m.auth_tokens.insert(encoded_token);
-              if (looks_like_ibm) {
-                // IBM requires a very specific login structure, and doesn't
-                // actually look at the status code.  TODO(ed).... Fix that
-                // upstream
-                nlohmann::json ret{
-                    {"data", "User '" + username + "' logged in"},
-                    {"message", "200 OK"},
-                    {"status", "ok"}};
-                res.add_header(
-                    "Set-Cookie",
-                    "SESSION=" + encoded_token + "; Secure; HttpOnly");
-                res.write(ret.dump());
-              } else {
-                // if content type is json, assume json token
-                nlohmann::json ret{{"token", encoded_token}};
+            auto& auth_middleware =
+                app.template get_middleware<PersistentData::Middleware>();
+            auto session = auth_middleware.generate_user_session(username);
 
-                res.write(ret.dump());
-                res.add_header("Content-Type", "application/json");
-              }
+            if (looks_like_ibm) {
+              // IBM requires a very specific login structure, and doesn't
+              // actually look at the status code.  TODO(ed).... Fix that
+              // upstream
+              nlohmann::json ret{{"data", "User '" + username + "' logged in"},
+                                 {"message", "200 OK"},
+                                 {"status", "ok"}};
+              res.add_header(
+                  "Set-Cookie",
+                  "SESSION=" + session.session_token + "; Secure; HttpOnly");
+              res.add_header("Set-Cookie", "XSRF-TOKEN=" + session.csrf_token);
+              res.write(ret.dump());
+            } else {
+              // if content type is json, assume json token
+              nlohmann::json ret{{"token", session.session_token}};
+
+              res.write(ret.dump());
+              res.add_header("Content-Type", "application/json");
             }
           }
 
@@ -224,4 +227,4 @@
       });
 }
 }  // namespaec TokenAuthorization
-}  // namespace crow
\ No newline at end of file
+}  // namespace crow
diff --git a/include/webassets.hpp b/include/webassets.hpp
index 988af76..7845d71 100644
--- a/include/webassets.hpp
+++ b/include/webassets.hpp
@@ -14,35 +14,38 @@
 namespace webassets {
 
 namespace filesystem = std::experimental::filesystem;
-static const char* gzip_string = "gzip";
-static const char* none_string = "none";
-static const char* if_none_match_string = "If-None-Match";
-static const char* content_encoding_string = "Content-Encoding";
-static const char* content_type_string = "Content-Type";
-static const char* etag_string = "ETag";
+
+struct cmp_str {
+  bool operator()(const char* a, const char* b) const {
+    return std::strcmp(a, b) < 0;
+  }
+};
 
 static boost::container::flat_set<std::string> routes;
 
 template <typename... Middlewares>
 void request_routes(Crow<Middlewares...>& app) {
-  const static boost::container::flat_map<const char*, const char*> content_types{
-      {{".css", "text/css;charset=UTF-8"},
-       {".html", "text/html;charset=UTF-8"},
-       {".js", "text/html;charset=UTF-8"},
-       {".png", "image/png;charset=UTF-8"},
-       {".woff", "application/x-font-woff"},
-       {".woff2", "application/x-font-woff2"},
-       {".ttf", "application/x-font-ttf"},
-       {".svg", "image/svg+xml"},
-       {".eot", "application/vnd.ms-fontobject"},
-       // dev tools don't care about map type, setting to json causes
-       // browser to show as text
-       // https://stackoverflow.com/questions/19911929/what-mime-type-should-i-use-for-javascript-source-map-files
-       {".map", "application/json"}}};
+  const static boost::container::flat_map<const char*, const char*, cmp_str>
+      content_types{
+          {{".css", "text/css;charset=UTF-8"},
+           {".html", "text/html;charset=UTF-8"},
+           {".js", "text/html;charset=UTF-8"},
+           {".png", "image/png;charset=UTF-8"},
+           {".woff", "application/x-font-woff"},
+           {".woff2", "application/x-font-woff2"},
+           {".ttf", "application/x-font-ttf"},
+           {".svg", "image/svg+xml"},
+           {".eot", "application/vnd.ms-fontobject"},
+           {".xml", "application/xml"},
+           // dev tools don't care about map type, setting to json causes
+           // browser to show as text
+           // https://stackoverflow.com/questions/19911929/what-mime-type-should-i-use-for-javascript-source-map-files
+           {".map", "application/json"}}};
   auto rootpath = filesystem::path("/usr/share/www/");
   auto dir_iter = filesystem::recursive_directory_iterator(rootpath);
   for (auto& dir : dir_iter) {
     auto absolute_path = dir.path();
+    auto absolute_path_str = dir.path().string();
     auto relative_path = filesystem::path(
         absolute_path.string().substr(rootpath.string().size() - 1));
     // make sure we don't recurse into certain directories
@@ -63,39 +66,42 @@
 
       if (webpath.filename() == "index.html") {
         webpath = webpath.parent_path();
+        if (webpath.string() != "/") {
+          webpath += "/";
+        }
       }
 
       routes.insert(webpath.string());
 
       std::string absolute_path_str = absolute_path.string();
       const char* content_type = nullptr;
-      auto content_type_it =
-          content_types.find(relative_path.extension().c_str());
+      auto content_type_it = content_types.find(webpath.extension().c_str());
       if (content_type_it != content_types.end()) {
         content_type = content_type_it->second;
       }
       app.route_dynamic(std::string(webpath.string()))(
           [is_gzip, absolute_path_str, content_type](const crow::request& req,
                                                      crow::response& res) {
-            if (is_gzip) {
-              res.add_header(content_encoding_string, gzip_string);
-            } else {
-              res.add_header(content_encoding_string, none_string);
-            }
+            static const char* content_type_string = "Content-Type";
             // std::string sha1("a576dc96a5c605b28afb032f3103630d61ac1068");
-            // res.add_header(etag_string, sha1);
+            // res.add_header("ETag", sha1);
 
-            // if (req.get_header_value(if_none_match_string) == sha1) {
+            // if (req.get_header_value("If-None-Match") == sha1) {
             //  res.code = 304;
             //} else {
             //  res.code = 200;
             // TODO, if you have a browser from the dark ages that doesn't
             // support
             // gzip, unzip it before sending based on Accept-Encoding header
-            //  res.add_header(content_encoding_string, gzip_string);
+            //  res.add_header("Content-Encoding", gzip_string);
             if (content_type != nullptr) {
               res.add_header(content_type_string, content_type);
             }
+
+            if (is_gzip) {
+              res.add_header("Content-Encoding", "gzip");
+            }
+
             // res.set_header("Cache-Control", "public, max-age=86400");
             std::ifstream inf(absolute_path_str);
             if (!inf) {
diff --git a/src/token_authorization_middleware_test.cpp b/src/token_authorization_middleware_test.cpp
index 004fddb..5857d2e 100644
--- a/src/token_authorization_middleware_test.cpp
+++ b/src/token_authorization_middleware_test.cpp
@@ -8,7 +8,8 @@
 
 // Tests that static urls are correctly passed
 TEST(TokenAuthentication, TestBasicReject) {
-  App<crow::TokenAuthorization::Middleware> app;
+  App<crow::PersistentData::Middleware, crow::TokenAuthorization::Middleware>
+      app;
   decltype(app)::server_t server(&app, "127.0.0.1", 45451);
   CROW_ROUTE(app, "/")([]() { return 200; });
   auto _ = async(launch::async, [&] { server.run(); });
@@ -46,7 +47,8 @@
 
 // Tests that Base64 basic strings work
 TEST(TokenAuthentication, TestRejectedResource) {
-  App<crow::TokenAuthorization::Middleware> app;
+  App<crow::PersistentData::Middleware, crow::TokenAuthorization::Middleware>
+      app;
   app.bindaddr("127.0.0.1").port(45451);
   CROW_ROUTE(app, "/")([]() { return 200; });
   auto _ = async(launch::async, [&] { app.run(); });
@@ -75,7 +77,8 @@
 
 // Tests that Base64 basic strings work
 TEST(TokenAuthentication, TestGetLoginUrl) {
-  App<crow::TokenAuthorization::Middleware> app;
+  App<crow::PersistentData::Middleware, crow::TokenAuthorization::Middleware>
+      app;
   app.bindaddr("127.0.0.1").port(45451);
   CROW_ROUTE(app, "/")([]() { return 200; });
   auto _ = async(launch::async, [&] { app.run(); });
@@ -104,7 +107,8 @@
 
 // Tests boundary conditions on login
 TEST(TokenAuthentication, TestPostBadLoginUrl) {
-  App<crow::TokenAuthorization::Middleware> app;
+  App<crow::PersistentData::Middleware, crow::TokenAuthorization::Middleware>
+      app;
   app.bindaddr("127.0.0.1").port(45451);
   CROW_ROUTE(app, "/")([]() { return 200; });
   auto _ = async(launch::async, [&] { app.run(); });
@@ -187,7 +191,8 @@
 };
 
 TEST(TokenAuthentication, TestSuccessfulLogin) {
-  App<crow::TokenAuthorization::Middleware> app;
+  App<crow::PersistentData::Middleware, crow::TokenAuthorization::Middleware>
+      app;
   app.bindaddr("127.0.0.1").port(45451);
   CROW_ROUTE(app, "/")([]() { return 200; });
   auto _ = async(launch::async, [&] { app.run(); });
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 7ae22b5..9640ac3 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -3,6 +3,7 @@
 #include <dbus_singleton.hpp>
 #include <intel_oem.hpp>
 #include <openbmc_dbus_rest.hpp>
+#include <persistent_data_middleware.hpp>
 #include <redfish_v1.hpp>
 #include <security_headers_middleware.hpp>
 #include <ssl_key_handler.hpp>
@@ -16,7 +17,8 @@
 
 int main(int argc, char** argv) {
   auto io = std::make_shared<boost::asio::io_service>();
-  crow::App<crow::TokenAuthorization::Middleware,
+  crow::App<crow::PersistentData::Middleware,
+            crow::TokenAuthorization::Middleware,
             crow::SecurityHeadersMiddleware>
       app(io);
 
