Skip to content
Open
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
104 changes: 104 additions & 0 deletions include/boost/json/impl/pointer.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,110 @@ value::set_at_pointer(
return try_set_at_pointer(sv, ref, opts).value();
}

bool
value::erase_at_pointer(
string_view sv,
system::error_code& ec)
{
ec.clear();
if(sv.empty()){
BOOST_JSON_FAIL(ec, error::syntax);
return false;
}

string_view previous_segment;

string_view segment = detail::next_segment(sv, ec);

auto result = this;
auto previous_result = this;

while (true)
{
if (ec.failed())
return false;

if (!result)
{
BOOST_JSON_FAIL(ec, error::not_found);
return false;
}

if( segment.empty() )
break;

previous_segment = segment;
previous_result = result;

switch (result->kind())
{
case boost::json::kind::object: {
auto& obj = result->get_object();

detail::pointer_token const token(segment);
segment = detail::next_segment(sv, ec);
if (ec.failed())
return false;

result = detail::if_contains_token(obj, token);
if( !result )
{
BOOST_JSON_FAIL(ec, error::not_found);
return false;
}
break;
}
case boost::json::kind::array: {
auto const index = detail::parse_number_token(segment, ec);
segment = detail::next_segment(sv, ec);
if (ec.failed())
return false;

auto& arr = result->get_array();
result = arr.if_contains(index);
if( !result )
{
BOOST_JSON_FAIL(ec, error::past_the_end);
return false;
}
break;
}
default: {
BOOST_JSON_FAIL(ec, error::value_is_scalar);
return false;
}
}
}

switch (previous_result->kind())
{
case boost::json::kind::object: {
auto& obj = previous_result->get_object();
detail::pointer_token const token(previous_segment);
key_value_pair* kv = detail::find_in_object(obj, token).first;
if (kv) {
obj.erase(kv);
return true;
}
return false;
}
case boost::json::kind::array: {
auto const index = detail::parse_number_token(previous_segment, ec);
auto& arr = previous_result->get_array();
if (arr.if_contains(index)){
arr.erase(arr.begin() + index);
return true;
}
return false;
}
default: {
BOOST_JSON_FAIL(ec, error::value_is_scalar);
return false;
}
}
}


} // namespace json
} // namespace boost

Expand Down
13 changes: 13 additions & 0 deletions include/boost/json/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3035,6 +3035,19 @@ class value

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

/** Remove an element via JSON Pointer.

@{
*/
BOOST_JSON_DECL
bool
erase_at_pointer(
string_view sv,
system::error_code& ec);

/// @}
//------------------------------------------------------

/** Check if two values are equal.

Two values are equal when they are the same kind and their referenced
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ local SOURCES =
doc_uses_allocator.cpp
doc_using_numbers.cpp
double.cpp
erase_at_pointer.cpp
error.cpp
fwd.cpp
json.cpp
Expand Down
Loading
Loading