mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 13:44:06 +00:00
Refactor value_builder
This commit is contained in:
parent
a342c936e4
commit
a90527ca7b
@ -165,9 +165,7 @@ extensions:
|
||||
[Skip UTF-8 Validation]
|
||||
[
|
||||
UTF-8 byte sequences appearing within strings
|
||||
are not checked for validity
|
||||
[br]
|
||||
(as defined by
|
||||
are not checked for validity (as defined by
|
||||
[@https://www.unicode.org/versions/Unicode13.0.0/UnicodeStandard-13.0.pdf The Unicode Standard Version 13.0 Section 3.9]).
|
||||
]
|
||||
[
|
||||
|
@ -104,6 +104,7 @@
|
||||
<member><link linkend="json.ref.boost__json__error_code">error_code</link></member>
|
||||
<member><link linkend="json.ref.boost__json__error_condition">error_condition</link></member>
|
||||
<member><link linkend="json.ref.boost__json__generic_category">generic_category</link></member>
|
||||
<member><link linkend="json.ref.boost__json__memory_resource">memory_resource</link></member>
|
||||
<member><link linkend="json.ref.boost__json__string_view">string_view</link></member>
|
||||
<member><link linkend="json.ref.boost__json__system_error">system_error</link></member>
|
||||
</simplelist>
|
||||
|
@ -7,6 +7,11 @@ INPUT = \
|
||||
$(LIB_DIR)/include/boost/json/detail/basic_parser.hpp \
|
||||
$(LIB_DIR)/include/boost/pilfer.hpp
|
||||
|
||||
# $(LIB_DIR)/include/boost/json/error.hpp \
|
||||
# $(LIB_DIR)/include/boost/json/string_view.hpp \
|
||||
# $(LIB_DIR)/include/boost/json/value_builder.hpp
|
||||
|
||||
|
||||
ALIASES += esafe="@par Exception Safety"
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
/*
|
||||
This example verifies that a file contains valid JSON.
|
||||
It is implementing by subclassing basic_parser
|
||||
*/
|
||||
|
||||
#include <boost/json.hpp>
|
||||
|
@ -28,17 +28,13 @@ class value_ref;
|
||||
/** A dynamically sized array of JSON values
|
||||
|
||||
This is the type used to represent JSON array values. It
|
||||
is modeled for equivalence to `std::vector<value>`.
|
||||
|
||||
<br>
|
||||
is modeled for equivalence to `std::vector<value>`.\n
|
||||
|
||||
The elements are stored contiguously, which means that
|
||||
elements can be accessed not only through iterators, but
|
||||
also using offsets to regular pointers to elements. A
|
||||
pointer to an element of an @ref array may be passed to
|
||||
any function that expects a pointer to @ref value.
|
||||
|
||||
<br>
|
||||
any function that expects a pointer to @ref value.\n
|
||||
|
||||
The storage of the array is handled automatically, being
|
||||
expanded and contracted as needed. Arrays usually occupy
|
||||
@ -48,16 +44,12 @@ class value_ref;
|
||||
is inserted, but only when the additional memory is used
|
||||
up. The total amount of allocated memory can be queried
|
||||
using the @ref capacity function. Extra memory can be
|
||||
relinquished by calling @ref shrink_to_fit.
|
||||
|
||||
<br>
|
||||
relinquished by calling @ref shrink_to_fit.\n
|
||||
|
||||
Reallocations are usually costly operations in terms of
|
||||
performance. The @ref reserve function can be used to
|
||||
eliminate reallocations if the number of elements is
|
||||
known beforehand.
|
||||
|
||||
<br>
|
||||
known beforehand.\n
|
||||
|
||||
The complexity (efficiency) of common operations on
|
||||
arrays is as follows:
|
||||
@ -99,6 +91,12 @@ class array
|
||||
class undo_construct;
|
||||
class undo_insert;
|
||||
|
||||
friend class value;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
explicit
|
||||
array(detail::unchecked_array&& ua);
|
||||
|
||||
public:
|
||||
/// The type used to represent unsigned integers
|
||||
using size_type = std::size_t;
|
||||
@ -155,13 +153,6 @@ public:
|
||||
destroy();
|
||||
}
|
||||
|
||||
#ifndef BOOST_JSON_DOCS
|
||||
// private
|
||||
explicit
|
||||
BOOST_JSON_DECL
|
||||
array(detail::unchecked_array&& ua);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
/** Default constructor.
|
||||
|
@ -39,9 +39,7 @@ namespace json {
|
||||
JSON is presented to the parser by one or more calls
|
||||
to @ref write_some. The parsing events are realized
|
||||
through member function calls to a handler passed as
|
||||
an argument to the write function.
|
||||
|
||||
<br>
|
||||
an argument to the write function.\n
|
||||
|
||||
The parser may dynamically allocate intermediate
|
||||
storage as needed to accommodate the nesting level
|
||||
@ -59,9 +57,7 @@ namespace json {
|
||||
function @ref parse. This class is designed for
|
||||
users who wish to perform custom actions instead of
|
||||
building a @ref value. For example, to produce a
|
||||
DOM from an external library.
|
||||
|
||||
<br>
|
||||
DOM from an external library.\n
|
||||
|
||||
To use this class it is necessary to create a derived
|
||||
class which calls @ref reset at the beginning of
|
||||
@ -378,9 +374,7 @@ public:
|
||||
parsing event. The parse proceeds from the
|
||||
current state, which is at the beginning of a
|
||||
new JSON or in the middle of the current JSON
|
||||
if any characters were already parsed.
|
||||
|
||||
<br>
|
||||
if any characters were already parsed.\n
|
||||
|
||||
The characters in the buffer are processed
|
||||
starting from the beginning, until one of the
|
||||
@ -410,10 +404,8 @@ public:
|
||||
member function returns `false`, it must set
|
||||
the error code to a suitable value. This error
|
||||
code will be returned by the write function to
|
||||
the caller.
|
||||
|
||||
<br>
|
||||
|
||||
the caller.\n
|
||||
|
||||
The following declaration meets the parser's
|
||||
handler requirements:
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
struct key_value_pair;
|
||||
class key_value_pair;
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
@ -21,27 +21,119 @@
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
#ifndef BOOST_JSON_STANDALONE
|
||||
|
||||
/// The type of error code used by the library.
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
/// The type of error category used by the library.
|
||||
using error_category = boost::system::error_category;
|
||||
|
||||
/// The type of error condition used by the library.
|
||||
using error_condition = boost::system::error_condition;
|
||||
|
||||
/// The type of system error thrown by the library.
|
||||
using system_error = boost::system::system_error;
|
||||
|
||||
#ifdef BOOST_JSON_DOCS
|
||||
|
||||
/** The type of error code used by the library.
|
||||
|
||||
This type alias is set depending
|
||||
on how the library is configured:
|
||||
|
||||
@par Use with Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
not defined, this type will be an alias
|
||||
for `boost::system::error_code`.
|
||||
Compiling a program using the library will
|
||||
require Boost, and a compiler conforming
|
||||
to C++11 or later.
|
||||
|
||||
@par Use without Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
defined, this type will be an alias
|
||||
for `std::error_code`.
|
||||
Compiling a program using the library will
|
||||
require only a compiler conforming to C++17
|
||||
or later.
|
||||
*/
|
||||
using error_code = __see_below__;
|
||||
|
||||
/** The type of error category used by the library.
|
||||
|
||||
This type alias is set depending
|
||||
on how the library is configured:
|
||||
|
||||
@par Use with Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
not defined, this type will be an alias
|
||||
for `boost::system::error_category`.
|
||||
Compiling a program using the library will
|
||||
require Boost, and a compiler conforming
|
||||
to C++11 or later.
|
||||
|
||||
@par Use without Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
defined, this type will be an alias
|
||||
for `std::error_category`.
|
||||
Compiling a program using the library will
|
||||
require only a compiler conforming to C++17
|
||||
or later.
|
||||
*/
|
||||
using error_category = __see_below__;
|
||||
|
||||
/** The type of error condition used by the library.
|
||||
|
||||
This type alias is set depending
|
||||
on how the library is configured:
|
||||
|
||||
@par Use with Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
not defined, this type will be an alias
|
||||
for `boost::system::error_condition`.
|
||||
Compiling a program using the library will
|
||||
require Boost, and a compiler conforming
|
||||
to C++11 or later.
|
||||
|
||||
@par Use without Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
defined, this type will be an alias
|
||||
for `std::error_condition`.
|
||||
Compiling a program using the library will
|
||||
require only a compiler conforming to C++17
|
||||
or later.
|
||||
*/
|
||||
using error_condition = __see_below__;
|
||||
|
||||
/** The type of system error thrown by the library.
|
||||
|
||||
This type alias is set depending
|
||||
on how the library is configured:
|
||||
|
||||
@par Use with Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
not defined, this type will be an alias
|
||||
for `boost::system::system_error`.
|
||||
Compiling a program using the library will
|
||||
require Boost, and a compiler conforming
|
||||
to C++11 or later.
|
||||
|
||||
@par Use without Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
defined, this type will be an alias
|
||||
for `std::system_error`.
|
||||
Compiling a program using the library will
|
||||
require only a compiler conforming to C++17
|
||||
or later.
|
||||
*/
|
||||
using system_error = __see_below__;
|
||||
|
||||
/// Returns the generic error category used by the library.
|
||||
error_category const&
|
||||
generic_category();
|
||||
#else
|
||||
|
||||
#elif ! defined(BOOST_JSON_STANDALONE)
|
||||
|
||||
using error_code = boost::system::error_code;
|
||||
using error_category = boost::system::error_category;
|
||||
using error_condition = boost::system::error_condition;
|
||||
using system_error = boost::system::system_error;
|
||||
using boost::system::generic_category;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
|
@ -73,13 +73,6 @@ public:
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
|
||||
object::
|
||||
object(object_test const*)
|
||||
{
|
||||
object_impl impl(3, 1, 3, 0, sp_);
|
||||
impl_.swap(impl);
|
||||
}
|
||||
|
||||
object::
|
||||
object(detail::unchecked_object&& uo)
|
||||
: sp_(uo.storage())
|
||||
@ -90,6 +83,13 @@ object(detail::unchecked_object&& uo)
|
||||
impl_.build();
|
||||
}
|
||||
|
||||
object::
|
||||
object(object_test const*)
|
||||
{
|
||||
object_impl impl(3, 1, 3, 0, sp_);
|
||||
impl_.swap(impl);
|
||||
}
|
||||
|
||||
object::
|
||||
object(storage_ptr sp) noexcept
|
||||
: sp_(std::move(sp))
|
||||
|
@ -20,6 +20,194 @@
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_document_begin(
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_document_end(
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_object_begin(
|
||||
error_code&)
|
||||
{
|
||||
vb.begin_object();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_object_end(
|
||||
error_code&)
|
||||
{
|
||||
vb.end_object();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_array_begin(
|
||||
error_code&)
|
||||
{
|
||||
vb.begin_array();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_array_end(
|
||||
error_code&)
|
||||
{
|
||||
vb.end_array();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_key_part(
|
||||
string_view s,
|
||||
error_code&)
|
||||
{
|
||||
vb.insert_key_part(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_key(
|
||||
string_view s,
|
||||
error_code&)
|
||||
{
|
||||
vb.insert_key(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_string_part(
|
||||
string_view s,
|
||||
error_code&)
|
||||
{
|
||||
vb.insert_string_part(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_string(
|
||||
string_view s,
|
||||
error_code&)
|
||||
{
|
||||
vb.insert_string(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_number_part(
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_int64(
|
||||
std::int64_t i,
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
vb.insert_int64(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_uint64(
|
||||
std::uint64_t u,
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
vb.insert_uint64(u);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_double(
|
||||
double d,
|
||||
string_view,
|
||||
error_code&)
|
||||
{
|
||||
vb.insert_double(d);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_bool(
|
||||
bool b,
|
||||
error_code&)
|
||||
{
|
||||
vb.insert_bool(b);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_null(error_code&)
|
||||
{
|
||||
vb.insert_null();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_comment_part(
|
||||
string_view, error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parser::
|
||||
handler::
|
||||
on_comment(
|
||||
string_view, error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
parser::
|
||||
parser() noexcept
|
||||
: parser(
|
||||
@ -122,12 +310,12 @@ value
|
||||
parser::
|
||||
release()
|
||||
{
|
||||
/*
|
||||
// VFALCO Do we need to put the throw
|
||||
// in a separate raise() function?
|
||||
if(! p_.is_complete())
|
||||
BOOST_THROW_EXCEPTION(
|
||||
std::logic_error(
|
||||
"no value"));
|
||||
*/
|
||||
return p_.handler().vb.release();
|
||||
}
|
||||
|
||||
|
@ -98,56 +98,7 @@ reset(storage_ptr sp) noexcept
|
||||
clear();
|
||||
sp_ = std::move(sp);
|
||||
lev_.st = state::begin;
|
||||
}
|
||||
|
||||
value
|
||||
value_builder::
|
||||
release()
|
||||
{
|
||||
// An exception here means that the value
|
||||
// was not properly constructed. For example,
|
||||
// an array or object was not closed, or
|
||||
// there was no top level value.
|
||||
if( lev_.st != state::top ||
|
||||
lev_.count != 1)
|
||||
BOOST_THROW_EXCEPTION(
|
||||
std::logic_error(
|
||||
"no value"));
|
||||
auto ua = pop_array();
|
||||
BOOST_ASSERT(rs_.empty());
|
||||
union U
|
||||
{
|
||||
value v;
|
||||
U(){}
|
||||
~U(){}
|
||||
};
|
||||
U u;
|
||||
ua.relocate(&u.v);
|
||||
lev_.st = state::need_reset;
|
||||
sp_ = {};
|
||||
return pilfer(u.v);
|
||||
}
|
||||
|
||||
void
|
||||
value_builder::
|
||||
clear() noexcept
|
||||
{
|
||||
destroy();
|
||||
rs_.clear();
|
||||
lev_.count = 0;
|
||||
key_size_ = 0;
|
||||
str_size_ = 0;
|
||||
lev_.st = state::need_reset;
|
||||
sp_ = {};
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
bool
|
||||
value_builder::
|
||||
on_document_begin(
|
||||
error_code&)
|
||||
{
|
||||
// reset() must be called before
|
||||
// building every new top level value.
|
||||
BOOST_ASSERT(lev_.st == state::begin);
|
||||
@ -161,24 +112,86 @@ on_document_begin(
|
||||
// inside a notional 1-element array.
|
||||
rs_.add(sizeof(value));
|
||||
lev_.st = state::top;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
value
|
||||
value_builder::
|
||||
on_document_end(error_code&)
|
||||
release()
|
||||
{
|
||||
// If this goes off, then an
|
||||
// array or object was never finished.
|
||||
// array or object was never closed.
|
||||
BOOST_ASSERT(lev_.st == state::top);
|
||||
BOOST_ASSERT(lev_.count == 1);
|
||||
return true;
|
||||
|
||||
auto ua = pop_array();
|
||||
BOOST_ASSERT(rs_.empty());
|
||||
union U
|
||||
{
|
||||
value v;
|
||||
U(){}
|
||||
~U(){}
|
||||
};
|
||||
U u;
|
||||
ua.relocate(&u.v);
|
||||
lev_.st = state::need_reset;
|
||||
|
||||
// give up the resource in case
|
||||
// it uses shared ownership.
|
||||
sp_ = {};
|
||||
|
||||
return pilfer(u.v);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_object_begin(error_code&)
|
||||
clear() noexcept
|
||||
{
|
||||
destroy();
|
||||
rs_.clear();
|
||||
lev_.count = 0;
|
||||
key_size_ = 0;
|
||||
str_size_ = 0;
|
||||
lev_.st = state::need_reset;
|
||||
|
||||
// give up the resource in case
|
||||
// it uses shared ownership.
|
||||
sp_ = {};
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
void
|
||||
value_builder::
|
||||
begin_array()
|
||||
{
|
||||
// prevent splits from exceptions
|
||||
rs_.prepare(
|
||||
sizeof(level) +
|
||||
sizeof(value) +
|
||||
alignof(value) - 1);
|
||||
push(lev_);
|
||||
lev_.align =
|
||||
detail::align_to<value>(rs_);
|
||||
rs_.add(sizeof(value));
|
||||
lev_.count = 0;
|
||||
lev_.st = state::arr;
|
||||
}
|
||||
|
||||
void
|
||||
value_builder::
|
||||
end_array()
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
lev_.st == state::arr);
|
||||
auto ua = pop_array();
|
||||
rs_.subtract(lev_.align);
|
||||
pop(lev_);
|
||||
emplace(std::move(ua));
|
||||
}
|
||||
|
||||
void
|
||||
value_builder::
|
||||
begin_object()
|
||||
{
|
||||
// prevent splits from exceptions
|
||||
rs_.prepare(
|
||||
@ -192,123 +205,65 @@ on_object_begin(error_code&)
|
||||
object::value_type));
|
||||
lev_.count = 0;
|
||||
lev_.st = state::obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_object_end(
|
||||
error_code& ec)
|
||||
end_object()
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
lev_.st == state::obj);
|
||||
auto uo = pop_object();
|
||||
rs_.subtract(lev_.align);
|
||||
pop(lev_);
|
||||
return emplace(
|
||||
ec, std::move(uo));
|
||||
emplace(std::move(uo));
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_array_begin(error_code&)
|
||||
insert_key_part(
|
||||
string_view s)
|
||||
{
|
||||
// prevent splits from exceptions
|
||||
rs_.prepare(
|
||||
sizeof(level) +
|
||||
sizeof(value) +
|
||||
alignof(value) - 1);
|
||||
push(lev_);
|
||||
lev_.align =
|
||||
detail::align_to<value>(rs_);
|
||||
rs_.add(sizeof(value));
|
||||
lev_.count = 0;
|
||||
lev_.st = state::arr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
value_builder::
|
||||
on_array_end(
|
||||
error_code& ec)
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
lev_.st == state::arr);
|
||||
auto ua = pop_array();
|
||||
rs_.subtract(lev_.align);
|
||||
pop(lev_);
|
||||
return emplace(
|
||||
ec, std::move(ua));
|
||||
}
|
||||
|
||||
bool
|
||||
value_builder::
|
||||
on_key_part(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
{
|
||||
if( s.size() >
|
||||
string::max_size() - key_size_)
|
||||
{
|
||||
ec = error::key_too_large;
|
||||
return false;
|
||||
}
|
||||
push_chars(s);
|
||||
key_size_ += static_cast<
|
||||
std::uint32_t>(s.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_key(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
insert_key(
|
||||
string_view s)
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
lev_.st == state::obj);
|
||||
if(! on_key_part(s, ec))
|
||||
return false;
|
||||
push_chars(s);
|
||||
key_size_ += static_cast<
|
||||
std::uint32_t>(s.size());
|
||||
push(key_size_);
|
||||
key_size_ = 0;
|
||||
lev_.st = state::key;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_string_part(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
insert_string_part(
|
||||
string_view s)
|
||||
{
|
||||
if( s.size() >
|
||||
string::max_size() - str_size_)
|
||||
{
|
||||
ec = error::string_too_large;
|
||||
return false;
|
||||
}
|
||||
push_chars(s);
|
||||
str_size_ += static_cast<
|
||||
std::uint32_t>(s.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_string(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
insert_string(
|
||||
string_view s)
|
||||
{
|
||||
if( s.size() >
|
||||
string::max_size() - str_size_)
|
||||
{
|
||||
ec = error::string_too_large;
|
||||
return false;
|
||||
}
|
||||
if(str_size_ == 0)
|
||||
{
|
||||
// fast path
|
||||
return emplace(ec, s, sp_);
|
||||
emplace(s, sp_);
|
||||
return;
|
||||
}
|
||||
|
||||
string str(sp_);
|
||||
@ -324,54 +279,46 @@ on_string(
|
||||
str.data() + sv.size(),
|
||||
s.data(), s.size());
|
||||
str.grow(sv.size() + s.size());
|
||||
return emplace(
|
||||
ec, std::move(str), sp_);
|
||||
emplace(std::move(str), sp_);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_int64(
|
||||
int64_t i,
|
||||
string_view,
|
||||
error_code& ec)
|
||||
insert_int64(
|
||||
int64_t i)
|
||||
{
|
||||
return emplace(ec, i, sp_);
|
||||
emplace(i, sp_);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_uint64(
|
||||
uint64_t u,
|
||||
string_view,
|
||||
error_code& ec)
|
||||
insert_uint64(
|
||||
uint64_t u)
|
||||
{
|
||||
return emplace(ec, u, sp_);
|
||||
emplace(u, sp_);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_double(
|
||||
double d,
|
||||
string_view,
|
||||
error_code& ec)
|
||||
insert_double(
|
||||
double d)
|
||||
{
|
||||
return emplace(ec, d, sp_);
|
||||
emplace(d, sp_);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_bool(
|
||||
bool b,
|
||||
error_code& ec)
|
||||
insert_bool(
|
||||
bool b)
|
||||
{
|
||||
return emplace(ec, b, sp_);
|
||||
emplace(b, sp_);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
on_null(error_code& ec)
|
||||
insert_null()
|
||||
{
|
||||
return emplace(ec, nullptr, sp_);
|
||||
emplace(nullptr, sp_);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -527,33 +474,19 @@ emplace_array(Args&&... args)
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
bool
|
||||
void
|
||||
value_builder::
|
||||
emplace(
|
||||
error_code& ec,
|
||||
Args&&... args)
|
||||
{
|
||||
if(lev_.st == state::key)
|
||||
{
|
||||
if(lev_.count <
|
||||
object::max_size())
|
||||
{
|
||||
emplace_object(std::forward<
|
||||
Args>(args)...);
|
||||
return true;
|
||||
}
|
||||
ec = error::object_too_large;
|
||||
return false;
|
||||
emplace_object(
|
||||
std::forward<Args>(args)...);
|
||||
return;
|
||||
}
|
||||
if(lev_.count <
|
||||
array::max_size())
|
||||
{
|
||||
emplace_array(std::forward<
|
||||
Args>(args)...);
|
||||
return true;
|
||||
}
|
||||
ec = error::array_too_large;
|
||||
return false;
|
||||
emplace_array(
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
@ -20,9 +20,35 @@
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
#ifndef BOOST_JSON_STANDALONE
|
||||
#ifdef BOOST_JSON_DOCS
|
||||
|
||||
/** The type of memory resource used by the library.
|
||||
|
||||
This type alias is set depending
|
||||
on how the library is configured:
|
||||
|
||||
@par Use with Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
not defined, this type will be an alias
|
||||
for `boost::container::pmr::memory_resource`.
|
||||
Compiling a program using the library will
|
||||
require Boost, and a compiler conforming
|
||||
to C++11 or later.
|
||||
|
||||
@par Use without Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
defined, this type will be an alias
|
||||
for `std::pmr::memory_resource`.
|
||||
Compiling a program using the library will
|
||||
require only a compiler conforming to C++17
|
||||
or later.
|
||||
*/
|
||||
using memory_resource = __see_below__;
|
||||
|
||||
#elif ! defined(BOOST_JSON_STANDALONE)
|
||||
|
||||
/// The type of memory_resource used by the library.
|
||||
using memory_resource = boost::container::pmr::memory_resource;
|
||||
|
||||
#else
|
||||
|
@ -35,24 +35,18 @@ class object_test;
|
||||
/** A dynamically sized associative container of JSON key/value pairs.
|
||||
|
||||
This is an associative container whose elements
|
||||
are key/value pairs with unique keys.
|
||||
|
||||
<br>
|
||||
are key/value pairs with unique keys.\n
|
||||
|
||||
The elements are stored contiguously, which means that
|
||||
elements can be accessed not only through iterators, but
|
||||
also using offsets to regular pointers to elements. A
|
||||
pointer to an element of an @ref object may be passed to
|
||||
any function that expects a pointer to
|
||||
@ref key_value_pair.
|
||||
|
||||
<br>
|
||||
@ref key_value_pair.\n
|
||||
|
||||
The container also maintains an internal index to speed
|
||||
up find operations, reducing the average complexity
|
||||
for most lookups and insertions
|
||||
|
||||
<br>
|
||||
for most lookups and insertions.\n
|
||||
|
||||
Reallocations are usually costly operations in terms of
|
||||
performance, as elements are copied and the internal
|
||||
@ -109,7 +103,14 @@ class object
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
friend class value;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
explicit
|
||||
object(detail::unchecked_object&& uo);
|
||||
|
||||
friend class object_test;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
object(object_test const*);
|
||||
|
||||
@ -177,13 +178,6 @@ public:
|
||||
impl_.destroy(sp_);
|
||||
}
|
||||
|
||||
#ifndef BOOST_JSON_DOCS
|
||||
// private
|
||||
BOOST_JSON_DECL
|
||||
explicit
|
||||
object(detail::unchecked_object&& uo);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
/** Default constructor.
|
||||
@ -1210,14 +1204,13 @@ public:
|
||||
|
||||
Returns a reference to the value that is mapped
|
||||
to a key equivalent to key, performing an insertion
|
||||
of a null value if such key does not already exist.
|
||||
<br>
|
||||
of a null value if such key does not already exist.\n
|
||||
|
||||
If an insertion occurs and results in a rehashing of
|
||||
the container, all iterators are invalidated. Otherwise
|
||||
iterators are not affected. References are not
|
||||
invalidated. Rehashing occurs only if the new
|
||||
number of elements is greater than
|
||||
@ref capacity().
|
||||
number of elements is greater than @ref capacity().
|
||||
|
||||
@par Complexity
|
||||
|
||||
|
@ -82,95 +82,24 @@ class parser
|
||||
{
|
||||
}
|
||||
|
||||
bool on_document_begin(error_code& ec)
|
||||
{
|
||||
return vb.on_document_begin(ec);
|
||||
}
|
||||
|
||||
bool on_document_end(error_code& ec)
|
||||
{
|
||||
return vb.on_document_end(ec);
|
||||
}
|
||||
|
||||
bool on_object_begin(error_code& ec)
|
||||
{
|
||||
return vb.on_object_begin(ec);
|
||||
}
|
||||
|
||||
bool on_object_end(error_code& ec)
|
||||
{
|
||||
return vb.on_object_end(ec);
|
||||
}
|
||||
|
||||
bool on_array_begin(error_code& ec)
|
||||
{
|
||||
return vb.on_array_begin(ec);
|
||||
}
|
||||
|
||||
bool on_array_end(error_code& ec)
|
||||
{
|
||||
return vb.on_array_end(ec);
|
||||
}
|
||||
|
||||
bool on_key_part(string_view s, error_code& ec)
|
||||
{
|
||||
return vb.on_key_part(s, ec);
|
||||
}
|
||||
|
||||
bool on_key(string_view s, error_code& ec)
|
||||
{
|
||||
return vb.on_key(s, ec);
|
||||
}
|
||||
|
||||
bool on_string_part(string_view s, error_code& ec)
|
||||
{
|
||||
return vb.on_string_part(s, ec);
|
||||
}
|
||||
|
||||
bool on_string(string_view s, error_code& ec)
|
||||
{
|
||||
return vb.on_string(s, ec);
|
||||
}
|
||||
|
||||
bool on_number_part(string_view s, error_code& ec)
|
||||
{
|
||||
return vb.on_number_part(s, ec);
|
||||
}
|
||||
|
||||
bool on_int64(std::int64_t i, string_view, error_code& ec)
|
||||
{
|
||||
return vb.on_int64(i, {}, ec);
|
||||
}
|
||||
|
||||
bool on_uint64(std::uint64_t u, string_view, error_code& ec)
|
||||
{
|
||||
return vb.on_uint64(u, {}, ec);
|
||||
}
|
||||
|
||||
bool on_double(double d, string_view, error_code& ec)
|
||||
{
|
||||
return vb.on_double(d, {}, ec);
|
||||
}
|
||||
|
||||
bool on_bool(bool b, error_code& ec)
|
||||
{
|
||||
return vb.on_bool(b, ec);
|
||||
}
|
||||
|
||||
bool on_null(error_code& ec)
|
||||
{
|
||||
return vb.on_null(ec);
|
||||
}
|
||||
|
||||
bool on_comment_part(string_view, error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool on_comment(string_view, error_code&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
inline bool on_document_begin(error_code& ec);
|
||||
inline bool on_document_end(error_code& ec);
|
||||
inline bool on_object_begin(error_code& ec);
|
||||
inline bool on_object_end(error_code& ec);
|
||||
inline bool on_array_begin(error_code& ec);
|
||||
inline bool on_array_end(error_code& ec);
|
||||
inline bool on_key_part(string_view s, error_code& ec);
|
||||
inline bool on_key(string_view s, error_code& ec);
|
||||
inline bool on_string_part(string_view s, error_code& ec);
|
||||
inline bool on_string(string_view s, error_code& ec);
|
||||
inline bool on_number_part(string_view, error_code&);
|
||||
inline bool on_int64(std::int64_t i, string_view, error_code& ec);
|
||||
inline bool on_uint64(std::uint64_t u, string_view, error_code& ec);
|
||||
inline bool on_double(double d, string_view, error_code& ec);
|
||||
inline bool on_bool(bool b, error_code& ec);
|
||||
inline bool on_null(error_code& ec);
|
||||
inline bool on_comment_part(string_view, error_code&);
|
||||
inline bool on_comment(string_view, error_code&);
|
||||
};
|
||||
|
||||
basic_parser<handler> p_;
|
||||
@ -204,9 +133,7 @@ public:
|
||||
|
||||
@note
|
||||
Before any JSON can be parsed, the function
|
||||
@ref reset must be called.
|
||||
|
||||
<br>
|
||||
@ref reset must be called.\n
|
||||
|
||||
The `sp` parameter is only used to
|
||||
allocate intermediate storage; it will not be used
|
||||
@ -241,9 +168,7 @@ public:
|
||||
|
||||
@note
|
||||
Before any JSON can be parsed, the function
|
||||
@ref reset must be called.
|
||||
|
||||
<br>
|
||||
@ref reset must be called.\n
|
||||
|
||||
The `sp` parameter is only used to
|
||||
allocate intermediate storage; it will not be used
|
||||
@ -333,9 +258,7 @@ public:
|
||||
buffer. The parse proceeds from the current
|
||||
state, which is at the beginning of a new JSON
|
||||
or in the middle of the current JSON if any
|
||||
characters were already parsed.
|
||||
|
||||
<br>
|
||||
characters were already parsed.\n
|
||||
|
||||
The characters in the buffer are processed
|
||||
starting from the beginning, until one of the
|
||||
@ -384,9 +307,7 @@ public:
|
||||
buffer. The parse proceeds from the current
|
||||
state, which is at the beginning of a new JSON
|
||||
or in the middle of the current JSON if any
|
||||
characters were already parsed.
|
||||
|
||||
<br>
|
||||
characters were already parsed.\n
|
||||
|
||||
The characters in the buffer are processed
|
||||
starting from the beginning, until one of the
|
||||
|
@ -21,9 +21,35 @@
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
#ifndef BOOST_JSON_STANDALONE
|
||||
#ifdef BOOST_JSON_DOCS
|
||||
|
||||
/** The type of string view used by the library.
|
||||
|
||||
This type alias is set depending
|
||||
on how the library is configured:
|
||||
|
||||
@par Use with Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
not defined, this type will be an alias
|
||||
for `boost::string_view`.
|
||||
Compiling a program using the library will
|
||||
require Boost, and a compiler conforming
|
||||
to C++11 or later.
|
||||
|
||||
@par Use without Boost
|
||||
|
||||
If the macro `BOOST_JSON_STANDALONE` is
|
||||
defined, this type will be an alias
|
||||
for `std::string_view`.
|
||||
Compiling a program using the library will
|
||||
require only a compiler conforming to C++17
|
||||
or later.
|
||||
*/
|
||||
using string_view = __see_below__;
|
||||
|
||||
#elif ! defined(BOOST_JSON_STANDALONE)
|
||||
|
||||
/// The type of string view used by the library.
|
||||
using string_view = boost::string_view;
|
||||
|
||||
#else
|
||||
|
@ -76,6 +76,11 @@ class value
|
||||
struct undo;
|
||||
struct init_iter;
|
||||
|
||||
friend class value_builder;
|
||||
friend class key_value_pair;
|
||||
inline value(detail::unchecked_object&& uo);
|
||||
inline value(detail::unchecked_array&& ua);
|
||||
|
||||
public:
|
||||
/** Destructor.
|
||||
|
||||
@ -90,12 +95,6 @@ public:
|
||||
BOOST_JSON_DECL
|
||||
~value();
|
||||
|
||||
#ifndef BOOST_JSON_DOCS
|
||||
// private
|
||||
inline value(detail::unchecked_object&& uo);
|
||||
inline value(detail::unchecked_array&& ua);
|
||||
#endif
|
||||
|
||||
/** Default constructor.
|
||||
|
||||
The constructed value is null,
|
||||
@ -2670,8 +2669,9 @@ swap(value& lhs, value& rhs)
|
||||
This is the type of element used by the @ref object
|
||||
container.
|
||||
*/
|
||||
struct key_value_pair
|
||||
class key_value_pair
|
||||
{
|
||||
public:
|
||||
/** Copy assignment (deleted).
|
||||
*/
|
||||
key_value_pair&
|
||||
|
@ -22,34 +22,53 @@ namespace json {
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
/** A factory for building a value DOM.
|
||||
/** A factory for building a value.
|
||||
|
||||
A value builder implements an algorithm for
|
||||
efficiently constructing a @ref value from an
|
||||
external source (provided by the caller).
|
||||
|
||||
The builder uses a dynamically allocated internal
|
||||
storage to hold portions of the document, allowing
|
||||
complete objects and arrays to be constructed using
|
||||
a single allocation when their contents are
|
||||
eventually known. This internal storage is reused
|
||||
when creating multiple values with the same builder.
|
||||
It uses a dynamically allocated internal storage
|
||||
to hold portions of the document, allowing complete
|
||||
objects and arrays to be constructed using a single
|
||||
allocation when their contents are eventually known.
|
||||
This internal storage is reused when creating multiple
|
||||
values with the same builder. \n
|
||||
|
||||
To use the builder construct it with an optionally
|
||||
specified memory resource to use for the internal
|
||||
storage. Then call @ref reset once before building
|
||||
each complete DOM, optionally specifying the
|
||||
memory resource to use for the resulting @ref value.
|
||||
Once the reset function is called, the value may
|
||||
be built iteratively by calling the appropriate
|
||||
insertion functions as desired. After construction
|
||||
is finished, the caller can take ownership of the
|
||||
resulting value by calling @ref release.
|
||||
|
||||
The functions @ref on_document_begin and
|
||||
@ref on_document_end must be called exactly once
|
||||
at the beginning and at the end of construction.
|
||||
The remaining event handling functions are called
|
||||
according to their descriptions to build the document.
|
||||
@par Example
|
||||
|
||||
The following code constructs a @ref value which
|
||||
when serialized produces a JSON object with three
|
||||
elements.
|
||||
|
||||
@code
|
||||
value_builder vb;
|
||||
vb.reset();
|
||||
vb.begin_object();
|
||||
vb.insert_key("a");
|
||||
vb.insert_int64(1);
|
||||
vb.insert_key("b");
|
||||
vb.insert_null();
|
||||
vb.insert_key("c");
|
||||
vb.insert_string("hello");
|
||||
vb.end_object();
|
||||
assert( to_string(vb.release()) == "{\"a\":1,\"b\":null,\"c\":\"hello\"}" );
|
||||
@endcode
|
||||
*/
|
||||
class value_builder
|
||||
{
|
||||
enum class state : char;
|
||||
|
||||
struct level
|
||||
{
|
||||
std::uint32_t count;
|
||||
@ -66,30 +85,26 @@ class value_builder
|
||||
public:
|
||||
/** Destructor.
|
||||
|
||||
All dynamically allocated memory, including
|
||||
any partially built results, is freed.
|
||||
All dynamically allocated memory and
|
||||
partial or complete elements is freed.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
~value_builder();
|
||||
|
||||
/** Constructor.
|
||||
|
||||
Constructs a empty builder using the default
|
||||
memory resource, or the optionally specified
|
||||
@ref storage_ptr, to allocate intermediate storage.
|
||||
Constructs a empty builder. Before any
|
||||
@ref value can be built, the function
|
||||
@ref reset must be called.
|
||||
|
||||
@note
|
||||
Before any @ref value can be built,
|
||||
the function @ref start must be called.
|
||||
|
||||
<br>
|
||||
|
||||
The `sp` parameter is only used to
|
||||
allocate intermediate storage; it will not be used
|
||||
The `sp` parameter is only used to allocate
|
||||
intermediate storage; it will not be used
|
||||
for the @ref value returned by @ref release.
|
||||
|
||||
@param sp The @ref storage_ptr to use for
|
||||
intermediate storage allocations.
|
||||
@param sp A pointer to the @ref memory_resource
|
||||
to use for intermediate storage allocations. If
|
||||
this argument is omitted, the default memory
|
||||
resource is used.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
explicit
|
||||
@ -98,31 +113,32 @@ public:
|
||||
/** Reserve internal storage space.
|
||||
|
||||
This function reserves space for `n` bytes
|
||||
in the parser's internal temporary storage.
|
||||
in the builders's internal temporary storage.
|
||||
The request is only a hint to the
|
||||
implementation.
|
||||
implementation.
|
||||
|
||||
@par Exception Safety
|
||||
|
||||
Strong guarantee.
|
||||
|
||||
@param n The number of bytes to reserve. A
|
||||
good choices is `C * sizeof(value)` where
|
||||
`C` is the total number of @ref value elements
|
||||
in a typical parsed JSON.
|
||||
@param n The number of bytes to reserve.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
reserve(std::size_t n);
|
||||
|
||||
/** Prepare the builder for a new value.
|
||||
/** Prepare to build a new value.
|
||||
|
||||
This function must be called before building
|
||||
a new @ref value. Any previously existing full
|
||||
or partial values are destroyed, but internal
|
||||
a new @ref value. Any previously existing partial
|
||||
or complete elements are destroyed, but internal
|
||||
dynamically allocated memory is preserved which
|
||||
may be reused to build new values.
|
||||
|
||||
@par Exception Safety
|
||||
|
||||
No-throw guarantee.
|
||||
|
||||
@param sp A pointer to the @ref memory_resource
|
||||
to use for the resulting value. The builder will
|
||||
acquire shared ownership of the memory resource.
|
||||
@ -131,13 +147,16 @@ public:
|
||||
void
|
||||
reset(storage_ptr sp = {}) noexcept;
|
||||
|
||||
/** Return the parsed JSON as a @ref value.
|
||||
/** Return the completed value.
|
||||
|
||||
If @ref is_complete() returns `true`, then the
|
||||
parsed value is returned. Otherwise an
|
||||
exception is thrown.
|
||||
|
||||
@throw std::logic_error `! is_complete()`
|
||||
@par Exception Safety
|
||||
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@return The parsed value. Ownership of this
|
||||
value is transferred to the caller.
|
||||
@ -153,10 +172,12 @@ public:
|
||||
internal memory which may be reused on a
|
||||
subsequent parse.
|
||||
|
||||
@note
|
||||
After calling this function, it is necessary
|
||||
to call @ref start before building a new value.
|
||||
|
||||
After this call, it is necessary to call
|
||||
@ref start to parse a new JSON incrementally.
|
||||
@par Exception Safety
|
||||
|
||||
No-throw guarantee.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
@ -164,339 +185,245 @@ public:
|
||||
|
||||
//--------------------------------------------
|
||||
|
||||
/** Begin building a new value.
|
||||
/** Insert an array.
|
||||
|
||||
This function must be called exactly once
|
||||
after calling @ref reset, before any other
|
||||
event functions are invoked.
|
||||
This function opens a new, empty array
|
||||
which will be inserted into the result as
|
||||
the next element of the currently open array
|
||||
or object, or as the top-level element if
|
||||
no other elements exist.\n
|
||||
|
||||
@return `true` on success.
|
||||
After calling this function, elements
|
||||
are inserted into the array by calling
|
||||
the other insertion functions (including
|
||||
@ref begin_array and @ref begin_object).\n
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_document_begin(
|
||||
error_code& ec);
|
||||
void
|
||||
begin_array();
|
||||
|
||||
/** Finish building a new value.
|
||||
/** Insert an array.
|
||||
|
||||
This function must be called exactly once
|
||||
before calling @ref release, and after all
|
||||
event functions have been called.
|
||||
This function closes the current array,
|
||||
which must have been opened by a previously
|
||||
balanced call to @ref begin_array.
|
||||
The array is then inserted into the currently
|
||||
open array or object, or the top level if no
|
||||
enclosing array or object is open.
|
||||
|
||||
@return `true` on success.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_document_end(
|
||||
error_code& ec);
|
||||
void
|
||||
end_array();
|
||||
|
||||
/** Begin building an object.
|
||||
/** Insert an object.
|
||||
|
||||
This instructs the builder to begin building
|
||||
a new JSON object, either as the top-level
|
||||
element of the resulting value, or as the
|
||||
next element of the current object or array
|
||||
being built.
|
||||
This function opens a new, empty object
|
||||
which will be inserted into the result as
|
||||
the next element of the currently open array
|
||||
or object, or as the top-level element if
|
||||
no other elements exist.\n
|
||||
|
||||
@return `true` on success.
|
||||
After calling this function, elements are
|
||||
inserted into the object by first inserting
|
||||
the key using @ref insert_key and
|
||||
@ref insert_key_part, and then calling
|
||||
the other insertion functions (including
|
||||
@ref begin_object and @ref begin_array) to
|
||||
add the value corresponding to the key.\n
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_object_begin(
|
||||
error_code& ec);
|
||||
void
|
||||
begin_object();
|
||||
|
||||
/** Finish building an object.
|
||||
/** Insert an object.
|
||||
|
||||
This event function instructs the builder that
|
||||
the object currently being built, which was created
|
||||
by the last call to @ref on_object_begin, is finished.
|
||||
This function closes the current object,
|
||||
which must have been opened by a previously
|
||||
balanced call to @ref begin_object.
|
||||
The object is then inserted into the currently
|
||||
open array or object, or the top level if no
|
||||
enclosing array or object is open.
|
||||
|
||||
@return `true` on success.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_object_end(
|
||||
error_code& ec);
|
||||
void
|
||||
end_object();
|
||||
|
||||
/** Begin building an array.
|
||||
|
||||
This instructs the builder to begin building
|
||||
a new JSON array, either as the top-level
|
||||
element of the resulting value, or as the
|
||||
next element of the current object or array
|
||||
being built.
|
||||
|
||||
@return `true` on success.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_array_begin(
|
||||
error_code& ec);
|
||||
|
||||
/** Finish building an array.
|
||||
|
||||
This function instructs the builder that the
|
||||
array currently being built, which was created
|
||||
by the last call to @ref on_array_begin, is finished.
|
||||
|
||||
@return `true` on success.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_array_end(
|
||||
error_code& ec);
|
||||
|
||||
/** Continue creating a key.
|
||||
/** Set the key for the next value.
|
||||
|
||||
This function appends the specified characters
|
||||
to the key being built as the next element of
|
||||
a currently open object. If a key is not currently
|
||||
being built, the behavior is undefined.
|
||||
to the current key, which must be part of an
|
||||
open object. If a key is not currently being
|
||||
built or an object is not open, the behavior
|
||||
is undefined.
|
||||
|
||||
@return `true` on success.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@param s The characters to append. This may be empty.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_key_part(
|
||||
string_view s,
|
||||
error_code& ec);
|
||||
void
|
||||
insert_key_part(
|
||||
string_view s);
|
||||
|
||||
/** Finish creating a key.
|
||||
/** Set the key for the next value.
|
||||
|
||||
This function appends the specified characters
|
||||
to the key being built as the next element of
|
||||
a currently open object, and finishes construction
|
||||
of the key. If a key is not currently being built,
|
||||
the behavior is undefined.
|
||||
to the current key, which must be part of an
|
||||
open object. If a key is not currently being
|
||||
built or an object is not open, the behavior
|
||||
is undefined. After the characters are inserted,
|
||||
the key is finished and a value must be inserted
|
||||
next.
|
||||
|
||||
@return `true` on success.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@param s The characters to append. This may be empty.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_key(
|
||||
string_view s,
|
||||
error_code& ec);
|
||||
void
|
||||
insert_key(
|
||||
string_view s);
|
||||
|
||||
/** Begin or continue creating a string.
|
||||
/** Insert a string.
|
||||
|
||||
This function appends the specified characters
|
||||
to the string being built. If a string is not
|
||||
currently being built, then a new empty string
|
||||
is started.
|
||||
to the current string, which will be created if
|
||||
it did not already exist from an immediately
|
||||
prior call to @ref insert_string_part.
|
||||
|
||||
@return `true` on success.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@param s The characters to append. This may be empty.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_string_part(
|
||||
string_view s,
|
||||
error_code& ec);
|
||||
void
|
||||
insert_string_part(
|
||||
string_view s);
|
||||
|
||||
/** Create a string or finish creating a string.
|
||||
/** Insert a string.
|
||||
|
||||
This function appends the specified characters
|
||||
to the string being built. If a string is not
|
||||
currently being built, then a new string is created
|
||||
with the specified characters.
|
||||
to the current string, which will be created if
|
||||
it did not already exist from an immediately prior
|
||||
call to @ref insert_string_part.
|
||||
The string is then inserted into the currently
|
||||
open array or object, or the top level if no
|
||||
array or object is open.
|
||||
|
||||
@return `true` on success.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@param s The characters to append. This may be empty.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_string(
|
||||
string_view s,
|
||||
error_code& ec);
|
||||
void
|
||||
insert_string(
|
||||
string_view s);
|
||||
|
||||
/** Begin building a number from a string.
|
||||
/** Insert a number.
|
||||
|
||||
This instructs the builder to begin building
|
||||
a new JSON number, either as the top-level
|
||||
element of the resulting value, or as the
|
||||
next element of the current object or array
|
||||
being built.
|
||||
This function inserts a number into the currently
|
||||
open array or object, or the top level if no
|
||||
array or object is open.
|
||||
|
||||
@note This function has no effect and always
|
||||
returns `true`.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@return `true` on success.
|
||||
|
||||
@param s The characters to append. This may be empty.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
bool
|
||||
on_number_part(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
{
|
||||
(void)s;
|
||||
(void)ec;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Build a number.
|
||||
|
||||
This function builds a number from the specified
|
||||
value and adds it as the top-level element of the
|
||||
resulting value, or as the next element of the
|
||||
current object or array being built.
|
||||
|
||||
@return `true` on success.
|
||||
|
||||
@param i The integer to build.
|
||||
|
||||
@param s The characters to append. This value is ignored.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@param i The number to insert.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_int64(
|
||||
int64_t i,
|
||||
string_view s,
|
||||
error_code& ec);
|
||||
void
|
||||
insert_int64(
|
||||
int64_t i);
|
||||
|
||||
/** Build a number.
|
||||
/** Insert a number.
|
||||
|
||||
This function builds a number from the specified
|
||||
value and adds it as the top-level element of the
|
||||
resulting value, or as the next element of the
|
||||
current object or array being built.
|
||||
This function inserts a number into the currently
|
||||
open array or object, or the top level if no
|
||||
array or object is open.
|
||||
|
||||
@return `true` on success.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@param i The unsigned integer to build.
|
||||
|
||||
@param s The characters to append. This value is ignored.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@param u The number to insert.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_uint64(
|
||||
uint64_t u,
|
||||
string_view s,
|
||||
error_code& ec);
|
||||
void
|
||||
insert_uint64(
|
||||
uint64_t u);
|
||||
|
||||
/** Build a number.
|
||||
/** Insert a number.
|
||||
|
||||
This function builds a number from the specified
|
||||
value and adds it as the top-level element of the
|
||||
resulting value, or as the next element of the
|
||||
current object or array being built.
|
||||
This function inserts a number into the currently
|
||||
open array or object, or the top level if no
|
||||
array or object is open.
|
||||
|
||||
@return `true` on success.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@param i The floating point number to build.
|
||||
|
||||
@param s The characters to append. This value is ignored.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@param d The number to insert.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_double(
|
||||
double d,
|
||||
string_view s,
|
||||
error_code& ec);
|
||||
void
|
||||
insert_double(
|
||||
double d);
|
||||
|
||||
/** Build a boolean.
|
||||
/** Insert a boolean.
|
||||
|
||||
This function builds a boolean from the specified
|
||||
value and adds it as the top-level element of the
|
||||
resulting value, or as the next element of the
|
||||
current object or array being built.
|
||||
This function inserts a boolean into the currently
|
||||
open array or object, or the top level if no
|
||||
array or object is open.
|
||||
|
||||
@return `true` on success.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
|
||||
@param b The boolean to build.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@param b The boolean to insert.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_bool(
|
||||
bool b,
|
||||
error_code& ec);
|
||||
void
|
||||
insert_bool(
|
||||
bool b);
|
||||
|
||||
/** Build a null.
|
||||
|
||||
This function builds a null from the specified
|
||||
value and adds it as the top-level element of the
|
||||
resulting value, or as the next element of the
|
||||
current object or array being built.
|
||||
This function inserts a null into the currently
|
||||
open array or object, or the top level if no
|
||||
array or object is open.
|
||||
|
||||
@return `true` on success.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
@par Exception Safety
|
||||
Basic guarantee.
|
||||
Calls to `memory_resource::allocate` may throw.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
bool
|
||||
on_null(error_code& ec);
|
||||
|
||||
/** Specify part of comment.
|
||||
|
||||
This function has no effect and always returns `true`.
|
||||
|
||||
@param s The characters to append. This value is ignored.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
bool
|
||||
on_comment_part(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
{
|
||||
(void)s;
|
||||
(void)ec;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Specify a comment.
|
||||
|
||||
This function has no effect and always returns `true`.
|
||||
|
||||
@param s The characters to append. This value is ignored.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
bool
|
||||
on_comment(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
{
|
||||
(void)s;
|
||||
(void)ec;
|
||||
return true;
|
||||
}
|
||||
void
|
||||
insert_null();
|
||||
|
||||
private:
|
||||
inline
|
||||
@ -522,9 +449,8 @@ private:
|
||||
Args&&... args);
|
||||
|
||||
template<class... Args>
|
||||
bool
|
||||
void
|
||||
emplace(
|
||||
error_code& ec,
|
||||
Args&&... args);
|
||||
|
||||
template<class T>
|
||||
|
@ -10,6 +10,8 @@
|
||||
// Test that header file is self-contained.
|
||||
#include <boost/json/value_builder.hpp>
|
||||
|
||||
#include <boost/json/serializer.hpp>
|
||||
|
||||
#include "test_suite.hpp"
|
||||
|
||||
namespace boost {
|
||||
@ -21,13 +23,20 @@ public:
|
||||
void
|
||||
testBuilder()
|
||||
{
|
||||
error_code ec;
|
||||
value_builder vb;
|
||||
vb.reset();
|
||||
vb.on_document_begin(ec);
|
||||
vb.on_null(ec);
|
||||
vb.on_document_end(ec);
|
||||
vb.release();
|
||||
// This is from the javadoc
|
||||
|
||||
value_builder vb;
|
||||
vb.reset();
|
||||
vb.begin_object();
|
||||
vb.insert_key("a");
|
||||
vb.insert_int64(1);
|
||||
vb.insert_key("b");
|
||||
vb.insert_null();
|
||||
vb.insert_key("c");
|
||||
vb.insert_string("hello");
|
||||
vb.end_object();
|
||||
assert( to_string(vb.release()) == "{\"a\":1,\"b\":null,\"c\":\"hello\"}" );
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user