Merge pull request #1153 from theodelrieu/refactor/no_virtual_sax
Refactor/no virtual sax
This commit is contained in:
commit
d5b21b051c
21 changed files with 795 additions and 339 deletions
5
Makefile
5
Makefile
|
@ -21,7 +21,10 @@ SRCS = include/nlohmann/json.hpp \
|
||||||
include/nlohmann/detail/json_ref.hpp \
|
include/nlohmann/detail/json_ref.hpp \
|
||||||
include/nlohmann/detail/macro_scope.hpp \
|
include/nlohmann/detail/macro_scope.hpp \
|
||||||
include/nlohmann/detail/macro_unscope.hpp \
|
include/nlohmann/detail/macro_unscope.hpp \
|
||||||
include/nlohmann/detail/meta.hpp \
|
include/nlohmann/detail/meta/cpp_future.hpp \
|
||||||
|
include/nlohmann/detail/meta/detected.hpp \
|
||||||
|
include/nlohmann/detail/meta/type_traits.hpp \
|
||||||
|
include/nlohmann/detail/meta/void_t.hpp \
|
||||||
include/nlohmann/detail/output/binary_writer.hpp \
|
include/nlohmann/detail/output/binary_writer.hpp \
|
||||||
include/nlohmann/detail/output/output_adapters.hpp \
|
include/nlohmann/detail/output/output_adapters.hpp \
|
||||||
include/nlohmann/detail/output/serializer.hpp \
|
include/nlohmann/detail/output/serializer.hpp \
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
|
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
#include <nlohmann/detail/meta.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
#include <valarray> // valarray
|
#include <valarray> // valarray
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
#include <nlohmann/detail/meta.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <nlohmann/detail/input/json_sax.hpp>
|
#include <nlohmann/detail/input/json_sax.hpp>
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
#include <nlohmann/detail/meta/is_sax.hpp>
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
|
@ -30,14 +31,14 @@ namespace detail
|
||||||
/*!
|
/*!
|
||||||
@brief deserialization of CBOR, MessagePack, and UBJSON values
|
@brief deserialization of CBOR, MessagePack, and UBJSON values
|
||||||
*/
|
*/
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
|
||||||
class binary_reader
|
class binary_reader
|
||||||
{
|
{
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using json_sax_t = json_sax<BasicJsonType>;
|
using json_sax_t = SAX;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
|
@ -47,6 +48,7 @@ class binary_reader
|
||||||
*/
|
*/
|
||||||
explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
|
explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
|
||||||
{
|
{
|
||||||
|
(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
|
||||||
assert(ia);
|
assert(ia);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +323,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x9F: // array (indefinite length)
|
case 0x9F: // array (indefinite length)
|
||||||
return get_cbor_array(json_sax_t::no_limit);
|
return get_cbor_array(std::size_t(-1));
|
||||||
|
|
||||||
// map (0x00..0x17 pairs of data items follow)
|
// map (0x00..0x17 pairs of data items follow)
|
||||||
case 0xA0:
|
case 0xA0:
|
||||||
|
@ -375,7 +377,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xBF: // map (indefinite length)
|
case 0xBF: // map (indefinite length)
|
||||||
return get_cbor_object(json_sax_t::no_limit);
|
return get_cbor_object(std::size_t(-1));
|
||||||
|
|
||||||
case 0xF4: // false
|
case 0xF4: // false
|
||||||
return sax->boolean(false);
|
return sax->boolean(false);
|
||||||
|
@ -1020,7 +1022,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param[in] len the length of the array or json_sax_t::no_limit for an
|
@param[in] len the length of the array or std::size_t(-1) for an
|
||||||
array of indefinite size
|
array of indefinite size
|
||||||
@return whether array creation completed
|
@return whether array creation completed
|
||||||
*/
|
*/
|
||||||
|
@ -1031,7 +1033,7 @@ class binary_reader
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len != json_sax_t::no_limit)
|
if (len != std::size_t(-1))
|
||||||
for (std::size_t i = 0; i < len; ++i)
|
for (std::size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not parse_cbor_internal()))
|
if (JSON_UNLIKELY(not parse_cbor_internal()))
|
||||||
|
@ -1054,7 +1056,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param[in] len the length of the object or json_sax_t::no_limit for an
|
@param[in] len the length of the object or std::size_t(-1) for an
|
||||||
object of indefinite size
|
object of indefinite size
|
||||||
@return whether object creation completed
|
@return whether object creation completed
|
||||||
*/
|
*/
|
||||||
|
@ -1066,7 +1068,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t key;
|
string_t key;
|
||||||
if (len != json_sax_t::no_limit)
|
if (len != std::size_t(-1))
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < len; ++i)
|
for (std::size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
@ -1558,7 +1560,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not sax->start_array()))
|
if (JSON_UNLIKELY(not sax->start_array(-1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1628,7 +1630,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not sax->start_object()))
|
if (JSON_UNLIKELY(not sax->start_object(-1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,6 @@ struct json_sax
|
||||||
/// type for strings
|
/// type for strings
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
|
||||||
/// constant to indicate that no size limit is given for array or object
|
|
||||||
static constexpr auto no_limit = std::size_t(-1);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief a null value was read
|
@brief a null value was read
|
||||||
@return whether parsing should proceed
|
@return whether parsing should proceed
|
||||||
|
@ -72,11 +69,11 @@ struct json_sax
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief the beginning of an object was read
|
@brief the beginning of an object was read
|
||||||
@param[in] elements number of object elements or no_limit if unknown
|
@param[in] elements number of object elements or -1 if unknown
|
||||||
@return whether parsing should proceed
|
@return whether parsing should proceed
|
||||||
@note binary formats may report the number of elements
|
@note binary formats may report the number of elements
|
||||||
*/
|
*/
|
||||||
virtual bool start_object(std::size_t elements = no_limit) = 0;
|
virtual bool start_object(std::size_t elements) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief an object key was read
|
@brief an object key was read
|
||||||
|
@ -93,11 +90,11 @@ struct json_sax
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief the beginning of an array was read
|
@brief the beginning of an array was read
|
||||||
@param[in] elements number of array elements or no_limit if unknown
|
@param[in] elements number of array elements or -1 if unknown
|
||||||
@return whether parsing should proceed
|
@return whether parsing should proceed
|
||||||
@note binary formats may report the number of elements
|
@note binary formats may report the number of elements
|
||||||
*/
|
*/
|
||||||
virtual bool start_array(std::size_t elements = no_limit) = 0;
|
virtual bool start_array(std::size_t elements) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief the end of an array was read
|
@brief the end of an array was read
|
||||||
|
@ -136,7 +133,7 @@ constructor contains the parsed value.
|
||||||
@tparam BasicJsonType the JSON type
|
@tparam BasicJsonType the JSON type
|
||||||
*/
|
*/
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
class json_sax_dom_parser : public json_sax<BasicJsonType>
|
class json_sax_dom_parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
@ -153,47 +150,47 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
|
||||||
: root(r), allow_exceptions(allow_exceptions_)
|
: root(r), allow_exceptions(allow_exceptions_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
handle_value(nullptr);
|
handle_value(nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool val) override
|
bool boolean(bool val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(number_integer_t val) override
|
bool number_integer(number_integer_t val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(number_unsigned_t val) override
|
bool number_unsigned(number_unsigned_t val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(number_float_t val, const string_t&) override
|
bool number_float(number_float_t val, const string_t&)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(string_t& val) override
|
bool string(string_t& val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t len) override
|
bool start_object(std::size_t len)
|
||||||
{
|
{
|
||||||
ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
|
ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
|
||||||
|
|
||||||
if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
|
if (JSON_UNLIKELY(len != -1 and len > ref_stack.back()->max_size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(408,
|
JSON_THROW(out_of_range::create(408,
|
||||||
"excessive object size: " + std::to_string(len)));
|
"excessive object size: " + std::to_string(len)));
|
||||||
|
@ -202,24 +199,24 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(string_t& val) override
|
bool key(string_t& val)
|
||||||
{
|
{
|
||||||
// add null at given key and store the reference for later
|
// add null at given key and store the reference for later
|
||||||
object_element = &(ref_stack.back()->m_value.object->operator[](val));
|
object_element = &(ref_stack.back()->m_value.object->operator[](val));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
ref_stack.pop_back();
|
ref_stack.pop_back();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t len) override
|
bool start_array(std::size_t len)
|
||||||
{
|
{
|
||||||
ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
|
ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
|
||||||
|
|
||||||
if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
|
if (JSON_UNLIKELY(len != -1 and len > ref_stack.back()->max_size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(408,
|
JSON_THROW(out_of_range::create(408,
|
||||||
"excessive array size: " + std::to_string(len)));
|
"excessive array size: " + std::to_string(len)));
|
||||||
|
@ -228,14 +225,14 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
ref_stack.pop_back();
|
ref_stack.pop_back();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&,
|
bool parse_error(std::size_t, const std::string&,
|
||||||
const detail::exception& ex) override
|
const detail::exception& ex)
|
||||||
{
|
{
|
||||||
errored = true;
|
errored = true;
|
||||||
if (allow_exceptions)
|
if (allow_exceptions)
|
||||||
|
@ -310,7 +307,7 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
class json_sax_dom_callback_parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
@ -328,43 +325,43 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
keep_stack.push_back(true);
|
keep_stack.push_back(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
handle_value(nullptr);
|
handle_value(nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool val) override
|
bool boolean(bool val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(number_integer_t val) override
|
bool number_integer(number_integer_t val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(number_unsigned_t val) override
|
bool number_unsigned(number_unsigned_t val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(number_float_t val, const string_t&) override
|
bool number_float(number_float_t val, const string_t&)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(string_t& val) override
|
bool string(string_t& val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t len) override
|
bool start_object(std::size_t len)
|
||||||
{
|
{
|
||||||
// check callback for object start
|
// check callback for object start
|
||||||
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
|
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
|
||||||
|
@ -376,7 +373,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
// check object limit
|
// check object limit
|
||||||
if (ref_stack.back())
|
if (ref_stack.back())
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
|
if (JSON_UNLIKELY(len != -1 and len > ref_stack.back()->max_size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(408,
|
JSON_THROW(out_of_range::create(408,
|
||||||
"excessive object size: " + std::to_string(len)));
|
"excessive object size: " + std::to_string(len)));
|
||||||
|
@ -386,7 +383,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(string_t& val) override
|
bool key(string_t& val)
|
||||||
{
|
{
|
||||||
BasicJsonType k = BasicJsonType(val);
|
BasicJsonType k = BasicJsonType(val);
|
||||||
|
|
||||||
|
@ -403,7 +400,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
if (ref_stack.back())
|
if (ref_stack.back())
|
||||||
{
|
{
|
||||||
|
@ -438,7 +435,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t len) override
|
bool start_array(std::size_t len)
|
||||||
{
|
{
|
||||||
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
|
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
|
||||||
keep_stack.push_back(keep);
|
keep_stack.push_back(keep);
|
||||||
|
@ -449,7 +446,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
// check array limit
|
// check array limit
|
||||||
if (ref_stack.back())
|
if (ref_stack.back())
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
|
if (JSON_UNLIKELY(len != -1 and len > ref_stack.back()->max_size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(408,
|
JSON_THROW(out_of_range::create(408,
|
||||||
"excessive array size: " + std::to_string(len)));
|
"excessive array size: " + std::to_string(len)));
|
||||||
|
@ -459,7 +456,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
bool keep = true;
|
bool keep = true;
|
||||||
|
|
||||||
|
@ -491,7 +488,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&,
|
bool parse_error(std::size_t, const std::string&,
|
||||||
const detail::exception& ex) override
|
const detail::exception& ex)
|
||||||
{
|
{
|
||||||
errored = true;
|
errored = true;
|
||||||
if (allow_exceptions)
|
if (allow_exceptions)
|
||||||
|
@ -614,7 +611,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
class json_sax_acceptor : public json_sax<BasicJsonType>
|
class json_sax_acceptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
@ -622,62 +619,62 @@ class json_sax_acceptor : public json_sax<BasicJsonType>
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool) override
|
bool boolean(bool)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(number_integer_t) override
|
bool number_integer(number_integer_t)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(number_unsigned_t) override
|
bool number_unsigned(number_unsigned_t)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(number_float_t, const string_t&) override
|
bool number_float(number_float_t, const string_t&)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(string_t&) override
|
bool string(string_t&)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t) override
|
bool start_object(std::size_t = -1)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(string_t&) override
|
bool key(string_t&)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t) override
|
bool start_array(std::size_t = -1)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&, const detail::exception&) override
|
bool parse_error(std::size_t, const std::string&, const detail::exception&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
#include <nlohmann/detail/meta/is_sax.hpp>
|
||||||
#include <nlohmann/detail/input/input_adapters.hpp>
|
#include <nlohmann/detail/input/input_adapters.hpp>
|
||||||
#include <nlohmann/detail/input/json_sax.hpp>
|
#include <nlohmann/detail/input/json_sax.hpp>
|
||||||
#include <nlohmann/detail/input/lexer.hpp>
|
#include <nlohmann/detail/input/lexer.hpp>
|
||||||
|
@ -54,8 +55,6 @@ class parser
|
||||||
value
|
value
|
||||||
};
|
};
|
||||||
|
|
||||||
using json_sax_t = json_sax<BasicJsonType>;
|
|
||||||
|
|
||||||
using parser_callback_t =
|
using parser_callback_t =
|
||||||
std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
|
std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
|
||||||
|
|
||||||
|
@ -144,8 +143,10 @@ class parser
|
||||||
return sax_parse(&sax_acceptor, strict);
|
return sax_parse(&sax_acceptor, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sax_parse(json_sax_t* sax, const bool strict = true)
|
template <typename SAX>
|
||||||
|
bool sax_parse(SAX* sax, const bool strict = true)
|
||||||
{
|
{
|
||||||
|
(void)detail::is_sax_static_asserts<SAX, BasicJsonType>{};
|
||||||
const bool result = sax_parse_internal(sax);
|
const bool result = sax_parse_internal(sax);
|
||||||
|
|
||||||
// strict mode: next byte must be EOF
|
// strict mode: next byte must be EOF
|
||||||
|
@ -160,7 +161,8 @@ class parser
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool sax_parse_internal(json_sax_t* sax)
|
template <typename SAX>
|
||||||
|
bool sax_parse_internal(SAX* sax)
|
||||||
{
|
{
|
||||||
// stack to remember the hieararchy of structured values we are parsing
|
// stack to remember the hieararchy of structured values we are parsing
|
||||||
// true = array; false = object
|
// true = array; false = object
|
||||||
|
@ -177,7 +179,7 @@ class parser
|
||||||
{
|
{
|
||||||
case token_type::begin_object:
|
case token_type::begin_object:
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not sax->start_object()))
|
if (JSON_UNLIKELY(not sax->start_object(-1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +227,7 @@ class parser
|
||||||
|
|
||||||
case token_type::begin_array:
|
case token_type::begin_array:
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not sax->start_array()))
|
if (JSON_UNLIKELY(not sax->start_array(-1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <nlohmann/detail/iterators/internal_iterator.hpp>
|
#include <nlohmann/detail/iterators/internal_iterator.hpp>
|
||||||
#include <nlohmann/detail/iterators/primitive_iterator.hpp>
|
#include <nlohmann/detail/iterators/primitive_iterator.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
#include <nlohmann/detail/meta.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
|
|
83
include/nlohmann/detail/meta/cpp_future.hpp
Normal file
83
include/nlohmann/detail/meta/cpp_future.hpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ciso646> // not
|
||||||
|
#include <cstddef> // size_t
|
||||||
|
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
// alias templates to reduce boilerplate
|
||||||
|
template<bool B, typename T = void>
|
||||||
|
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||||
|
|
||||||
|
// implementation of C++14 index_sequence and affiliates
|
||||||
|
// source: https://stackoverflow.com/a/32223343
|
||||||
|
template<std::size_t... Ints>
|
||||||
|
struct index_sequence
|
||||||
|
{
|
||||||
|
using type = index_sequence;
|
||||||
|
using value_type = std::size_t;
|
||||||
|
static constexpr std::size_t size() noexcept
|
||||||
|
{
|
||||||
|
return sizeof...(Ints);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Sequence1, class Sequence2>
|
||||||
|
struct merge_and_renumber;
|
||||||
|
|
||||||
|
template<std::size_t... I1, std::size_t... I2>
|
||||||
|
struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
|
||||||
|
: index_sequence < I1..., (sizeof...(I1) + I2)... > {};
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
struct make_index_sequence
|
||||||
|
: merge_and_renumber < typename make_index_sequence < N / 2 >::type,
|
||||||
|
typename make_index_sequence < N - N / 2 >::type > {};
|
||||||
|
|
||||||
|
template<> struct make_index_sequence<0> : index_sequence<> {};
|
||||||
|
template<> struct make_index_sequence<1> : index_sequence<0> {};
|
||||||
|
|
||||||
|
template<typename... Ts>
|
||||||
|
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation of two C++17 constructs: conjunction, negation. This is needed
|
||||||
|
to avoid evaluating all the traits in a condition
|
||||||
|
|
||||||
|
For example: not std::is_same<void, T>::value and has_value_type<T>::value
|
||||||
|
will not compile when T = void (on MSVC at least). Whereas
|
||||||
|
conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
|
||||||
|
stop evaluating if negation<...>::value == false
|
||||||
|
|
||||||
|
Please note that those constructs must be used with caution, since symbols can
|
||||||
|
become very long quickly (which can slow down compilation and cause MSVC
|
||||||
|
internal compiler errors). Only use it when you have to (see example ahead).
|
||||||
|
*/
|
||||||
|
template<class...> struct conjunction : std::true_type {};
|
||||||
|
template<class B1> struct conjunction<B1> : B1 {};
|
||||||
|
template<class B1, class... Bn>
|
||||||
|
struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
|
||||||
|
|
||||||
|
template<class B> struct negation : std::integral_constant<bool, not B::value> {};
|
||||||
|
|
||||||
|
// dispatch utility (taken from ranges-v3)
|
||||||
|
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
|
||||||
|
template<> struct priority_tag<0> {};
|
||||||
|
|
||||||
|
// taken from ranges-v3
|
||||||
|
template<typename T>
|
||||||
|
struct static_const
|
||||||
|
{
|
||||||
|
static constexpr T value{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr T static_const<T>::value;
|
||||||
|
}
|
||||||
|
}
|
56
include/nlohmann/detail/meta/detected.hpp
Normal file
56
include/nlohmann/detail/meta/detected.hpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <nlohmann/detail/meta/void_t.hpp>
|
||||||
|
|
||||||
|
// http://en.cppreference.com/w/cpp/experimental/is_detected
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct nonesuch
|
||||||
|
{
|
||||||
|
nonesuch() = delete;
|
||||||
|
~nonesuch() = delete;
|
||||||
|
nonesuch(nonesuch const&) = delete;
|
||||||
|
void operator=(nonesuch const&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Default,
|
||||||
|
class AlwaysVoid,
|
||||||
|
template <class...> class Op,
|
||||||
|
class... Args>
|
||||||
|
struct detector
|
||||||
|
{
|
||||||
|
using value_t = std::false_type;
|
||||||
|
using type = Default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Default, template <class...> class Op, class... Args>
|
||||||
|
struct detector<Default, void_t<Op<Args...>>, Op, Args...>
|
||||||
|
{
|
||||||
|
using value_t = std::true_type;
|
||||||
|
using type = Op<Args...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class...> class Op, class... Args>
|
||||||
|
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
|
||||||
|
|
||||||
|
template <template <class...> class Op, class... Args>
|
||||||
|
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
|
||||||
|
|
||||||
|
template <class Default, template <class...> class Op, class... Args>
|
||||||
|
using detected_or = detector<Default, void, Op, Args...>;
|
||||||
|
|
||||||
|
template <class Default, template <class...> class Op, class... Args>
|
||||||
|
using detected_or_t = typename detected_or<Default, Op, Args...>::type;
|
||||||
|
|
||||||
|
template <class Expected, template <class...> class Op, class... Args>
|
||||||
|
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
|
||||||
|
|
||||||
|
template <class To, template <class...> class Op, class... Args>
|
||||||
|
using is_detected_convertible =
|
||||||
|
std::is_convertible<detected_t<Op, Args...>, To>;
|
||||||
|
}
|
||||||
|
}
|
141
include/nlohmann/detail/meta/is_sax.hpp
Normal file
141
include/nlohmann/detail/meta/is_sax.hpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // size_t
|
||||||
|
#include <utility> // declval
|
||||||
|
|
||||||
|
#include <nlohmann/detail/meta/detected.hpp>
|
||||||
|
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
using null_function_t = decltype(std::declval<T&>().null());
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using boolean_function_t =
|
||||||
|
decltype(std::declval<T&>().boolean(std::declval<bool>()));
|
||||||
|
|
||||||
|
template <typename T, typename Integer>
|
||||||
|
using number_integer_function_t =
|
||||||
|
decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
|
||||||
|
|
||||||
|
template <typename T, typename Unsigned>
|
||||||
|
using number_unsigned_function_t =
|
||||||
|
decltype(std::declval<T &>().number_unsigned(std::declval<Unsigned>()));
|
||||||
|
|
||||||
|
template <typename T, typename Float, typename String>
|
||||||
|
using number_float_function_t = decltype(std::declval<T &>().number_float(
|
||||||
|
std::declval<Float>(), std::declval<const String &>()));
|
||||||
|
|
||||||
|
template <typename T, typename String>
|
||||||
|
using string_function_t =
|
||||||
|
decltype(std::declval<T &>().string(std::declval<String &>()));
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using start_object_function_t =
|
||||||
|
decltype(std::declval<T &>().start_object(std::declval<std::size_t>()));
|
||||||
|
|
||||||
|
template <typename T, typename String>
|
||||||
|
using key_function_t =
|
||||||
|
decltype(std::declval<T &>().key(std::declval<String &>()));
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using end_object_function_t = decltype(std::declval<T &>().end_object());
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using start_array_function_t =
|
||||||
|
decltype(std::declval<T &>().start_array(std::declval<std::size_t>()));
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using end_array_function_t = decltype(std::declval<T &>().end_array());
|
||||||
|
|
||||||
|
template <typename T, typename Exception>
|
||||||
|
using parse_error_function_t = decltype(std::declval<T &>().parse_error(
|
||||||
|
std::declval<std::size_t>(), std::declval<const std::string &>(),
|
||||||
|
std::declval<const Exception &>()));
|
||||||
|
|
||||||
|
template <typename SAX, typename BasicJsonType>
|
||||||
|
struct is_sax
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static_assert(is_basic_json<BasicJsonType>::value,
|
||||||
|
"BasicJsonType must be of type basic_json<...>");
|
||||||
|
|
||||||
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
using exception_t = typename BasicJsonType::exception;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr bool value =
|
||||||
|
is_detected_exact<bool, null_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, boolean_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, number_integer_function_t, SAX,
|
||||||
|
number_integer_t>::value &&
|
||||||
|
is_detected_exact<bool, number_unsigned_function_t, SAX,
|
||||||
|
number_unsigned_t>::value &&
|
||||||
|
is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
|
||||||
|
string_t>::value &&
|
||||||
|
is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
|
||||||
|
is_detected_exact<bool, start_object_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
|
||||||
|
is_detected_exact<bool, end_object_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, start_array_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, end_array_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename SAX, typename BasicJsonType>
|
||||||
|
struct is_sax_static_asserts
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static_assert(is_basic_json<BasicJsonType>::value,
|
||||||
|
"BasicJsonType must be of type basic_json<...>");
|
||||||
|
|
||||||
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
using exception_t = typename BasicJsonType::exception;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool null()");
|
||||||
|
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool boolean(bool)");
|
||||||
|
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool boolean(bool)");
|
||||||
|
static_assert(
|
||||||
|
is_detected_exact<bool, number_integer_function_t, SAX,
|
||||||
|
number_integer_t>::value,
|
||||||
|
"Missing/invalid function: bool number_integer(number_integer_t)");
|
||||||
|
static_assert(
|
||||||
|
is_detected_exact<bool, number_unsigned_function_t, SAX,
|
||||||
|
number_unsigned_t>::value,
|
||||||
|
"Missing/invalid function: bool number_unsigned(number_unsigned_t)");
|
||||||
|
static_assert(is_detected_exact<bool, number_float_function_t, SAX,
|
||||||
|
number_float_t, string_t>::value,
|
||||||
|
"Missing/invalid function: bool number_float(number_float_t, const string_t&)");
|
||||||
|
static_assert(
|
||||||
|
is_detected_exact<bool, string_function_t, SAX, string_t>::value,
|
||||||
|
"Missing/invalid function: bool string(string_t&)");
|
||||||
|
static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool start_object(std::size_t)");
|
||||||
|
static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
|
||||||
|
"Missing/invalid function: bool key(string_t&)");
|
||||||
|
static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool end_object()");
|
||||||
|
static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool start_array(std::size_t)");
|
||||||
|
static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool end_array()");
|
||||||
|
static_assert(
|
||||||
|
is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
|
||||||
|
"Missing/invalid function: bool parse_error(std::size_t, const "
|
||||||
|
"std::string&, const exception&)");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ciso646> // not
|
#include <ciso646> // not
|
||||||
#include <cstddef> // size_t
|
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
|
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
|
||||||
#include <utility> // declval
|
#include <utility> // declval
|
||||||
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
|
@ -30,68 +30,6 @@ template<typename> struct is_basic_json : std::false_type {};
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
||||||
|
|
||||||
// alias templates to reduce boilerplate
|
|
||||||
template<bool B, typename T = void>
|
|
||||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
|
||||||
|
|
||||||
// implementation of C++14 index_sequence and affiliates
|
|
||||||
// source: https://stackoverflow.com/a/32223343
|
|
||||||
template<std::size_t... Ints>
|
|
||||||
struct index_sequence
|
|
||||||
{
|
|
||||||
using type = index_sequence;
|
|
||||||
using value_type = std::size_t;
|
|
||||||
static constexpr std::size_t size() noexcept
|
|
||||||
{
|
|
||||||
return sizeof...(Ints);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Sequence1, class Sequence2>
|
|
||||||
struct merge_and_renumber;
|
|
||||||
|
|
||||||
template<std::size_t... I1, std::size_t... I2>
|
|
||||||
struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
|
|
||||||
: index_sequence < I1..., (sizeof...(I1) + I2)... > {};
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct make_index_sequence
|
|
||||||
: merge_and_renumber < typename make_index_sequence < N / 2 >::type,
|
|
||||||
typename make_index_sequence < N - N / 2 >::type > {};
|
|
||||||
|
|
||||||
template<> struct make_index_sequence<0> : index_sequence<> {};
|
|
||||||
template<> struct make_index_sequence<1> : index_sequence<0> {};
|
|
||||||
|
|
||||||
template<typename... Ts>
|
|
||||||
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Implementation of two C++17 constructs: conjunction, negation. This is needed
|
|
||||||
to avoid evaluating all the traits in a condition
|
|
||||||
|
|
||||||
For example: not std::is_same<void, T>::value and has_value_type<T>::value
|
|
||||||
will not compile when T = void (on MSVC at least). Whereas
|
|
||||||
conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
|
|
||||||
stop evaluating if negation<...>::value == false
|
|
||||||
|
|
||||||
Please note that those constructs must be used with caution, since symbols can
|
|
||||||
become very long quickly (which can slow down compilation and cause MSVC
|
|
||||||
internal compiler errors). Only use it when you have to (see example ahead).
|
|
||||||
*/
|
|
||||||
template<class...> struct conjunction : std::true_type {};
|
|
||||||
template<class B1> struct conjunction<B1> : B1 {};
|
|
||||||
template<class B1, class... Bn>
|
|
||||||
struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
|
|
||||||
|
|
||||||
template<class B> struct negation : std::integral_constant<bool, not B::value> {};
|
|
||||||
|
|
||||||
// dispatch utility (taken from ranges-v3)
|
|
||||||
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
|
|
||||||
template<> struct priority_tag<0> {};
|
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// has_/is_ functions //
|
// has_/is_ functions //
|
||||||
////////////////////////
|
////////////////////////
|
||||||
|
@ -264,15 +202,5 @@ struct is_compatible_type
|
||||||
is_compatible_complete_type<BasicJsonType, CompatibleType>>
|
is_compatible_complete_type<BasicJsonType, CompatibleType>>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
// taken from ranges-v3
|
|
||||||
template<typename T>
|
|
||||||
struct static_const
|
|
||||||
{
|
|
||||||
static constexpr T value{};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr T static_const<T>::value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
10
include/nlohmann/detail/meta/void_t.hpp
Normal file
10
include/nlohmann/detail/meta/void_t.hpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename...>
|
||||||
|
using void_t = void;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/conversions/to_chars.hpp>
|
#include <nlohmann/detail/conversions/to_chars.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
#include <nlohmann/detail/meta.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
#include <nlohmann/detail/output/output_adapters.hpp>
|
#include <nlohmann/detail/output/output_adapters.hpp>
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,8 @@ SOFTWARE.
|
||||||
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
#include <nlohmann/detail/meta.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
#include <nlohmann/detail/exceptions.hpp>
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
#include <nlohmann/detail/conversions/from_json.hpp>
|
#include <nlohmann/detail/conversions/from_json.hpp>
|
||||||
|
@ -170,7 +171,7 @@ class basic_json
|
||||||
friend class ::nlohmann::detail::iter_impl;
|
friend class ::nlohmann::detail::iter_impl;
|
||||||
template<typename BasicJsonType, typename CharType>
|
template<typename BasicJsonType, typename CharType>
|
||||||
friend class ::nlohmann::detail::binary_writer;
|
friend class ::nlohmann::detail::binary_writer;
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType, typename SAX>
|
||||||
friend class ::nlohmann::detail::binary_reader;
|
friend class ::nlohmann::detail::binary_reader;
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
friend class ::nlohmann::detail::json_sax_dom_parser;
|
friend class ::nlohmann::detail::json_sax_dom_parser;
|
||||||
|
@ -211,6 +212,7 @@ class basic_json
|
||||||
using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
|
using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
|
||||||
|
|
||||||
using input_format_t = detail::input_format_t;
|
using input_format_t = detail::input_format_t;
|
||||||
|
using json_sax_t = json_sax<basic_json>;
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
// exceptions //
|
// exceptions //
|
||||||
|
@ -1112,8 +1114,6 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
using parser_callback_t = typename parser::parser_callback_t;
|
using parser_callback_t = typename parser::parser_callback_t;
|
||||||
|
|
||||||
using json_sax_t = typename parser::json_sax_t;
|
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// constructors //
|
// constructors //
|
||||||
//////////////////
|
//////////////////
|
||||||
|
@ -6013,7 +6013,8 @@ class basic_json
|
||||||
return parser(i).accept(true);
|
return parser(i).accept(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sax_parse(detail::input_adapter&& i, json_sax_t* sax,
|
template <typename SAX>
|
||||||
|
static bool sax_parse(detail::input_adapter&& i, SAX* sax,
|
||||||
input_format_t format = input_format_t::json,
|
input_format_t format = input_format_t::json,
|
||||||
const bool strict = true)
|
const bool strict = true)
|
||||||
{
|
{
|
||||||
|
@ -6023,7 +6024,7 @@ class basic_json
|
||||||
case input_format_t::json:
|
case input_format_t::json:
|
||||||
return parser(std::move(i)).sax_parse(sax, strict);
|
return parser(std::move(i)).sax_parse(sax, strict);
|
||||||
default:
|
default:
|
||||||
return binary_reader(std::move(i)).sax_parse(format, sax, strict);
|
return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6096,11 +6097,11 @@ class basic_json
|
||||||
return parser(detail::input_adapter(first, last)).accept(true);
|
return parser(detail::input_adapter(first, last)).accept(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class IteratorType, typename std::enable_if<
|
template<class IteratorType, class SAX, typename std::enable_if<
|
||||||
std::is_base_of<
|
std::is_base_of<
|
||||||
std::random_access_iterator_tag,
|
std::random_access_iterator_tag,
|
||||||
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
||||||
static bool sax_parse(IteratorType first, IteratorType last, json_sax_t* sax)
|
static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
|
||||||
{
|
{
|
||||||
return parser(detail::input_adapter(first, last)).sax_parse(sax);
|
return parser(detail::input_adapter(first, last)).sax_parse(sax);
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,41 +238,17 @@ contains a `mapped_type`, whereas `std::vector` fails the test.
|
||||||
std::is_integral<decltype(detect(std::declval<T>()))>::value; \
|
std::is_integral<decltype(detect(std::declval<T>()))>::value; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta.hpp>
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <ciso646> // not
|
#include <ciso646> // not
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <limits> // numeric_limits
|
|
||||||
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
|
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
|
||||||
#include <utility> // declval
|
|
||||||
|
|
||||||
// #include <nlohmann/json_fwd.hpp>
|
|
||||||
|
|
||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
{
|
{
|
||||||
/*!
|
|
||||||
@brief detail namespace with internal helper functions
|
|
||||||
|
|
||||||
This namespace collects functions that should not be exposed,
|
|
||||||
implementations of some @ref basic_json methods, and meta-programming helpers.
|
|
||||||
|
|
||||||
@since version 2.1.0
|
|
||||||
*/
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/////////////
|
|
||||||
// helpers //
|
|
||||||
/////////////
|
|
||||||
|
|
||||||
template<typename> struct is_basic_json : std::false_type {};
|
|
||||||
|
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
|
||||||
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
|
||||||
|
|
||||||
// alias templates to reduce boilerplate
|
// alias templates to reduce boilerplate
|
||||||
template<bool B, typename T = void>
|
template<bool B, typename T = void>
|
||||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||||
|
@ -335,6 +311,54 @@ template<class B> struct negation : std::integral_constant<bool, not B::value> {
|
||||||
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
|
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
|
||||||
template<> struct priority_tag<0> {};
|
template<> struct priority_tag<0> {};
|
||||||
|
|
||||||
|
// taken from ranges-v3
|
||||||
|
template<typename T>
|
||||||
|
struct static_const
|
||||||
|
{
|
||||||
|
static constexpr T value{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr T static_const<T>::value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#include <ciso646> // not
|
||||||
|
#include <limits> // numeric_limits
|
||||||
|
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
|
||||||
|
#include <utility> // declval
|
||||||
|
|
||||||
|
// #include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
@brief detail namespace with internal helper functions
|
||||||
|
|
||||||
|
This namespace collects functions that should not be exposed,
|
||||||
|
implementations of some @ref basic_json methods, and meta-programming helpers.
|
||||||
|
|
||||||
|
@since version 2.1.0
|
||||||
|
*/
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
/////////////
|
||||||
|
// helpers //
|
||||||
|
/////////////
|
||||||
|
|
||||||
|
template<typename> struct is_basic_json : std::false_type {};
|
||||||
|
|
||||||
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
|
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// has_/is_ functions //
|
// has_/is_ functions //
|
||||||
////////////////////////
|
////////////////////////
|
||||||
|
@ -507,16 +531,6 @@ struct is_compatible_type
|
||||||
is_compatible_complete_type<BasicJsonType, CompatibleType>>
|
is_compatible_complete_type<BasicJsonType, CompatibleType>>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
// taken from ranges-v3
|
|
||||||
template<typename T>
|
|
||||||
struct static_const
|
|
||||||
{
|
|
||||||
static constexpr T value{};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr T static_const<T>::value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,7 +964,9 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
|
||||||
|
|
||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta.hpp>
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/value_t.hpp>
|
// #include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
|
@ -1335,7 +1351,9 @@ constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::va
|
||||||
#include <valarray> // valarray
|
#include <valarray> // valarray
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta.hpp>
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/value_t.hpp>
|
// #include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
|
@ -3539,6 +3557,218 @@ scan_number_done:
|
||||||
|
|
||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/is_sax.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdint> // size_t
|
||||||
|
#include <utility> // declval
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/detected.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/void_t.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename...>
|
||||||
|
using void_t = void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// http://en.cppreference.com/w/cpp/experimental/is_detected
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct nonesuch
|
||||||
|
{
|
||||||
|
nonesuch() = delete;
|
||||||
|
~nonesuch() = delete;
|
||||||
|
nonesuch(nonesuch const&) = delete;
|
||||||
|
void operator=(nonesuch const&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Default,
|
||||||
|
class AlwaysVoid,
|
||||||
|
template <class...> class Op,
|
||||||
|
class... Args>
|
||||||
|
struct detector
|
||||||
|
{
|
||||||
|
using value_t = std::false_type;
|
||||||
|
using type = Default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Default, template <class...> class Op, class... Args>
|
||||||
|
struct detector<Default, void_t<Op<Args...>>, Op, Args...>
|
||||||
|
{
|
||||||
|
using value_t = std::true_type;
|
||||||
|
using type = Op<Args...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class...> class Op, class... Args>
|
||||||
|
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
|
||||||
|
|
||||||
|
template <template <class...> class Op, class... Args>
|
||||||
|
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
|
||||||
|
|
||||||
|
template <class Default, template <class...> class Op, class... Args>
|
||||||
|
using detected_or = detector<Default, void, Op, Args...>;
|
||||||
|
|
||||||
|
template <class Default, template <class...> class Op, class... Args>
|
||||||
|
using detected_or_t = typename detected_or<Default, Op, Args...>::type;
|
||||||
|
|
||||||
|
template <class Expected, template <class...> class Op, class... Args>
|
||||||
|
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
|
||||||
|
|
||||||
|
template <class To, template <class...> class Op, class... Args>
|
||||||
|
using is_detected_convertible =
|
||||||
|
std::is_convertible<detected_t<Op, Args...>, To>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
using null_function_t = decltype(std::declval<T&>().null());
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using boolean_function_t =
|
||||||
|
decltype(std::declval<T&>().boolean(std::declval<bool>()));
|
||||||
|
|
||||||
|
template <typename T, typename Integer>
|
||||||
|
using number_integer_function_t =
|
||||||
|
decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
|
||||||
|
|
||||||
|
template <typename T, typename Unsigned>
|
||||||
|
using number_unsigned_function_t =
|
||||||
|
decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
|
||||||
|
|
||||||
|
template <typename T, typename Float, typename String>
|
||||||
|
using number_float_function_t = decltype(std::declval<T&>().number_float(
|
||||||
|
std::declval<Float>(), std::declval<const String&>()));
|
||||||
|
|
||||||
|
template <typename T, typename String>
|
||||||
|
using string_function_t =
|
||||||
|
decltype(std::declval<T&>().string(std::declval<String&>()));
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using start_object_function_t =
|
||||||
|
decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
|
||||||
|
|
||||||
|
template <typename T, typename String>
|
||||||
|
using key_function_t =
|
||||||
|
decltype(std::declval<T&>().key(std::declval<String&>()));
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using end_object_function_t = decltype(std::declval<T&>().end_object());
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using start_array_function_t =
|
||||||
|
decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using end_array_function_t = decltype(std::declval<T&>().end_array());
|
||||||
|
|
||||||
|
template <typename T, typename Exception>
|
||||||
|
using parse_error_function_t = decltype(std::declval<T&>().parse_error(
|
||||||
|
std::declval<std::size_t>(), std::declval<const std::string&>(),
|
||||||
|
std::declval<const Exception&>()));
|
||||||
|
|
||||||
|
template <typename SAX, typename BasicJsonType>
|
||||||
|
struct is_sax
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static_assert(is_basic_json<BasicJsonType>::value,
|
||||||
|
"BasicJsonType must be of type basic_json<...>");
|
||||||
|
|
||||||
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
using exception_t = typename BasicJsonType::exception;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr bool value =
|
||||||
|
is_detected_exact<bool, null_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, boolean_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, number_integer_function_t, SAX,
|
||||||
|
number_integer_t>::value &&
|
||||||
|
is_detected_exact<bool, number_unsigned_function_t, SAX,
|
||||||
|
number_unsigned_t>::value &&
|
||||||
|
is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
|
||||||
|
string_t>::value &&
|
||||||
|
is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
|
||||||
|
is_detected_exact<bool, start_object_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
|
||||||
|
is_detected_exact<bool, end_object_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, start_array_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, end_array_function_t, SAX>::value &&
|
||||||
|
is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename SAX, typename BasicJsonType>
|
||||||
|
struct is_sax_static_asserts
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static_assert(is_basic_json<BasicJsonType>::value,
|
||||||
|
"BasicJsonType must be of type basic_json<...>");
|
||||||
|
|
||||||
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
using exception_t = typename BasicJsonType::exception;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool null()");
|
||||||
|
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool boolean(bool)");
|
||||||
|
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool boolean(bool)");
|
||||||
|
static_assert(
|
||||||
|
is_detected_exact<bool, number_integer_function_t, SAX,
|
||||||
|
number_integer_t>::value,
|
||||||
|
"Missing/invalid function: bool number_integer(number_integer_t)");
|
||||||
|
static_assert(
|
||||||
|
is_detected_exact<bool, number_unsigned_function_t, SAX,
|
||||||
|
number_unsigned_t>::value,
|
||||||
|
"Missing/invalid function: bool number_unsigned(number_unsigned_t)");
|
||||||
|
static_assert(is_detected_exact<bool, number_float_function_t, SAX,
|
||||||
|
number_float_t, string_t>::value,
|
||||||
|
"Missing/invalid function: bool number_float(number_float_t, const string_t&)");
|
||||||
|
static_assert(
|
||||||
|
is_detected_exact<bool, string_function_t, SAX, string_t>::value,
|
||||||
|
"Missing/invalid function: bool string(string_t&)");
|
||||||
|
static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool start_object(std::size_t)");
|
||||||
|
static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
|
||||||
|
"Missing/invalid function: bool key(string_t&)");
|
||||||
|
static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool end_object()");
|
||||||
|
static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool start_array(std::size_t)");
|
||||||
|
static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
|
||||||
|
"Missing/invalid function: bool end_array()");
|
||||||
|
static_assert(
|
||||||
|
is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
|
||||||
|
"Missing/invalid function: bool parse_error(std::size_t, const "
|
||||||
|
"std::string&, const exception&)");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #include <nlohmann/detail/input/input_adapters.hpp>
|
// #include <nlohmann/detail/input/input_adapters.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/input/json_sax.hpp>
|
// #include <nlohmann/detail/input/json_sax.hpp>
|
||||||
|
@ -3571,9 +3801,6 @@ struct json_sax
|
||||||
/// type for strings
|
/// type for strings
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
|
||||||
/// constant to indicate that no size limit is given for array or object
|
|
||||||
static constexpr auto no_limit = std::size_t(-1);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief a null value was read
|
@brief a null value was read
|
||||||
@return whether parsing should proceed
|
@return whether parsing should proceed
|
||||||
|
@ -3618,11 +3845,11 @@ struct json_sax
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief the beginning of an object was read
|
@brief the beginning of an object was read
|
||||||
@param[in] elements number of object elements or no_limit if unknown
|
@param[in] elements number of object elements or -1 if unknown
|
||||||
@return whether parsing should proceed
|
@return whether parsing should proceed
|
||||||
@note binary formats may report the number of elements
|
@note binary formats may report the number of elements
|
||||||
*/
|
*/
|
||||||
virtual bool start_object(std::size_t elements = no_limit) = 0;
|
virtual bool start_object(std::size_t elements) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief an object key was read
|
@brief an object key was read
|
||||||
|
@ -3639,11 +3866,11 @@ struct json_sax
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief the beginning of an array was read
|
@brief the beginning of an array was read
|
||||||
@param[in] elements number of array elements or no_limit if unknown
|
@param[in] elements number of array elements or -1 if unknown
|
||||||
@return whether parsing should proceed
|
@return whether parsing should proceed
|
||||||
@note binary formats may report the number of elements
|
@note binary formats may report the number of elements
|
||||||
*/
|
*/
|
||||||
virtual bool start_array(std::size_t elements = no_limit) = 0;
|
virtual bool start_array(std::size_t elements) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief the end of an array was read
|
@brief the end of an array was read
|
||||||
|
@ -3682,7 +3909,7 @@ constructor contains the parsed value.
|
||||||
@tparam BasicJsonType the JSON type
|
@tparam BasicJsonType the JSON type
|
||||||
*/
|
*/
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
class json_sax_dom_parser : public json_sax<BasicJsonType>
|
class json_sax_dom_parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
@ -3699,47 +3926,47 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
|
||||||
: root(r), allow_exceptions(allow_exceptions_)
|
: root(r), allow_exceptions(allow_exceptions_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
handle_value(nullptr);
|
handle_value(nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool val) override
|
bool boolean(bool val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(number_integer_t val) override
|
bool number_integer(number_integer_t val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(number_unsigned_t val) override
|
bool number_unsigned(number_unsigned_t val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(number_float_t val, const string_t&) override
|
bool number_float(number_float_t val, const string_t&)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(string_t& val) override
|
bool string(string_t& val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t len) override
|
bool start_object(std::size_t len)
|
||||||
{
|
{
|
||||||
ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
|
ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
|
||||||
|
|
||||||
if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
|
if (JSON_UNLIKELY(len != -1 and len > ref_stack.back()->max_size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(408,
|
JSON_THROW(out_of_range::create(408,
|
||||||
"excessive object size: " + std::to_string(len)));
|
"excessive object size: " + std::to_string(len)));
|
||||||
|
@ -3748,24 +3975,24 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(string_t& val) override
|
bool key(string_t& val)
|
||||||
{
|
{
|
||||||
// add null at given key and store the reference for later
|
// add null at given key and store the reference for later
|
||||||
object_element = &(ref_stack.back()->m_value.object->operator[](val));
|
object_element = &(ref_stack.back()->m_value.object->operator[](val));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
ref_stack.pop_back();
|
ref_stack.pop_back();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t len) override
|
bool start_array(std::size_t len)
|
||||||
{
|
{
|
||||||
ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
|
ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
|
||||||
|
|
||||||
if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
|
if (JSON_UNLIKELY(len != -1 and len > ref_stack.back()->max_size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(408,
|
JSON_THROW(out_of_range::create(408,
|
||||||
"excessive array size: " + std::to_string(len)));
|
"excessive array size: " + std::to_string(len)));
|
||||||
|
@ -3774,14 +4001,14 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
ref_stack.pop_back();
|
ref_stack.pop_back();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&,
|
bool parse_error(std::size_t, const std::string&,
|
||||||
const detail::exception& ex) override
|
const detail::exception& ex)
|
||||||
{
|
{
|
||||||
errored = true;
|
errored = true;
|
||||||
if (allow_exceptions)
|
if (allow_exceptions)
|
||||||
|
@ -3856,7 +4083,7 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
class json_sax_dom_callback_parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
@ -3874,43 +4101,43 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
keep_stack.push_back(true);
|
keep_stack.push_back(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
handle_value(nullptr);
|
handle_value(nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool val) override
|
bool boolean(bool val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(number_integer_t val) override
|
bool number_integer(number_integer_t val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(number_unsigned_t val) override
|
bool number_unsigned(number_unsigned_t val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(number_float_t val, const string_t&) override
|
bool number_float(number_float_t val, const string_t&)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(string_t& val) override
|
bool string(string_t& val)
|
||||||
{
|
{
|
||||||
handle_value(val);
|
handle_value(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t len) override
|
bool start_object(std::size_t len)
|
||||||
{
|
{
|
||||||
// check callback for object start
|
// check callback for object start
|
||||||
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
|
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
|
||||||
|
@ -3922,7 +4149,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
// check object limit
|
// check object limit
|
||||||
if (ref_stack.back())
|
if (ref_stack.back())
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
|
if (JSON_UNLIKELY(len != -1 and len > ref_stack.back()->max_size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(408,
|
JSON_THROW(out_of_range::create(408,
|
||||||
"excessive object size: " + std::to_string(len)));
|
"excessive object size: " + std::to_string(len)));
|
||||||
|
@ -3932,7 +4159,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(string_t& val) override
|
bool key(string_t& val)
|
||||||
{
|
{
|
||||||
BasicJsonType k = BasicJsonType(val);
|
BasicJsonType k = BasicJsonType(val);
|
||||||
|
|
||||||
|
@ -3949,7 +4176,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
if (ref_stack.back())
|
if (ref_stack.back())
|
||||||
{
|
{
|
||||||
|
@ -3984,7 +4211,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t len) override
|
bool start_array(std::size_t len)
|
||||||
{
|
{
|
||||||
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
|
const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
|
||||||
keep_stack.push_back(keep);
|
keep_stack.push_back(keep);
|
||||||
|
@ -3995,7 +4222,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
// check array limit
|
// check array limit
|
||||||
if (ref_stack.back())
|
if (ref_stack.back())
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
|
if (JSON_UNLIKELY(len != -1 and len > ref_stack.back()->max_size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(408,
|
JSON_THROW(out_of_range::create(408,
|
||||||
"excessive array size: " + std::to_string(len)));
|
"excessive array size: " + std::to_string(len)));
|
||||||
|
@ -4005,7 +4232,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
bool keep = true;
|
bool keep = true;
|
||||||
|
|
||||||
|
@ -4037,7 +4264,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&,
|
bool parse_error(std::size_t, const std::string&,
|
||||||
const detail::exception& ex) override
|
const detail::exception& ex)
|
||||||
{
|
{
|
||||||
errored = true;
|
errored = true;
|
||||||
if (allow_exceptions)
|
if (allow_exceptions)
|
||||||
|
@ -4160,7 +4387,7 @@ class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
class json_sax_acceptor : public json_sax<BasicJsonType>
|
class json_sax_acceptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
|
@ -4168,62 +4395,62 @@ class json_sax_acceptor : public json_sax<BasicJsonType>
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool) override
|
bool boolean(bool)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(number_integer_t) override
|
bool number_integer(number_integer_t)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(number_unsigned_t) override
|
bool number_unsigned(number_unsigned_t)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(number_float_t, const string_t&) override
|
bool number_float(number_float_t, const string_t&)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(string_t&) override
|
bool string(string_t&)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t) override
|
bool start_object(std::size_t = -1)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(string_t&) override
|
bool key(string_t&)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t) override
|
bool start_array(std::size_t = -1)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&, const detail::exception&) override
|
bool parse_error(std::size_t, const std::string&, const detail::exception&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4277,8 +4504,6 @@ class parser
|
||||||
value
|
value
|
||||||
};
|
};
|
||||||
|
|
||||||
using json_sax_t = json_sax<BasicJsonType>;
|
|
||||||
|
|
||||||
using parser_callback_t =
|
using parser_callback_t =
|
||||||
std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
|
std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
|
||||||
|
|
||||||
|
@ -4367,8 +4592,10 @@ class parser
|
||||||
return sax_parse(&sax_acceptor, strict);
|
return sax_parse(&sax_acceptor, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sax_parse(json_sax_t* sax, const bool strict = true)
|
template <typename SAX>
|
||||||
|
bool sax_parse(SAX* sax, const bool strict = true)
|
||||||
{
|
{
|
||||||
|
// (void)detail::is_sax_static_asserts<SAX, BasicJsonType>{};
|
||||||
const bool result = sax_parse_internal(sax);
|
const bool result = sax_parse_internal(sax);
|
||||||
|
|
||||||
// strict mode: next byte must be EOF
|
// strict mode: next byte must be EOF
|
||||||
|
@ -4383,7 +4610,8 @@ class parser
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool sax_parse_internal(json_sax_t* sax)
|
template <typename SAX>
|
||||||
|
bool sax_parse_internal(SAX* sax)
|
||||||
{
|
{
|
||||||
// stack to remember the hieararchy of structured values we are parsing
|
// stack to remember the hieararchy of structured values we are parsing
|
||||||
// true = array; false = object
|
// true = array; false = object
|
||||||
|
@ -4400,7 +4628,7 @@ class parser
|
||||||
{
|
{
|
||||||
case token_type::begin_object:
|
case token_type::begin_object:
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not sax->start_object()))
|
if (JSON_UNLIKELY(not sax->start_object(-1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4448,7 +4676,7 @@ class parser
|
||||||
|
|
||||||
case token_type::begin_array:
|
case token_type::begin_array:
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not sax->start_array()))
|
if (JSON_UNLIKELY(not sax->start_array(-1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4873,7 +5101,7 @@ template<typename BasicJsonType> struct internal_iterator
|
||||||
|
|
||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta.hpp>
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/value_t.hpp>
|
// #include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
|
@ -5742,6 +5970,8 @@ class output_adapter
|
||||||
|
|
||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/meta/is_sax.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/value_t.hpp>
|
// #include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
@ -5756,14 +5986,14 @@ namespace detail
|
||||||
/*!
|
/*!
|
||||||
@brief deserialization of CBOR, MessagePack, and UBJSON values
|
@brief deserialization of CBOR, MessagePack, and UBJSON values
|
||||||
*/
|
*/
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
|
||||||
class binary_reader
|
class binary_reader
|
||||||
{
|
{
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using number_float_t = typename BasicJsonType::number_float_t;
|
using number_float_t = typename BasicJsonType::number_float_t;
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using json_sax_t = json_sax<BasicJsonType>;
|
using json_sax_t = SAX;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
|
@ -5773,6 +6003,7 @@ class binary_reader
|
||||||
*/
|
*/
|
||||||
explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
|
explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
|
||||||
{
|
{
|
||||||
|
(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
|
||||||
assert(ia);
|
assert(ia);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6047,7 +6278,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x9F: // array (indefinite length)
|
case 0x9F: // array (indefinite length)
|
||||||
return get_cbor_array(json_sax_t::no_limit);
|
return get_cbor_array(std::size_t(-1));
|
||||||
|
|
||||||
// map (0x00..0x17 pairs of data items follow)
|
// map (0x00..0x17 pairs of data items follow)
|
||||||
case 0xA0:
|
case 0xA0:
|
||||||
|
@ -6101,7 +6332,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xBF: // map (indefinite length)
|
case 0xBF: // map (indefinite length)
|
||||||
return get_cbor_object(json_sax_t::no_limit);
|
return get_cbor_object(std::size_t(-1));
|
||||||
|
|
||||||
case 0xF4: // false
|
case 0xF4: // false
|
||||||
return sax->boolean(false);
|
return sax->boolean(false);
|
||||||
|
@ -6746,7 +6977,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param[in] len the length of the array or json_sax_t::no_limit for an
|
@param[in] len the length of the array or std::size_t(-1) for an
|
||||||
array of indefinite size
|
array of indefinite size
|
||||||
@return whether array creation completed
|
@return whether array creation completed
|
||||||
*/
|
*/
|
||||||
|
@ -6757,7 +6988,7 @@ class binary_reader
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len != json_sax_t::no_limit)
|
if (len != std::size_t(-1))
|
||||||
for (std::size_t i = 0; i < len; ++i)
|
for (std::size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not parse_cbor_internal()))
|
if (JSON_UNLIKELY(not parse_cbor_internal()))
|
||||||
|
@ -6780,7 +7011,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param[in] len the length of the object or json_sax_t::no_limit for an
|
@param[in] len the length of the object or std::size_t(-1) for an
|
||||||
object of indefinite size
|
object of indefinite size
|
||||||
@return whether object creation completed
|
@return whether object creation completed
|
||||||
*/
|
*/
|
||||||
|
@ -6792,7 +7023,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t key;
|
string_t key;
|
||||||
if (len != json_sax_t::no_limit)
|
if (len != std::size_t(-1))
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < len; ++i)
|
for (std::size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
|
@ -7284,7 +7515,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not sax->start_array()))
|
if (JSON_UNLIKELY(not sax->start_array(-1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -7354,7 +7585,7 @@ class binary_reader
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(not sax->start_object()))
|
if (JSON_UNLIKELY(not sax->start_object(-1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -9488,7 +9719,7 @@ char* to_chars(char* first, char* last, FloatType value)
|
||||||
|
|
||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta.hpp>
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/output/output_adapters.hpp>
|
// #include <nlohmann/detail/output/output_adapters.hpp>
|
||||||
|
|
||||||
|
@ -11022,7 +11253,7 @@ class basic_json
|
||||||
friend class ::nlohmann::detail::iter_impl;
|
friend class ::nlohmann::detail::iter_impl;
|
||||||
template<typename BasicJsonType, typename CharType>
|
template<typename BasicJsonType, typename CharType>
|
||||||
friend class ::nlohmann::detail::binary_writer;
|
friend class ::nlohmann::detail::binary_writer;
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType, typename SAX>
|
||||||
friend class ::nlohmann::detail::binary_reader;
|
friend class ::nlohmann::detail::binary_reader;
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
friend class ::nlohmann::detail::json_sax_dom_parser;
|
friend class ::nlohmann::detail::json_sax_dom_parser;
|
||||||
|
@ -11063,6 +11294,7 @@ class basic_json
|
||||||
using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
|
using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
|
||||||
|
|
||||||
using input_format_t = detail::input_format_t;
|
using input_format_t = detail::input_format_t;
|
||||||
|
using json_sax_t = json_sax<basic_json>;
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
// exceptions //
|
// exceptions //
|
||||||
|
@ -11964,8 +12196,6 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
using parser_callback_t = typename parser::parser_callback_t;
|
using parser_callback_t = typename parser::parser_callback_t;
|
||||||
|
|
||||||
using json_sax_t = typename parser::json_sax_t;
|
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// constructors //
|
// constructors //
|
||||||
//////////////////
|
//////////////////
|
||||||
|
@ -16865,7 +17095,8 @@ class basic_json
|
||||||
return parser(i).accept(true);
|
return parser(i).accept(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sax_parse(detail::input_adapter&& i, json_sax_t* sax,
|
template <typename SAX>
|
||||||
|
static bool sax_parse(detail::input_adapter&& i, SAX* sax,
|
||||||
input_format_t format = input_format_t::json,
|
input_format_t format = input_format_t::json,
|
||||||
const bool strict = true)
|
const bool strict = true)
|
||||||
{
|
{
|
||||||
|
@ -16875,7 +17106,7 @@ class basic_json
|
||||||
case input_format_t::json:
|
case input_format_t::json:
|
||||||
return parser(std::move(i)).sax_parse(sax, strict);
|
return parser(std::move(i)).sax_parse(sax, strict);
|
||||||
default:
|
default:
|
||||||
return binary_reader(std::move(i)).sax_parse(format, sax, strict);
|
return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16948,11 +17179,11 @@ class basic_json
|
||||||
return parser(detail::input_adapter(first, last)).accept(true);
|
return parser(detail::input_adapter(first, last)).accept(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class IteratorType, typename std::enable_if<
|
template<class IteratorType, class SAX, typename std::enable_if<
|
||||||
std::is_base_of<
|
std::is_base_of<
|
||||||
std::random_access_iterator_tag,
|
std::random_access_iterator_tag,
|
||||||
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
||||||
static bool sax_parse(IteratorType first, IteratorType last, json_sax_t* sax)
|
static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
|
||||||
{
|
{
|
||||||
return parser(detail::input_adapter(first, last)).sax_parse(sax);
|
return parser(detail::input_adapter(first, last)).sax_parse(sax);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,68 +34,68 @@ using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
class SaxCountdown : public nlohmann::json::json_sax_t
|
class SaxCountdown
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
explicit SaxCountdown(const int count) : events_left(count)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool) override
|
bool boolean(bool)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t) override
|
bool number_integer(json::number_integer_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t) override
|
bool number_unsigned(json::number_unsigned_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(json::number_float_t, const std::string&) override
|
bool number_float(json::number_float_t, const std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(std::string&) override
|
bool string(std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t) override
|
bool start_object(std::size_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(std::string&) override
|
bool key(std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t) override
|
bool start_array(std::size_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&, const json::exception&) override
|
bool parse_error(std::size_t, const std::string&, const json::exception&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,48 +35,48 @@ using nlohmann::json;
|
||||||
|
|
||||||
#include <valarray>
|
#include <valarray>
|
||||||
|
|
||||||
class SaxEventLogger : public nlohmann::json::json_sax_t
|
class SaxEventLogger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
events.push_back("null()");
|
events.push_back("null()");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool val) override
|
bool boolean(bool val)
|
||||||
{
|
{
|
||||||
events.push_back(val ? "boolean(true)" : "boolean(false)");
|
events.push_back(val ? "boolean(true)" : "boolean(false)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t val) override
|
bool number_integer(json::number_integer_t val)
|
||||||
{
|
{
|
||||||
events.push_back("number_integer(" + std::to_string(val) + ")");
|
events.push_back("number_integer(" + std::to_string(val) + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t val) override
|
bool number_unsigned(json::number_unsigned_t val)
|
||||||
{
|
{
|
||||||
events.push_back("number_unsigned(" + std::to_string(val) + ")");
|
events.push_back("number_unsigned(" + std::to_string(val) + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(json::number_float_t, const std::string& s) override
|
bool number_float(json::number_float_t, const std::string& s)
|
||||||
{
|
{
|
||||||
events.push_back("number_float(" + s + ")");
|
events.push_back("number_float(" + s + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(std::string& val) override
|
bool string(std::string& val)
|
||||||
{
|
{
|
||||||
events.push_back("string(" + val + ")");
|
events.push_back("string(" + val + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t elements) override
|
bool start_object(std::size_t elements)
|
||||||
{
|
{
|
||||||
if (elements == no_limit)
|
if (elements == std::size_t(-1))
|
||||||
{
|
{
|
||||||
events.push_back("start_object()");
|
events.push_back("start_object()");
|
||||||
}
|
}
|
||||||
|
@ -87,21 +87,21 @@ class SaxEventLogger : public nlohmann::json::json_sax_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(std::string& val) override
|
bool key(std::string& val)
|
||||||
{
|
{
|
||||||
events.push_back("key(" + val + ")");
|
events.push_back("key(" + val + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
events.push_back("end_object()");
|
events.push_back("end_object()");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t elements) override
|
bool start_array(std::size_t elements)
|
||||||
{
|
{
|
||||||
if (elements == no_limit)
|
if (elements == std::size_t(-1))
|
||||||
{
|
{
|
||||||
events.push_back("start_array()");
|
events.push_back("start_array()");
|
||||||
}
|
}
|
||||||
|
@ -112,13 +112,13 @@ class SaxEventLogger : public nlohmann::json::json_sax_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
events.push_back("end_array()");
|
events.push_back("end_array()");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t position, const std::string&, const json::exception&) override
|
bool parse_error(std::size_t position, const std::string&, const json::exception&)
|
||||||
{
|
{
|
||||||
errored = true;
|
errored = true;
|
||||||
events.push_back("parse_error(" + std::to_string(position) + ")");
|
events.push_back("parse_error(" + std::to_string(position) + ")");
|
||||||
|
|
|
@ -35,45 +35,45 @@ using nlohmann::json;
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <valarray>
|
#include <valarray>
|
||||||
|
|
||||||
struct SaxEventLogger : public nlohmann::json::json_sax_t
|
struct SaxEventLogger
|
||||||
{
|
{
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
events.push_back("null()");
|
events.push_back("null()");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool val) override
|
bool boolean(bool val)
|
||||||
{
|
{
|
||||||
events.push_back(val ? "boolean(true)" : "boolean(false)");
|
events.push_back(val ? "boolean(true)" : "boolean(false)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t val) override
|
bool number_integer(json::number_integer_t val)
|
||||||
{
|
{
|
||||||
events.push_back("number_integer(" + std::to_string(val) + ")");
|
events.push_back("number_integer(" + std::to_string(val) + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t val) override
|
bool number_unsigned(json::number_unsigned_t val)
|
||||||
{
|
{
|
||||||
events.push_back("number_unsigned(" + std::to_string(val) + ")");
|
events.push_back("number_unsigned(" + std::to_string(val) + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(json::number_float_t, const std::string& s) override
|
bool number_float(json::number_float_t, const std::string& s)
|
||||||
{
|
{
|
||||||
events.push_back("number_float(" + s + ")");
|
events.push_back("number_float(" + s + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(std::string& val) override
|
bool string(std::string& val)
|
||||||
{
|
{
|
||||||
events.push_back("string(" + val + ")");
|
events.push_back("string(" + val + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t elements) override
|
bool start_object(std::size_t elements)
|
||||||
{
|
{
|
||||||
if (elements == std::size_t(-1))
|
if (elements == std::size_t(-1))
|
||||||
{
|
{
|
||||||
|
@ -86,19 +86,19 @@ struct SaxEventLogger : public nlohmann::json::json_sax_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(std::string& val) override
|
bool key(std::string& val)
|
||||||
{
|
{
|
||||||
events.push_back("key(" + val + ")");
|
events.push_back("key(" + val + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object()override
|
bool end_object()
|
||||||
{
|
{
|
||||||
events.push_back("end_object()");
|
events.push_back("end_object()");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t elements) override
|
bool start_array(std::size_t elements)
|
||||||
{
|
{
|
||||||
if (elements == std::size_t(-1))
|
if (elements == std::size_t(-1))
|
||||||
{
|
{
|
||||||
|
@ -111,13 +111,13 @@ struct SaxEventLogger : public nlohmann::json::json_sax_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
events.push_back("end_array()");
|
events.push_back("end_array()");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t position, const std::string&, const json::exception&) override
|
bool parse_error(std::size_t position, const std::string&, const json::exception&)
|
||||||
{
|
{
|
||||||
events.push_back("parse_error(" + std::to_string(position) + ")");
|
events.push_back("parse_error(" + std::to_string(position) + ")");
|
||||||
return false;
|
return false;
|
||||||
|
@ -128,9 +128,9 @@ struct SaxEventLogger : public nlohmann::json::json_sax_t
|
||||||
|
|
||||||
struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
|
struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
|
||||||
{
|
{
|
||||||
bool start_object(std::size_t elements) override
|
bool start_object(std::size_t elements)
|
||||||
{
|
{
|
||||||
if (elements == no_limit)
|
if (elements == -1)
|
||||||
{
|
{
|
||||||
events.push_back("start_object()");
|
events.push_back("start_object()");
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
|
||||||
|
|
||||||
struct SaxEventLoggerExitAfterKey : public SaxEventLogger
|
struct SaxEventLoggerExitAfterKey : public SaxEventLogger
|
||||||
{
|
{
|
||||||
bool key(std::string& val) override
|
bool key(std::string& val)
|
||||||
{
|
{
|
||||||
events.push_back("key(" + val + ")");
|
events.push_back("key(" + val + ")");
|
||||||
return false;
|
return false;
|
||||||
|
@ -153,9 +153,9 @@ struct SaxEventLoggerExitAfterKey : public SaxEventLogger
|
||||||
|
|
||||||
struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
|
struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
|
||||||
{
|
{
|
||||||
bool start_array(std::size_t elements) override
|
bool start_array(std::size_t elements)
|
||||||
{
|
{
|
||||||
if (elements == no_limit)
|
if (elements == -1)
|
||||||
{
|
{
|
||||||
events.push_back("start_array()");
|
events.push_back("start_array()");
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,8 +317,8 @@ TEST_CASE("object inspection")
|
||||||
SECTION("round trips")
|
SECTION("round trips")
|
||||||
{
|
{
|
||||||
for (const auto& s :
|
for (const auto& s :
|
||||||
{"3.141592653589793", "1000000000000000010E5"
|
{"3.141592653589793", "1000000000000000010E5"
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
json j1 = json::parse(s);
|
json j1 = json::parse(s);
|
||||||
std::string s1 = j1.dump();
|
std::string s1 = j1.dump();
|
||||||
|
|
|
@ -34,68 +34,68 @@ using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
class SaxCountdown : public nlohmann::json::json_sax_t
|
class SaxCountdown
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
explicit SaxCountdown(const int count) : events_left(count)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool) override
|
bool boolean(bool)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t) override
|
bool number_integer(json::number_integer_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t) override
|
bool number_unsigned(json::number_unsigned_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(json::number_float_t, const std::string&) override
|
bool number_float(json::number_float_t, const std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(std::string&) override
|
bool string(std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t) override
|
bool start_object(std::size_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(std::string&) override
|
bool key(std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t) override
|
bool start_array(std::size_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&, const json::exception&) override
|
bool parse_error(std::size_t, const std::string&, const json::exception&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,68 +34,68 @@ using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
class SaxCountdown : public nlohmann::json::json_sax_t
|
class SaxCountdown
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
explicit SaxCountdown(const int count) : events_left(count)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool null() override
|
bool null()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean(bool) override
|
bool boolean(bool)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t) override
|
bool number_integer(json::number_integer_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t) override
|
bool number_unsigned(json::number_unsigned_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool number_float(json::number_float_t, const std::string&) override
|
bool number_float(json::number_float_t, const std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool string(std::string&) override
|
bool string(std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_object(std::size_t) override
|
bool start_object(std::size_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key(std::string&) override
|
bool key(std::string&)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_object() override
|
bool end_object()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start_array(std::size_t) override
|
bool start_array(std::size_t)
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool end_array() override
|
bool end_array()
|
||||||
{
|
{
|
||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t, const std::string&, const json::exception&) override
|
bool parse_error(std::size_t, const std::string&, const json::exception&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue