mirror of
https://github.com/boostorg/json.git
synced 2026-02-15 13:12:17 +00:00
value work
This commit is contained in:
@@ -18,18 +18,169 @@
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Special members
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
value::
|
||||
~value()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
value::
|
||||
value() noexcept
|
||||
: value(
|
||||
json::kind::null,
|
||||
default_storage())
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
value(storage_ptr sp) noexcept
|
||||
: value(
|
||||
json::kind::null,
|
||||
std::move(sp))
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
value(json::kind k) noexcept
|
||||
: value(
|
||||
k,
|
||||
default_storage())
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
value(
|
||||
json::kind k,
|
||||
storage_ptr sp) noexcept
|
||||
{
|
||||
switch(k)
|
||||
{
|
||||
case json::kind::object:
|
||||
::new(&obj_) object(
|
||||
std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::array:
|
||||
::new(&arr_) array(
|
||||
std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
::new(&str_) string(
|
||||
string::allocator_type(
|
||||
std::move(sp)));
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
::new(&nat_.num_) number;
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::boolean:
|
||||
case json::kind::null:
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
break;
|
||||
}
|
||||
kind_ = k;
|
||||
}
|
||||
|
||||
value::
|
||||
value(value const& other)
|
||||
: value(
|
||||
other,
|
||||
other.get_storage())
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
value(
|
||||
value const& other,
|
||||
storage_ptr sp)
|
||||
{
|
||||
switch(other.kind_)
|
||||
{
|
||||
case json::kind::object:
|
||||
::new(&obj_) object(
|
||||
other.obj_, std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::array:
|
||||
::new(&arr_) array(
|
||||
other.arr_, std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
// workaround for some stdlibs
|
||||
construct_string(
|
||||
other.str_,
|
||||
std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
::new(&nat_.num_) number(
|
||||
other.nat_.num_);
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::boolean:
|
||||
nat_.bool_ = other.nat_.bool_;
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::null:
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(sp));
|
||||
break;
|
||||
}
|
||||
kind_ = other.kind_;
|
||||
}
|
||||
|
||||
value::
|
||||
value(pilfered<value> p) noexcept
|
||||
{
|
||||
auto& other = p.get();
|
||||
switch(other.kind_)
|
||||
{
|
||||
case json::kind::object:
|
||||
relocate(&obj_, other.obj_);
|
||||
::new(&other.nat_.sp_) storage_ptr;
|
||||
break;
|
||||
|
||||
case json::kind::array:
|
||||
relocate(&arr_, other.arr_);
|
||||
::new(&other.nat_.sp_) storage_ptr;
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
relocate(&str_, other.str_);
|
||||
::new(&other.nat_.sp_) storage_ptr;
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
relocate(&nat_.num_, other.nat_.num_);
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(other.nat_.sp_));
|
||||
break;
|
||||
|
||||
case json::kind::boolean:
|
||||
nat_.bool_ = other.nat_.bool_;
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(other.nat_.sp_));
|
||||
break;
|
||||
|
||||
case json::kind::null:
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(other.nat_.sp_));
|
||||
break;
|
||||
}
|
||||
kind_ = other.kind_;
|
||||
other.kind_ = json::kind::null;
|
||||
}
|
||||
|
||||
value::
|
||||
value(value&& other) noexcept
|
||||
{
|
||||
@@ -94,109 +245,15 @@ value(
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
::new(&str_) string(
|
||||
// workaround for some stdlibs
|
||||
construct_string(
|
||||
std::move(other.str_),
|
||||
string::allocator_type(
|
||||
std::move(sp)));
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
relocate(&nat_.num_, other.nat_.num_);
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::boolean:
|
||||
nat_.bool_ = other.nat_.bool_;
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::null:
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(sp));
|
||||
break;
|
||||
}
|
||||
kind_ = other.kind_;
|
||||
}
|
||||
|
||||
value::
|
||||
value(pilfered<value> p) noexcept
|
||||
{
|
||||
auto& other = p.get();
|
||||
switch(other.kind_)
|
||||
{
|
||||
case json::kind::object:
|
||||
relocate(&obj_, other.obj_);
|
||||
::new(&other.nat_.sp_) storage_ptr;
|
||||
break;
|
||||
|
||||
case json::kind::array:
|
||||
relocate(&arr_, other.arr_);
|
||||
::new(&other.nat_.sp_) storage_ptr;
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
relocate(&str_, other.str_);
|
||||
::new(&other.nat_.sp_) storage_ptr;
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
relocate(&nat_.num_, other.nat_.num_);
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(other.nat_.sp_));
|
||||
break;
|
||||
|
||||
case json::kind::boolean:
|
||||
nat_.bool_ = other.nat_.bool_;
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(other.nat_.sp_));
|
||||
break;
|
||||
|
||||
case json::kind::null:
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(other.nat_.sp_));
|
||||
break;
|
||||
}
|
||||
kind_ = other.kind_;
|
||||
other.kind_ = json::kind::null;
|
||||
}
|
||||
|
||||
value::
|
||||
value(value const& other)
|
||||
: value(
|
||||
other,
|
||||
other.get_storage())
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
value(
|
||||
value const& other,
|
||||
storage_ptr sp)
|
||||
{
|
||||
switch(other.kind_)
|
||||
{
|
||||
case json::kind::object:
|
||||
::new(&obj_) object(
|
||||
other.obj_, std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::array:
|
||||
::new(&arr_) array(
|
||||
other.arr_, std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
::new(&str_) string(
|
||||
other.str_,
|
||||
string::allocator_type(
|
||||
std::move(sp)));
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
::new(&nat_.num_) number(
|
||||
other.nat_.num_);
|
||||
relocate(
|
||||
&nat_.num_, other.nat_.num_);
|
||||
::new(&nat_.sp_) storage_ptr(
|
||||
std::move(sp));
|
||||
break;
|
||||
@@ -220,7 +277,7 @@ value::
|
||||
operator=(value&& other)
|
||||
{
|
||||
undo u(this);
|
||||
move(
|
||||
::new(this) value(
|
||||
std::move(other),
|
||||
u.old.get_storage());
|
||||
u.commit = true;
|
||||
@@ -235,50 +292,18 @@ operator=(value const& other)
|
||||
return *this;
|
||||
|
||||
undo u(this);
|
||||
::new(this) value(
|
||||
other, u.old.get_storage());
|
||||
::new(this) value(other,
|
||||
u.old.get_storage());
|
||||
u.commit = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Construction and Assignment
|
||||
// Conversion
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
value::
|
||||
value() noexcept
|
||||
: value(
|
||||
json::kind::null,
|
||||
default_storage())
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
value(storage_ptr sp) noexcept
|
||||
: value(
|
||||
json::kind::null,
|
||||
std::move(sp))
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
value(json::kind k) noexcept
|
||||
: value(
|
||||
k,
|
||||
default_storage())
|
||||
{
|
||||
}
|
||||
|
||||
value::
|
||||
value(
|
||||
json::kind k,
|
||||
storage_ptr sp) noexcept
|
||||
{
|
||||
construct(k, std::move(sp));
|
||||
}
|
||||
|
||||
value::
|
||||
value(object obj) noexcept
|
||||
: obj_(std::move(obj))
|
||||
@@ -308,7 +333,9 @@ value::
|
||||
value(
|
||||
array arr,
|
||||
storage_ptr sp)
|
||||
: arr_(std::move(arr), std::move(sp))
|
||||
: arr_(
|
||||
std::move(arr),
|
||||
std::move(sp))
|
||||
, kind_(json::kind::array)
|
||||
{
|
||||
}
|
||||
@@ -324,9 +351,11 @@ value::
|
||||
value(
|
||||
string str,
|
||||
storage_ptr sp)
|
||||
: str_(move_string(str, sp))
|
||||
, kind_(json::kind::string)
|
||||
{
|
||||
// workaround for some stdlibs
|
||||
construct_string(
|
||||
std::move(str),
|
||||
std::move(sp));
|
||||
}
|
||||
|
||||
value::
|
||||
@@ -362,15 +391,15 @@ value(
|
||||
{
|
||||
if(maybe_object(init))
|
||||
{
|
||||
kind_ = json::kind::object;
|
||||
::new(&obj_) object(
|
||||
init, std::move(sp));
|
||||
kind_ = json::kind::object;
|
||||
}
|
||||
else
|
||||
{
|
||||
kind_ = json::kind::array;
|
||||
::new(&arr_) array(
|
||||
init, std::move(sp));
|
||||
kind_ = json::kind::array;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,12 +407,11 @@ value&
|
||||
value::
|
||||
operator=(object obj)
|
||||
{
|
||||
object tmp(
|
||||
undo u(this);
|
||||
::new(this) value(
|
||||
std::move(obj),
|
||||
destroy());
|
||||
::new(&obj_) object(
|
||||
std::move(tmp));
|
||||
kind_ = json::kind::object;
|
||||
u.old.get_storage());
|
||||
u.commit = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -391,61 +419,23 @@ value&
|
||||
value::
|
||||
operator=(array arr)
|
||||
{
|
||||
array tmp(
|
||||
undo u(this);
|
||||
::new(this) value(
|
||||
std::move(arr),
|
||||
destroy());
|
||||
::new(&arr_) array(
|
||||
std::move(tmp));
|
||||
kind_ = json::kind::array;
|
||||
u.old.get_storage());
|
||||
u.commit = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
struct value::op_assign_string
|
||||
{
|
||||
value& this_;
|
||||
|
||||
template<class S>
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
operator()(S& str)
|
||||
{
|
||||
// workaround for missing std::string
|
||||
// ctors in some stdlib versions
|
||||
auto tmp = S(typename
|
||||
string::allocator_type(
|
||||
this_.get_storage()));
|
||||
tmp = std::move(str);
|
||||
this_.destroy();
|
||||
::new(&this_.str_) string(
|
||||
std::move(tmp));
|
||||
this_.kind_ = json::kind::string;
|
||||
}
|
||||
|
||||
template<class S>
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
operator()(S& str)
|
||||
{
|
||||
auto tmp = S(
|
||||
std::move(str), typename
|
||||
string::allocator_type(
|
||||
this_.get_storage()));
|
||||
this_.destroy();
|
||||
::new(&this_.str_) string(
|
||||
std::move(tmp));
|
||||
this_.kind_ = json::kind::string;
|
||||
}
|
||||
};
|
||||
|
||||
value&
|
||||
value::
|
||||
operator=(string str)
|
||||
{
|
||||
op_assign_string{*this}(str);
|
||||
undo u(this);
|
||||
::new(this) value(
|
||||
std::move(str),
|
||||
u.old.get_storage());
|
||||
u.commit = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -461,29 +451,31 @@ reset(json::kind k) noexcept
|
||||
{
|
||||
if(kind_ != k)
|
||||
{
|
||||
construct(k, destroy());
|
||||
undo u(this);
|
||||
::new(this) value(
|
||||
k, u.old.get_storage());
|
||||
u.commit = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
switch(kind_)
|
||||
{
|
||||
switch(kind_)
|
||||
{
|
||||
case json::kind::object:
|
||||
obj_.clear();
|
||||
break;
|
||||
case json::kind::object:
|
||||
obj_.clear();
|
||||
break;
|
||||
|
||||
case json::kind::array:
|
||||
arr_.clear();
|
||||
break;
|
||||
case json::kind::array:
|
||||
arr_.clear();
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
str_.clear();
|
||||
break;
|
||||
case json::kind::string:
|
||||
str_.clear();
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
case json::kind::boolean:
|
||||
case json::kind::null:
|
||||
break;
|
||||
}
|
||||
case json::kind::number:
|
||||
case json::kind::boolean:
|
||||
case json::kind::null:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,36 +932,6 @@ pop_back()
|
||||
|
||||
// private
|
||||
|
||||
template<class S>
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value, string>::type
|
||||
value::
|
||||
move_string(S& str, storage_ptr& sp)
|
||||
{
|
||||
// workaround for missing std::string
|
||||
// ctors in some stdlib versions
|
||||
auto s = string(typename
|
||||
string::allocator_type(
|
||||
std::move(sp)));
|
||||
s = std::move(str);
|
||||
return s;
|
||||
}
|
||||
|
||||
template<class S>
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value, string>::type
|
||||
value::
|
||||
move_string(S& str, storage_ptr& sp)
|
||||
{
|
||||
return {std::move(str), typename
|
||||
string::allocator_type(
|
||||
std::move(sp))};
|
||||
}
|
||||
|
||||
storage_ptr
|
||||
value::
|
||||
destroy() noexcept
|
||||
@@ -1005,220 +967,44 @@ destroy() noexcept
|
||||
return sp;
|
||||
}
|
||||
|
||||
void
|
||||
template<class S>
|
||||
auto
|
||||
value::
|
||||
construct(
|
||||
json::kind k,
|
||||
storage_ptr sp) noexcept
|
||||
construct_string(
|
||||
S&& str, storage_ptr sp) ->
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
|
||||
{
|
||||
switch(k)
|
||||
{
|
||||
case json::kind::object:
|
||||
// requires: noexcept construction
|
||||
::new(&obj_) object(std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::array:
|
||||
// requires: noexcept construction
|
||||
::new(&arr_) array(std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
// requires: noexcept construction
|
||||
::new(&str_) string(
|
||||
string::allocator_type(
|
||||
std::move(sp)));
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
::new(&nat_.num_) number{};
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
break;
|
||||
|
||||
case json::kind::boolean:
|
||||
case json::kind::null:
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
break;
|
||||
}
|
||||
kind_ = k;
|
||||
// workaround for missing std::string
|
||||
// ctors in some stdlib versions
|
||||
auto s = string(typename
|
||||
string::allocator_type(
|
||||
std::move(sp)));
|
||||
s = std::move(str);
|
||||
::new(&str_) string(
|
||||
std::move(s));
|
||||
kind_ = json::kind::string;
|
||||
}
|
||||
|
||||
struct value::op_move_string
|
||||
{
|
||||
value& this_;
|
||||
storage_ptr& sp_;
|
||||
|
||||
template<class S>
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
operator()(S& str)
|
||||
{
|
||||
// workaround for missing std::string
|
||||
// ctors in some stdlib versions
|
||||
auto tmp = S(typename
|
||||
string::allocator_type(sp_));
|
||||
tmp = std::move(str);
|
||||
::new(&this_.str_) string(std::move(tmp));
|
||||
}
|
||||
|
||||
template<class S>
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
operator()(S& str)
|
||||
{
|
||||
::new(&this_.str_) string(
|
||||
std::move(str), typename
|
||||
string::allocator_type(sp_));
|
||||
}
|
||||
};
|
||||
|
||||
// unchecked
|
||||
void
|
||||
template<class S>
|
||||
auto
|
||||
value::
|
||||
move(
|
||||
value&& other, storage_ptr sp)
|
||||
construct_string(
|
||||
S&& str, storage_ptr sp) ->
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
{
|
||||
switch(other.kind_)
|
||||
{
|
||||
case json::kind::object:
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
::new(&obj_) object(
|
||||
std::move(other.obj_), sp);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
kind_ = json::kind::null;
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
kind_ = other.kind_;
|
||||
sp = other.obj_.release_storage();
|
||||
other.obj_.~object();
|
||||
::new(&other.nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
other.kind_ = json::kind::null;
|
||||
break;
|
||||
|
||||
case json::kind::array:
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
::new(&arr_) array(
|
||||
std::move(other.arr_), sp);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
kind_ = json::kind::null;
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
kind_ = other.kind_;
|
||||
sp = other.arr_.release_storage();
|
||||
other.arr_.~array();
|
||||
::new(&other.nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
other.kind_ = json::kind::null;
|
||||
break;
|
||||
|
||||
case json::kind::string:
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
#endif
|
||||
{
|
||||
op_move_string{*this, sp}(other.str_);
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
catch(...)
|
||||
{
|
||||
kind_ = json::kind::null;
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
kind_ = other.kind_;
|
||||
sp = other.str_.get_allocator().get_storage();
|
||||
other.str_.~string();
|
||||
::new(&other.nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
other.kind_ = json::kind::null;
|
||||
break;
|
||||
|
||||
case json::kind::number:
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
::new(&nat_.num_) number(
|
||||
std::move(other.nat_.num_));
|
||||
kind_ = other.kind_;
|
||||
other.nat_.num_.~number();
|
||||
other.kind_ = json::kind::null;
|
||||
break;
|
||||
|
||||
case json::kind::boolean:
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
nat_.bool_ = other.nat_.bool_;
|
||||
kind_ = other.kind_;
|
||||
other.kind_ = json::kind::null;
|
||||
break;
|
||||
|
||||
case json::kind::null:
|
||||
::new(&nat_.sp_)
|
||||
storage_ptr(std::move(sp));
|
||||
kind_ = other.kind_;
|
||||
other.kind_ = json::kind::null;
|
||||
break;
|
||||
}
|
||||
::new(&str_) string(std::move(str),
|
||||
typename string::allocator_type(
|
||||
std::move(sp)));
|
||||
kind_ = json::kind::string;
|
||||
}
|
||||
|
||||
struct value::op_copy_string
|
||||
{
|
||||
value& this_;
|
||||
storage_ptr& sp_;
|
||||
|
||||
template<class S>
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
operator()(S const& str)
|
||||
{
|
||||
// workaround for missing std::string
|
||||
// ctors in some stdlib versions
|
||||
auto tmp = string(typename
|
||||
string::allocator_type(sp_));
|
||||
tmp = str;
|
||||
::new(&this_.str_) string(std::move(tmp));
|
||||
}
|
||||
|
||||
template<class S>
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type
|
||||
operator()(S const& str)
|
||||
{
|
||||
::new(&this_.str_) string(str,
|
||||
typename string::allocator_type(sp_));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// friends
|
||||
|
||||
@@ -121,54 +121,10 @@ class value
|
||||
json::kind kind_;
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Special members
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/// Destroy a value and all of its contents
|
||||
BOOST_JSON_DECL
|
||||
~value();
|
||||
|
||||
/// Move constructor
|
||||
BOOST_JSON_DECL
|
||||
value(value&& other) noexcept;
|
||||
|
||||
/// Storage-extended move constructor
|
||||
BOOST_JSON_DECL
|
||||
value(
|
||||
value&& other,
|
||||
storage_ptr sp);
|
||||
|
||||
/// Pilfer constructor
|
||||
BOOST_JSON_DECL
|
||||
value(pilfered<value> other) noexcept;
|
||||
|
||||
/// Construct a copy of a value
|
||||
BOOST_JSON_DECL
|
||||
value(value const& other);
|
||||
|
||||
/// Construct a copy of a value using the specified storage
|
||||
BOOST_JSON_DECL
|
||||
value(
|
||||
value const& other,
|
||||
storage_ptr sp);
|
||||
|
||||
/// Move-assign a value
|
||||
BOOST_JSON_DECL
|
||||
value& operator=(value&& other);
|
||||
|
||||
/// Assign a copy of a value
|
||||
BOOST_JSON_DECL
|
||||
value& operator=(value const& other);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Construction and Assignment
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Construct a null value using the default storage.
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
@@ -206,70 +162,110 @@ public:
|
||||
json::kind k,
|
||||
storage_ptr sp) noexcept;
|
||||
|
||||
/** Construct a value from an object.
|
||||
/// Copy constructor
|
||||
BOOST_JSON_DECL
|
||||
value(value const& other);
|
||||
|
||||
/// Storage-extended copy constructor
|
||||
BOOST_JSON_DECL
|
||||
value(
|
||||
value const& other,
|
||||
storage_ptr sp);
|
||||
|
||||
/// Pilfer constructor
|
||||
BOOST_JSON_DECL
|
||||
value(pilfered<value> other) noexcept;
|
||||
|
||||
/// Move constructor
|
||||
BOOST_JSON_DECL
|
||||
value(value&& other) noexcept;
|
||||
|
||||
/// Storage-extended move constructor
|
||||
BOOST_JSON_DECL
|
||||
value(
|
||||
value&& other,
|
||||
storage_ptr sp);
|
||||
|
||||
/// Move assignment
|
||||
BOOST_JSON_DECL
|
||||
value& operator=(value&& other);
|
||||
|
||||
/// Copy assignment
|
||||
BOOST_JSON_DECL
|
||||
value& operator=(value const& other);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Conversion
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Construct an object
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(object obj) noexcept;
|
||||
|
||||
/** Construct a value from an object using the specified storage
|
||||
/** Construct an object
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(object obj, storage_ptr sp);
|
||||
|
||||
/** Construct a value from an array.
|
||||
/** Construct an array
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(array arr) noexcept;
|
||||
|
||||
/** Construct a value from an array using the specified storage
|
||||
/** Construct an array
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(array arr, storage_ptr sp);
|
||||
|
||||
/** Construct a value from a string.
|
||||
/** Construct a string
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(string str) noexcept;
|
||||
|
||||
/** Construct a value from a string using the specified storage
|
||||
/** Construct a string
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(string str, storage_ptr sp);
|
||||
|
||||
/** Construct a value from a number
|
||||
/** Construct a number
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(number num);
|
||||
|
||||
/** Construct a value from a number using the specified storage
|
||||
/** Construct a number
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(number num, storage_ptr sp);
|
||||
|
||||
/** Construct an array from an initializer list.
|
||||
/** Construct an object or array
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(std::initializer_list<value> init);
|
||||
value(
|
||||
std::initializer_list<value> init);
|
||||
|
||||
/** Construct an array from an initializer list using the specified storage.
|
||||
/** Construct an object or array
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value(std::initializer_list<value> init,
|
||||
value(
|
||||
std::initializer_list<value> init,
|
||||
storage_ptr sp);
|
||||
|
||||
/** Assign a value from an object
|
||||
/** Assign an object
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value&
|
||||
operator=(object obj);
|
||||
|
||||
/** Assign a value from an array
|
||||
/** Assign an array
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value&
|
||||
operator=(array arr);
|
||||
|
||||
/** Assign a value from a string
|
||||
/** Assign a string
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
value&
|
||||
@@ -381,7 +377,7 @@ public:
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/// Construct a value from another type
|
||||
/// Construct from another type
|
||||
template<
|
||||
class T
|
||||
#ifndef GENERATING_DOCUMENTATION
|
||||
@@ -394,7 +390,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a value from another type using the specified storage
|
||||
/// Construct from another type using the specified storage
|
||||
template<
|
||||
class T
|
||||
#ifndef GENERATING_DOCUMENTATION
|
||||
@@ -893,26 +889,6 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
struct op_assign_string;
|
||||
struct op_move_string;
|
||||
struct op_copy_string;
|
||||
|
||||
template<class S>
|
||||
static
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value, string>::type
|
||||
move_string(S& str, storage_ptr& store);
|
||||
|
||||
template<class S>
|
||||
static
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value, string>::type
|
||||
move_string(S& str, storage_ptr& store);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
storage_ptr
|
||||
destroy() noexcept;
|
||||
@@ -922,9 +898,23 @@ private:
|
||||
construct(
|
||||
json::kind, storage_ptr) noexcept;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
void
|
||||
move(value&&, storage_ptr);
|
||||
template<class S>
|
||||
auto
|
||||
construct_string(
|
||||
S&& str, storage_ptr store) ->
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type;
|
||||
|
||||
template<class S>
|
||||
auto
|
||||
construct_string(
|
||||
S&& str, storage_ptr store) ->
|
||||
typename std::enable_if<
|
||||
std::is_constructible<S, string,
|
||||
typename string::allocator_type
|
||||
>::value>::type;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
friend
|
||||
|
||||
Reference in New Issue
Block a user