Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions include/boost/json/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace boost {
namespace json {

class value;
class value_ref;

/** A dynamically sized array of JSON values

Expand Down Expand Up @@ -458,7 +459,7 @@ class array
*/
BOOST_JSON_DECL
array(
std::initializer_list<value> init,
std::initializer_list<value_ref> init,
storage_ptr sp = {});

//------------------------------------------------------
Expand Down Expand Up @@ -535,7 +536,7 @@ class array
BOOST_JSON_DECL
array&
operator=(
std::initializer_list<value> init);
std::initializer_list<value_ref> init);

//------------------------------------------------------

Expand Down Expand Up @@ -1271,7 +1272,7 @@ class array
iterator
insert(
const_iterator pos,
std::initializer_list<value> init);
std::initializer_list<value_ref> init);

/** Insert a constructed element in-place.

Expand Down Expand Up @@ -1604,10 +1605,6 @@ class array
void
copy(array const& other);

inline
void
copy(std::initializer_list<value> init);

BOOST_JSON_DECL
void
reserve_impl(std::size_t capacity);
Expand Down
2 changes: 0 additions & 2 deletions include/boost/json/detail/impl/object_impl.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,6 @@ destroy(
key_value_pair* p,
std::size_t n) noexcept
{
if(n == 0)
return;
if(! p->value().storage()->need_free())
return;
p += n;
Expand Down
45 changes: 14 additions & 31 deletions include/boost/json/impl/array.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ undo_insert(
std::size_t n,
array& self)
: self_(self)
, n_(static_cast<std::size_t>(n))
, n_(n)
, pos(self.impl_.index_of(pos_))
{
if(n > max_size())
Expand Down Expand Up @@ -186,12 +186,15 @@ array(

array::
array(
std::initializer_list<value> init,
std::initializer_list<value_ref> init,
storage_ptr sp)
: sp_(std::move(sp))
{
undo_construct u(*this);
copy(init);
reserve(init.size());
value_ref::write_array(
data(), init, sp_);
impl_.size(init.size());
u.commit = true;
}

Expand Down Expand Up @@ -222,7 +225,7 @@ operator=(array&& other)
array&
array::
operator=(
std::initializer_list<value> init)
std::initializer_list<value_ref> init)
{
array tmp(init, sp_);
this->~array();
Expand Down Expand Up @@ -312,14 +315,14 @@ auto
array::
insert(
const_iterator pos,
std::initializer_list<value> init) ->
iterator
std::initializer_list<
value_ref> init) ->
iterator
{
undo_insert u(pos,
static_cast<std::size_t>(
init.size()), *this);
for(auto const& v : init)
u.emplace(v);
undo_insert u(
pos, init.size(), *this);
value_ref::write_array(
impl_.data() + u.pos, init, sp_);
u.commit = true;
return impl_.data() + u.pos;
}
Expand Down Expand Up @@ -489,26 +492,6 @@ copy(array const& other)
}
}

void
array::
copy(
std::initializer_list<value> init)
{
if(init.size() > max_size())
BOOST_JSON_THROW(
std::length_error(
"size > max_size()"));
reserve(static_cast<
std::size_t>(init.size()));
for(auto const& v : init)
{
::new(
impl_.data() +
impl_.size()) value(v, sp_);
impl_.size(impl_.size() + 1);
}
}

void
array::
reserve_impl(std::size_t capacity)
Expand Down
90 changes: 79 additions & 11 deletions include/boost/json/impl/object.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,48 @@ object(

object::
object(
init_list init,
std::initializer_list<std::pair<
key_type, value_ref>> init,
std::size_t min_capacity,
storage_ptr sp)
: sp_(std::move(sp))
{
undo_construct u(this);
insert_range(
init.begin(),
init.end(),
min_capacity);
using FwdIt = std::pair<
key_type, value_ref> const*;
struct place_impl : place_range
{
FwdIt it;
std::size_t n;
storage_ptr const& sp;

place_impl(
FwdIt it_,
std::size_t n_,
storage_ptr const& sp_)
: it(it_)
, n(n_)
, sp(sp_)
{
}

bool
operator()(void* dest) override
{
if(n-- == 0)
return false;
::new(dest) value_type(
it->first,
it->second.make_value(sp));
++it;
return true;
}
};
if( min_capacity < init.size())
min_capacity = init.size();
place_impl f(
init.begin(), init.size(), sp_);
insert_range_impl(min_capacity, f);
u.self = nullptr;
}

Expand Down Expand Up @@ -198,7 +230,8 @@ operator=(object const& other)
object&
object::
operator=(
init_list init)
std::initializer_list<std::pair<
key_type, value_ref>> init)
{
object tmp(init, sp_);
this->~object();
Expand All @@ -221,12 +254,47 @@ clear() noexcept

void
object::
insert(init_list init)
insert(
std::initializer_list<std::pair<
key_type, value_ref>> init)
{
insert_range(
init.begin(),
init.end(),
init.size());
using FwdIt = std::pair<
key_type, value_ref> const*;
struct place_impl : place_range
{
FwdIt it;
std::size_t n;
storage_ptr const& sp;

place_impl(
FwdIt it_,
std::size_t n_,
storage_ptr const& sp_)
: it(it_)
, n(n_)
, sp(sp_)
{
}

bool
operator()(void* dest) override
{
if(n-- == 0)
return false;
::new(dest) value_type(
it->first,
it->second.make_value(sp));
++it;
return true;
}
};
auto const n0 = size();
if(init.size() > max_size() - n0)
BOOST_JSON_THROW(
detail::object_too_large_exception());
place_impl f(
init.begin(), init.size(), sp_);
insert_range_impl(n0 + init.size(), f);
}

auto
Expand Down
Loading