🔨 reorganized interfaces for parse/accept functions #623
We now rely on implicit conversions to an input_adapter object in the parse/accept functions.
This commit is contained in:
parent
18e0430bfe
commit
9b1c058810
3 changed files with 94 additions and 233 deletions
289
src/json.hpp
289
src/json.hpp
|
@ -1267,19 +1267,19 @@ constexpr T static_const<T>::value;
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
/// abstract input adapter interface
|
/// abstract input adapter interface
|
||||||
struct input_adapter
|
struct input_adapter_protocol
|
||||||
{
|
{
|
||||||
virtual int get_character() = 0;
|
virtual int get_character() = 0;
|
||||||
virtual std::string read(std::size_t offset, std::size_t length) = 0;
|
virtual std::string read(std::size_t offset, std::size_t length) = 0;
|
||||||
virtual ~input_adapter() = default;
|
virtual ~input_adapter_protocol() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// a type to simplify interfaces
|
/// a type to simplify interfaces
|
||||||
using input_adapter_t = std::shared_ptr<input_adapter>;
|
using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
|
||||||
|
|
||||||
/// input adapter for cached stream input
|
/// input adapter for cached stream input
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
class cached_input_stream_adapter : public input_adapter
|
class cached_input_stream_adapter : public input_adapter_protocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit cached_input_stream_adapter(std::istream& i)
|
explicit cached_input_stream_adapter(std::istream& i)
|
||||||
|
@ -1386,7 +1386,7 @@ class cached_input_stream_adapter : public input_adapter
|
||||||
};
|
};
|
||||||
|
|
||||||
/// input adapter for buffer input
|
/// input adapter for buffer input
|
||||||
class input_buffer_adapter : public input_adapter
|
class input_buffer_adapter : public input_adapter_protocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
input_buffer_adapter(const char* b, std::size_t l)
|
input_buffer_adapter(const char* b, std::size_t l)
|
||||||
|
@ -1429,27 +1429,22 @@ class input_buffer_adapter : public input_adapter
|
||||||
const char* start;
|
const char* start;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct input_adapter_factory
|
class input_adapter
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
// native support
|
// native support
|
||||||
|
|
||||||
/// input adapter for input stream
|
/// input adapter for input stream
|
||||||
static std::shared_ptr<input_adapter> create(std::istream& i)
|
input_adapter(std::istream& i)
|
||||||
{
|
: ia(std::make_shared<cached_input_stream_adapter<16384>>(i)) {}
|
||||||
return std::make_shared<cached_input_stream_adapter<16384>> (i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// input adapter for input stream
|
/// input adapter for input stream
|
||||||
static std::shared_ptr<input_adapter> create(std::istream&& i)
|
input_adapter(std::istream&& i)
|
||||||
{
|
: ia(std::make_shared<cached_input_stream_adapter<16384>>(i)) {}
|
||||||
return std::make_shared<cached_input_stream_adapter<16384>>(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// input adapter for buffer
|
/// input adapter for buffer
|
||||||
static std::shared_ptr<input_adapter> create(const char* b, std::size_t l)
|
input_adapter(const char* b, std::size_t l)
|
||||||
{
|
: ia(std::make_shared<input_buffer_adapter>(b, l)) {}
|
||||||
return std::make_shared<input_buffer_adapter>(b, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
// derived support
|
// derived support
|
||||||
|
|
||||||
|
@ -1461,11 +1456,9 @@ struct input_adapter_factory
|
||||||
typename std::remove_pointer<CharT>::type>::value and
|
typename std::remove_pointer<CharT>::type>::value and
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
static std::shared_ptr<input_adapter> create(CharT b)
|
input_adapter(CharT b)
|
||||||
{
|
: input_adapter(reinterpret_cast<const char*>(b),
|
||||||
return create(reinterpret_cast<const char*>(b),
|
std::strlen(reinterpret_cast<const char*>(b))) {}
|
||||||
std::strlen(reinterpret_cast<const char*>(b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// input adapter for iterator range with contiguous storage
|
/// input adapter for iterator range with contiguous storage
|
||||||
template <class IteratorType,
|
template <class IteratorType,
|
||||||
|
@ -1474,8 +1467,7 @@ struct input_adapter_factory
|
||||||
IteratorType>::iterator_category,
|
IteratorType>::iterator_category,
|
||||||
std::random_access_iterator_tag>::value,
|
std::random_access_iterator_tag>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
static std::shared_ptr<input_adapter> create(IteratorType first,
|
input_adapter(IteratorType first, IteratorType last)
|
||||||
IteratorType last)
|
|
||||||
{
|
{
|
||||||
// assertion to check that the iterator range is indeed contiguous,
|
// assertion to check that the iterator range is indeed contiguous,
|
||||||
// see http://stackoverflow.com/a/35008842/266378 for more discussion
|
// see http://stackoverflow.com/a/35008842/266378 for more discussion
|
||||||
|
@ -1496,22 +1488,19 @@ struct input_adapter_factory
|
||||||
if (JSON_LIKELY(len > 0))
|
if (JSON_LIKELY(len > 0))
|
||||||
{
|
{
|
||||||
// there is at least one element: use the address of first
|
// there is at least one element: use the address of first
|
||||||
return create(reinterpret_cast<const char*>(&(*first)), len);
|
ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// the address of first cannot be used - use nullptr
|
// the address of first cannot be used - use nullptr
|
||||||
return create(nullptr, len);
|
ia = std::make_shared<input_buffer_adapter>(nullptr, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// input adapter for array
|
/// input adapter for array
|
||||||
template <class T, std::size_t N>
|
template <class T, std::size_t N>
|
||||||
static std::shared_ptr<input_adapter> create(T (&array)[N])
|
input_adapter(T (&array)[N])
|
||||||
{
|
: input_adapter(std::begin(array), std::end(array)) {}
|
||||||
// delegate the call to the iterator-range overload
|
|
||||||
return create(std::begin(array), std::end(array));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// input adapter for contiguous container
|
/// input adapter for contiguous container
|
||||||
template <
|
template <
|
||||||
|
@ -1523,11 +1512,17 @@ struct input_adapter_factory
|
||||||
std::declval<ContiguousContainer const>()))>::
|
std::declval<ContiguousContainer const>()))>::
|
||||||
iterator_category>::value,
|
iterator_category>::value,
|
||||||
int >::type = 0 >
|
int >::type = 0 >
|
||||||
static std::shared_ptr<input_adapter> create(const ContiguousContainer& c)
|
input_adapter(const ContiguousContainer& c)
|
||||||
|
: input_adapter(std::begin(c), std::end(c)) {}
|
||||||
|
|
||||||
|
operator input_adapter_t()
|
||||||
{
|
{
|
||||||
// delegate the call to the iterator-range overload
|
return ia;
|
||||||
return create(std::begin(c), std::end(c));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// the actual adapter
|
||||||
|
input_adapter_t ia = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
|
@ -12817,15 +12812,36 @@ class basic_json
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from an array
|
@brief deserialize from a compatible input
|
||||||
|
|
||||||
This function reads from an array of 1-byte values.
|
This function reads from a compatible input. Examples are:
|
||||||
|
- an array of 1-byte values
|
||||||
|
- strings with character/literal type with size of 1 byte
|
||||||
|
- input streams
|
||||||
|
- container with contiguous storage of 1-byte values. Compatible container
|
||||||
|
types include `std::vector`, `std::string`, `std::array`,
|
||||||
|
`std::valarray`, and `std::initializer_list`. Furthermore, C-style
|
||||||
|
arrays can be used with `std::begin()`/`std::end()`. User-defined
|
||||||
|
containers can be used as long as they implement random-access iterators
|
||||||
|
and a contiguous storage.
|
||||||
|
|
||||||
@pre Each element of the container has a size of 1 byte. Violating this
|
@pre Each element of the container has a size of 1 byte. Violating this
|
||||||
precondition yields undefined behavior. **This precondition is enforced
|
precondition yields undefined behavior. **This precondition is enforced
|
||||||
with a static assertion.**
|
with a static assertion.**
|
||||||
|
|
||||||
@param[in] array array to read from
|
@pre The container storage is contiguous. Violating this precondition
|
||||||
|
yields undefined behavior. **This precondition is enforced with an
|
||||||
|
assertion.**
|
||||||
|
@pre Each element of the container has a size of 1 byte. Violating this
|
||||||
|
precondition yields undefined behavior. **This precondition is enforced
|
||||||
|
with a static assertion.**
|
||||||
|
|
||||||
|
@warning There is no way to enforce all preconditions at compile-time. If
|
||||||
|
the function is called with a noncompliant container and with
|
||||||
|
assertions switched off, the behavior is undefined and will most
|
||||||
|
likely yield segmentation violation.
|
||||||
|
|
||||||
|
@param[in] i input to read from
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
which is used to control the deserialization by filtering unwanted values
|
which is used to control the deserialization by filtering unwanted values
|
||||||
(optional)
|
(optional)
|
||||||
|
@ -12846,130 +12862,44 @@ class basic_json
|
||||||
@liveexample{The example below demonstrates the `parse()` function reading
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
from an array.,parse__array__parser_callback_t}
|
from an array.,parse__array__parser_callback_t}
|
||||||
|
|
||||||
@since version 2.0.3
|
|
||||||
*/
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
static basic_json parse(T (&array)[N],
|
|
||||||
const parser_callback_t cb = nullptr)
|
|
||||||
{
|
|
||||||
// delegate the call to the iterator-range parse overload
|
|
||||||
return parse(std::begin(array), std::end(array), cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
static bool accept(T (&array)[N])
|
|
||||||
{
|
|
||||||
// delegate the call to the iterator-range accept overload
|
|
||||||
return accept(std::begin(array), std::end(array));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief deserialize from string literal
|
|
||||||
|
|
||||||
@tparam CharT character/literal type with size of 1 byte
|
|
||||||
@param[in] s string literal to read a serialized JSON value from
|
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
|
||||||
which is used to control the deserialization by filtering unwanted values
|
|
||||||
(optional)
|
|
||||||
|
|
||||||
@return result of the deserialization
|
|
||||||
|
|
||||||
@throw parse_error.101 in case of an unexpected token
|
|
||||||
@throw parse_error.102 if to_unicode fails or surrogate error
|
|
||||||
@throw parse_error.103 if to_unicode fails
|
|
||||||
|
|
||||||
@complexity Linear in the length of the input. The parser is a predictive
|
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
|
||||||
@a cb has a super-linear complexity.
|
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
|
||||||
@note String containers like `std::string` or @ref string_t can be parsed
|
|
||||||
with @ref parse(const ContiguousContainer&, const parser_callback_t)
|
|
||||||
|
|
||||||
@liveexample{The example below demonstrates the `parse()` function with
|
@liveexample{The example below demonstrates the `parse()` function with
|
||||||
and without callback function.,parse__string__parser_callback_t}
|
and without callback function.,parse__string__parser_callback_t}
|
||||||
|
|
||||||
@sa @ref parse(std::istream&, const parser_callback_t) for a version that
|
|
||||||
reads from an input stream
|
|
||||||
|
|
||||||
@since version 1.0.0 (originally for @ref string_t)
|
|
||||||
*/
|
|
||||||
template<typename CharT, typename std::enable_if<
|
|
||||||
std::is_pointer<CharT>::value and
|
|
||||||
std::is_integral<typename std::remove_pointer<CharT>::type>::value and
|
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
|
|
||||||
static basic_json parse(const CharT s,
|
|
||||||
const parser_callback_t cb = nullptr)
|
|
||||||
{
|
|
||||||
basic_json result;
|
|
||||||
parser(detail::input_adapter_factory::create(s), cb).parse(true, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename CharT, typename std::enable_if<
|
|
||||||
std::is_pointer<CharT>::value and
|
|
||||||
std::is_integral<typename std::remove_pointer<CharT>::type>::value and
|
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
|
|
||||||
static bool accept(const CharT s)
|
|
||||||
{
|
|
||||||
return parser(detail::input_adapter_factory::create(s)).accept(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief deserialize from stream
|
|
||||||
|
|
||||||
@param[in,out] i stream to read a serialized JSON value from
|
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
|
||||||
which is used to control the deserialization by filtering unwanted values
|
|
||||||
(optional)
|
|
||||||
|
|
||||||
@return result of the deserialization
|
|
||||||
|
|
||||||
@throw parse_error.101 in case of an unexpected token
|
|
||||||
@throw parse_error.102 if to_unicode fails or surrogate error
|
|
||||||
@throw parse_error.103 if to_unicode fails
|
|
||||||
|
|
||||||
@complexity Linear in the length of the input. The parser is a predictive
|
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
|
||||||
@a cb has a super-linear complexity.
|
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
|
||||||
|
|
||||||
@liveexample{The example below demonstrates the `parse()` function with
|
@liveexample{The example below demonstrates the `parse()` function with
|
||||||
and without callback function.,parse__istream__parser_callback_t}
|
and without callback function.,parse__istream__parser_callback_t}
|
||||||
|
|
||||||
@sa @ref parse(const CharT, const parser_callback_t) for a version
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
that reads from a string
|
from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 2.0.3 (contiguous containers)
|
||||||
*/
|
*/
|
||||||
static basic_json parse(std::istream& i,
|
static basic_json parse(detail::input_adapter i,
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
parser(detail::input_adapter_factory::create(i), cb).parse(true, result);
|
parser(i, cb).parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool accept(std::istream& i)
|
|
||||||
{
|
|
||||||
return parser(detail::input_adapter_factory::create(i)).accept(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@copydoc parse(std::istream&, const parser_callback_t)
|
@copydoc basic_json parse(detail::input_adapter, const parser_callback_t)
|
||||||
*/
|
*/
|
||||||
static basic_json parse(std::istream&& i,
|
static basic_json parse(detail::input_adapter& i,
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
parser(detail::input_adapter_factory::create(i), cb).parse(true, result);
|
parser(i, cb).parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool accept(std::istream&& i)
|
static bool accept(detail::input_adapter i)
|
||||||
{
|
{
|
||||||
return parser(detail::input_adapter_factory::create(i)).accept(true);
|
return parser(i).accept(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool accept(detail::input_adapter& i)
|
||||||
|
{
|
||||||
|
return parser(i).accept(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -13025,7 +12955,7 @@ class basic_json
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
parser(detail::input_adapter_factory::create(first, last), cb).parse(true, result);
|
parser(detail::input_adapter(first, last), cb).parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13035,76 +12965,7 @@ class basic_json
|
||||||
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
||||||
static bool accept(IteratorType first, IteratorType last)
|
static bool accept(IteratorType first, IteratorType last)
|
||||||
{
|
{
|
||||||
return parser(detail::input_adapter_factory::create(first, last)).accept(true);
|
return parser(detail::input_adapter(first, last)).accept(true);
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief deserialize from a container with contiguous storage
|
|
||||||
|
|
||||||
This function reads from a container with contiguous storage of 1-byte
|
|
||||||
values. Compatible container types include `std::vector`, `std::string`,
|
|
||||||
`std::array`, and `std::initializer_list`. User-defined containers can be
|
|
||||||
used as long as they implement random-access iterators and a contiguous
|
|
||||||
storage.
|
|
||||||
|
|
||||||
@pre The container storage is contiguous. Violating this precondition
|
|
||||||
yields undefined behavior. **This precondition is enforced with an
|
|
||||||
assertion.**
|
|
||||||
@pre Each element of the container has a size of 1 byte. Violating this
|
|
||||||
precondition yields undefined behavior. **This precondition is enforced
|
|
||||||
with a static assertion.**
|
|
||||||
|
|
||||||
@warning There is no way to enforce all preconditions at compile-time. If
|
|
||||||
the function is called with a noncompliant container and with
|
|
||||||
assertions switched off, the behavior is undefined and will most
|
|
||||||
likely yield segmentation violation.
|
|
||||||
|
|
||||||
@tparam ContiguousContainer container type with contiguous storage
|
|
||||||
@param[in] c container to read from
|
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
|
||||||
which is used to control the deserialization by filtering unwanted values
|
|
||||||
(optional)
|
|
||||||
|
|
||||||
@return result of the deserialization
|
|
||||||
|
|
||||||
@throw parse_error.101 in case of an unexpected token
|
|
||||||
@throw parse_error.102 if to_unicode fails or surrogate error
|
|
||||||
@throw parse_error.103 if to_unicode fails
|
|
||||||
|
|
||||||
@complexity Linear in the length of the input. The parser is a predictive
|
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
|
||||||
@a cb has a super-linear complexity.
|
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
|
||||||
|
|
||||||
@liveexample{The example below demonstrates the `parse()` function reading
|
|
||||||
from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
|
|
||||||
|
|
||||||
@since version 2.0.3
|
|
||||||
*/
|
|
||||||
template<class ContiguousContainer, typename std::enable_if<
|
|
||||||
not std::is_pointer<ContiguousContainer>::value and
|
|
||||||
std::is_base_of<
|
|
||||||
std::random_access_iterator_tag,
|
|
||||||
typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
|
|
||||||
, int>::type = 0>
|
|
||||||
static basic_json parse(const ContiguousContainer& c,
|
|
||||||
const parser_callback_t cb = nullptr)
|
|
||||||
{
|
|
||||||
// delegate the call to the iterator-range parse overload
|
|
||||||
return parse(std::begin(c), std::end(c), cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ContiguousContainer, typename std::enable_if<
|
|
||||||
not std::is_pointer<ContiguousContainer>::value and
|
|
||||||
std::is_base_of<
|
|
||||||
std::random_access_iterator_tag,
|
|
||||||
typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
|
|
||||||
, int>::type = 0>
|
|
||||||
static bool accept(const ContiguousContainer& c)
|
|
||||||
{
|
|
||||||
// delegate the call to the iterator-range accept overload
|
|
||||||
return accept(std::begin(c), std::end(c));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -13117,7 +12978,7 @@ class basic_json
|
||||||
JSON_DEPRECATED
|
JSON_DEPRECATED
|
||||||
friend std::istream& operator<<(basic_json& j, std::istream& i)
|
friend std::istream& operator<<(basic_json& j, std::istream& i)
|
||||||
{
|
{
|
||||||
parser(detail::input_adapter_factory::create(i)).parse(false, j);
|
parser(detail::input_adapter(i)).parse(false, j);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13148,7 +13009,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
friend std::istream& operator>>(std::istream& i, basic_json& j)
|
friend std::istream& operator>>(std::istream& i, basic_json& j)
|
||||||
{
|
{
|
||||||
parser(detail::input_adapter_factory::create(i)).parse(false, j);
|
parser(detail::input_adapter(i)).parse(false, j);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13478,7 +13339,7 @@ class basic_json
|
||||||
static basic_json from_cbor(const std::vector<uint8_t>& v,
|
static basic_json from_cbor(const std::vector<uint8_t>& v,
|
||||||
const std::size_t start_index = 0)
|
const std::size_t start_index = 0)
|
||||||
{
|
{
|
||||||
binary_reader br(detail::input_adapter_factory::create(v.begin() + static_cast<difference_type>(start_index), v.end()));
|
binary_reader br(detail::input_adapter(v.begin() + static_cast<difference_type>(start_index), v.end()));
|
||||||
return br.parse_cbor();
|
return br.parse_cbor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13553,7 +13414,7 @@ class basic_json
|
||||||
static basic_json from_msgpack(const std::vector<uint8_t>& v,
|
static basic_json from_msgpack(const std::vector<uint8_t>& v,
|
||||||
const std::size_t start_index = 0)
|
const std::size_t start_index = 0)
|
||||||
{
|
{
|
||||||
binary_reader br(detail::input_adapter_factory::create(v.begin() + static_cast<difference_type>(start_index), v.end()));
|
binary_reader br(detail::input_adapter(v.begin() + static_cast<difference_type>(start_index), v.end()));
|
||||||
return br.parse_msgpack();
|
return br.parse_msgpack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ using nlohmann::json;
|
||||||
json::lexer::token_type scan_string(const char* s);
|
json::lexer::token_type scan_string(const char* s);
|
||||||
json::lexer::token_type scan_string(const char* s)
|
json::lexer::token_type scan_string(const char* s)
|
||||||
{
|
{
|
||||||
return json::lexer(nlohmann::detail::input_adapter_factory::create(s)).scan();
|
return json::lexer(nlohmann::detail::input_adapter(s)).scan();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("lexer class")
|
TEST_CASE("lexer class")
|
||||||
|
|
|
@ -40,13 +40,13 @@ bool accept_helper(const std::string& s);
|
||||||
json parser_helper(const std::string& s)
|
json parser_helper(const std::string& s)
|
||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
json::parser(nlohmann::detail::input_adapter_factory::create(s)).parse(true, j);
|
json::parser(nlohmann::detail::input_adapter(s)).parse(true, j);
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool accept_helper(const std::string& s)
|
bool accept_helper(const std::string& s)
|
||||||
{
|
{
|
||||||
return json::parser(nlohmann::detail::input_adapter_factory::create(s)).accept(true);
|
return json::parser(nlohmann::detail::input_adapter(s)).accept(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("parser class")
|
TEST_CASE("parser class")
|
||||||
|
@ -1009,7 +1009,7 @@ TEST_CASE("parser class")
|
||||||
case ('r'):
|
case ('r'):
|
||||||
case ('t'):
|
case ('t'):
|
||||||
{
|
{
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s.c_str()))).accept());
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s.c_str()))).accept());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1022,7 +1022,7 @@ TEST_CASE("parser class")
|
||||||
// any other combination of backslash and character is invalid
|
// any other combination of backslash and character is invalid
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s.c_str()))).accept() == false);
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s.c_str()))).accept() == false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1081,27 +1081,27 @@ TEST_CASE("parser class")
|
||||||
if (valid(c))
|
if (valid(c))
|
||||||
{
|
{
|
||||||
CAPTURE(s1);
|
CAPTURE(s1);
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s1.c_str()))).accept());
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s1.c_str()))).accept());
|
||||||
CAPTURE(s2);
|
CAPTURE(s2);
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s2.c_str()))).accept());
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s2.c_str()))).accept());
|
||||||
CAPTURE(s3);
|
CAPTURE(s3);
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s3.c_str()))).accept());
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s3.c_str()))).accept());
|
||||||
CAPTURE(s4);
|
CAPTURE(s4);
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s4.c_str()))).accept());
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s4.c_str()))).accept());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CAPTURE(s1);
|
CAPTURE(s1);
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s1.c_str()))).accept() == false);
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s1.c_str()))).accept() == false);
|
||||||
|
|
||||||
CAPTURE(s2);
|
CAPTURE(s2);
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s2.c_str()))).accept() == false);
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s2.c_str()))).accept() == false);
|
||||||
|
|
||||||
CAPTURE(s3);
|
CAPTURE(s3);
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s3.c_str()))).accept() == false);
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s3.c_str()))).accept() == false);
|
||||||
|
|
||||||
CAPTURE(s4);
|
CAPTURE(s4);
|
||||||
CHECK(json::parser(nlohmann::detail::input_adapter_factory::create(std::string(s4.c_str()))).accept() == false);
|
CHECK(json::parser(nlohmann::detail::input_adapter(std::string(s4.c_str()))).accept() == false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1311,7 @@ TEST_CASE("parser class")
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
|
std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
|
||||||
json j;
|
json j;
|
||||||
json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
|
json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);
|
||||||
CHECK(j == json(true));
|
CHECK(j == json(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1319,7 +1319,7 @@ TEST_CASE("parser class")
|
||||||
{
|
{
|
||||||
std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
|
std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
|
||||||
json j;
|
json j;
|
||||||
json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
|
json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);
|
||||||
CHECK(j == json(true));
|
CHECK(j == json(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1327,7 +1327,7 @@ TEST_CASE("parser class")
|
||||||
{
|
{
|
||||||
uint8_t v[] = {'t', 'r', 'u', 'e'};
|
uint8_t v[] = {'t', 'r', 'u', 'e'};
|
||||||
json j;
|
json j;
|
||||||
json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
|
json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);
|
||||||
CHECK(j == json(true));
|
CHECK(j == json(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1340,7 +1340,7 @@ TEST_CASE("parser class")
|
||||||
{
|
{
|
||||||
std::string v = {'t', 'r', 'u', 'e'};
|
std::string v = {'t', 'r', 'u', 'e'};
|
||||||
json j;
|
json j;
|
||||||
json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
|
json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);
|
||||||
CHECK(j == json(true));
|
CHECK(j == json(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,7 +1348,7 @@ TEST_CASE("parser class")
|
||||||
{
|
{
|
||||||
std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
|
std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
|
||||||
json j;
|
json j;
|
||||||
json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
|
json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);
|
||||||
CHECK(j == json(true));
|
CHECK(j == json(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1356,7 +1356,7 @@ TEST_CASE("parser class")
|
||||||
{
|
{
|
||||||
std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'};
|
std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'};
|
||||||
json j;
|
json j;
|
||||||
json::parser(nlohmann::detail::input_adapter_factory::create(std::begin(v), std::end(v))).parse(true, j);
|
json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);
|
||||||
CHECK(j == json(true));
|
CHECK(j == json(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue