From c7a69ae03e17196c8d605bdd92e0fc1e58d54c21 Mon Sep 17 00:00:00 2001
From: Niels Lohmann <mail@nlohmann.me>
Date: Sat, 22 Jul 2017 15:18:38 +0200
Subject: [PATCH] :zap: started working on parser with provded result reference
 #418

Internally, the parser now writes its result into a JSON value provided as a reference. To be usable, the public interfaces need to be extended.
---
 src/json.hpp                   | 100 ++--
 test/src/unit-class_parser.cpp | 921 +++++++++++++++++----------------
 2 files changed, 527 insertions(+), 494 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index b57525a5..33f08761 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -3107,19 +3107,19 @@ class parser
     /*!
     @brief public parser interface
 
-    @param[in] strict  whether to expect the last token to be EOF
-    @return parsed JSON value
+    @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
     */
-    BasicJsonType parse(const bool strict = true)
+    void parse(const bool strict, BasicJsonType& result)
     {
         // read first token
         get_token();
 
-        BasicJsonType result = parse_internal(true);
+        parse_internal(true, result);
         result.assert_invariant();
 
         if (strict)
@@ -3128,9 +3128,12 @@ class parser
             expect(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() ? BasicJsonType() : std::move(result);
+        // set top-level value to null if it was discarded by the callback
+        // function
+        if (result.is_discarded())
+        {
+            result = nullptr;
+        }
     }
 
     /*!
@@ -3164,17 +3167,19 @@ class parser
     @throw parse_error.102 if to_unicode fails or surrogate error
     @throw parse_error.103 if to_unicode fails
     */
-    BasicJsonType parse_internal(bool keep)
+    void parse_internal(bool keep, BasicJsonType& result)
     {
-        auto result = BasicJsonType(value_t::discarded);
+        // start with a discarded value
+        if (not result.is_discarded())
+        {
+            result.m_type = value_t::discarded;
+        }
 
         switch (last_token)
         {
             case token_type::begin_object:
             {
-                if (keep and (not callback or
-                              ((keep = callback(depth++, parse_event_t::object_start,
-                                                result)) != 0)))
+                if (keep and (not callback or ((keep = callback(depth++, parse_event_t::object_start, result)))))
                 {
                     // explicitly set result to object to cope with {}
                     result.m_type = value_t::object;
@@ -3187,15 +3192,15 @@ class parser
                 // 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))
+                    if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
                     {
-                        result = BasicJsonType(value_t::discarded);
+                        result.m_type = value_t::discarded;
                     }
-                    return result;
+                    break;
                 }
 
                 // parse values
+                BasicJsonType value;
                 while (true)
                 {
                     // store key
@@ -3222,7 +3227,8 @@ class parser
 
                     // parse and add value
                     get_token();
-                    auto value = parse_internal(keep);
+                    value = value_t::discarded;
+                    parse_internal(keep, value);
                     if (keep and keep_tag and not value.is_discarded())
                     {
                         result[key] = std::move(value);
@@ -3241,20 +3247,16 @@ class parser
                     break;
                 }
 
-                if (keep and callback and
-                        not callback(--depth, parse_event_t::object_end, result))
+                if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
                 {
-                    result = BasicJsonType(value_t::discarded);
+                    result.m_type = value_t::discarded;
                 }
-
-                return result;
+                break;
             }
 
             case token_type::begin_array:
             {
-                if (keep and (not callback or
-                              ((keep = callback(depth++, parse_event_t::array_start,
-                                                result)) != 0)))
+                if (keep and (not callback or ((keep = callback(depth++, parse_event_t::array_start, result)))))
                 {
                     // explicitly set result to object to cope with []
                     result.m_type = value_t::array;
@@ -3267,19 +3269,19 @@ class parser
                 // closing ] -> we are done
                 if (last_token == token_type::end_array)
                 {
-                    if (callback and
-                            not callback(--depth, parse_event_t::array_end, result))
+                    if (callback and not callback(--depth, parse_event_t::array_end, result))
                     {
-                        result = BasicJsonType(value_t::discarded);
+                        result.m_type = value_t::discarded;
                     }
-                    return result;
+                    break;
                 }
 
                 // parse values
+                BasicJsonType value;
                 while (true)
                 {
                     // parse value
-                    auto value = parse_internal(keep);
+                    parse_internal(keep, value);
                     if (keep and not value.is_discarded())
                     {
                         result.push_back(std::move(value));
@@ -3298,13 +3300,11 @@ class parser
                     break;
                 }
 
-                if (keep and callback and
-                        not callback(--depth, parse_event_t::array_end, result))
+                if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
                 {
-                    result = BasicJsonType(value_t::discarded);
+                    result.m_type = value_t::discarded;
                 }
-
-                return result;
+                break;
             }
 
             case token_type::literal_null:
@@ -3315,7 +3315,8 @@ class parser
 
             case token_type::value_string:
             {
-                result = BasicJsonType(m_lexer.get_string());
+                result.m_type = value_t::string;
+                result.m_value = m_lexer.get_string();
                 break;
             }
 
@@ -3359,7 +3360,6 @@ class parser
                                                     m_lexer.get_token_string() +
                                                     "'"));
                 }
-
                 break;
             }
 
@@ -3378,12 +3378,10 @@ class parser
             }
         }
 
-        if (keep and callback and
-                not callback(depth, parse_event_t::value, result))
+        if (keep and callback and not callback(depth, parse_event_t::value, result))
         {
-            result = BasicJsonType(value_t::discarded);
+            result.m_type = value_t::discarded;
         }
