Function sample_parse_reuse_tree
Synopsis
#include <samples/quickstart.cpp>
void sample_parse_reuse_tree()
Description
parse into an existing tree, maybe into a node
demonstrate reuse/modification of tree when parsing
Mentioned in
- Getting Started / Quick start
Source
Lines 1340-1485 in samples/quickstart.cpp. Line 53 in samples/quickstart.cpp.
void sample_parse_reuse_tree()
{
ryml::Tree tree;
// it will always be faster if the tree's size is conveniently reserved:
tree.reserve(30); // reserve 30 nodes (good enough for this sample)
// if you are using the tree's arena to serialize data,
// then reserve also the arena's size:
tree.reserve(256); // reserve 256 characters (good enough for this sample)
// now parse into the tree:
ryml::parse("{foo: 1, bar: [2, 3]}", &tree);
ryml::NodeRef root = tree.rootref();
CHECK(root.num_children() == 2);
CHECK(root.is_map());
CHECK(root["foo"].is_keyval());
CHECK(root["foo"].key() == "foo");
CHECK(root["foo"].val() == "1");
CHECK(root["bar"].is_seq());
CHECK(root["bar"].has_key());
CHECK(root["bar"].key() == "bar");
CHECK(root["bar"][0].val() == "2");
CHECK(root["bar"][1].val() == "3");
CHECK(ryml::emitrs<std::string>(tree) == R"(foo: 1
bar:
- 2
- 3
)");
// WATCHOUT: parsing into an existing tree will APPEND to it:
ryml::parse("{foo2: 12, bar2: [22, 32]}", &tree);
CHECK(ryml::emitrs<std::string>(tree) == R"(foo: 1
bar:
- 2
- 3
foo2: 12
bar2:
- 22
- 32
)");
CHECK(root.num_children() == 4);
CHECK(root["foo2"].is_keyval());
CHECK(root["foo2"].key() == "foo2");
CHECK(root["foo2"].val() == "12");
CHECK(root["bar2"].is_seq());
CHECK(root["bar2"].has_key());
CHECK(root["bar2"].key() == "bar2");
CHECK(root["bar2"][0].val() == "22");
CHECK(root["bar2"][1].val() == "32");
// clear first before parsing into an existing tree.
tree.clear();
ryml::parse("[a, b, {x0: 1, x1: 2}]", &tree);
CHECK(ryml::emitrs<std::string>(tree) == R"(- a
- b
- x0: 1
x1: 2
)");
CHECK(root.is_seq());
CHECK(root[0].val() == "a");
CHECK(root[1].val() == "b");
CHECK(root[2].is_map());
CHECK(root[2]["x0"].val() == "1");
CHECK(root[2]["x1"].val() == "2");
// we can parse directly into a node nested deep in an existing tree:
ryml::parse("{champagne: Dom Perignon, coffee: Arabica}", root.append_child());
CHECK(ryml::emitrs<std::string>(tree) == R"(- a
- b
- x0: 1
x1: 2
- champagne: Dom Perignon
coffee: Arabica
)");
CHECK(root.is_seq());
CHECK(root[0].val() == "a");
CHECK(root[1].val() == "b");
CHECK(root[2].is_map());
CHECK(root[2]["x0"].val() == "1");
CHECK(root[2]["x1"].val() == "2");
CHECK(root[3].is_map());
CHECK(root[3]["champagne"].val() == "Dom Perignon");
CHECK(root[3]["coffee"].val() == "Arabica");
// watchout: to add to an existing node within a map, the node's key must first be set:
ryml::NodeRef more = root[3].append_child({ryml::KEYMAP, "more"});
ryml::NodeRef beer = root[3].append_child({ryml::KEYSEQ, "beer"});
ryml::parse("{vinho verde: Soalheiro, vinho tinto: Redoma 2017}", more);
ryml::parse("[Rochefort 10, Busch, Leffe Rituel]", beer);
CHECK(ryml::emitrs<std::string>(tree) == R"(- a
- b
- x0: 1
x1: 2
- champagne: Dom Perignon
coffee: Arabica
more:
vinho verde: Soalheiro
vinho tinto: Redoma 2017
beer:
- Rochefort 10
- Busch
- Leffe Rituel
)");
ryml::parse("[foo, bar, baz, bat]", root);
CHECK(ryml::emitrs<std::string>(tree) == R"(- a
- b
- x0: 1
x1: 2
- champagne: Dom Perignon
coffee: Arabica
more:
vinho verde: Soalheiro
vinho tinto: Redoma 2017
beer:
- Rochefort 10
- Busch
- Leffe Rituel
- foo
- bar
- baz
- bat
)");
ryml::parse("[Kasteel Donker]", beer);
CHECK(ryml::emitrs<std::string>(tree) == R"(- a
- b
- x0: 1
x1: 2
- champagne: Dom Perignon
coffee: Arabica
more:
vinho verde: Soalheiro
vinho tinto: Redoma 2017
beer:
- Rochefort 10
- Busch
- Leffe Rituel
- Kasteel Donker
- foo
- bar
- baz
- bat
)");
}