Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Accessing Deeply Nested Elements

In order to allow conveniently retrieving and changing deeply nested elements of value objects the library implements RFC 6901 (JSON Pointer):

value jv = { {"one", 1}, {"two", 2} };
assert( jv.at("one") == jv.at_pointer("/one") );

jv.at_pointer("/one") = {{"foo", "bar"}};
assert( jv.at("one").at("foo") == jv.at_pointer("/one/foo") );

jv.at_pointer("/one/foo") = {true, 4, "qwerty"};
assert( jv.at("one").at("foo").at(1) == jv.at_pointer("/one/foo/1") );

This is particularly useful when throwing exceptions is undesirable. For example, compare

object* obj = jv.if_object();
if( !obj )
    return nullptr;

value* val = obj->if_contains("one");
if( !val )
    return nullptr;

obj = val->if_object();
if( !obj )
    return nullptr;

val = obj->if_contains("foo");
if( !val )
    return nullptr;

array* arr = val->if_array();
if( !arr )
    return nullptr;

return arr->if_contains(1);

with

boost::system::error_code ec;
return jv.find_pointer("/one/foo/1", ec);

The library also allows changing and adding deeply nested elements. The function set_at_pointer traverses the value similarly to at_pointer, but additionally, it can create missing elements in certain cases:

value jv;
jv.set_at_pointer("/two/bar/0", 12);
assert( jv.is_object() );
assert( jv.at_pointer("/two").is_object() );
assert( jv.at_pointer("/two/bar").is_array() );
assert( jv.at_pointer("/two/bar/0") == 12 );

The specific behavior is controlled by an optional parameter of type set_pointer_options. For example, here's the same example with a different option:

set_pointer_options opts;
opts.create_arrays = false;

jv.set_at_pointer("/two/bar/0", 12, opts);
assert( jv.is_object() );
assert( jv.at_pointer("/two").is_object() );
assert( jv.at_pointer("/two/bar").is_object() ); // object, not array
assert( jv.at_pointer("/two/bar/0") == 12 );

PrevUpHomeNext