From a79d634ccbbbccfacf5ada18d5fe2a1ce6ab338a Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Mon, 22 Aug 2016 21:40:07 +0200
Subject: [PATCH] integrated proposals for #290

---
 .../parse__array__parser_callback_t.cpp       |  28 --
 .../parse__array__parser_callback_t.link      |   1 -
 .../parse__array__parser_callback_t.output    |  20 --
 src/json.hpp                                  | 291 ++++++------------
 src/json.hpp.re2c                             | 291 ++++++------------
 5 files changed, 200 insertions(+), 431 deletions(-)
 delete mode 100644 doc/examples/parse__array__parser_callback_t.cpp
 delete mode 100644 doc/examples/parse__array__parser_callback_t.link
 delete mode 100644 doc/examples/parse__array__parser_callback_t.output

diff --git a/doc/examples/parse__array__parser_callback_t.cpp b/doc/examples/parse__array__parser_callback_t.cpp
deleted file mode 100644
index 8e086d20..00000000
--- a/doc/examples/parse__array__parser_callback_t.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <json.hpp>
-
-using json = nlohmann::json;
-
-int main()
-{
-    // a JSON text
-    char text[] = R"(
-    {
-        "Image": {
-            "Width":  800,
-            "Height": 600,
-            "Title":  "View from 15th Floor",
-            "Thumbnail": {
-                "Url":    "http://www.example.com/image/481989943",
-                "Height": 125,
-                "Width":  100
-            },
-            "Animated" : false,
-            "IDs": [116, 943, 234, 38793]
-        }
-    }
-    )";
-
-    // parse and serialize JSON
-    json j_complete = json::parse(text);
-    std::cout << std::setw(4) << j_complete << "\n\n";
-}
diff --git a/doc/examples/parse__array__parser_callback_t.link b/doc/examples/parse__array__parser_callback_t.link
deleted file mode 100644
index a1d3cd34..00000000
--- a/doc/examples/parse__array__parser_callback_t.link
+++ /dev/null
@@ -1 +0,0 @@
-<a target="_blank" href="http://melpon.org/wandbox/permlink/LvZQq5fybVH1nh9L"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/parse__array__parser_callback_t.output b/doc/examples/parse__array__parser_callback_t.output
deleted file mode 100644
index 62bb8586..00000000
--- a/doc/examples/parse__array__parser_callback_t.output
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "Image": {
-        "Animated": false,
-        "Height": 600,
-        "IDs": [
-            116,
-            943,
-            234,
-            38793
-        ],
-        "Thumbnail": {
-            "Height": 125,
-            "Url": "http://www.example.com/image/481989943",
-            "Width": 100
-        },
-        "Title": "View from 15th Floor",
-        "Width": 800
-    }
-}
-
diff --git a/src/json.hpp b/src/json.hpp
index 5a35b16d..ac5c78b3 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -1165,11 +1165,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class CompatibleObjectType, typename
-              std::enable_if<
-                  std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
-                  std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value, int>::type
-              = 0>
+    template<class CompatibleObjectType, typename std::enable_if<
+                 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
+                 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value, int>::type = 0>
     basic_json(const CompatibleObjectType& val)
         : m_type(value_t::object)
     {
@@ -1230,16 +1228,14 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class CompatibleArrayType, typename
-              std::enable_if<
-                  not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
-                  std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value, int>::type
-              = 0>
+    template<class CompatibleArrayType, typename std::enable_if<
+                 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
+                 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value, int>::type = 0>
     basic_json(const CompatibleArrayType& val)
         : m_type(value_t::array)
     {
@@ -1325,10 +1321,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class CompatibleStringType, typename
-              std::enable_if<
-                  std::is_constructible<string_t, CompatibleStringType>::value, int>::type
-              = 0>
+    template<class CompatibleStringType, typename std::enable_if<
+                 std::is_constructible<string_t, CompatibleStringType>::value, int>::type = 0>
     basic_json(const CompatibleStringType& val)
         : basic_json(string_t(val))
     {
@@ -1378,12 +1372,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename T,
-             typename std::enable_if<
-                 not (std::is_same<T, int>::value)
-                 and std::is_same<T, number_integer_t>::value
-                 , int>::type
-             = 0>
+    template<typename T, typename std::enable_if<
+                 not (std::is_same<T, int>::value) and
+                 std::is_same<T, number_integer_t>::value, int>::type = 0>
     basic_json(const number_integer_t val) noexcept
         : m_type(value_t::number_integer), m_value(val)
     {
@@ -1447,13 +1438,11 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename CompatibleNumberIntegerType, typename
-             std::enable_if<
+    template<typename CompatibleNumberIntegerType, typename std::enable_if<
                  std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
                  std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
                  std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
-                 CompatibleNumberIntegerType>::type
-             = 0>
+                 CompatibleNumberIntegerType>::type = 0>
     basic_json(const CompatibleNumberIntegerType val) noexcept
         : m_type(value_t::number_integer),
           m_value(static_cast<number_integer_t>(val))
@@ -1478,12 +1467,9 @@ class basic_json
 
     @since version 2.0.0
     */
-    template<typename T,
-             typename std::enable_if<
-                 not (std::is_same<T, int>::value)
-                 and std::is_same<T, number_unsigned_t>::value
-                 , int>::type
-             = 0>
+    template<typename T, typename std::enable_if<
+                 not (std::is_same<T, int>::value) and
+                 std::is_same<T, number_unsigned_t>::value, int>::type = 0>
     basic_json(const number_unsigned_t val) noexcept
         : m_type(value_t::number_unsigned), m_value(val)
     {
@@ -1510,13 +1496,11 @@ class basic_json
 
     @since version 2.0.0
     */
-    template <typename CompatibleNumberUnsignedType, typename
-              std::enable_if <
-                  std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
-                  std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
-                  not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
-                  CompatibleNumberUnsignedType>::type
-              = 0>
+    template<typename CompatibleNumberUnsignedType, typename std::enable_if <
+                 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
+                 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
+                 not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
+                 CompatibleNumberUnsignedType>::type = 0>
     basic_json(const CompatibleNumberUnsignedType val) noexcept
         : m_type(value_t::number_unsigned),
           m_value(static_cast<number_unsigned_t>(val))
@@ -1592,11 +1576,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename CompatibleNumberFloatType, typename = typename
-             std::enable_if<
+    template<typename CompatibleNumberFloatType, typename = typename std::enable_if<
                  std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
-                 std::is_floating_point<CompatibleNumberFloatType>::value>::type
-             >
+                 std::is_floating_point<CompatibleNumberFloatType>::value>::type>
     basic_json(const CompatibleNumberFloatType val) noexcept
         : basic_json(number_float_t(val))
     {
@@ -1863,12 +1845,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class InputIT, typename
-              std::enable_if<
-                  std::is_same<InputIT, typename basic_json_t::iterator>::value or
-                  std::is_same<InputIT, typename basic_json_t::const_iterator>::value
-                  , int>::type
-              = 0>
+    template<class InputIT, typename std::enable_if<
+                 std::is_same<InputIT, typename basic_json_t::iterator>::value or
+                 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
     basic_json(InputIT first, InputIT last)
     {
         assert(first.m_object != nullptr);
@@ -2616,11 +2595,9 @@ class basic_json
     //////////////////
 
     /// get an object (explicit)
-    template <class T, typename
-              std::enable_if<
-                  std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
-                  std::is_convertible<basic_json_t, typename T::mapped_type>::value
-                  , int>::type = 0>
+    template<class T, typename std::enable_if<
+                 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
+                 std::is_convertible<basic_json_t, typename T::mapped_type>::value, int>::type = 0>
     T get_impl(T*) const
     {
         if (is_object())
@@ -2647,14 +2624,12 @@ class basic_json
     }
 
     /// get an array (explicit)
-    template <class T, typename
-              std::enable_if<
-                  std::is_convertible<basic_json_t, typename T::value_type>::value and
-                  not std::is_same<basic_json_t, typename T::value_type>::value and
-                  not std::is_arithmetic<T>::value and
-                  not std::is_convertible<std::string, T>::value and
-                  not has_mapped_type<T>::value
-                  , int>::type = 0>
+    template<class T, typename std::enable_if<
+                 std::is_convertible<basic_json_t, typename T::value_type>::value and
+                 not std::is_same<basic_json_t, typename T::value_type>::value and
+                 not std::is_arithmetic<T>::value and
+                 not std::is_convertible<std::string, T>::value and
+                 not has_mapped_type<T>::value, int>::type = 0>
     T get_impl(T*) const
     {
         if (is_array())
@@ -2674,11 +2649,9 @@ class basic_json
     }
 
     /// get an array (explicit)
-    template <class T, typename
-              std::enable_if<
-                  std::is_convertible<basic_json_t, T>::value and
-                  not std::is_same<basic_json_t, T>::value
-                  , int>::type = 0>
+    template<class T, typename std::enable_if<
+                 std::is_convertible<basic_json_t, T>::value and
+                 not std::is_same<basic_json_t, T>::value, int>::type = 0>
     std::vector<T> get_impl(std::vector<T>*) const
     {
         if (is_array())
@@ -2699,11 +2672,9 @@ class basic_json
     }
 
     /// get an array (explicit)
-    template <class T, typename
-              std::enable_if<
-                  std::is_same<basic_json, typename T::value_type>::value and
-                  not has_mapped_type<T>::value
-                  , int>::type = 0>
+    template<class T, typename std::enable_if<
+                 std::is_same<basic_json, typename T::value_type>::value and
+                 not has_mapped_type<T>::value, int>::type = 0>
     T get_impl(T*) const
     {
         if (is_array())
@@ -2730,10 +2701,8 @@ class basic_json
     }
 
     /// get a string (explicit)
-    template <typename T, typename
-              std::enable_if<
-                  std::is_convertible<string_t, T>::value
-                  , int>::type = 0>
+    template<typename T, typename std::enable_if<
+                 std::is_convertible<string_t, T>::value, int>::type = 0>
     T get_impl(T*) const
     {
         if (is_string())
@@ -2747,10 +2716,8 @@ class basic_json
     }
 
     /// get a number (explicit)
-    template<typename T, typename
-             std::enable_if<
-                 std::is_arithmetic<T>::value
-                 , int>::type = 0>
+    template<typename T, typename std::enable_if<
+                 std::is_arithmetic<T>::value, int>::type = 0>
     T get_impl(T*) const
     {
         switch (m_type)
@@ -2939,10 +2906,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename ValueType, typename
-             std::enable_if<
-                 not std::is_pointer<ValueType>::value
-                 , int>::type = 0>
+    template<typename ValueType, typename std::enable_if<
+                 not std::is_pointer<ValueType>::value, int>::type = 0>
     ValueType get() const
     {
         return get_impl(static_cast<ValueType*>(nullptr));
@@ -2975,10 +2940,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename PointerType, typename
-             std::enable_if<
-                 std::is_pointer<PointerType>::value
-                 , int>::type = 0>
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
     PointerType get() noexcept
     {
         // delegate the call to get_ptr
@@ -2989,10 +2952,8 @@ class basic_json
     @brief get a pointer value (explicit)
     @copydoc get()
     */
-    template<typename PointerType, typename
-             std::enable_if<
-                 std::is_pointer<PointerType>::value
-                 , int>::type = 0>
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
     constexpr const PointerType get() const noexcept
     {
         // delegate the call to get_ptr
@@ -3025,10 +2986,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename PointerType, typename
-             std::enable_if<
-                 std::is_pointer<PointerType>::value
-                 , int>::type = 0>
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
     PointerType get_ptr() noexcept
     {
         // get the type of the PointerType (remove pointer and const)
@@ -3054,11 +3013,9 @@ class basic_json
     @brief get a pointer value (implicit)
     @copydoc get_ptr()
     */
-    template<typename PointerType, typename
-             std::enable_if<
-                 std::is_pointer<PointerType>::value
-                 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
-                 , int>::type = 0>
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value and
+                 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
     constexpr const PointerType get_ptr() const noexcept
     {
         // get the type of the PointerType (remove pointer and const)
@@ -3106,10 +3063,8 @@ class basic_json
 
     @since version 1.1.0
     */
-    template<typename ReferenceType, typename
-             std::enable_if<
-                 std::is_reference<ReferenceType>::value
-                 , int>::type = 0>
+    template<typename ReferenceType, typename std::enable_if<
+                 std::is_reference<ReferenceType>::value, int>::type = 0>
     ReferenceType get_ref()
     {
         // delegate call to get_ref_impl
@@ -3120,11 +3075,9 @@ class basic_json
     @brief get a reference value (implicit)
     @copydoc get_ref()
     */
-    template<typename ReferenceType, typename
-             std::enable_if<
-                 std::is_reference<ReferenceType>::value
-                 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
-                 , int>::type = 0>
+    template<typename ReferenceType, typename std::enable_if<
+                 std::is_reference<ReferenceType>::value and
+                 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
     ReferenceType get_ref() const
     {
         // delegate call to get_ref_impl
@@ -3159,10 +3112,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template < typename ValueType, typename
-               std::enable_if <
-                   not std::is_pointer<ValueType>::value
-                   and not std::is_same<ValueType, typename string_t::value_type>::value
+    template < typename ValueType, typename std::enable_if <
+                   not std::is_pointer<ValueType>::value and
+                   not std::is_same<ValueType, typename string_t::value_type>::value
 #ifndef _MSC_VER  // Fix for issue #167 operator<< abiguity under VS2015
                    and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
 #endif
@@ -3752,10 +3704,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class ValueType, typename
-              std::enable_if<
-                  std::is_convertible<basic_json_t, ValueType>::value
-                  , int>::type = 0>
+    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
     {
         // at only works for objects
@@ -3828,10 +3778,8 @@ class basic_json
 
     @since version 2.0.2
     */
-    template <class ValueType, typename
-              std::enable_if<
-                  std::is_convertible<basic_json_t, ValueType>::value
-                  , int>::type = 0>
+    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
     {
         // at only works for objects
@@ -3992,12 +3940,10 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class IteratorType, typename
-              std::enable_if<
-                  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
-                  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value
-                  , int>::type
-              = 0>
+    template<class IteratorType, typename std::enable_if<
+                 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+                 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+             = 0>
     IteratorType erase(IteratorType pos)
     {
         // make sure iterator fits the current value
@@ -4101,12 +4047,10 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class IteratorType, typename
-              std::enable_if<
-                  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
-                  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value
-                  , int>::type
-              = 0>
+    template<class IteratorType, typename std::enable_if<
+                 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+                 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+             = 0>
     IteratorType erase(IteratorType first, IteratorType last)
     {
         // make sure iterator fits the current value
@@ -5935,6 +5879,7 @@ class basic_json
     /*!
     @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
@@ -5958,45 +5903,12 @@ class basic_json
 
     @since version 1.0.0 (originally for @ref string_t)
     */
-    static basic_json parse(const char* s,
+    template<typename CharT, typename std::enable_if<
+                 std::is_integral<CharT>::value and sizeof(CharT) == 1, int>::type = 0>
+    static basic_json parse(const CharT* s,
                             const parser_callback_t cb = nullptr)
     {
-        return parser(s, cb).parse();
-    }
-
-    /*!
-    @brief deserialize from an array
-
-    This function reads from an array of 1-byte values.
-
-    @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
-    @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 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);
+        return parser(reinterpret_cast<const char*>(s), cb).parse();
     }
 
     /*!
@@ -6059,6 +5971,7 @@ class basic_json
              assertions switched off, the behavior is undefined and will most
              likely yield segmentation violation.
 
+    @tparam IteratorType iterator of container with contiguous storage
     @param[in] first  begin of the range to parse (included)
     @param[in] last  end of the range to parse (excluded)
     @param[in] cb  a parser callback function of type @ref parser_callback_t
@@ -6078,13 +5991,10 @@ class basic_json
 
     @since version 2.0.3
     */
-    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>
+    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 basic_json parse(IteratorType first, IteratorType last,
                             const parser_callback_t cb = nullptr)
     {
@@ -6132,6 +6042,7 @@ class basic_json
              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
@@ -6150,11 +6061,10 @@ class basic_json
 
     @since version 2.0.3
     */
-    template<class ContiguousContainer, typename
-             std::enable_if<
+    template<class ContiguousContainer, typename std::enable_if<
                  std::is_base_of<
                      std::random_access_iterator_tag,
-                     typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer>()))>::iterator_category>::value
+                     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)
@@ -9048,11 +8958,10 @@ basic_json_parser_63:
         {}
 
         /// 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>
+        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)),
@@ -10569,7 +10478,7 @@ namespace std
 
 @since version 1.0.0
 */
-template <>
+template<>
 inline void swap(nlohmann::json& j1,
                  nlohmann::json& j2) noexcept(
                      is_nothrow_move_constructible<nlohmann::json>::value and
@@ -10580,7 +10489,7 @@ inline void swap(nlohmann::json& j1,
 }
 
 /// hash value for JSON objects
-template <>
+template<>
 struct hash<nlohmann::json>
 {
     /*!
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index a5b8a14f..dffb11af 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -1165,11 +1165,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class CompatibleObjectType, typename
-              std::enable_if<
-                  std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
-                  std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value, int>::type
-              = 0>
+    template<class CompatibleObjectType, typename std::enable_if<
+                 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
+                 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value, int>::type = 0>
     basic_json(const CompatibleObjectType& val)
         : m_type(value_t::object)
     {
@@ -1230,16 +1228,14 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class CompatibleArrayType, typename
-              std::enable_if<
-                  not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
-                  not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
-                  std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value, int>::type
-              = 0>
+    template<class CompatibleArrayType, typename std::enable_if<
+                 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
+                 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
+                 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value, int>::type = 0>
     basic_json(const CompatibleArrayType& val)
         : m_type(value_t::array)
     {
@@ -1325,10 +1321,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class CompatibleStringType, typename
-              std::enable_if<
-                  std::is_constructible<string_t, CompatibleStringType>::value, int>::type
-              = 0>
+    template<class CompatibleStringType, typename std::enable_if<
+                 std::is_constructible<string_t, CompatibleStringType>::value, int>::type = 0>
     basic_json(const CompatibleStringType& val)
         : basic_json(string_t(val))
     {
@@ -1378,12 +1372,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename T,
-             typename std::enable_if<
-                 not (std::is_same<T, int>::value)
-                 and std::is_same<T, number_integer_t>::value
-                 , int>::type
-             = 0>
+    template<typename T, typename std::enable_if<
+                 not (std::is_same<T, int>::value) and
+                 std::is_same<T, number_integer_t>::value, int>::type = 0>
     basic_json(const number_integer_t val) noexcept
         : m_type(value_t::number_integer), m_value(val)
     {
@@ -1447,13 +1438,11 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename CompatibleNumberIntegerType, typename
-             std::enable_if<
+    template<typename CompatibleNumberIntegerType, typename std::enable_if<
                  std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
                  std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
                  std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
-                 CompatibleNumberIntegerType>::type
-             = 0>
+                 CompatibleNumberIntegerType>::type = 0>
     basic_json(const CompatibleNumberIntegerType val) noexcept
         : m_type(value_t::number_integer),
           m_value(static_cast<number_integer_t>(val))
@@ -1478,12 +1467,9 @@ class basic_json
 
     @since version 2.0.0
     */
-    template<typename T,
-             typename std::enable_if<
-                 not (std::is_same<T, int>::value)
-                 and std::is_same<T, number_unsigned_t>::value
-                 , int>::type
-             = 0>
+    template<typename T, typename std::enable_if<
+                 not (std::is_same<T, int>::value) and
+                 std::is_same<T, number_unsigned_t>::value, int>::type = 0>
     basic_json(const number_unsigned_t val) noexcept
         : m_type(value_t::number_unsigned), m_value(val)
     {
@@ -1510,13 +1496,11 @@ class basic_json
 
     @since version 2.0.0
     */
-    template <typename CompatibleNumberUnsignedType, typename
-              std::enable_if <
-                  std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
-                  std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
-                  not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
-                  CompatibleNumberUnsignedType>::type
-              = 0>
+    template<typename CompatibleNumberUnsignedType, typename std::enable_if <
+                 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
+                 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
+                 not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
+                 CompatibleNumberUnsignedType>::type = 0>
     basic_json(const CompatibleNumberUnsignedType val) noexcept
         : m_type(value_t::number_unsigned),
           m_value(static_cast<number_unsigned_t>(val))
@@ -1592,11 +1576,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename CompatibleNumberFloatType, typename = typename
-             std::enable_if<
+    template<typename CompatibleNumberFloatType, typename = typename std::enable_if<
                  std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
-                 std::is_floating_point<CompatibleNumberFloatType>::value>::type
-             >
+                 std::is_floating_point<CompatibleNumberFloatType>::value>::type>
     basic_json(const CompatibleNumberFloatType val) noexcept
         : basic_json(number_float_t(val))
     {
@@ -1863,12 +1845,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class InputIT, typename
-              std::enable_if<
-                  std::is_same<InputIT, typename basic_json_t::iterator>::value or
-                  std::is_same<InputIT, typename basic_json_t::const_iterator>::value
-                  , int>::type
-              = 0>
+    template<class InputIT, typename std::enable_if<
+                 std::is_same<InputIT, typename basic_json_t::iterator>::value or
+                 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
     basic_json(InputIT first, InputIT last)
     {
         assert(first.m_object != nullptr);
@@ -2616,11 +2595,9 @@ class basic_json
     //////////////////
 
     /// get an object (explicit)
-    template <class T, typename
-              std::enable_if<
-                  std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
-                  std::is_convertible<basic_json_t, typename T::mapped_type>::value
-                  , int>::type = 0>
+    template<class T, typename std::enable_if<
+                 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
+                 std::is_convertible<basic_json_t, typename T::mapped_type>::value, int>::type = 0>
     T get_impl(T*) const
     {
         if (is_object())
@@ -2647,14 +2624,12 @@ class basic_json
     }
 
     /// get an array (explicit)
-    template <class T, typename
-              std::enable_if<
-                  std::is_convertible<basic_json_t, typename T::value_type>::value and
-                  not std::is_same<basic_json_t, typename T::value_type>::value and
-                  not std::is_arithmetic<T>::value and
-                  not std::is_convertible<std::string, T>::value and
-                  not has_mapped_type<T>::value
-                  , int>::type = 0>
+    template<class T, typename std::enable_if<
+                 std::is_convertible<basic_json_t, typename T::value_type>::value and
+                 not std::is_same<basic_json_t, typename T::value_type>::value and
+                 not std::is_arithmetic<T>::value and
+                 not std::is_convertible<std::string, T>::value and
+                 not has_mapped_type<T>::value, int>::type = 0>
     T get_impl(T*) const
     {
         if (is_array())
@@ -2674,11 +2649,9 @@ class basic_json
     }
 
     /// get an array (explicit)
-    template <class T, typename
-              std::enable_if<
-                  std::is_convertible<basic_json_t, T>::value and
-                  not std::is_same<basic_json_t, T>::value
-                  , int>::type = 0>
+    template<class T, typename std::enable_if<
+                 std::is_convertible<basic_json_t, T>::value and
+                 not std::is_same<basic_json_t, T>::value, int>::type = 0>
     std::vector<T> get_impl(std::vector<T>*) const
     {
         if (is_array())
@@ -2699,11 +2672,9 @@ class basic_json
     }
 
     /// get an array (explicit)
-    template <class T, typename
-              std::enable_if<
-                  std::is_same<basic_json, typename T::value_type>::value and
-                  not has_mapped_type<T>::value
-                  , int>::type = 0>
+    template<class T, typename std::enable_if<
+                 std::is_same<basic_json, typename T::value_type>::value and
+                 not has_mapped_type<T>::value, int>::type = 0>
     T get_impl(T*) const
     {
         if (is_array())
@@ -2730,10 +2701,8 @@ class basic_json
     }
 
     /// get a string (explicit)
-    template <typename T, typename
-              std::enable_if<
-                  std::is_convertible<string_t, T>::value
-                  , int>::type = 0>
+    template<typename T, typename std::enable_if<
+                 std::is_convertible<string_t, T>::value, int>::type = 0>
     T get_impl(T*) const
     {
         if (is_string())
@@ -2747,10 +2716,8 @@ class basic_json
     }
 
     /// get a number (explicit)
-    template<typename T, typename
-             std::enable_if<
-                 std::is_arithmetic<T>::value
-                 , int>::type = 0>
+    template<typename T, typename std::enable_if<
+                 std::is_arithmetic<T>::value, int>::type = 0>
     T get_impl(T*) const
     {
         switch (m_type)
@@ -2939,10 +2906,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename ValueType, typename
-             std::enable_if<
-                 not std::is_pointer<ValueType>::value
-                 , int>::type = 0>
+    template<typename ValueType, typename std::enable_if<
+                 not std::is_pointer<ValueType>::value, int>::type = 0>
     ValueType get() const
     {
         return get_impl(static_cast<ValueType*>(nullptr));
@@ -2975,10 +2940,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename PointerType, typename
-             std::enable_if<
-                 std::is_pointer<PointerType>::value
-                 , int>::type = 0>
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
     PointerType get() noexcept
     {
         // delegate the call to get_ptr
@@ -2989,10 +2952,8 @@ class basic_json
     @brief get a pointer value (explicit)
     @copydoc get()
     */
-    template<typename PointerType, typename
-             std::enable_if<
-                 std::is_pointer<PointerType>::value
-                 , int>::type = 0>
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
     constexpr const PointerType get() const noexcept
     {
         // delegate the call to get_ptr
@@ -3025,10 +2986,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template<typename PointerType, typename
-             std::enable_if<
-                 std::is_pointer<PointerType>::value
-                 , int>::type = 0>
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
     PointerType get_ptr() noexcept
     {
         // get the type of the PointerType (remove pointer and const)
@@ -3054,11 +3013,9 @@ class basic_json
     @brief get a pointer value (implicit)
     @copydoc get_ptr()
     */
-    template<typename PointerType, typename
-             std::enable_if<
-                 std::is_pointer<PointerType>::value
-                 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
-                 , int>::type = 0>
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value and
+                 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
     constexpr const PointerType get_ptr() const noexcept
     {
         // get the type of the PointerType (remove pointer and const)
@@ -3106,10 +3063,8 @@ class basic_json
 
     @since version 1.1.0
     */
-    template<typename ReferenceType, typename
-             std::enable_if<
-                 std::is_reference<ReferenceType>::value
-                 , int>::type = 0>
+    template<typename ReferenceType, typename std::enable_if<
+                 std::is_reference<ReferenceType>::value, int>::type = 0>
     ReferenceType get_ref()
     {
         // delegate call to get_ref_impl
@@ -3120,11 +3075,9 @@ class basic_json
     @brief get a reference value (implicit)
     @copydoc get_ref()
     */
-    template<typename ReferenceType, typename
-             std::enable_if<
-                 std::is_reference<ReferenceType>::value
-                 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
-                 , int>::type = 0>
+    template<typename ReferenceType, typename std::enable_if<
+                 std::is_reference<ReferenceType>::value and
+                 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
     ReferenceType get_ref() const
     {
         // delegate call to get_ref_impl
@@ -3159,10 +3112,9 @@ class basic_json
 
     @since version 1.0.0
     */
-    template < typename ValueType, typename
-               std::enable_if <
-                   not std::is_pointer<ValueType>::value
-                   and not std::is_same<ValueType, typename string_t::value_type>::value
+    template < typename ValueType, typename std::enable_if <
+                   not std::is_pointer<ValueType>::value and
+                   not std::is_same<ValueType, typename string_t::value_type>::value
 #ifndef _MSC_VER  // Fix for issue #167 operator<< abiguity under VS2015
                    and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
 #endif
@@ -3752,10 +3704,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class ValueType, typename
-              std::enable_if<
-                  std::is_convertible<basic_json_t, ValueType>::value
-                  , int>::type = 0>
+    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
     {
         // at only works for objects
@@ -3828,10 +3778,8 @@ class basic_json
 
     @since version 2.0.2
     */
-    template <class ValueType, typename
-              std::enable_if<
-                  std::is_convertible<basic_json_t, ValueType>::value
-                  , int>::type = 0>
+    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
     {
         // at only works for objects
@@ -3992,12 +3940,10 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class IteratorType, typename
-              std::enable_if<
-                  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
-                  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value
-                  , int>::type
-              = 0>
+    template<class IteratorType, typename std::enable_if<
+                 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+                 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+             = 0>
     IteratorType erase(IteratorType pos)
     {
         // make sure iterator fits the current value
@@ -4101,12 +4047,10 @@ class basic_json
 
     @since version 1.0.0
     */
-    template <class IteratorType, typename
-              std::enable_if<
-                  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
-                  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value
-                  , int>::type
-              = 0>
+    template<class IteratorType, typename std::enable_if<
+                 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+                 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+             = 0>
     IteratorType erase(IteratorType first, IteratorType last)
     {
         // make sure iterator fits the current value
@@ -5935,6 +5879,7 @@ class basic_json
     /*!
     @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
@@ -5958,45 +5903,12 @@ class basic_json
 
     @since version 1.0.0 (originally for @ref string_t)
     */
-    static basic_json parse(const char* s,
+    template<typename CharT, typename std::enable_if<
+                 std::is_integral<CharT>::value and sizeof(CharT) == 1, int>::type = 0>
+    static basic_json parse(const CharT* s,
                             const parser_callback_t cb = nullptr)
     {
-        return parser(s, cb).parse();
-    }
-
-    /*!
-    @brief deserialize from an array
-
-    This function reads from an array of 1-byte values.
-
-    @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
-    @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 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);
+        return parser(reinterpret_cast<const char*>(s), cb).parse();
     }
 
     /*!
@@ -6059,6 +5971,7 @@ class basic_json
              assertions switched off, the behavior is undefined and will most
              likely yield segmentation violation.
 
+    @tparam IteratorType iterator of container with contiguous storage
     @param[in] first  begin of the range to parse (included)
     @param[in] last  end of the range to parse (excluded)
     @param[in] cb  a parser callback function of type @ref parser_callback_t
@@ -6078,13 +5991,10 @@ class basic_json
 
     @since version 2.0.3
     */
-    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>
+    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 basic_json parse(IteratorType first, IteratorType last,
                             const parser_callback_t cb = nullptr)
     {
@@ -6132,6 +6042,7 @@ class basic_json
              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
@@ -6150,11 +6061,10 @@ class basic_json
 
     @since version 2.0.3
     */
-    template<class ContiguousContainer, typename
-             std::enable_if<
+    template<class ContiguousContainer, typename std::enable_if<
                  std::is_base_of<
                      std::random_access_iterator_tag,
-                     typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer>()))>::iterator_category>::value
+                     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)
@@ -8345,11 +8255,10 @@ class basic_json
         {}
 
         /// 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>
+        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)),
@@ -9866,7 +9775,7 @@ namespace std
 
 @since version 1.0.0
 */
-template <>
+template<>
 inline void swap(nlohmann::json& j1,
                  nlohmann::json& j2) noexcept(
                      is_nothrow_move_constructible<nlohmann::json>::value and
@@ -9877,7 +9786,7 @@ inline void swap(nlohmann::json& j1,
 }
 
 /// hash value for JSON objects
-template <>
+template<>
 struct hash<nlohmann::json>
 {
     /*!