-        return result;
     }
 
     /*!
@@ -12892,7 +12890,9 @@ class basic_json
     static basic_json parse(const CharT s,
                             const parser_callback_t cb = nullptr)
     {
-        return parser(detail::input_adapter_factory::create(s), cb).parse(true);
+        basic_json result;
+        parser(detail::input_adapter_factory::create(s), cb).parse(true, result);
+        return result;
     }
 
     template<typename CharT, typename std::enable_if<
@@ -12935,7 +12935,9 @@ class basic_json
     static basic_json parse(std::istream& i,
                             const parser_callback_t cb = nullptr)
     {
-        return parser(detail::input_adapter_factory::create(i), cb).parse(true);
+        basic_json result;
+        parser(detail::input_adapter_factory::create(i), cb).parse(true, result);
+        return result;
     }
 
     static bool accept(std::istream& i)
@@ -12949,7 +12951,9 @@ class basic_json
     static basic_json parse(std::istream&& i,
                             const parser_callback_t cb = nullptr)
     {
-        return parser(detail::input_adapter_factory::create(i), cb).parse(true);
+        basic_json result;
+        parser(detail::input_adapter_factory::create(i), cb).parse(true, result);
+        return result;
     }
 
     static bool accept(std::istream&& i)
@@ -13009,7 +13013,9 @@ class basic_json
     static basic_json parse(IteratorType first, IteratorType last,
                             const parser_callback_t cb = nullptr)
     {
-        return parser(detail::input_adapter_factory::create(first, last), cb).parse(true);
+        basic_json result;
+        parser(detail::input_adapter_factory::create(first, last), cb).parse(true, result);
+        return result;
     }
 
     template<class IteratorType, typename std::enable_if<
@@ -13100,7 +13106,7 @@ class basic_json
     JSON_DEPRECATED
     friend std::istream& operator<<(basic_json& j, std::istream& i)
     {
-        j = parser(detail::input_adapter_factory::create(i)).parse(false);
+        parser(detail::input_adapter_factory::create(i)).parse(false, j);
         return i;
     }
 
@@ -13131,7 +13137,7 @@ class basic_json
     */
     friend std::istream& operator>>(std::istream& i, basic_json& j)
     {
-        j = parser(detail::input_adapter_factory::create(i)).parse(false);
+        parser(detail::input_adapter_factory::create(i)).parse(false, j);
         return i;
     }
 
diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp
index 59765eda..5175ce83 100644
--- a/test/src/unit-class_parser.cpp
+++ b/test/src/unit-class_parser.cpp
@@ -34,36 +34,51 @@ using nlohmann::json;
 
 #include <valarray>
 
+json parser_helper(const std::string& s);
+bool accept_helper(const std::string& s);
+
+json parser_helper(const std::string& s)
+{
+    json j;
+    json::parser(nlohmann::detail::input_adapter_factory::create(s)).parse(true, j);
+    return j;
+}
+
+bool accept_helper(const std::string& s)
+{
+    return json::parser(nlohmann::detail::input_adapter_factory::create(s)).accept(true);
+}
+
 TEST_CASE("parser class")
 {
     SECTION("parse")
     {
         SECTION("null")
         {
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("null"))).parse() == json(nullptr));
+            CHECK(parser_helper("null") == json(nullptr));
         }
 
         SECTION("true")
         {
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("true"))).parse() == json(true));
+            CHECK(parser_helper("true") == json(true));
         }
 
         SECTION("false")
         {
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("false"))).parse() == json(false));
+            CHECK(parser_helper("false") == json(false));
         }
 
         SECTION("array")
         {
             SECTION("empty array")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[]"))).parse() == json(json::value_t::array));
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[ ]"))).parse() == json(json::value_t::array));
+                CHECK(parser_helper("[]") == json(json::value_t::array));
+                CHECK(parser_helper("[ ]") == json(json::value_t::array));
             }
 
             SECTION("nonempty array")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[true, false, null]"))).parse() == json({true, false, nullptr}));
+                CHECK(parser_helper("[true, false, null]") == json({true, false, nullptr}));
             }
         }
 
@@ -71,113 +86,113 @@ TEST_CASE("parser class")
         {
             SECTION("empty object")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{}"))).parse() == json(json::value_t::object));
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{ }"))).parse() == json(json::value_t::object));
+                CHECK(parser_helper("{}") == json(json::value_t::object));
+                CHECK(parser_helper("{ }") == json(json::value_t::object));
             }
 
             SECTION("nonempty object")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"\": true, \"one\": 1, \"two\": null}"))).parse() == json({{"", true}, {"one", 1}, {"two", nullptr}}));
+                CHECK(parser_helper("{\"\": true, \"one\": 1, \"two\": null}") == json({{"", true}, {"one", 1}, {"two", nullptr}}));
             }
         }
 
         SECTION("string")
         {
             // empty string
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\""))).parse() == json(json::value_t::string));
+            CHECK(parser_helper("\"\"") == json(json::value_t::string));
 
             SECTION("errors")
             {
                 // error: tab in string
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\t\""))).parse(), json::parse_error&);
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\t\""))).parse(),
+                CHECK_THROWS_AS(parser_helper("\"\t\""), json::parse_error&);
+                CHECK_THROWS_WITH(parser_helper("\"\t\""),
                                   "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0009>'");
                 // error: newline in string
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\n\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\r\""))).parse(), json::parse_error&);
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\n\""))).parse(),
+                CHECK_THROWS_AS(parser_helper("\"\n\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\r\""), json::parse_error&);
+                CHECK_THROWS_WITH(parser_helper("\"\n\""),
                                   "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000A>'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\r\""))).parse(),
+                CHECK_THROWS_WITH(parser_helper("\"\r\""),
                                   "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000D>'");
                 // error: backspace in string
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\b\""))).parse(), json::parse_error&);
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\b\""))).parse(),
+                CHECK_THROWS_AS(parser_helper("\"\b\""), json::parse_error&);
+                CHECK_THROWS_WITH(parser_helper("\"\b\""),
                                   "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0008>'");
                 // improve code coverage
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\uFF01"))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[-4:1,]"))).parse(), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\uFF01"), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("[-4:1,]"), json::parse_error&);
                 // unescaped control characters
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x00\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x01\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x02\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x03\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x04\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x05\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x06\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x07\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x08\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x09\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0a\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0b\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0c\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0d\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0e\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0f\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x10\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x11\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x12\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x13\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x14\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x15\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x16\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x17\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x18\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x19\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1a\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1b\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1c\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1d\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1e\""))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1f\""))).parse(), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x00\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x01\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x02\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x03\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x04\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x05\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x06\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x07\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x08\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x09\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x0a\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x0b\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x0c\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x0d\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x0e\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x0f\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x10\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x11\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x12\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x13\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x14\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x15\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x16\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x17\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x18\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x19\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x1a\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x1b\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x1c\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x1d\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x1e\""), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("\"\x1f\""), json::parse_error&);
             }
 
             SECTION("escaped")
             {
                 // quotation mark "\""
                 auto r1 = R"("\"")"_json;
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\\"\""))).parse() == r1);
+                CHECK(parser_helper("\"\\\"\"") == r1);
                 // reverse solidus "\\"
                 auto r2 = R"("\\")"_json;
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\\\\""))).parse() == r2);
+                CHECK(parser_helper("\"\\\\\"") == r2);
                 // solidus
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\/\""))).parse() == R"("/")"_json);
+                CHECK(parser_helper("\"\\/\"") == R"("/")"_json);
                 // backspace
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\b\""))).parse() == json("\b"));
+                CHECK(parser_helper("\"\\b\"") == json("\b"));
                 // formfeed
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\f\""))).parse() == json("\f"));
+                CHECK(parser_helper("\"\\f\"") == json("\f"));
                 // newline
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\n\""))).parse() == json("\n"));
+                CHECK(parser_helper("\"\\n\"") == json("\n"));
                 // carriage return
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\r\""))).parse() == json("\r"));
+                CHECK(parser_helper("\"\\r\"") == json("\r"));
                 // horizontal tab
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\t\""))).parse() == json("\t"));
+                CHECK(parser_helper("\"\\t\"") == json("\t"));
 
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0001\""))).parse().get<json::string_t>() == "\x01");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u000a\""))).parse().get<json::string_t>() == "\n");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u00b0\""))).parse().get<json::string_t>() == "°");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0c00\""))).parse().get<json::string_t>() == "ఀ");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\ud000\""))).parse().get<json::string_t>() == "퀀");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u000E\""))).parse().get<json::string_t>() == "\x0E");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u00F0\""))).parse().get<json::string_t>() == "ð");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0100\""))).parse().get<json::string_t>() == "Ā");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u2000\""))).parse().get<json::string_t>() == " ");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\uFFFF\""))).parse().get<json::string_t>() == "￿");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u20AC\""))).parse().get<json::string_t>() == "€");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"€\""))).parse().get<json::string_t>() == "€");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"🎈\""))).parse().get<json::string_t>() == "🎈");
+                CHECK(parser_helper("\"\\u0001\"").get<json::string_t>() == "\x01");
+                CHECK(parser_helper("\"\\u000a\"").get<json::string_t>() == "\n");
+                CHECK(parser_helper("\"\\u00b0\"").get<json::string_t>() == "°");
+                CHECK(parser_helper("\"\\u0c00\"").get<json::string_t>() == "ఀ");
+                CHECK(parser_helper("\"\\ud000\"").get<json::string_t>() == "퀀");
+                CHECK(parser_helper("\"\\u000E\"").get<json::string_t>() == "\x0E");
+                CHECK(parser_helper("\"\\u00F0\"").get<json::string_t>() == "ð");
+                CHECK(parser_helper("\"\\u0100\"").get<json::string_t>() == "Ā");
+                CHECK(parser_helper("\"\\u2000\"").get<json::string_t>() == " ");
+                CHECK(parser_helper("\"\\uFFFF\"").get<json::string_t>() == "￿");
+                CHECK(parser_helper("\"\\u20AC\"").get<json::string_t>() == "€");
+                CHECK(parser_helper("\"€\"").get<json::string_t>() == "€");
+                CHECK(parser_helper("\"🎈\"").get<json::string_t>() == "🎈");
 
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\ud80c\\udc60\""))).parse().get<json::string_t>() == u8"\U00013060");
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\ud83c\\udf1e\""))).parse().get<json::string_t>() == "🌞");
+                CHECK(parser_helper("\"\\ud80c\\udc60\"").get<json::string_t>() == u8"\U00013060");
+                CHECK(parser_helper("\"\\ud83c\\udf1e\"").get<json::string_t>() == "🌞");
             }
         }
 
@@ -187,40 +202,40 @@ TEST_CASE("parser class")
             {
                 SECTION("without exponent")
                 {
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-128"))).parse() == json(-128));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0"))).parse() == json(-0));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0"))).parse() == json(0));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("128"))).parse() == json(128));
+                    CHECK(parser_helper("-128") == json(-128));
+                    CHECK(parser_helper("-0") == json(-0));
+                    CHECK(parser_helper("0") == json(0));
+                    CHECK(parser_helper("128") == json(128));
                 }
 
                 SECTION("with exponent")
                 {
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0e1"))).parse() == json(0e1));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0E1"))).parse() == json(0e1));
+                    CHECK(parser_helper("0e1") == json(0e1));
+                    CHECK(parser_helper("0E1") == json(0e1));
 
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E-4"))).parse() == json(10000e-4));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E-3"))).parse() == json(10000e-3));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E-2"))).parse() == json(10000e-2));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E-1"))).parse() == json(10000e-1));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E0"))).parse() == json(10000e0));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E1"))).parse() == json(10000e1));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E2"))).parse() == json(10000e2));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E3"))).parse() == json(10000e3));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E4"))).parse() == json(10000e4));
+                    CHECK(parser_helper("10000E-4") == json(10000e-4));
+                    CHECK(parser_helper("10000E-3") == json(10000e-3));
+                    CHECK(parser_helper("10000E-2") == json(10000e-2));
+                    CHECK(parser_helper("10000E-1") == json(10000e-1));
+                    CHECK(parser_helper("10000E0") == json(10000e0));
+                    CHECK(parser_helper("10000E1") == json(10000e1));
+                    CHECK(parser_helper("10000E2") == json(10000e2));
+                    CHECK(parser_helper("10000E3") == json(10000e3));
+                    CHECK(parser_helper("10000E4") == json(10000e4));
 
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e-4"))).parse() == json(10000e-4));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e-3"))).parse() == json(10000e-3));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e-2"))).parse() == json(10000e-2));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e-1"))).parse() == json(10000e-1));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e0"))).parse() == json(10000e0));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e1"))).parse() == json(10000e1));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e2"))).parse() == json(10000e2));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e3"))).parse() == json(10000e3));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e4"))).parse() == json(10000e4));
+                    CHECK(parser_helper("10000e-4") == json(10000e-4));
+                    CHECK(parser_helper("10000e-3") == json(10000e-3));
+                    CHECK(parser_helper("10000e-2") == json(10000e-2));
+                    CHECK(parser_helper("10000e-1") == json(10000e-1));
+                    CHECK(parser_helper("10000e0") == json(10000e0));
+                    CHECK(parser_helper("10000e1") == json(10000e1));
+                    CHECK(parser_helper("10000e2") == json(10000e2));
+                    CHECK(parser_helper("10000e3") == json(10000e3));
+                    CHECK(parser_helper("10000e4") == json(10000e4));
 
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0e1"))).parse() == json(-0e1));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E1"))).parse() == json(-0e1));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E123"))).parse() == json(-0e123));
+                    CHECK(parser_helper("-0e1") == json(-0e1));
+                    CHECK(parser_helper("-0E1") == json(-0e1));
+                    CHECK(parser_helper("-0E123") == json(-0e123));
                 }
 
                 SECTION("edge cases")
@@ -232,9 +247,9 @@ TEST_CASE("parser class")
                     // agree exactly on their numeric values.
 
                     // -(2**53)+1
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-9007199254740991"))).parse().get<int64_t>() == -9007199254740991);
+                    CHECK(parser_helper("-9007199254740991").get<int64_t>() == -9007199254740991);
                     // (2**53)-1
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("9007199254740991"))).parse().get<int64_t>() == 9007199254740991);
+                    CHECK(parser_helper("9007199254740991").get<int64_t>() == 9007199254740991);
                 }
 
                 SECTION("over the edge cases")  // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers)
@@ -247,11 +262,11 @@ TEST_CASE("parser class")
                     // i.e. -(2**63) -> (2**64)-1.
 
                     // -(2**63)    ** Note: compilers see negative literals as negated positive numbers (hence the -1))
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-9223372036854775808"))).parse().get<int64_t>() == -9223372036854775807 - 1);
+                    CHECK(parser_helper("-9223372036854775808").get<int64_t>() == -9223372036854775807 - 1);
                     // (2**63)-1
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("9223372036854775807"))).parse().get<int64_t>() == 9223372036854775807);
+                    CHECK(parser_helper("9223372036854775807").get<int64_t>() == 9223372036854775807);
                     // (2**64)-1
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("18446744073709551615"))).parse().get<uint64_t>() == 18446744073709551615u);
+                    CHECK(parser_helper("18446744073709551615").get<uint64_t>() == 18446744073709551615u);
                 }
             }
 
@@ -259,85 +274,85 @@ TEST_CASE("parser class")
             {
                 SECTION("without exponent")
                 {
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-128.5"))).parse() == json(-128.5));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0.999"))).parse() == json(0.999));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("128.5"))).parse() == json(128.5));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0"))).parse() == json(-0.0));
+                    CHECK(parser_helper("-128.5") == json(-128.5));
+                    CHECK(parser_helper("0.999") == json(0.999));
+                    CHECK(parser_helper("128.5") == json(128.5));
+                    CHECK(parser_helper("-0.0") == json(-0.0));
                 }
 
                 SECTION("with exponent")
                 {
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-128.5E3"))).parse() == json(-128.5E3));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-128.5E-3"))).parse() == json(-128.5E-3));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0e1"))).parse() == json(-0.0e1));
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0E1"))).parse() == json(-0.0e1));
+                    CHECK(parser_helper("-128.5E3") == json(-128.5E3));
+                    CHECK(parser_helper("-128.5E-3") == json(-128.5E-3));
+                    CHECK(parser_helper("-0.0e1") == json(-0.0e1));
+                    CHECK(parser_helper("-0.0E1") == json(-0.0e1));
                 }
             }
 
             SECTION("overflow")
             {
                 // overflows during parsing yield an exception
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1.18973e+4932"))).parse() == json(), json::out_of_range&);
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1.18973e+4932"))).parse() == json(),
+                CHECK_THROWS_AS(parser_helper("1.18973e+4932") == json(), json::out_of_range&);
+                CHECK_THROWS_WITH(parser_helper("1.18973e+4932") == json(),
                                   "[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'");
             }
 
             SECTION("invalid numbers")
             {
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("01"))).parse(),      json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("--1"))).parse(),     json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1."))).parse(),      json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E"))).parse(),      json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E-"))).parse(),     json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1.E1"))).parse(),    json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-1E"))).parse(),     json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E#"))).parse(),    json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E-#"))).parse(),   json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0#"))).parse(),     json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0:"))).parse(),   json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0Z"))).parse(),   json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E123:"))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0e0-:"))).parse(),  json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0e-:"))).parse(),   json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0f"))).parse(),     json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("01"),      json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("--1"),     json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("1."),      json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("1E"),      json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("1E-"),     json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("1.E1"),    json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-1E"),     json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0E#"),    json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0E-#"),   json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0#"),     json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0.0:"),   json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0.0Z"),   json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0E123:"), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0e0-:"),  json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0e-:"),   json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("-0f"),     json::parse_error&);
 
                 // numbers must not begin with "+"
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("+1"))).parse(), json::parse_error&);
-                CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("+0"))).parse(), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("+1"), json::parse_error&);
+                CHECK_THROWS_AS(parser_helper("+0"), json::parse_error&);
 
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("01"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("01"),
                                   "[json.exception.parse_error.101] parse error at 2: syntax error - unexpected number literal; expected end of input");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-01"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-01"),
                                   "[json.exception.parse_error.101] parse error at 3: syntax error - unexpected number literal; expected end of input");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("--1"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("--1"),
                                   "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '--'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1."))).parse(),
+                CHECK_THROWS_WITH(parser_helper("1."),
                                   "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '1.'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("1E"),
                                   "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E-"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("1E-"),
                                   "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after exponent sign; last read: '1E-'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1.E1"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("1.E1"),
                                   "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '1.E'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-1E"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-1E"),
                                   "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '-1E'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E#"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0E#"),
                                   "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '-0E#'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E-#"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0E-#"),
                                   "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0E-#'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0#"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0#"),
                                   "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: '-0#'; expected end of input");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0:"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0.0:"),
                                   "[json.exception.parse_error.101] parse error at 5: syntax error - unexpected ':'; expected end of input");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0Z"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0.0Z"),
                                   "[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; last read: '-0.0Z'; expected end of input");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E123:"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0E123:"),
                                   "[json.exception.parse_error.101] parse error at 7: syntax error - unexpected ':'; expected end of input");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0e0-:"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0e0-:"),
                                   "[json.exception.parse_error.101] parse error at 6: syntax error - invalid number; expected digit after '-'; last read: '-:'; expected end of input");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0e-:"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0e-:"),
                                   "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0e-:'");
-                CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0f"))).parse(),
+                CHECK_THROWS_WITH(parser_helper("-0f"),
                                   "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: '-0f'; expected end of input");
             }
         }
@@ -347,30 +362,30 @@ TEST_CASE("parser class")
     {
         SECTION("null")
         {
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("null"))).accept());
+            CHECK(accept_helper("null"));
         }
 
         SECTION("true")
         {
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("true"))).accept());
+            CHECK(accept_helper("true"));
         }
 
         SECTION("false")
         {
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("false"))).accept());
+            CHECK(accept_helper("false"));
         }
 
         SECTION("array")
         {
             SECTION("empty array")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[]"))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[ ]"))).accept());
+                CHECK(accept_helper("[]"));
+                CHECK(accept_helper("[ ]"));
             }
 
             SECTION("nonempty array")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[true, false, null]"))).accept());
+                CHECK(accept_helper("[true, false, null]"));
             }
         }
 
@@ -378,105 +393,105 @@ TEST_CASE("parser class")
         {
             SECTION("empty object")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{}"))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{ }"))).accept());
+                CHECK(accept_helper("{}"));
+                CHECK(accept_helper("{ }"));
             }
 
             SECTION("nonempty object")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"\": true, \"one\": 1, \"two\": null}"))).accept());
+                CHECK(accept_helper("{\"\": true, \"one\": 1, \"two\": null}"));
             }
         }
 
         SECTION("string")
         {
             // empty string
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\""))).accept());
+            CHECK(accept_helper("\"\""));
 
             SECTION("errors")
             {
                 // error: tab in string
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\t\""))).accept() == false);
+                CHECK(accept_helper("\"\t\"") == false);
                 // error: newline in string
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\n\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\r\""))).accept() == false);
+                CHECK(accept_helper("\"\n\"") == false);
+                CHECK(accept_helper("\"\r\"") == false);
                 // error: backspace in string
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\b\""))).accept() == false);
+                CHECK(accept_helper("\"\b\"") == false);
                 // improve code coverage
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\uFF01"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[-4:1,]"))).accept() == false);
+                CHECK(accept_helper("\uFF01") == false);
+                CHECK(accept_helper("[-4:1,]") == false);
                 // unescaped control characters
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x00\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x01\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x02\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x03\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x04\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x05\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x06\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x07\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x08\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x09\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0a\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0b\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0c\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0d\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0e\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x0f\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x10\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x11\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x12\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x13\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x14\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x15\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x16\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x17\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x18\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x19\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1a\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1b\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1c\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1d\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1e\""))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\x1f\""))).accept() == false);
+                CHECK(accept_helper("\"\x00\"") == false);
+                CHECK(accept_helper("\"\x01\"") == false);
+                CHECK(accept_helper("\"\x02\"") == false);
+                CHECK(accept_helper("\"\x03\"") == false);
+                CHECK(accept_helper("\"\x04\"") == false);
+                CHECK(accept_helper("\"\x05\"") == false);
+                CHECK(accept_helper("\"\x06\"") == false);
+                CHECK(accept_helper("\"\x07\"") == false);
+                CHECK(accept_helper("\"\x08\"") == false);
+                CHECK(accept_helper("\"\x09\"") == false);
+                CHECK(accept_helper("\"\x0a\"") == false);
+                CHECK(accept_helper("\"\x0b\"") == false);
+                CHECK(accept_helper("\"\x0c\"") == false);
+                CHECK(accept_helper("\"\x0d\"") == false);
+                CHECK(accept_helper("\"\x0e\"") == false);
+                CHECK(accept_helper("\"\x0f\"") == false);
+                CHECK(accept_helper("\"\x10\"") == false);
+                CHECK(accept_helper("\"\x11\"") == false);
+                CHECK(accept_helper("\"\x12\"") == false);
+                CHECK(accept_helper("\"\x13\"") == false);
+                CHECK(accept_helper("\"\x14\"") == false);
+                CHECK(accept_helper("\"\x15\"") == false);
+                CHECK(accept_helper("\"\x16\"") == false);
+                CHECK(accept_helper("\"\x17\"") == false);
+                CHECK(accept_helper("\"\x18\"") == false);
+                CHECK(accept_helper("\"\x19\"") == false);
+                CHECK(accept_helper("\"\x1a\"") == false);
+                CHECK(accept_helper("\"\x1b\"") == false);
+                CHECK(accept_helper("\"\x1c\"") == false);
+                CHECK(accept_helper("\"\x1d\"") == false);
+                CHECK(accept_helper("\"\x1e\"") == false);
+                CHECK(accept_helper("\"\x1f\"") == false);
             }
 
             SECTION("escaped")
             {
                 // quotation mark "\""
                 auto r1 = R"("\"")"_json;
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\\"\""))).accept());
+                CHECK(accept_helper("\"\\\"\""));
                 // reverse solidus "\\"
                 auto r2 = R"("\\")"_json;
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\\\\""))).accept());
+                CHECK(accept_helper("\"\\\\\""));
                 // solidus
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\/\""))).accept());
+                CHECK(accept_helper("\"\\/\""));
                 // backspace
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\b\""))).accept());
+                CHECK(accept_helper("\"\\b\""));
                 // formfeed
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\f\""))).accept());
+                CHECK(accept_helper("\"\\f\""));
                 // newline
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\n\""))).accept());
+                CHECK(accept_helper("\"\\n\""));
                 // carriage return
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\r\""))).accept());
+                CHECK(accept_helper("\"\\r\""));
                 // horizontal tab
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\t\""))).accept());
+                CHECK(accept_helper("\"\\t\""));
 
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0001\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u000a\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u00b0\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0c00\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\ud000\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u000E\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u00F0\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0100\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u2000\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\uFFFF\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u20AC\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"€\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"🎈\""))).accept());
+                CHECK(accept_helper("\"\\u0001\""));
+                CHECK(accept_helper("\"\\u000a\""));
+                CHECK(accept_helper("\"\\u00b0\""));
+                CHECK(accept_helper("\"\\u0c00\""));
+                CHECK(accept_helper("\"\\ud000\""));
+                CHECK(accept_helper("\"\\u000E\""));
+                CHECK(accept_helper("\"\\u00F0\""));
+                CHECK(accept_helper("\"\\u0100\""));
+                CHECK(accept_helper("\"\\u2000\""));
+                CHECK(accept_helper("\"\\uFFFF\""));
+                CHECK(accept_helper("\"\\u20AC\""));
+                CHECK(accept_helper("\"€\""));
+                CHECK(accept_helper("\"🎈\""));
 
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\ud80c\\udc60\""))).accept());
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\ud83c\\udf1e\""))).accept());
+                CHECK(accept_helper("\"\\ud80c\\udc60\""));
+                CHECK(accept_helper("\"\\ud83c\\udf1e\""));
             }
         }
 
