Skip to content

Commit

Permalink
fix inconsistent choice of init list constructor
Browse files Browse the repository at this point in the history
On some compilers value{x} invokes initializer_list constructor, on
others it is equivalent to value(x). This is very problematic, but this
isn't something we can fix. On the other hand, we CAN make init list
construction to be equivalent to value(x), if the size of init list is
one. This commit does exactly that.
  • Loading branch information
grisumbras committed Aug 23, 2023
1 parent f48b6dd commit a00c90b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
12 changes: 11 additions & 1 deletion include/boost/json/impl/value.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,23 @@ value(
storage_ptr sp)
{
if(value_ref::maybe_object(init))
{
::new(&obj_) object(
value_ref::make_object(
init, std::move(sp)));
else
}
else if( init.size() != 1 )
{
::new(&arr_) array(
value_ref::make_array(
init, std::move(sp)));
}
else
{
::new(&sca_) scalar();
value temp = init.begin()->make_value( std::move(sp) );
swap(temp);
}
}

//----------------------------------------------------------
Expand Down
15 changes: 10 additions & 5 deletions include/boost/json/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1014,11 +1014,16 @@ class value

/** Construct from an initializer-list
If the initializer list consists of key/value
pairs, an @ref object is created. Otherwise
an @ref array is created. The contents of the
initializer list are copied to the newly constructed
value using the specified memory resource.
@li If the initializer list consists of key/value
pairs, an @ref object is created; otherwise,
@li if the size of the initializer list is exactly 1, the object is
constructed directly from that sole element; otherwise,
@li an @ref array is created.
The contents of the initializer list are copied to the newly
constructed value using the specified memory resource.
@par Complexity
Linear in `init.size()`.
Expand Down
9 changes: 9 additions & 0 deletions test/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2131,6 +2131,15 @@ class value_test
void
testInitList()
{
{
value jv{};
BOOST_TEST( jv.is_null() );
}
{
value jv{0};
BOOST_TEST( jv == 0 );
}

check_array(value{0,0,0}, 0, 0, 0);
check_array(value{false,false,false}, false, false, false);
check_array(value{false,2,false}, false, 2, false);
Expand Down

0 comments on commit a00c90b

Please sign in to comment.