516 CHECK(root.is_map());
520 CHECK(root.tree() == &tree);
521 CHECK(root.id() == root_id);
536 CHECK(tree[
"foo"].is_keyval());
537 CHECK(tree[
"foo"].val() ==
"1");
538 CHECK(tree[
"foo"].key() ==
"foo");
539 CHECK(tree[
"bar"].is_seq());
540 CHECK(tree[
"bar"].has_key());
541 CHECK(tree[
"bar"].key() ==
"bar");
543 CHECK(tree[
"bar"][0].val() ==
"2");
544 CHECK(tree[
"bar"][1].val() ==
"3");
545 CHECK(tree[
"john"].val() ==
"doe");
549 CHECK(tree[0].
id() == tree[
"foo"].
id());
550 CHECK(tree[1].
id() == tree[
"bar"].
id());
551 CHECK(tree[2].
id() == tree[
"john"].
id());
553 CHECK(tree[0].
id() == tree[
"foo"].
id());
554 CHECK(tree[1].
id() == tree[
"bar"].
id());
555 CHECK(tree[2].
id() == tree[
"john"].
id());
557 CHECK(bar[0].val() ==
"2");
558 CHECK(bar[1].val() ==
"3");
563 CHECK(tree[
"foo"].key() ==
"foo");
564 CHECK(tree[
"bar"].key() ==
"bar");
565 CHECK(tree[
"john"].key() ==
"john");
570 CHECK(root[
"foo"].
id() == root[0].
id());
571 CHECK(root[
"bar"].
id() == root[1].
id());
572 CHECK(root[
"john"].
id() == root[2].
id());
607 CHECK(root.num_children() == 3);
610 CHECK(root.first_child().id() == root[
"foo"].id());
611 CHECK(root.last_child().id() == root[
"john"].id());
631 CHECK(child.key() == expected_keys[count++]);
637 CHECK(child.key() == expected_keys[count++]);
643 CHECK(tree.
key(child_id) == expected_keys[count++]);
652 CHECK(tree.
key(child_id) == expected_keys[count++]);
727 int foo = 0, bar0 = 0, bar1 = 0;
728 root[
"foo"].
load(&foo);
729 root[
"bar"][0].load(&bar0);
730 root[
"bar"][1].load(&bar1);
738 int foo = 0, bar0 = 0, bar1 = 0;
739 CHECK(root[
"foo"].deserialize(&foo));
740 CHECK(root[
"bar"][0].deserialize(&bar0));
741 CHECK(root[
"bar"][1].deserialize(&bar1));
750 std::string john_str, bar_str;
751 root[
"john"].load(&john_str);
752 root[
"bar"].load_key(&bar_str);
753 CHECK(john_str ==
"doe");
754 CHECK(bar_str ==
"bar");
755 std::vector<int> bar_actual, bar_expected{{2, 3}};
756 root[
"bar"].load(&bar_actual);
757 CHECK(bar_actual == bar_expected);
775 wroot[
"foo"].
set_val(
"says you");
782 CHECK(root[
"foo"].val() ==
"says you");
783 CHECK(root[
"bar"][0].val() ==
"-2");
784 CHECK(root[
"bar"][1].val() ==
"-3");
785 CHECK(root[
"john"].val() ==
"ron");
806 CHECK(root[
"foo"].val() ==
"says who");
807 CHECK(root[
"bar"][0].val() ==
"20");
808 CHECK(root[
"bar"][1].val() ==
"30");
809 CHECK(root[
"john"].val() ==
"deere");
813 std::string ok(
"in_scope");
817 CHECK(root[
"john"].val() ==
"in_scope");
823 CHECK(tree.
arena() ==
"says who2030deerein_scope2.42.400000");
830 CHECK(root.num_children() == 5);
831 wroot[
"newkeyval"].
set_val(
"shiny and new");
835 CHECK(root.num_children() == 7);
836 CHECK(root[
"newkeyval"].key() ==
"newkeyval");
837 CHECK(root[
"newkeyval"].val() ==
"shiny and new");
838 CHECK(root[
"newkeyval (serialized)"].key() ==
"newkeyval (serialized)");
839 CHECK(root[
"newkeyval (serialized)"].val() ==
"shiny and new (serialized)");
845 CHECK(root[
"bar"].num_children() == 2);
846 wroot[
"bar"][2].
set_val(
"oh so nice");
848 CHECK(root[
"bar"].num_children() == 4);
849 CHECK(root[
"bar"][2].val() ==
"oh so nice");
850 CHECK(root[
"bar"][3].val() ==
"oh so nice (serialized)");
852 CHECK(root.num_children() == 7);
857 CHECK(root.num_children() == 9);
858 CHECK(root[
"newseq"].num_children() == 0);
859 CHECK(root[
"newseq"].is_seq());
860 CHECK(root[
"newseq (serialized)"].num_children() == 0);
861 CHECK(root[
"newseq (serialized)"].is_seq());
863 CHECK(root.num_children() == 9);
868 CHECK(root.num_children() == 11);
869 CHECK(root[
"newmap"].num_children() == 0);
870 CHECK(root[
"newmap"].is_map());
871 CHECK(root[
"newmap (serialized)"].num_children() == 0);
872 CHECK(root[
"newmap (serialized)"].is_map());
902 CHECK(!root.has_child(
"I am not nothing"));
904 CHECK(nothing.invalid());
905 nothing = wroot[
"I am nothing"];
906 CHECK(!nothing.invalid());
907 CHECK(nothing.is_seed());
908 CHECK(!root.has_child(
"I am nothing"));
909 CHECK(!nothing.readable());
913 CHECK(!root.has_child(
"I am something"));
914 CHECK(!something.invalid());
915 CHECK(something.is_seed());
916 CHECK(!something.readable());
920 something.set_val(
"indeed");
921 CHECK(root.has_child(
"I am something"));
922 CHECK(root[
"I am something"].val() ==
"indeed");
923 CHECK(!something.invalid());
924 CHECK(!something.is_seed());
926 CHECK(something.readable());
930 CHECK(!constsomethingnew.invalid());
931 CHECK(constsomethingnew.readable());
951 if(wbar.readable() && wbar.is_seq())
953 CHECK(wbar[0].readable() && wbar[0].val() ==
"20");
954 CHECK( ! wbar[100].readable());
955 CHECK( ! wbar[100].readable() || wbar[100].val() ==
"100");
957 CHECK( ! wbar[0].is_seed() && wbar[0].val() ==
"20");
958 CHECK(wbar[100].is_seed() || wbar[100].val() ==
"100");
984 CHECK(!seed_node.readable());
987 return seed_node.at(
"is").at(
"an").at(
"invalid").at(
"operation");
994 return seed_node[
"is"][
"an"][
"invalid"][
"operation"];
1005 "foo: says who" "\n"
1006 "bar: [20,30,oh so nice,oh so nice (serialized)]" "\n"
1007 "john: in_scope" "\n"
1009 "digits: 2.400000" "\n"
1010 "newkeyval: shiny and new" "\n"
1011 "newkeyval (serialized): shiny and new (serialized)" "\n"
1013 "newseq (serialized): []" "\n"
1015 "newmap (serialized): {}" "\n"
1016 "I am something: indeed" "\n"
1025 std::stringstream ss;
1027 std::string stream_result = ss.str();
1029 std::string str_result = ryml::emitrs_yaml<std::string>(tree);
1034 CHECK(buf_result == expected_result);
1035 CHECK(str_result == expected_result);
1036 CHECK(stream_result == expected_result);
1052 CHECK(tree[
"bar"][0].val() ==
"21");
1054 CHECK(tree[
"bar"][0].val() ==
"22");
1060 constnoderef = noderef;
1066 noderef = tree[
"bar"][0];
1067 constnoderef = consttree[
"bar"][0];
1071 CHECK(constnoderef == noderef);
1072 CHECK(!(constnoderef != noderef));
1087 CHECK(
parser.location_contents(loc).begins_with(
"30"));
1088 CHECK(loc.line == 1u);
1089 CHECK(loc.col == 9u);
1098 "# UTF8/16/32 can be placed directly in any scalar:" "\n"
1100 "en: Planet (Gas)" "\n"
1101 "fr: Planète (Gazeuse)" "\n"
1102 "ru: Планета (Газ)" "\n"
1106 "# UTF8 decoding only happens in double-quoted strings," "\n"
1107 "# as per the YAML standard" "\n"
1109 "decode this: \"\\u263A c\\x61f\\xE9\"" "\n"
1110 "and this as well: \"\\u2705 \\U0001D11E\"" "\n"
1111 "not decoded: '\\u263A \\xE2\\x98\\xBA'" "\n"
1112 "neither this: '\\u2705 \\U0001D11E'" "\n");
1114 CHECK(langs[
"en"].val() ==
"Planet (Gas)");
1115 CHECK(langs[
"fr"].val() ==
"Planète (Gazeuse)");
1116 CHECK(langs[
"ru"].val() ==
"Планета (Газ)");
1117 CHECK(langs[
"ja"].val() ==
"惑星(ガス)");
1118 CHECK(langs[
"zh"].val() ==
"行星(气体)");
1122 CHECK(langs[
"decode this"].val() ==
"☺ café");
1123 CHECK(langs[
"and this as well"].val() ==
"✅ 𝄞");
1124 CHECK(langs[
"not decoded"].val() ==
"\\u263A \\xE2\\x98\\xBA");
1125 CHECK(langs[
"neither this"].val() ==
"\\u2705 \\U0001D11E");
csubstr const & key(id_type node) const
ConstNodeRef last_sibling() const RYML_NOEXCEPT
Forward to Tree::last_sibling().
id_type first_child(id_type node) const
id_type num_siblings() const RYML_NOEXCEPT
O(num_children).
ryml::Callbacks callbacks()
a helper to create the Callbacks object for the custom error handler
Location location(Parser const &parser) const
bool is_seq() const RYML_NOEXCEPT
Forward to Tree::is_seq().
ConstNodeRef parent() const RYML_NOEXCEPT
Forward to Tree::parent().
bool check_assertion_occurs(Fn &&fn)
checking that an assertion occurs while calling fn.
ConstNodeRef last_child() const RYML_NOEXCEPT
Forward to Tree::last_child().
Shows how to create a scoped error handler.
The event handler to create a ryml Tree.
id_type id() const noexcept
id_type first_sibling(id_type node) const
bool has_key() const RYML_NOEXCEPT
Forward to Tree::has_key().
void load(T *v, bool check_readable=true) const
(1) deserialize the node's contents (val or container) to the given variable, forwarding to the user-...
bool is_map(id_type node) const
bool invalid() const noexcept
csubstr arena() const
get the current arena
ConstNodeRef next_sibling() const RYML_NOEXCEPT
Forward to Tree::next_sibling().
print the real number in floating point format (like f)
real_< T > real(T val, int precision, RealFormat_e fmt=FTOA_FLOAT)
void set_val(csubstr val)
void parse_in_arena(Parser *parser, csubstr filename, csubstr yaml, Tree *tree, id_type node_id)
(1) parse YAML into an existing tree node. The filename will be used in any error messages arising du...
ConstNodeRef first_sibling() const RYML_NOEXCEPT
Forward to Tree::first_sibling().
id_type root_id() const
Get the id of the root node. The tree must not be empty. The tree can be empty only when constructed ...
ConstNodeRef first_child() const RYML_NOEXCEPT
Forward to Tree::first_child().
A reference to a node in an existing yaml tree, offering a more convenient API than the index-based A...
RYML_ID_TYPE id_type
The type of a node id in the YAML tree; to override the default type, define the macro RYML_ID_TYPE t...
Options to give to the ParseEngine to control its behavior.
bool in_arena(csubstr s) const
return true if the given substring is part of the tree's string arena
bool is_seq(id_type node) const
Callbacks const & callbacks() const
bool readable() const noexcept
because a ConstNodeRef cannot be used to write to the tree, readable() has the same meaning as !inval...
holds a source or yaml file position, for example when an error is detected; See also location_format...
#define CHECK(predicate)
a testing assertion, used only in this quickstart
ConstNodeRef prev_sibling() const RYML_NOEXCEPT
Forward to Tree::prev_sibling().
Holds a pointer to an existing tree, and a node id.
id_type next_sibling(id_type node) const
substr emit_yaml(Tree const &t, EmitOptions const &opts, substr buf, bool error_on_excess)
(1) emit YAML to the given buffer.
NodeRef rootref()
Get the root as a NodeRef . Note that a non-const Tree implicitly converts to NodeRef.
This is the main driver of parsing logic: it scans the YAML or JSON source for tokens, and emits the appropriate sequence of parsing events to its event handler.
bool empty() const noexcept
csubstr val() const RYML_NOEXCEPT
Forward to Tree::val().
bool check_error_occurs(Fn &&fn)
checking that an error occurs while calling fn
const_children_view children() const RYML_NOEXCEPT
get an iterable view over children
bool is_val() const RYML_NOEXCEPT
Forward to Tree::is_val().
void parse_in_place(Parser *parser, csubstr filename, substr yaml, Tree *tree, id_type node_id)
(1) parse YAML into an existing tree node.
void set_serialized(T const &v)
serialize a variable to this node.
void set_key_serialized(T const &k)
serialize a variable, then assign the result to the node's key
id_type find_child(id_type node, csubstr const &key) const
find child by name, or NONE if no child is found with this key like Tree::child(), but return a ReadResult with the status
bool has_val() const RYML_NOEXCEPT
Forward to Tree::has_val().
csubstr key() const RYML_NOEXCEPT
Forward to Tree::key().