@@ -486,40 +501,40 @@ TEST_CASE("parser class")
             {
                 SECTION("without exponent")
                 {
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-128"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("128"))).accept());
+                    CHECK(accept_helper("-128"));
+                    CHECK(accept_helper("-0"));
+                    CHECK(accept_helper("0"));
+                    CHECK(accept_helper("128"));
                 }
 
                 SECTION("with exponent")
                 {
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0e1"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0E1"))).accept());
+                    CHECK(accept_helper("0e1"));
+                    CHECK(accept_helper("0E1"));
 
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E-4"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E-3"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E-2"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E-1"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E0"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E1"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E2"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E3"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000E4"))).accept());
+                    CHECK(accept_helper("10000E-4"));
+                    CHECK(accept_helper("10000E-3"));
+                    CHECK(accept_helper("10000E-2"));
+                    CHECK(accept_helper("10000E-1"));
+                    CHECK(accept_helper("10000E0"));
+                    CHECK(accept_helper("10000E1"));
+                    CHECK(accept_helper("10000E2"));
+                    CHECK(accept_helper("10000E3"));
+                    CHECK(accept_helper("10000E4"));
 
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e-4"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e-3"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e-2"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e-1"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e0"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e1"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e2"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e3"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("10000e4"))).accept());
+                    CHECK(accept_helper("10000e-4"));
+                    CHECK(accept_helper("10000e-3"));
+                    CHECK(accept_helper("10000e-2"));
+                    CHECK(accept_helper("10000e-1"));
+                    CHECK(accept_helper("10000e0"));
+                    CHECK(accept_helper("10000e1"));
+                    CHECK(accept_helper("10000e2"));
+                    CHECK(accept_helper("10000e3"));
+                    CHECK(accept_helper("10000e4"));
 
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0e1"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E1"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E123"))).accept());
+                    CHECK(accept_helper("-0e1"));
+                    CHECK(accept_helper("-0E1"));
+                    CHECK(accept_helper("-0E123"));
                 }
 
                 SECTION("edge cases")
@@ -531,9 +546,9 @@ TEST_CASE("parser class")
                     // agree exactly on their numeric values.
 
                     // -(2**53)+1
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-9007199254740991"))).accept());
+                    CHECK(accept_helper("-9007199254740991"));
                     // (2**53)-1
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("9007199254740991"))).accept());
+                    CHECK(accept_helper("9007199254740991"));
                 }
 
                 SECTION("over the edge cases")  // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers)
@@ -546,11 +561,11 @@ TEST_CASE("parser class")
                     // i.e. -(2**63) -> (2**64)-1.
 
                     // -(2**63)    ** Note: compilers see negative literals as negated positive numbers (hence the -1))
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-9223372036854775808"))).accept());
+                    CHECK(accept_helper("-9223372036854775808"));
                     // (2**63)-1
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("9223372036854775807"))).accept());
+                    CHECK(accept_helper("9223372036854775807"));
                     // (2**64)-1
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("18446744073709551615"))).accept());
+                    CHECK(accept_helper("18446744073709551615"));
                 }
             }
 
@@ -558,49 +573,49 @@ TEST_CASE("parser class")
             {
                 SECTION("without exponent")
                 {
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-128.5"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0.999"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("128.5"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0"))).accept());
+                    CHECK(accept_helper("-128.5"));
+                    CHECK(accept_helper("0.999"));
+                    CHECK(accept_helper("128.5"));
+                    CHECK(accept_helper("-0.0"));
                 }
 
                 SECTION("with exponent")
                 {
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-128.5E3"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-128.5E-3"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0e1"))).accept());
-                    CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0E1"))).accept());
+                    CHECK(accept_helper("-128.5E3"));
+                    CHECK(accept_helper("-128.5E-3"));
+                    CHECK(accept_helper("-0.0e1"));
+                    CHECK(accept_helper("-0.0E1"));
                 }
             }
 
             SECTION("overflow")
             {
                 // overflows during parsing yield an exception, but is accepted anyway
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1.18973e+4932"))).accept());
+                CHECK(accept_helper("1.18973e+4932"));
             }
 
             SECTION("invalid numbers")
             {
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("01"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("--1"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1."))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E-"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1.E1"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-1E"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E#"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E-#"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0#"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0:"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0.0Z"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0E123:"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0e0-:"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0e-:"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0f"))).accept() == false);
+                CHECK(accept_helper("01") == false);
+                CHECK(accept_helper("--1") == false);
+                CHECK(accept_helper("1.") == false);
+                CHECK(accept_helper("1E") == false);
+                CHECK(accept_helper("1E-") == false);
+                CHECK(accept_helper("1.E1") == false);
+                CHECK(accept_helper("-1E") == false);
+                CHECK(accept_helper("-0E#") == false);
+                CHECK(accept_helper("-0E-#") == false);
+                CHECK(accept_helper("-0#") == false);
+                CHECK(accept_helper("-0.0:") == false);
+                CHECK(accept_helper("-0.0Z") == false);
+                CHECK(accept_helper("-0E123:") == false);
+                CHECK(accept_helper("-0e0-:") == false);
+                CHECK(accept_helper("-0e-:") == false);
+                CHECK(accept_helper("-0f") == false);
 
                 // numbers must not begin with "+"
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("+1"))).accept() == false);
-                CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("+0"))).accept() == false);
+                CHECK(accept_helper("+1") == false);
+                CHECK(accept_helper("+0") == false);
             }
         }
     }
@@ -608,152 +623,152 @@ TEST_CASE("parser class")
     SECTION("parse errors")
     {
         // unexpected end of number
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0."))).parse(),  json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-"))).parse(),   json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("--"))).parse(),  json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0."))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-."))).parse(),  json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-:"))).parse(),  json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0.:"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("e."))).parse(),  json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e."))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e/"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e:"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E."))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E/"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E:"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0."))).parse(),
+        CHECK_THROWS_AS(parser_helper("0."),  json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("-"),   json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("--"),  json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("-0."), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("-."),  json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("-:"),  json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("0.:"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("e."),  json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("1e."), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("1e/"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("1e:"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("1E."), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("1E/"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("1E:"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("0."),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '0.'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("-"),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("--"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("--"),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '--'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0."))).parse(),
+        CHECK_THROWS_WITH(parser_helper("-0."),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after '.'; last read: '-0.'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-."))).parse(),
+        CHECK_THROWS_WITH(parser_helper("-."),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-.'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-:"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("-:"),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-:'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0.:"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("0.:"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '0.:'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("e."))).parse(),
+        CHECK_THROWS_WITH(parser_helper("e."),
                           "[json.exception.parse_error.101] parse error at 1: syntax error - invalid literal; last read: 'e'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e."))).parse(),
+        CHECK_THROWS_WITH(parser_helper("1e."),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e.'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e/"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("1e/"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e/'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e:"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("1e:"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e:'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E."))).parse(),
+        CHECK_THROWS_WITH(parser_helper("1E."),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E.'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E/"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("1E/"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E/'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E:"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("1E:"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E:'");
 
         // unexpected end of null
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("n"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("nu"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("nul"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("n"))).parse(),
+        CHECK_THROWS_AS(parser_helper("n"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("nu"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("nul"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("n"),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 'n'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("nu"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("nu"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'nu'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("nul"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("nul"),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'nul'");
 
         // unexpected end of true
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("t"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("tr"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("tru"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("t"))).parse(),
+        CHECK_THROWS_AS(parser_helper("t"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("tr"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("tru"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("t"),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 't'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("tr"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("tr"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'tr'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("tru"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("tru"),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'tru'");
 
         // unexpected end of false
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("f"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fa"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fal"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fals"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("f"))).parse(),
+        CHECK_THROWS_AS(parser_helper("f"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("fa"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("fal"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("fals"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("f"),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 'f'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fa"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("fa"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'fa'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fal"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("fal"),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'fal'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fals"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("fals"),
                           "[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; last read: 'fals'");
 
         // missing/unexpected end of array
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("["))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1,"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1,]"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("]"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("["))).parse(),
+        CHECK_THROWS_AS(parser_helper("["), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("[1"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("[1,"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("[1,]"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("]"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("["),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - unexpected end of input; expected '[', '{', or a literal");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("[1"),
                           "[json.exception.parse_error.101] parse error at 3: syntax error - unexpected end of input; expected ']'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1,"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("[1,"),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - unexpected end of input; expected '[', '{', or a literal");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1,]"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("[1,]"),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - unexpected ']'; expected '[', '{', or a literal");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("]"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("]"),
                           "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected ']'; expected '[', '{', or a literal");
 
         // missing/unexpected end of object
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\""))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":}"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":1,}"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("}"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{"))).parse(),
+        CHECK_THROWS_AS(parser_helper("{"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("{\"foo\""), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("{\"foo\":"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("{\"foo\":}"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("{\"foo\":1,}"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("}"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("{"),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - unexpected end of input; expected string literal");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\""))).parse(),
+        CHECK_THROWS_WITH(parser_helper("{\"foo\""),
                           "[json.exception.parse_error.101] parse error at 7: syntax error - unexpected end of input; expected ':'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("{\"foo\":"),
                           "[json.exception.parse_error.101] parse error at 8: syntax error - unexpected end of input; expected '[', '{', or a literal");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":}"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("{\"foo\":}"),
                           "[json.exception.parse_error.101] parse error at 8: syntax error - unexpected '}'; expected '[', '{', or a literal");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":1,}"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("{\"foo\":1,}"),
                           "[json.exception.parse_error.101] parse error at 10: syntax error - unexpected '}'; expected string literal");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("}"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("}"),
                           "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected '}'; expected '[', '{', or a literal");
 
         // missing/unexpected end of string
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\""))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\\""))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u\""))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0\""))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u01\""))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u012\""))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u01"))).parse(), json::parse_error&);
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u012"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\""))).parse(),
+        CHECK_THROWS_AS(parser_helper("\""), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\\""), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\u\""), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\u0\""), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\u01\""), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\u012\""), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\u"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\u0"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\u01"), json::parse_error&);
+        CHECK_THROWS_AS(parser_helper("\"\\u012"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("\""),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: missing closing quote; last read: '\"'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\\""))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\\""),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: missing closing quote; last read: '\"\\\"'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u\""))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\u\""),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u\"'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0\""))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\u0\""),
                           "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0\"'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u01\""))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\u01\""),
                           "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u012\""))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\u012\""),
                           "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012\"'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\u"),
                           "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\u0"),
                           "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u01"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\u01"),
                           "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01'");
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u012"))).parse(),
+        CHECK_THROWS_WITH(parser_helper("\"\\u012"),
                           "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012'");
 
         // invalid escapes
@@ -773,7 +788,7 @@ TEST_CASE("parser class")
                 case ('r'):
                 case ('t'):
                 {
-                    CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s.c_str()))).parse());
+                    CHECK_NOTHROW(parser_helper(s.c_str()));
                     break;
                 }
 
@@ -786,11 +801,11 @@ TEST_CASE("parser class")
                 // any other combination of backslash and character is invalid
                 default:
                 {
-                    CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s.c_str()))).parse(), json::parse_error&);
+                    CHECK_THROWS_AS(parser_helper(s.c_str()), json::parse_error&);
                     // only check error message if c is not a control character
                     if (c > 0x1f)
                     {
-                        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s.c_str()))).parse(),
+                        CHECK_THROWS_WITH(parser_helper(s.c_str()),
                                           "[json.exception.parse_error.101] parse error at 3: syntax error - invalid string: forbidden character after backslash; last read: '\"\\" + std::string(1, static_cast<char>(c)) + "'");
                     }
                     break;
@@ -851,49 +866,49 @@ TEST_CASE("parser class")
                 if (valid(c))
                 {
                     CAPTURE(s1);
-                    CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s1.c_str()))).parse());
+                    CHECK_NOTHROW(parser_helper(s1.c_str()));
                     CAPTURE(s2);
-                    CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s2.c_str()))).parse());
+                    CHECK_NOTHROW(parser_helper(s2.c_str()));
                     CAPTURE(s3);
-                    CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s3.c_str()))).parse());
+                    CHECK_NOTHROW(parser_helper(s3.c_str()));
                     CAPTURE(s4);
-                    CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s4.c_str()))).parse());
+                    CHECK_NOTHROW(parser_helper(s4.c_str()));
                 }
                 else
                 {
                     CAPTURE(s1);
-                    CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s1.c_str()))).parse(), json::parse_error&);
+                    CHECK_THROWS_AS(parser_helper(s1.c_str()), json::parse_error&);
                     // only check error message if c is not a control character
                     if (c > 0x1f)
                     {
-                        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s1.c_str()))).parse(),
+                        CHECK_THROWS_WITH(parser_helper(s1.c_str()),
                                           "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s1.substr(0, 7) + "'");
                     }
 
                     CAPTURE(s2);
-                    CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s2.c_str()))).parse(), json::parse_error&);
+                    CHECK_THROWS_AS(parser_helper(s2.c_str()), json::parse_error&);
                     // only check error message if c is not a control character
                     if (c > 0x1f)
                     {
-                        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s2.c_str()))).parse(),
+                        CHECK_THROWS_WITH(parser_helper(s2.c_str()),
                                           "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s2.substr(0, 6) + "'");
                     }
 
                     CAPTURE(s3);
-                    CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s3.c_str()))).parse(), json::parse_error&);
+                    CHECK_THROWS_AS(parser_helper(s3.c_str()), json::parse_error&);
                     // only check error message if c is not a control character
                     if (c > 0x1f)
                     {
-                        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s3.c_str()))).parse(),
+                        CHECK_THROWS_WITH(parser_helper(s3.c_str()),
                                           "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s3.substr(0, 5) + "'");
                     }
 
                     CAPTURE(s4);
-                    CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s4.c_str()))).parse(), json::parse_error&);
+                    CHECK_THROWS_AS(parser_helper(s4.c_str()), json::parse_error&);
                     // only check error message if c is not a control character
                     if (c > 0x1f)
                     {
-                        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s4.c_str()))).parse(),
+                        CHECK_THROWS_WITH(parser_helper(s4.c_str()),
                                           "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s4.substr(0, 4) + "'");
                     }
                 }
@@ -919,63 +934,63 @@ TEST_CASE("parser class")
     SECTION("parse errors (accept)")
     {
         // unexpected end of number
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0."))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("--"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-0."))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-."))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("-:"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("0.:"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("e."))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e."))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e/"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1e:"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E."))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E/"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("1E:"))).accept() == false);
+        CHECK(accept_helper("0.") == false);
+        CHECK(accept_helper("-") == false);
+        CHECK(accept_helper("--") == false);
+        CHECK(accept_helper("-0.") == false);
+        CHECK(accept_helper("-.") == false);
+        CHECK(accept_helper("-:") == false);
+        CHECK(accept_helper("0.:") == false);
+        CHECK(accept_helper("e.") == false);
+        CHECK(accept_helper("1e.") == false);
+        CHECK(accept_helper("1e/") == false);
+        CHECK(accept_helper("1e:") == false);
+        CHECK(accept_helper("1E.") == false);
+        CHECK(accept_helper("1E/") == false);
+        CHECK(accept_helper("1E:") == false);
 
         // unexpected end of null
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("n"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("nu"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("nul"))).accept() == false);
+        CHECK(accept_helper("n") == false);
+        CHECK(accept_helper("nu") == false);
+        CHECK(accept_helper("nul") == false);
 
         // unexpected end of true
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("t"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("tr"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("tru"))).accept() == false);
+        CHECK(accept_helper("t") == false);
+        CHECK(accept_helper("tr") == false);
+        CHECK(accept_helper("tru") == false);
 
         // unexpected end of false
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("f"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fa"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fal"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("fals"))).accept() == false);
+        CHECK(accept_helper("f") == false);
+        CHECK(accept_helper("fa") == false);
+        CHECK(accept_helper("fal") == false);
+        CHECK(accept_helper("fals") == false);
 
         // missing/unexpected end of array
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("["))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1,"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[1,]"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("]"))).accept() == false);
+        CHECK(accept_helper("[") == false);
+        CHECK(accept_helper("[1") == false);
+        CHECK(accept_helper("[1,") == false);
+        CHECK(accept_helper("[1,]") == false);
+        CHECK(accept_helper("]") == false);
 
         // missing/unexpected end of object
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":}"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{\"foo\":1,}"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("}"))).accept() == false);
+        CHECK(accept_helper("{") == false);
+        CHECK(accept_helper("{\"foo\"") == false);
+        CHECK(accept_helper("{\"foo\":") == false);
+        CHECK(accept_helper("{\"foo\":}") == false);
+        CHECK(accept_helper("{\"foo\":1,}") == false);
+        CHECK(accept_helper("}") == false);
 
         // missing/unexpected end of string
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u01\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u012\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u0"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u01"))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\u012"))).accept() == false);
+        CHECK(accept_helper("\"") == false);
+        CHECK(accept_helper("\"\\\"") == false);
+        CHECK(accept_helper("\"\\u\"") == false);
+        CHECK(accept_helper("\"\\u0\"") == false);
+        CHECK(accept_helper("\"\\u01\"") == false);
+        CHECK(accept_helper("\"\\u012\"") == false);
+        CHECK(accept_helper("\"\\u") == false);
+        CHECK(accept_helper("\"\\u0") == false);
+        CHECK(accept_helper("\"\\u01") == false);
+        CHECK(accept_helper("\"\\u012") == false);
 
         // invalid escapes
         for (int c = 1; c < 128; ++c)
@@ -1092,22 +1107,22 @@ TEST_CASE("parser class")
         }
 
         // missing part of a surrogate pair
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\uD80C\""))).accept() == false);
+        CHECK(accept_helper("\"\\uD80C\"") == false);
         // invalid surrogate pair
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\uD80C\\uD80C\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\uD80C\\u0000\""))).accept() == false);
-        CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("\"\\uD80C\\uFFFF\""))).accept() == false);
+        CHECK(accept_helper("\"\\uD80C\\uD80C\"") == false);
+        CHECK(accept_helper("\"\\uD80C\\u0000\"") == false);
+        CHECK(accept_helper("\"\\uD80C\\uFFFF\"") == false);
     }
 
     SECTION("tests found by mutate++")
     {
         // test case to make sure no comma preceeds the first key
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{,\"key\": false}"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("{,\"key\": false}"))).parse(),
+        CHECK_THROWS_AS(parser_helper("{,\"key\": false}"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("{,\"key\": false}"),
                           "[json.exception.parse_error.101] parse error at 2: syntax error - unexpected ','; expected string literal");
         // test case to make sure an object is properly closed
-        CHECK_THROWS_AS(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[{\"key\": false true]"))).parse(), json::parse_error&);
-        CHECK_THROWS_WITH(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("[{\"key\": false true]"))).parse(),
+        CHECK_THROWS_AS(parser_helper("[{\"key\": false true]"), json::parse_error&);
+        CHECK_THROWS_WITH(parser_helper("[{\"key\": false true]"),
                           "[json.exception.parse_error.101] parse error at 19: syntax error - unexpected true literal; expected '}'");
 
         // test case to make sure the callback is properly evaluated after reading a key
@@ -1295,42 +1310,54 @@ TEST_CASE("parser class")
         SECTION("from std::vector")
         {
             std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse() == json(true));
+            json j;
+            json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
+            CHECK(j == json(true));
         }
 
         SECTION("from std::array")
         {
             std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse() == json(true));
+            json j;
+            json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
+            CHECK(j == json(true));
         }
 
         SECTION("from array")
         {
             uint8_t v[] = {'t', 'r', 'u', 'e'};
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse() == json(true));
+            json j;
+            json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
+            CHECK(j == json(true));
         }
 
         SECTION("from char literal")
         {
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string("true"))).parse() == json(true));
+            CHECK(parser_helper("true") == json(true));
         }
 
         SECTION("from std::string")
         {
             std::string v = {'t', 'r', 'u', 'e'};
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse() == json(true));
+            json j;
+            json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
+            CHECK(j == json(true));
         }
 
         SECTION("from std::initializer_list")
         {
             std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse() == json(true));
+            json j;
+            json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
+            CHECK(j == json(true));
         }
 
         SECTION("from std::valarray")
         {
             std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'};
-            CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse() == json(true));
+            json j;
+            json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
+            CHECK(j == json(true));
         }
     }
 }