diff --git a/README.md b/README.md index d4d1a18b4..8be614084 100644 --- a/README.md +++ b/README.md @@ -541,7 +541,7 @@ CHECK(tree.arena() == "says who2030deere"); // the result of serializations to t // root["john"] = ryml::to_csubstr(ok); // don't, will dangle wroot["john"] << ryml::to_csubstr(ok); // OK, copy to the tree's arena } -CHECK(root["john"] == "in_scope"); // OK! +CHECK(root["john"].val() == "in_scope"); // OK! // serializing floating points: wroot["float"] << 2.4; // to force a particular precision or float format: @@ -592,8 +592,9 @@ CHECK(root["newmap"].is_map()); CHECK(root["newmap (serialized)"].num_children() == 0); CHECK(root["newmap (serialized)"].is_map()); // -// When the tree is mutable, operator[] does not mutate the tree -// until the returned node is written to. +// When the tree is mutable, operator[] first searches the tree +// for the does not mutate the tree until the returned node is +// written to. // // Until such time, the NodeRef object keeps in itself the required // information to write to the proper place in the tree. This is @@ -615,8 +616,10 @@ CHECK(root["newmap (serialized)"].is_map()); // tree. // CHECK(!root.has_child("I am not nothing")); -ryml::NodeRef nothing = wroot["I am nothing"]; -CHECK(nothing.valid()); // points at the tree, and a specific place in the tree +ryml::NodeRef nothing; +CHECK(nothing.invalid()); // invalid because it points at nothing +nothing = wroot["I am nothing"]; +CHECK(!nothing.invalid()); // points at the tree, and a specific place in the tree CHECK(nothing.is_seed()); // ... but nothing is there yet. CHECK(!root.has_child("I am nothing")); // same as above CHECK(!nothing.readable()); // ... and this node cannot be used to @@ -624,27 +627,27 @@ CHECK(!nothing.readable()); // ... and this node cannot be used to ryml::NodeRef something = wroot["I am something"]; ryml::ConstNodeRef constsomething = wroot["I am something"]; CHECK(!root.has_child("I am something")); // same as above -CHECK(something.valid()); +CHECK(!something.invalid()); CHECK(something.is_seed()); // same as above CHECK(!something.readable()); // same as above -CHECK(!constsomething.valid()); // NOTE: because a ConstNodeRef cannot be - // used to mutate a tree, it is only valid() - // if it is pointing at an existing node. +CHECK(constsomething.invalid()); // NOTE: because a ConstNodeRef cannot be + // used to mutate a tree, it is only valid() + // if it is pointing at an existing node. something = "indeed"; // this will commit the seed to the tree, mutating at the proper place CHECK(root.has_child("I am something")); CHECK(root["I am something"].val() == "indeed"); -CHECK(something.valid()); // it was already valid +CHECK(!something.invalid()); // it was already valid CHECK(!something.is_seed()); // now the tree has this node, so the // ref is no longer a seed CHECK(something.readable()); // and it is now readable // // now the constref is also valid (but it needs to be reassigned): ryml::ConstNodeRef constsomethingnew = wroot["I am something"]; -CHECK(constsomethingnew.valid()); +CHECK(!constsomethingnew.invalid()); CHECK(constsomethingnew.readable()); // note that the old constref is now stale, because it only keeps // the state at creation: -CHECK(!constsomething.valid()); +CHECK(constsomething.invalid()); CHECK(!constsomething.readable()); // // ----------------------------------------------------------- @@ -664,6 +667,7 @@ ryml::NodeRef wbar = wroot["bar"]; if(wbar.readable() && wbar.is_seq()) // .is_seq() requires .readable() { CHECK(wbar[0].readable() && wbar[0].val() == "20"); + CHECK( ! wbar[100].readable()); CHECK( ! wbar[100].readable() || wbar[100].val() == "100"); // <- no crash because it is not .readable(), so never tries to call .val() // this would work as well: CHECK( ! wbar[0].is_seed() && wbar[0].val() == "20"); @@ -785,49 +789,6 @@ ryml::Location loc = parser.location(tree2["bar"][1]); CHECK(parser.location_contents(loc).begins_with("30")); CHECK(loc.line == 3u); CHECK(loc.col == 4u); -// For further details in location tracking, -// refer to the sample function below. -``` - -The [quickstart.cpp sample](./samples/quickstart.cpp) (from which the -above overview was taken) has many more detailed examples, and should -be your first port of call to find out any particular point about -ryml's API. It is tested in the CI, and thus has the correct behavior. -There you can find the following subjects being addressed: - -```c++ -sample_quick_overview(); ///< briefly skim over most of the features -sample_substr(); ///< about ryml's string views (from c4core) -sample_parse_file(); ///< ready-to-go example of parsing a file from disk -sample_parse_in_place(); ///< parse a mutable YAML source buffer -sample_parse_in_arena(); ///< parse a read-only YAML source buffer -sample_parse_reuse_tree(); ///< parse into an existing tree, maybe into a node -sample_parse_reuse_parser(); ///< reuse an existing parser -sample_parse_reuse_tree_and_parser(); ///< how to reuse existing trees and parsers -sample_iterate_trees(); ///< visit individual nodes and iterate through trees -sample_create_trees(); ///< programatically create trees -sample_tree_arena(); ///< interact with the tree's serialization arena -sample_fundamental_types(); ///< serialize/deserialize fundamental types -sample_formatting(); ///< control formatting when serializing/deserializing -sample_base64(); ///< encode/decode base64 -sample_user_scalar_types(); ///< serialize/deserialize scalar (leaf/string) types -sample_user_container_types(); ///< serialize/deserialize container (map or seq) types -sample_std_types(); ///< serialize/deserialize STL containers -sample_float_precision(); ///< control precision of serialized floats -sample_emit_to_container(); ///< emit to memory, eg a string or vector-like container -sample_emit_to_stream(); ///< emit to a stream, eg std::ostream -sample_emit_to_file(); ///< emit to a FILE* -sample_emit_nested_node(); ///< pick a nested node as the root when emitting -sample_emit_style(); ///< set the nodes to FLOW/BLOCK format -sample_json(); ///< JSON parsing and emitting -sample_anchors_and_aliases(); ///< deal with YAML anchors and aliases -sample_tags(); ///< deal with YAML type tags -sample_docs(); ///< deal with YAML docs -sample_error_handler(); ///< set a custom error handler -sample_global_allocator(); ///< set a global allocator for ryml -sample_per_tree_allocator(); ///< set per-tree allocators -sample_static_trees(); ///< how to use static trees in ryml -sample_location_tracking(); ///< track node locations in the parsed source tree ``` diff --git a/changelog/current.md b/changelog/current.md index 099f3d067..afad6d057 100644 --- a/changelog/current.md +++ b/changelog/current.md @@ -2,10 +2,10 @@ Fix major error handling problem reported in [#389](https://github.com/biojppm/rapidyaml/issues/389) ([PR#411](https://github.com/biojppm/rapidyaml/pull/411)): - - The `NodeRef` and `ConstNodeRef` classes had many methods marked `noexcept` that were doing assertions which could throw exceptions, causing an abort instead of a throw whenever the assertion called an exception-throwing error callback. + - The `NodeRef` and `ConstNodeRef` classes are now conditional noexcept using `RYML_NOEXCEPT`, which evaluates either to nothing when assertions are enabled, and to `noexcept` otherwise. The problem was that these classes had many methods explicitly marked `noexcept`, but were doing assertions which could throw exceptions, causing an abort instead of a throw whenever the assertion called an exception-throwing error callback. - Also, this problem was compounded by exceptions being enabled in every build type -- despite the intention to have them only in debug builds. There was a problem in the preprocessor code to enable assertions which led to assertions being enabled in release builds even when `RYML_USE_ASSERT` was defined to 0. Thanks to @jdrouhard for reporting this. - Although the code is and was extensively tested, the testing was addressing mostly the happy path. Tests were added to ensure that the error behavior is as intended. - - Together with this changeset, a major revision was carried out of the asserting/checking status of each function in the node classes. In most cases, assertions were added to functions cases that were missing them. So **beware** - user code that was invalid will now assert or error out. Also, assertions and checks are now directed as much as possible to the callbacks of the closest scope, ie if a tree has custom callbacks, errors should go through those callbacks. + - Together with this changeset, a major revision was carried out of the asserting/checking status of each function in the node classes. In most cases, assertions were added to functions cases that were missing them. So **beware** - user code that was invalid will now assert or error out. Also, assertions and checks are now directed as much as possible to the callbacks of the closest scope, ie if a tree has custom callbacks, errors within the tree class should go through those callbacks. - Also, the intended assertion behavior is now in place: *no assertions in release builds*. **Beware** as well - user code which was relying on this will now silently succeed and return garbage in release builds. See the next points, which may help: - Added new methods to the `NodeRef`/`ConstNodeRef` classes: ```c++ @@ -38,9 +38,21 @@ Fix major error handling problem reported in [#389](https://github.com/biojppm/r /** Likewise, but return a seed node when pos is not found */ NodeRef at(csubstr key); ``` + - The state for `NodeRef` was refined, and now there are three mutually exclusive states (and class predicates) for an object of this class: + - `.invalid()` when the object was not initialized to any node + - `.readable()` when the object points at an existing tree+node + - `.is_seed()` when the object points at an hypotethic tree+node + - The previous state `.valid()` was deprecated: its semantics were confusing as it actually could be any of `.readable()` or `.is_seed()` + - Deprecated also the following methods for `NodeRef`/`ConstNodeRef`: + ```c++ + RYML_DEPRECATED() bool operator== (std::nullptr_t) const; + RYML_DEPRECATED() bool operator!= (std::nullptr_t) const; + RYML_DEPRECATED() bool operator== (csubstr val) const; + RYML_DEPRECATED() bool operator!= (csubstr val) const; + ``` - Added macros and respective cmake options to control error handling: - - `RYML_USE_ASSERT` - enable assertions regardless of build type. This is disabled by default. - - `RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS` - defines the same macro, which will make the default error handler provided by ryml throw exceptions instead of calling `std::abort()`. This is disabled by default. + - `RYML_USE_ASSERT` - enable assertions regardless of build type. This is disabled by default. This macro was already defined; the current PR adds the cmake option. + - `RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS` - make the default error handler provided by ryml throw exceptions instead of calling `std::abort()`. This is disabled by default. - Also, `RYML_DEBUG_BREAK()` is now enabled only if `RYML_DBG` is defined, as reported in [#362](https://github.com/biojppm/rapidyaml/issues/362). @@ -62,6 +74,7 @@ Fix major error handling problem reported in [#389](https://github.com/biojppm/r - Fix [#356](https://github.com/biojppm/rapidyaml/issues/356) - fix overzealous check in `emit_as()`. An id may be larger than the tree's size, eg when nodes were removed. ([PR#357](https://github.com/biojppm/rapidyaml/pull/357)). - Fix [#417](https://github.com/biojppm/rapidyaml/issues/417)) - add quickstart example explaining how to avoid precision loss while serializing floats ([PR#420](https://github.com/biojppm/rapidyaml/pull/420)). + ### Thanks - @Neko-Box-Coder diff --git a/samples/quickstart.cpp b/samples/quickstart.cpp index 64b89fcf4..889cff178 100644 --- a/samples/quickstart.cpp +++ b/samples/quickstart.cpp @@ -467,7 +467,7 @@ void sample_quick_overview() // root["john"] = ryml::to_csubstr(ok); // don't, will dangle wroot["john"] << ryml::to_csubstr(ok); // OK, copy to the tree's arena } - CHECK(root["john"] == "in_scope"); // OK! + CHECK(root["john"].val() == "in_scope"); // OK! // serializing floating points: wroot["float"] << 2.4; // to force a particular precision or float format: @@ -518,8 +518,9 @@ void sample_quick_overview() CHECK(root["newmap (serialized)"].num_children() == 0); CHECK(root["newmap (serialized)"].is_map()); // - // When the tree is mutable, operator[] does not mutate the tree - // until the returned node is written to. + // When the tree is mutable, operator[] first searches the tree + // for the does not mutate the tree until the returned node is + // written to. // // Until such time, the NodeRef object keeps in itself the required // information to write to the proper place in the tree. This is @@ -541,8 +542,10 @@ void sample_quick_overview() // tree. // CHECK(!root.has_child("I am not nothing")); - ryml::NodeRef nothing = wroot["I am nothing"]; - CHECK(nothing.valid()); // points at the tree, and a specific place in the tree + ryml::NodeRef nothing; + CHECK(nothing.invalid()); // invalid because it points at nothing + nothing = wroot["I am nothing"]; + CHECK(!nothing.invalid()); // points at the tree, and a specific place in the tree CHECK(nothing.is_seed()); // ... but nothing is there yet. CHECK(!root.has_child("I am nothing")); // same as above CHECK(!nothing.readable()); // ... and this node cannot be used to @@ -550,27 +553,27 @@ void sample_quick_overview() ryml::NodeRef something = wroot["I am something"]; ryml::ConstNodeRef constsomething = wroot["I am something"]; CHECK(!root.has_child("I am something")); // same as above - CHECK(something.valid()); + CHECK(!something.invalid()); CHECK(something.is_seed()); // same as above CHECK(!something.readable()); // same as above - CHECK(!constsomething.valid()); // NOTE: because a ConstNodeRef cannot be - // used to mutate a tree, it is only valid() - // if it is pointing at an existing node. + CHECK(constsomething.invalid()); // NOTE: because a ConstNodeRef cannot be + // used to mutate a tree, it is only valid() + // if it is pointing at an existing node. something = "indeed"; // this will commit the seed to the tree, mutating at the proper place CHECK(root.has_child("I am something")); CHECK(root["I am something"].val() == "indeed"); - CHECK(something.valid()); // it was already valid + CHECK(!something.invalid()); // it was already valid CHECK(!something.is_seed()); // now the tree has this node, so the // ref is no longer a seed CHECK(something.readable()); // and it is now readable // // now the constref is also valid (but it needs to be reassigned): ryml::ConstNodeRef constsomethingnew = wroot["I am something"]; - CHECK(constsomethingnew.valid()); + CHECK(!constsomethingnew.invalid()); CHECK(constsomethingnew.readable()); // note that the old constref is now stale, because it only keeps // the state at creation: - CHECK(!constsomething.valid()); + CHECK(constsomething.invalid()); CHECK(!constsomething.readable()); // // ----------------------------------------------------------- @@ -590,6 +593,7 @@ void sample_quick_overview() if(wbar.readable() && wbar.is_seq()) // .is_seq() requires .readable() { CHECK(wbar[0].readable() && wbar[0].val() == "20"); + CHECK( ! wbar[100].readable()); CHECK( ! wbar[100].readable() || wbar[100].val() == "100"); // <- no crash because it is not .readable(), so never tries to call .val() // this would work as well: CHECK( ! wbar[0].is_seed() && wbar[0].val() == "20"); @@ -1994,13 +1998,13 @@ cars: GTO void sample_create_trees() { ryml::NodeRef doe; - CHECK(!doe.valid()); // it's pointing at nowhere + CHECK(doe.invalid()); // it's pointing at nowhere ryml::Tree tree; ryml::NodeRef root = tree.rootref(); root |= ryml::MAP; // mark root as a map doe = root["doe"]; - CHECK(doe.valid()); // it's now pointing at the tree + CHECK(!doe.invalid()); // it's now pointing at the tree CHECK(doe.is_seed()); // but the tree has nothing there, so this is only a seed // set the value of the node @@ -3957,8 +3961,8 @@ ship_to: *id001 CHECK( ! tree["val"].is_key_ref()); // notice *valref is now turned to val CHECK( ! tree["val"].is_val_ref()); // notice *valref is now turned to val - CHECK(tree["ship_to"]["city"] == "East Centerville"); - CHECK(tree["ship_to"]["state"] == "KS"); + CHECK(tree["ship_to"]["city"].val() == "East Centerville"); + CHECK(tree["ship_to"]["state"].val() == "KS"); } diff --git a/src/c4/yml/emit.def.hpp b/src/c4/yml/emit.def.hpp index cf184ad77..8f904bcc2 100644 --- a/src/c4/yml/emit.def.hpp +++ b/src/c4/yml/emit.def.hpp @@ -38,7 +38,7 @@ substr Emitter::emit_as(EmitType_e type, Tree const& t, bool error_on_ex template substr Emitter::emit_as(EmitType_e type, ConstNodeRef const& n, bool error_on_excess) { - _RYML_CB_CHECK(n.tree()->callbacks(), n.valid()); + _RYML_CB_CHECK(n.tree()->callbacks(), n.readable()); return this->emit_as(type, *n.tree(), n.id(), error_on_excess); } diff --git a/src/c4/yml/emit.hpp b/src/c4/yml/emit.hpp index c7cdd2a1a..09ae9fc3c 100644 --- a/src/c4/yml/emit.hpp +++ b/src/c4/yml/emit.hpp @@ -433,7 +433,7 @@ CharOwningContainer emitrs_json(Tree const& t) template substr emitrs_yaml(ConstNodeRef const& n, CharOwningContainer * cont) { - _RYML_CB_CHECK(n.tree()->callbacks(), n.valid()); + _RYML_CB_CHECK(n.tree()->callbacks(), n.readable()); return emitrs_yaml(*n.tree(), n.id(), cont); } template @@ -447,7 +447,7 @@ RYML_DEPRECATE_EMITRS substr emitrs(ConstNodeRef const& n, CharOwningContainer * template substr emitrs_json(ConstNodeRef const& n, CharOwningContainer * cont) { - _RYML_CB_CHECK(n.tree()->callbacks(), n.valid()); + _RYML_CB_CHECK(n.tree()->callbacks(), n.readable()); return emitrs_json(*n.tree(), n.id(), cont); } @@ -457,7 +457,7 @@ substr emitrs_json(ConstNodeRef const& n, CharOwningContainer * cont) template CharOwningContainer emitrs_yaml(ConstNodeRef const& n) { - _RYML_CB_CHECK(n.tree()->callbacks(), n.valid()); + _RYML_CB_CHECK(n.tree()->callbacks(), n.readable()); CharOwningContainer c; emitrs_yaml(*n.tree(), n.id(), &c); return c; @@ -473,7 +473,7 @@ RYML_DEPRECATE_EMITRS CharOwningContainer emitrs(ConstNodeRef const& n) template CharOwningContainer emitrs_json(ConstNodeRef const& n) { - _RYML_CB_CHECK(n.tree()->callbacks(), n.valid()); + _RYML_CB_CHECK(n.tree()->callbacks(), n.readable()); CharOwningContainer c; emitrs_json(*n.tree(), n.id(), &c); return c; diff --git a/src/c4/yml/node.hpp b/src/c4/yml/node.hpp index 12bc6d259..f4672d69b 100644 --- a/src/c4/yml/node.hpp +++ b/src/c4/yml/node.hpp @@ -160,10 +160,10 @@ struct RoNodeMethods #define id__ ((Impl const* C4_RESTRICT)this)->m_id // require readable: this is a precondition for reading from the // tree using this object. - #define _C4RV() \ + #define _C4RR() \ RYML_ASSERT(tree_ != nullptr); \ _RYML_CB_ASSERT(tree_->m_callbacks, id_ != NONE); \ - _RYML_CB_ASSERT(tree_->m_callbacks, (!(((Impl const* C4_RESTRICT)this)->is_seed()))); + _RYML_CB_ASSERT(tree_->m_callbacks, (((Impl const* C4_RESTRICT)this)->readable())); #define _C4_IF_MUTABLE(ty) typename std::enable_if::value, ty>::type public: @@ -177,24 +177,24 @@ struct RoNodeMethods template C4_ALWAYS_INLINE auto get() RYML_NOEXCEPT -> _C4_IF_MUTABLE(NodeData*) { return ((Impl const*)this)->readable() ? tree__->get(id__) : nullptr; } - C4_ALWAYS_INLINE NodeType type() const RYML_NOEXCEPT { _C4RV(); return tree_->type(id_); } - C4_ALWAYS_INLINE const char* type_str() const RYML_NOEXCEPT { _C4RV(); return tree_->type_str(id_); } + C4_ALWAYS_INLINE NodeType type() const RYML_NOEXCEPT { _C4RR(); return tree_->type(id_); } + C4_ALWAYS_INLINE const char* type_str() const RYML_NOEXCEPT { _C4RR(); return tree_->type_str(id_); } - C4_ALWAYS_INLINE csubstr key() const RYML_NOEXCEPT { _C4RV(); return tree_->key(id_); } - C4_ALWAYS_INLINE csubstr key_tag() const RYML_NOEXCEPT { _C4RV(); return tree_->key_tag(id_); } - C4_ALWAYS_INLINE csubstr key_ref() const RYML_NOEXCEPT { _C4RV(); return tree_->key_ref(id_); } - C4_ALWAYS_INLINE csubstr key_anchor() const RYML_NOEXCEPT { _C4RV(); return tree_->key_anchor(id_); } + C4_ALWAYS_INLINE csubstr key() const RYML_NOEXCEPT { _C4RR(); return tree_->key(id_); } + C4_ALWAYS_INLINE csubstr key_tag() const RYML_NOEXCEPT { _C4RR(); return tree_->key_tag(id_); } + C4_ALWAYS_INLINE csubstr key_ref() const RYML_NOEXCEPT { _C4RR(); return tree_->key_ref(id_); } + C4_ALWAYS_INLINE csubstr key_anchor() const RYML_NOEXCEPT { _C4RR(); return tree_->key_anchor(id_); } - C4_ALWAYS_INLINE csubstr val() const RYML_NOEXCEPT { _C4RV(); return tree_->val(id_); } - C4_ALWAYS_INLINE csubstr val_tag() const RYML_NOEXCEPT { _C4RV(); return tree_->val_tag(id_); } - C4_ALWAYS_INLINE csubstr val_ref() const RYML_NOEXCEPT { _C4RV(); return tree_->val_ref(id_); } - C4_ALWAYS_INLINE csubstr val_anchor() const RYML_NOEXCEPT { _C4RV(); return tree_->val_anchor(id_); } + C4_ALWAYS_INLINE csubstr val() const RYML_NOEXCEPT { _C4RR(); return tree_->val(id_); } + C4_ALWAYS_INLINE csubstr val_tag() const RYML_NOEXCEPT { _C4RR(); return tree_->val_tag(id_); } + C4_ALWAYS_INLINE csubstr val_ref() const RYML_NOEXCEPT { _C4RR(); return tree_->val_ref(id_); } + C4_ALWAYS_INLINE csubstr val_anchor() const RYML_NOEXCEPT { _C4RR(); return tree_->val_anchor(id_); } - C4_ALWAYS_INLINE NodeScalar const& keysc() const RYML_NOEXCEPT { _C4RV(); return tree_->keysc(id_); } - C4_ALWAYS_INLINE NodeScalar const& valsc() const RYML_NOEXCEPT { _C4RV(); return tree_->valsc(id_); } + C4_ALWAYS_INLINE NodeScalar const& keysc() const RYML_NOEXCEPT { _C4RR(); return tree_->keysc(id_); } + C4_ALWAYS_INLINE NodeScalar const& valsc() const RYML_NOEXCEPT { _C4RR(); return tree_->valsc(id_); } - C4_ALWAYS_INLINE bool key_is_null() const RYML_NOEXCEPT { _C4RV(); return tree_->key_is_null(id_); } - C4_ALWAYS_INLINE bool val_is_null() const RYML_NOEXCEPT { _C4RV(); return tree_->val_is_null(id_); } + C4_ALWAYS_INLINE bool key_is_null() const RYML_NOEXCEPT { _C4RR(); return tree_->key_is_null(id_); } + C4_ALWAYS_INLINE bool val_is_null() const RYML_NOEXCEPT { _C4RR(); return tree_->val_is_null(id_); } /** @} */ @@ -203,33 +203,33 @@ struct RoNodeMethods /** @name node property predicates */ /** @{ */ - C4_ALWAYS_INLINE bool empty() const RYML_NOEXCEPT { _C4RV(); return tree_->empty(id_); } - C4_ALWAYS_INLINE bool is_stream() const RYML_NOEXCEPT { _C4RV(); return tree_->is_stream(id_); } - C4_ALWAYS_INLINE bool is_doc() const RYML_NOEXCEPT { _C4RV(); return tree_->is_doc(id_); } - C4_ALWAYS_INLINE bool is_container() const RYML_NOEXCEPT { _C4RV(); return tree_->is_container(id_); } - C4_ALWAYS_INLINE bool is_map() const RYML_NOEXCEPT { _C4RV(); return tree_->is_map(id_); } - C4_ALWAYS_INLINE bool is_seq() const RYML_NOEXCEPT { _C4RV(); return tree_->is_seq(id_); } - C4_ALWAYS_INLINE bool has_val() const RYML_NOEXCEPT { _C4RV(); return tree_->has_val(id_); } - C4_ALWAYS_INLINE bool has_key() const RYML_NOEXCEPT { _C4RV(); return tree_->has_key(id_); } - C4_ALWAYS_INLINE bool is_val() const RYML_NOEXCEPT { _C4RV(); return tree_->is_val(id_); } - C4_ALWAYS_INLINE bool is_keyval() const RYML_NOEXCEPT { _C4RV(); return tree_->is_keyval(id_); } - C4_ALWAYS_INLINE bool has_key_tag() const RYML_NOEXCEPT { _C4RV(); return tree_->has_key_tag(id_); } - C4_ALWAYS_INLINE bool has_val_tag() const RYML_NOEXCEPT { _C4RV(); return tree_->has_val_tag(id_); } - C4_ALWAYS_INLINE bool has_key_anchor() const RYML_NOEXCEPT { _C4RV(); return tree_->has_key_anchor(id_); } - C4_ALWAYS_INLINE bool is_key_anchor() const RYML_NOEXCEPT { _C4RV(); return tree_->is_key_anchor(id_); } - C4_ALWAYS_INLINE bool has_val_anchor() const RYML_NOEXCEPT { _C4RV(); return tree_->has_val_anchor(id_); } - C4_ALWAYS_INLINE bool is_val_anchor() const RYML_NOEXCEPT { _C4RV(); return tree_->is_val_anchor(id_); } - C4_ALWAYS_INLINE bool has_anchor() const RYML_NOEXCEPT { _C4RV(); return tree_->has_anchor(id_); } - C4_ALWAYS_INLINE bool is_anchor() const RYML_NOEXCEPT { _C4RV(); return tree_->is_anchor(id_); } - C4_ALWAYS_INLINE bool is_key_ref() const RYML_NOEXCEPT { _C4RV(); return tree_->is_key_ref(id_); } - C4_ALWAYS_INLINE bool is_val_ref() const RYML_NOEXCEPT { _C4RV(); return tree_->is_val_ref(id_); } - C4_ALWAYS_INLINE bool is_ref() const RYML_NOEXCEPT { _C4RV(); return tree_->is_ref(id_); } - C4_ALWAYS_INLINE bool is_anchor_or_ref() const RYML_NOEXCEPT { _C4RV(); return tree_->is_anchor_or_ref(id_); } - C4_ALWAYS_INLINE bool is_key_quoted() const RYML_NOEXCEPT { _C4RV(); return tree_->is_key_quoted(id_); } - C4_ALWAYS_INLINE bool is_val_quoted() const RYML_NOEXCEPT { _C4RV(); return tree_->is_val_quoted(id_); } - C4_ALWAYS_INLINE bool is_quoted() const RYML_NOEXCEPT { _C4RV(); return tree_->is_quoted(id_); } - C4_ALWAYS_INLINE bool parent_is_seq() const RYML_NOEXCEPT { _C4RV(); return tree_->parent_is_seq(id_); } - C4_ALWAYS_INLINE bool parent_is_map() const RYML_NOEXCEPT { _C4RV(); return tree_->parent_is_map(id_); } + C4_ALWAYS_INLINE bool empty() const RYML_NOEXCEPT { _C4RR(); return tree_->empty(id_); } + C4_ALWAYS_INLINE bool is_stream() const RYML_NOEXCEPT { _C4RR(); return tree_->is_stream(id_); } + C4_ALWAYS_INLINE bool is_doc() const RYML_NOEXCEPT { _C4RR(); return tree_->is_doc(id_); } + C4_ALWAYS_INLINE bool is_container() const RYML_NOEXCEPT { _C4RR(); return tree_->is_container(id_); } + C4_ALWAYS_INLINE bool is_map() const RYML_NOEXCEPT { _C4RR(); return tree_->is_map(id_); } + C4_ALWAYS_INLINE bool is_seq() const RYML_NOEXCEPT { _C4RR(); return tree_->is_seq(id_); } + C4_ALWAYS_INLINE bool has_val() const RYML_NOEXCEPT { _C4RR(); return tree_->has_val(id_); } + C4_ALWAYS_INLINE bool has_key() const RYML_NOEXCEPT { _C4RR(); return tree_->has_key(id_); } + C4_ALWAYS_INLINE bool is_val() const RYML_NOEXCEPT { _C4RR(); return tree_->is_val(id_); } + C4_ALWAYS_INLINE bool is_keyval() const RYML_NOEXCEPT { _C4RR(); return tree_->is_keyval(id_); } + C4_ALWAYS_INLINE bool has_key_tag() const RYML_NOEXCEPT { _C4RR(); return tree_->has_key_tag(id_); } + C4_ALWAYS_INLINE bool has_val_tag() const RYML_NOEXCEPT { _C4RR(); return tree_->has_val_tag(id_); } + C4_ALWAYS_INLINE bool has_key_anchor() const RYML_NOEXCEPT { _C4RR(); return tree_->has_key_anchor(id_); } + C4_ALWAYS_INLINE bool is_key_anchor() const RYML_NOEXCEPT { _C4RR(); return tree_->is_key_anchor(id_); } + C4_ALWAYS_INLINE bool has_val_anchor() const RYML_NOEXCEPT { _C4RR(); return tree_->has_val_anchor(id_); } + C4_ALWAYS_INLINE bool is_val_anchor() const RYML_NOEXCEPT { _C4RR(); return tree_->is_val_anchor(id_); } + C4_ALWAYS_INLINE bool has_anchor() const RYML_NOEXCEPT { _C4RR(); return tree_->has_anchor(id_); } + C4_ALWAYS_INLINE bool is_anchor() const RYML_NOEXCEPT { _C4RR(); return tree_->is_anchor(id_); } + C4_ALWAYS_INLINE bool is_key_ref() const RYML_NOEXCEPT { _C4RR(); return tree_->is_key_ref(id_); } + C4_ALWAYS_INLINE bool is_val_ref() const RYML_NOEXCEPT { _C4RR(); return tree_->is_val_ref(id_); } + C4_ALWAYS_INLINE bool is_ref() const RYML_NOEXCEPT { _C4RR(); return tree_->is_ref(id_); } + C4_ALWAYS_INLINE bool is_anchor_or_ref() const RYML_NOEXCEPT { _C4RR(); return tree_->is_anchor_or_ref(id_); } + C4_ALWAYS_INLINE bool is_key_quoted() const RYML_NOEXCEPT { _C4RR(); return tree_->is_key_quoted(id_); } + C4_ALWAYS_INLINE bool is_val_quoted() const RYML_NOEXCEPT { _C4RR(); return tree_->is_val_quoted(id_); } + C4_ALWAYS_INLINE bool is_quoted() const RYML_NOEXCEPT { _C4RR(); return tree_->is_quoted(id_); } + C4_ALWAYS_INLINE bool parent_is_seq() const RYML_NOEXCEPT { _C4RR(); return tree_->parent_is_seq(id_); } + C4_ALWAYS_INLINE bool parent_is_map() const RYML_NOEXCEPT { _C4RR(); return tree_->parent_is_map(id_); } /** @} */ @@ -238,22 +238,22 @@ struct RoNodeMethods /** @name hierarchy predicates */ /** @{ */ - C4_ALWAYS_INLINE bool is_root() const RYML_NOEXCEPT { _C4RV(); return tree_->is_root(id_); } - C4_ALWAYS_INLINE bool has_parent() const RYML_NOEXCEPT { _C4RV(); return tree_->has_parent(id_); } + C4_ALWAYS_INLINE bool is_root() const RYML_NOEXCEPT { _C4RR(); return tree_->is_root(id_); } + C4_ALWAYS_INLINE bool has_parent() const RYML_NOEXCEPT { _C4RR(); return tree_->has_parent(id_); } - C4_ALWAYS_INLINE bool has_child(ConstImpl const& n) const RYML_NOEXCEPT { _C4RV(); return n.readable() ? tree_->has_child(id_, n.m_id) : false; } - C4_ALWAYS_INLINE bool has_child(size_t node) const RYML_NOEXCEPT { _C4RV(); return tree_->has_child(id_, node); } - C4_ALWAYS_INLINE bool has_child(csubstr name) const RYML_NOEXCEPT { _C4RV(); return tree_->has_child(id_, name); } - C4_ALWAYS_INLINE bool has_children() const RYML_NOEXCEPT { _C4RV(); return tree_->has_children(id_); } + C4_ALWAYS_INLINE bool has_child(ConstImpl const& n) const RYML_NOEXCEPT { _C4RR(); return n.readable() ? tree_->has_child(id_, n.m_id) : false; } + C4_ALWAYS_INLINE bool has_child(size_t node) const RYML_NOEXCEPT { _C4RR(); return tree_->has_child(id_, node); } + C4_ALWAYS_INLINE bool has_child(csubstr name) const RYML_NOEXCEPT { _C4RR(); return tree_->has_child(id_, name); } + C4_ALWAYS_INLINE bool has_children() const RYML_NOEXCEPT { _C4RR(); return tree_->has_children(id_); } - C4_ALWAYS_INLINE bool has_sibling(ConstImpl const& n) const RYML_NOEXCEPT { _C4RV(); return n.readable() ? tree_->has_sibling(id_, n.m_id) : false; } - C4_ALWAYS_INLINE bool has_sibling(size_t node) const RYML_NOEXCEPT { _C4RV(); return tree_->has_sibling(id_, node); } - C4_ALWAYS_INLINE bool has_sibling(csubstr name) const RYML_NOEXCEPT { _C4RV(); return tree_->has_sibling(id_, name); } + C4_ALWAYS_INLINE bool has_sibling(ConstImpl const& n) const RYML_NOEXCEPT { _C4RR(); return n.readable() ? tree_->has_sibling(id_, n.m_id) : false; } + C4_ALWAYS_INLINE bool has_sibling(size_t node) const RYML_NOEXCEPT { _C4RR(); return tree_->has_sibling(id_, node); } + C4_ALWAYS_INLINE bool has_sibling(csubstr name) const RYML_NOEXCEPT { _C4RR(); return tree_->has_sibling(id_, name); } /** does not count with this */ - C4_ALWAYS_INLINE bool has_other_siblings() const RYML_NOEXCEPT { _C4RV(); return tree_->has_other_siblings(id_); } + C4_ALWAYS_INLINE bool has_other_siblings() const RYML_NOEXCEPT { _C4RR(); return tree_->has_other_siblings(id_); } /** counts with this */ - RYML_DEPRECATED("use has_other_siblings()") bool has_siblings() const RYML_NOEXCEPT { _C4RV(); return tree_->has_siblings(id_); } + RYML_DEPRECATED("use has_other_siblings()") bool has_siblings() const RYML_NOEXCEPT { _C4RR(); return tree_->has_siblings(id_); } /** @} */ @@ -269,59 +269,59 @@ struct RoNodeMethods C4_ALWAYS_INLINE ConstImpl doc(size_t num) const RYML_NOEXCEPT { RYML_ASSERT(tree_); return {tree_, tree_->doc(num)}; } template - C4_ALWAYS_INLINE auto parent() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->parent(id__)}; } - C4_ALWAYS_INLINE ConstImpl parent() const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->parent(id_)}; } + C4_ALWAYS_INLINE auto parent() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->parent(id__)}; } + C4_ALWAYS_INLINE ConstImpl parent() const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->parent(id_)}; } template - C4_ALWAYS_INLINE auto first_child() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->first_child(id__)}; } - C4_ALWAYS_INLINE ConstImpl first_child() const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->first_child(id_)}; } + C4_ALWAYS_INLINE auto first_child() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->first_child(id__)}; } + C4_ALWAYS_INLINE ConstImpl first_child() const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->first_child(id_)}; } template - C4_ALWAYS_INLINE auto last_child() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->last_child(id__)}; } - C4_ALWAYS_INLINE ConstImpl last_child () const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->last_child (id_)}; } + C4_ALWAYS_INLINE auto last_child() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->last_child(id__)}; } + C4_ALWAYS_INLINE ConstImpl last_child () const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->last_child (id_)}; } template - C4_ALWAYS_INLINE auto child(size_t pos) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->child(id__, pos)}; } - C4_ALWAYS_INLINE ConstImpl child(size_t pos) const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->child(id_, pos)}; } + C4_ALWAYS_INLINE auto child(size_t pos) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->child(id__, pos)}; } + C4_ALWAYS_INLINE ConstImpl child(size_t pos) const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->child(id_, pos)}; } template - C4_ALWAYS_INLINE auto find_child(csubstr name) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->find_child(id__, name)}; } - C4_ALWAYS_INLINE ConstImpl find_child(csubstr name) const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->find_child(id_, name)}; } + C4_ALWAYS_INLINE auto find_child(csubstr name) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->find_child(id__, name)}; } + C4_ALWAYS_INLINE ConstImpl find_child(csubstr name) const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->find_child(id_, name)}; } template - C4_ALWAYS_INLINE auto prev_sibling() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->prev_sibling(id__)}; } - C4_ALWAYS_INLINE ConstImpl prev_sibling() const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->prev_sibling(id_)}; } + C4_ALWAYS_INLINE auto prev_sibling() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->prev_sibling(id__)}; } + C4_ALWAYS_INLINE ConstImpl prev_sibling() const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->prev_sibling(id_)}; } template - C4_ALWAYS_INLINE auto next_sibling() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->next_sibling(id__)}; } - C4_ALWAYS_INLINE ConstImpl next_sibling() const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->next_sibling(id_)}; } + C4_ALWAYS_INLINE auto next_sibling() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->next_sibling(id__)}; } + C4_ALWAYS_INLINE ConstImpl next_sibling() const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->next_sibling(id_)}; } template - C4_ALWAYS_INLINE auto first_sibling() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->first_sibling(id__)}; } - C4_ALWAYS_INLINE ConstImpl first_sibling() const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->first_sibling(id_)}; } + C4_ALWAYS_INLINE auto first_sibling() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->first_sibling(id__)}; } + C4_ALWAYS_INLINE ConstImpl first_sibling() const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->first_sibling(id_)}; } template - C4_ALWAYS_INLINE auto last_sibling() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->last_sibling(id__)}; } - C4_ALWAYS_INLINE ConstImpl last_sibling () const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->last_sibling(id_)}; } + C4_ALWAYS_INLINE auto last_sibling() RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->last_sibling(id__)}; } + C4_ALWAYS_INLINE ConstImpl last_sibling () const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->last_sibling(id_)}; } template - C4_ALWAYS_INLINE auto sibling(size_t pos) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->sibling(id__, pos)}; } - C4_ALWAYS_INLINE ConstImpl sibling(size_t pos) const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->sibling(id_, pos)}; } + C4_ALWAYS_INLINE auto sibling(size_t pos) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->sibling(id__, pos)}; } + C4_ALWAYS_INLINE ConstImpl sibling(size_t pos) const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->sibling(id_, pos)}; } template - C4_ALWAYS_INLINE auto find_sibling(csubstr name) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RV(); return {tree__, tree__->find_sibling(id__, name)}; } - C4_ALWAYS_INLINE ConstImpl find_sibling(csubstr name) const RYML_NOEXCEPT { _C4RV(); return {tree_, tree_->find_sibling(id_, name)}; } + C4_ALWAYS_INLINE auto find_sibling(csubstr name) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _C4RR(); return {tree__, tree__->find_sibling(id__, name)}; } + C4_ALWAYS_INLINE ConstImpl find_sibling(csubstr name) const RYML_NOEXCEPT { _C4RR(); return {tree_, tree_->find_sibling(id_, name)}; } /** O(#num_children) */ - C4_ALWAYS_INLINE size_t child_pos(ConstImpl const& n) const RYML_NOEXCEPT { _C4RV(); _RYML_CB_ASSERT(tree_->m_callbacks, n.readable()); return tree_->child_pos(id_, n.m_id); } + C4_ALWAYS_INLINE size_t child_pos(ConstImpl const& n) const RYML_NOEXCEPT { _C4RR(); _RYML_CB_ASSERT(tree_->m_callbacks, n.readable()); return tree_->child_pos(id_, n.m_id); } /** O(#num_children) */ - C4_ALWAYS_INLINE size_t num_children() const RYML_NOEXCEPT { _C4RV(); return tree_->num_children(id_); } + C4_ALWAYS_INLINE size_t num_children() const RYML_NOEXCEPT { _C4RR(); return tree_->num_children(id_); } /** O(#num_siblings) */ - C4_ALWAYS_INLINE size_t num_siblings() const RYML_NOEXCEPT { _C4RV(); return tree_->num_siblings(id_); } - C4_ALWAYS_INLINE size_t num_other_siblings() const RYML_NOEXCEPT { _C4RV(); return tree_->num_other_siblings(id_); } - C4_ALWAYS_INLINE size_t sibling_pos(ConstImpl const& n) const RYML_NOEXCEPT { _C4RV(); _RYML_CB_ASSERT(tree_->callbacks(), n.readable()); return tree_->child_pos(tree_->parent(id_), n.m_id); } + C4_ALWAYS_INLINE size_t num_siblings() const RYML_NOEXCEPT { _C4RR(); return tree_->num_siblings(id_); } + C4_ALWAYS_INLINE size_t num_other_siblings() const RYML_NOEXCEPT { _C4RR(); return tree_->num_other_siblings(id_); } + C4_ALWAYS_INLINE size_t sibling_pos(ConstImpl const& n) const RYML_NOEXCEPT { _C4RR(); _RYML_CB_ASSERT(tree_->callbacks(), n.readable()); return tree_->child_pos(tree_->parent(id_), n.m_id); } /** @} */ @@ -352,7 +352,7 @@ struct RoNodeMethods template C4_ALWAYS_INLINE auto operator[] (csubstr key) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { - _C4RV(); + _C4RR(); size_t ch = tree__->find_child(id__, key); return ch != NONE ? Impl(tree__, ch) : Impl(tree__, id__, key); } @@ -378,7 +378,7 @@ struct RoNodeMethods template C4_ALWAYS_INLINE auto operator[] (size_t pos) RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { - _C4RV(); + _C4RR(); size_t ch = tree__->child(id__, pos); return ch != NONE ? Impl(tree__, ch) : Impl(tree__, id__, pos); } @@ -394,7 +394,7 @@ struct RoNodeMethods * @see https://github.com/biojppm/rapidyaml/issues/389 */ C4_ALWAYS_INLINE ConstImpl operator[] (csubstr key) const RYML_NOEXCEPT { - _C4RV(); + _C4RR(); size_t ch = tree_->find_child(id_, key); _RYML_CB_ASSERT(tree_->m_callbacks, ch != NONE); return {tree_, ch}; @@ -411,7 +411,7 @@ struct RoNodeMethods * @see https://github.com/biojppm/rapidyaml/issues/389 */ C4_ALWAYS_INLINE ConstImpl operator[] (size_t pos) const RYML_NOEXCEPT { - _C4RV(); + _C4RR(); size_t ch = tree_->child(id_, pos); _RYML_CB_ASSERT(tree_->m_callbacks, ch != NONE); return {tree_, ch}; @@ -557,7 +557,7 @@ struct RoNodeMethods template ConstImpl const& operator>> (T &v) const { - _C4RV(); + _C4RR(); if( ! read((ConstImpl const&)*this, &v)) _RYML_CB_ERR(tree_->m_callbacks, "could not deserialize value"); return *((ConstImpl const*)this); @@ -567,7 +567,7 @@ struct RoNodeMethods template ConstImpl const& operator>> (Key v) const { - _C4RV(); + _C4RR(); if( ! from_chars(key(), &v.k)) _RYML_CB_ERR(tree_->m_callbacks, "could not deserialize key"); return *((ConstImpl const*)this); @@ -592,7 +592,7 @@ struct RoNodeMethods * @return the size of base64-decoded blob */ size_t deserialize_key(fmt::base64_wrapper v) const { - _C4RV(); + _C4RR(); return from_chars(key(), &v); } /** decode the base64-encoded key and assign the @@ -600,16 +600,16 @@ struct RoNodeMethods * @return the size of base64-decoded blob */ size_t deserialize_val(fmt::base64_wrapper v) const { - _C4RV(); + _C4RR(); return from_chars(val(), &v); }; template bool get_if(csubstr name, T *var) const { - _C4RV(); + _C4RR(); ConstImpl ch = find_child(name); - if(!ch.valid()) + if(!ch.readable()) return false; ch >> *var; return true; @@ -618,9 +618,9 @@ struct RoNodeMethods template bool get_if(csubstr name, T *var, T const& fallback) const { - _C4RV(); + _C4RR(); ConstImpl ch = find_child(name); - if(ch.valid()) + if(ch.readable()) { ch >> *var; return true; @@ -655,28 +655,28 @@ struct RoNodeMethods using const_children_view = detail::children_view_; template - C4_ALWAYS_INLINE auto begin() RYML_NOEXCEPT -> _C4_IF_MUTABLE(iterator) { _C4RV(); return iterator(tree__, tree__->first_child(id__)); } - C4_ALWAYS_INLINE const_iterator begin() const RYML_NOEXCEPT { _C4RV(); return const_iterator(tree_, tree_->first_child(id_)); } - C4_ALWAYS_INLINE const_iterator cbegin() const RYML_NOEXCEPT { _C4RV(); return const_iterator(tree_, tree_->first_child(id_)); } + C4_ALWAYS_INLINE auto begin() RYML_NOEXCEPT -> _C4_IF_MUTABLE(iterator) { _C4RR(); return iterator(tree__, tree__->first_child(id__)); } + C4_ALWAYS_INLINE const_iterator begin() const RYML_NOEXCEPT { _C4RR(); return const_iterator(tree_, tree_->first_child(id_)); } + C4_ALWAYS_INLINE const_iterator cbegin() const RYML_NOEXCEPT { _C4RR(); return const_iterator(tree_, tree_->first_child(id_)); } template - C4_ALWAYS_INLINE auto end() RYML_NOEXCEPT -> _C4_IF_MUTABLE(iterator) { _C4RV(); return iterator(tree__, NONE); } - C4_ALWAYS_INLINE const_iterator end() const RYML_NOEXCEPT { _C4RV(); return const_iterator(tree_, NONE); } - C4_ALWAYS_INLINE const_iterator cend() const RYML_NOEXCEPT { _C4RV(); return const_iterator(tree_, tree_->first_child(id_)); } + C4_ALWAYS_INLINE auto end() RYML_NOEXCEPT -> _C4_IF_MUTABLE(iterator) { _C4RR(); return iterator(tree__, NONE); } + C4_ALWAYS_INLINE const_iterator end() const RYML_NOEXCEPT { _C4RR(); return const_iterator(tree_, NONE); } + C4_ALWAYS_INLINE const_iterator cend() const RYML_NOEXCEPT { _C4RR(); return const_iterator(tree_, tree_->first_child(id_)); } /** get an iterable view over children */ template - C4_ALWAYS_INLINE auto children() RYML_NOEXCEPT -> _C4_IF_MUTABLE(children_view) { _C4RV(); return children_view(begin(), end()); } + C4_ALWAYS_INLINE auto children() RYML_NOEXCEPT -> _C4_IF_MUTABLE(children_view) { _C4RR(); return children_view(begin(), end()); } /** get an iterable view over children */ - C4_ALWAYS_INLINE const_children_view children() const RYML_NOEXCEPT { _C4RV(); return const_children_view(begin(), end()); } + C4_ALWAYS_INLINE const_children_view children() const RYML_NOEXCEPT { _C4RR(); return const_children_view(begin(), end()); } /** get an iterable view over children */ - C4_ALWAYS_INLINE const_children_view cchildren() const RYML_NOEXCEPT { _C4RV(); return const_children_view(begin(), end()); } + C4_ALWAYS_INLINE const_children_view cchildren() const RYML_NOEXCEPT { _C4RR(); return const_children_view(begin(), end()); } /** get an iterable view over all siblings (including the calling node) */ template C4_ALWAYS_INLINE auto siblings() RYML_NOEXCEPT -> _C4_IF_MUTABLE(children_view) { - _C4RV(); + _C4RR(); NodeData const *nd = tree__->get(id__); return (nd->m_parent != NONE) ? // does it have a parent? children_view(iterator(tree__, tree_->get(nd->m_parent)->m_first_child), iterator(tree__, NONE)) @@ -686,7 +686,7 @@ struct RoNodeMethods /** get an iterable view over all siblings (including the calling node) */ C4_ALWAYS_INLINE const_children_view siblings() const RYML_NOEXCEPT { - _C4RV(); + _C4RR(); NodeData const *nd = tree_->get(id_); return (nd->m_parent != NONE) ? // does it have a parent? const_children_view(const_iterator(tree_, tree_->get(nd->m_parent)->m_first_child), const_iterator(tree_, NONE)) @@ -700,7 +700,7 @@ struct RoNodeMethods template bool visit(Visitor fn, size_t indentation_level=0, bool skip_root=true) const RYML_NOEXCEPT { - _C4RV(); + _C4RR(); return detail::_visit(*(ConstImpl const*)this, fn, indentation_level, skip_root); } /** visit every child node calling fn(node) */ @@ -708,7 +708,7 @@ struct RoNodeMethods auto visit(Visitor fn, size_t indentation_level=0, bool skip_root=true) RYML_NOEXCEPT -> _C4_IF_MUTABLE(bool) { - _C4RV(); + _C4RR(); return detail::_visit(*(Impl*)this, fn, indentation_level, skip_root); } @@ -716,7 +716,7 @@ struct RoNodeMethods template bool visit_stacked(Visitor fn, size_t indentation_level=0, bool skip_root=true) const RYML_NOEXCEPT { - _C4RV(); + _C4RR(); return detail::_visit_stacked(*(ConstImpl const*)this, fn, indentation_level, skip_root); } /** visit every child node calling fn(node, level) */ @@ -724,7 +724,7 @@ struct RoNodeMethods auto visit_stacked(Visitor fn, size_t indentation_level=0, bool skip_root=true) RYML_NOEXCEPT -> _C4_IF_MUTABLE(bool) { - _C4RV(); + _C4RR(); return detail::_visit_stacked(*(Impl*)this, fn, indentation_level, skip_root); } @@ -737,7 +737,7 @@ struct RoNodeMethods #endif #undef _C4_IF_MUTABLE - #undef _C4RV + #undef _C4RR #undef tree_ #undef tree__ #undef id_ @@ -808,16 +808,20 @@ class RYML_EXPORT ConstNodeRef : public detail::RoNodeMethodsoperator== (that); } - C4_ALWAYS_INLINE C4_PURE bool operator== (std::nullptr_t) const noexcept { return m_tree == nullptr || m_id == NONE; } - C4_ALWAYS_INLINE C4_PURE bool operator!= (std::nullptr_t) const noexcept { return ! this->operator== (nullptr); } + RYML_DEPRECATED("use invalid()") bool operator== (std::nullptr_t) const noexcept { return m_tree == nullptr || m_id == NONE; } + RYML_DEPRECATED("use !invalid()") bool operator!= (std::nullptr_t) const noexcept { return !(m_tree == nullptr || m_id == NONE); } - C4_ALWAYS_INLINE bool operator== (csubstr val) const RYML_NOEXCEPT { RYML_ASSERT(m_tree); _RYML_CB_ASSERT(m_tree->m_callbacks, m_id != NONE); return m_tree->val(m_id) == val; } - C4_ALWAYS_INLINE bool operator!= (csubstr val) const RYML_NOEXCEPT { RYML_ASSERT(m_tree); _RYML_CB_ASSERT(m_tree->m_callbacks, m_id != NONE); return m_tree->val(m_id) != val; } + RYML_DEPRECATED("use (this->val() == s)") bool operator== (csubstr s) const RYML_NOEXCEPT { RYML_ASSERT(m_tree); _RYML_CB_ASSERT(m_tree->m_callbacks, m_id != NONE); return m_tree->val(m_id) == s; } + RYML_DEPRECATED("use (this->val() != s)") bool operator!= (csubstr s) const RYML_NOEXCEPT { RYML_ASSERT(m_tree); _RYML_CB_ASSERT(m_tree->m_callbacks, m_id != NONE); return m_tree->val(m_id) != s; } /** @} */ @@ -863,10 +867,10 @@ class RYML_EXPORT ConstNodeRef : public detail::RoNodeMethods /** @name state_queries * @{ */ - /** true if the object is pointing at a tree and id. @see the doc for the NodeRef */ - inline bool valid() const { return m_tree != nullptr && m_id != NONE; } - /** true if the object is valid() and in seed state. @see the doc for the NodeRef */ - inline bool is_seed() const { return valid() && (m_seed.str != nullptr || m_seed.len != NONE); } - /** true if the object is valid() and NOT in seed state. @see the doc for the NodeRef */ - inline bool readable() const { return valid() && !is_seed(); } + /** true if the object is not referring to any existing or seed node @see the doc for the NodeRef */ + inline bool invalid() const { return m_tree == nullptr || m_id == NONE; } + /** true if the object is not invalid and in seed state. @see the doc for the NodeRef */ + inline bool is_seed() const { return (m_tree != NULL && m_id != NONE) && (m_seed.str != nullptr || m_seed.len != (size_t)NONE); } + /** true if the object is not invalid and not in seed state. @see the doc for the NodeRef */ + inline bool readable() const { return (m_tree != NULL && m_id != NONE) && (m_seed.str == nullptr && m_seed.len == (size_t)NONE); } + + RYML_DEPRECATED("use one of readable(), is_seed() or !invalid()") inline bool valid() const { return m_tree != nullptr && m_id != NONE; } inline void _clear_seed() { /*do the following manually or an assert is triggered: */ m_seed.str = nullptr; m_seed.len = NONE; } @@ -975,15 +981,18 @@ class RYML_EXPORT NodeRef : public detail::RoNodeMethods /** @name comparisons */ /** @{ */ - inline bool operator== (NodeRef const& that) const + bool operator== (NodeRef const& that) const { if(m_tree == that.m_tree && m_id == that.m_id) { - if(is_seed() == that.is_seed()) + bool seed = is_seed(); + if(seed == that.is_seed()) { - if(is_seed()) + if(seed) { - return (m_seed.len == that.m_seed.len) && (m_seed.str == that.m_seed.str || m_seed == that.m_seed); + return (m_seed.len == that.m_seed.len) + && (m_seed.str == that.m_seed.str + || m_seed == that.m_seed); // do strcmp only in the last resort } return true; } @@ -995,11 +1004,11 @@ class RYML_EXPORT NodeRef : public detail::RoNodeMethods inline bool operator== (ConstNodeRef const& that) const { return m_tree == that.m_tree && m_id == that.m_id && !is_seed(); } inline bool operator!= (ConstNodeRef const& that) const { return ! this->operator==(that); } - inline bool operator== (std::nullptr_t) const { return m_tree == nullptr || m_id == NONE || is_seed(); } - inline bool operator!= (std::nullptr_t) const { return ! this->operator==(nullptr); } + RYML_DEPRECATED("use !readable()") bool operator== (std::nullptr_t) const { return m_tree == nullptr || m_id == NONE || is_seed(); } + RYML_DEPRECATED("use readable()") bool operator!= (std::nullptr_t) const { return !(m_tree == nullptr || m_id == NONE || is_seed()); } - inline bool operator== (csubstr val) const { _C4RV(); _RYML_CB_ASSERT(m_tree->m_callbacks, has_val()); return m_tree->val(m_id) == val; } - inline bool operator!= (csubstr val) const { _C4RV(); _RYML_CB_ASSERT(m_tree->m_callbacks, has_val()); return m_tree->val(m_id) != val; } + RYML_DEPRECATED("use (this->val() == s)") bool operator== (csubstr s) const { _C4RV(); _RYML_CB_ASSERT(m_tree->m_callbacks, has_val()); return m_tree->val(m_id) == s; } + RYML_DEPRECATED("use (this->val() != s)") bool operator!= (csubstr s) const { _C4RV(); _RYML_CB_ASSERT(m_tree->m_callbacks, has_val()); return m_tree->val(m_id) != s; } /** @} */ @@ -1229,7 +1238,7 @@ class RYML_EXPORT NodeRef : public detail::RoNodeMethods } else { - _RYML_CB_ASSERT(m_tree->m_callbacks, valid()); + _RYML_CB_ASSERT(m_tree->m_callbacks, readable()); } } diff --git a/src/c4/yml/parse.cpp b/src/c4/yml/parse.cpp index 5e52a9697..0007e4d50 100644 --- a/src/c4/yml/parse.cpp +++ b/src/c4/yml/parse.cpp @@ -5528,7 +5528,7 @@ csubstr Parser::location_contents(Location const& loc) const Location Parser::location(ConstNodeRef node) const { - _RYML_CB_ASSERT(m_stack.m_callbacks, node.valid()); + _RYML_CB_ASSERT(m_stack.m_callbacks, node.readable()); return location(*node.tree(), node.id()); } diff --git a/test/test_case.cpp b/test/test_case.cpp index bdde31463..d317a51b0 100644 --- a/test/test_case.cpp +++ b/test/test_case.cpp @@ -362,8 +362,8 @@ void CaseNode::compare_child(yml::ConstNodeRef const& n, size_t pos) const if(type & MAP) { - auto actualch = n.find_child(expectedch.key); - if(actualch != nullptr) + ConstNodeRef actualch = n.find_child(expectedch.key); + if(!actualch.invalid()) { // there may be duplicate keys. if(actualch.id() != n[pos].id()) @@ -475,7 +475,7 @@ void CaseNode::compare(yml::ConstNodeRef const& actual, bool ignore_quote) const compare_child(actual, ic++); } - if(actual.first_child() != nullptr) + if(!actual.first_child().invalid()) { ic = 0; for(auto const ch : actual.first_child().siblings()) @@ -522,7 +522,7 @@ void print_path(ConstNodeRef const& n) size_t len = 0; char buf[1024]; ConstNodeRef p = n; - while(p != nullptr) + while(p.readable()) { if(p.has_key()) { @@ -539,7 +539,7 @@ void print_path(ConstNodeRef const& n) C4_ASSERT(len < sizeof(buf)); size_t pos = len; p = n; - while(p.valid() && p != nullptr) + while(p.readable()) { if(p.has_key()) { @@ -683,7 +683,7 @@ void test_invariants(ConstNodeRef const& n) EXPECT_TRUE(s.has_sibling(n)) _MORE_INFO; EXPECT_EQ(s.parent().get(), n.parent().get()) _MORE_INFO; } - if(n.parent() != nullptr) + if(n.parent().readable()) { EXPECT_EQ(n.parent().num_children() > 1, n.has_other_siblings()) _MORE_INFO; EXPECT_TRUE(n.parent().has_child(n)) _MORE_INFO; @@ -755,7 +755,7 @@ size_t test_tree_invariants(ConstNodeRef const& n) if(n.get()->m_prev_sibling == NONE) { - if(parent != nullptr) + if(parent.readable()) { EXPECT_EQ(parent.first_child().get(), n.get()); EXPECT_EQ(parent.first_child().id(), n.id()); @@ -764,14 +764,14 @@ size_t test_tree_invariants(ConstNodeRef const& n) if(n.get()->m_next_sibling == NONE) { - if(parent != nullptr) + if(parent.readable()) { EXPECT_EQ(parent.last_child().get(), n.get()); EXPECT_EQ(parent.last_child().id(), n.id()); } } - if(parent == nullptr) + if(!parent.readable()) { EXPECT_TRUE(n.is_root()); EXPECT_EQ(n.prev_sibling().get(), nullptr); diff --git a/test/test_github_issues.cpp b/test/test_github_issues.cpp index 3c12307fc..df68fd578 100644 --- a/test/test_github_issues.cpp +++ b/test/test_github_issues.cpp @@ -93,10 +93,11 @@ TEST(github, 60) ASSERT_TRUE(root.is_map()); ASSERT_TRUE(root.has_child("traits")); auto rb = root["traits"]["roleBonuses"][0]; - ASSERT_TRUE(rb.valid()); + ASSERT_FALSE(rb.invalid()); + ASSERT_TRUE(rb.readable()); EXPECT_EQ(rb["bonus"].val(), "5"); auto txt = rb["bonusText"]; - ASSERT_TRUE(txt.valid()); + ASSERT_TRUE(txt.readable()); ASSERT_TRUE(txt.is_map()); EXPECT_TRUE(txt.has_child("de")); EXPECT_TRUE(txt.has_child("en")); diff --git a/test/test_group.hpp b/test/test_group.hpp index f661ec9b5..fe0b4550a 100644 --- a/test/test_group.hpp +++ b/test/test_group.hpp @@ -15,6 +15,9 @@ #elif defined(__GNUC__) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunknown-pragmas" +# if __GNUC__ > 5 +# pragma GCC diagnostic ignored "-Wunused-const-variable" +# endif //# pragma GCC diagnostic ignored "-Wpragma-system-header-outside-header" #endif diff --git a/test/test_noderef.cpp b/test/test_noderef.cpp index 121ef2a87..017b0f518 100644 --- a/test/test_noderef.cpp +++ b/test/test_noderef.cpp @@ -196,27 +196,27 @@ TEST(NodeRef, valid_vs_seed_vs_readable) Tree tree = parse_in_arena("foo: bar"); NodeRef foo = tree["foo"]; ConstNodeRef const_foo = tree["foo"]; - EXPECT_TRUE(foo.valid()); + EXPECT_FALSE(foo.invalid()); EXPECT_FALSE(foo.is_seed()); EXPECT_TRUE(foo.readable()); - EXPECT_TRUE(const_foo.valid()); + EXPECT_FALSE(const_foo.invalid()); EXPECT_FALSE(const_foo.is_seed()); EXPECT_TRUE(const_foo.readable()); NodeRef none; - EXPECT_FALSE(none.valid()); + EXPECT_TRUE(none.invalid()); EXPECT_FALSE(none.is_seed()); EXPECT_FALSE(none.readable()); ConstNodeRef const_none; - EXPECT_FALSE(const_none.valid()); + EXPECT_TRUE(const_none.invalid()); EXPECT_FALSE(const_none.is_seed()); EXPECT_FALSE(const_none.readable()); none = tree["none"]; - EXPECT_TRUE(none.valid()); + EXPECT_FALSE(none.invalid()); EXPECT_TRUE(none.is_seed()); EXPECT_FALSE(none.readable()); ASSERT_FALSE(tree.rootref().has_child(none)); const_none = tree["none"]; - EXPECT_FALSE(const_none.valid()); + EXPECT_TRUE(const_none.invalid()); EXPECT_FALSE(const_none.is_seed()); EXPECT_TRUE(none.is_seed()); EXPECT_FALSE(none.readable()); @@ -339,10 +339,6 @@ void test_fail_read(Tree *tree, NodeT node) //_TEST_FAIL(const_node.visit([](const NodeT &n, size_t level){ (void)n; (void)level; return false; })); _TEST_SUCCEED(const_node == node); _TEST_SUCCEED(const_node != node); - _TEST_SUCCEED(const_node == nullptr); - _TEST_SUCCEED(const_node != nullptr); - _TEST_FAIL(const_node == "val"); - _TEST_FAIL(const_node != "val"); if(std::is_same::value) { ConstNodeRef other; @@ -375,7 +371,7 @@ TEST(NodeRef, cannot_read_from_invalid) NodeRef none; ASSERT_EQ(none.tree(), nullptr); ASSERT_EQ(none.id(), NONE); - EXPECT_FALSE(none.valid()); + EXPECT_TRUE(none.invalid()); EXPECT_FALSE(none.is_seed()); EXPECT_FALSE(none.readable()); test_fail_read(nullptr, none); @@ -396,7 +392,7 @@ TEST(ConstNodeRef, cannot_read_from_invalid) ConstNodeRef const_none; ASSERT_EQ(const_none.tree(), nullptr); ASSERT_EQ(const_none.id(), NONE); - EXPECT_FALSE(const_none.valid()); + EXPECT_TRUE(const_none.invalid()); EXPECT_FALSE(const_none.is_seed()); EXPECT_FALSE(const_none.readable()); test_fail_read(nullptr, const_none); @@ -422,7 +418,7 @@ TEST(NodeRef, cannot_read_from_seed) NodeRef none = tree["none"]; ASSERT_EQ(none.tree(), &tree); ASSERT_EQ(none.id(), 0); - EXPECT_TRUE(none.valid()); + EXPECT_FALSE(none.invalid()); EXPECT_TRUE(none.is_seed()); EXPECT_FALSE(none.readable()); test_fail_read(&tree, none); @@ -436,7 +432,7 @@ TEST(NodeRef, cannot_read_from_seed_subject) NodeRef none = tree["none"]; ASSERT_EQ(none.tree(), &tree); ASSERT_EQ(none.id(), 0); - EXPECT_TRUE(none.valid()); + EXPECT_FALSE(none.invalid()); EXPECT_TRUE(none.is_seed()); EXPECT_FALSE(none.readable()); test_fail_read(&tree, none); @@ -450,7 +446,7 @@ TEST(ConstNodeRef, cannot_read_from_seed_subject) ConstNodeRef const_none = tree["none"]; ASSERT_EQ(const_none.tree(), &tree); ASSERT_EQ(const_none.id(), NONE); - EXPECT_FALSE(const_none.valid()); + EXPECT_TRUE(const_none.invalid()); EXPECT_FALSE(const_none.is_seed()); EXPECT_FALSE(const_none.readable()); test_fail_read(&tree, const_none); @@ -732,7 +728,7 @@ TEST(NodeRef, remove_child__issue_356) SCOPED_TRACE(id); NodeRef formats = root["formats"]; std::cout << id << " id=" << formats.id() << "\n"; - EXPECT_TRUE(formats.valid()); + EXPECT_TRUE(formats.readable()); print_tree(tree); check_invariants(tree); EXPECT_EQ(emitrs_yaml(formats), expected); diff --git a/test/test_tree.cpp b/test/test_tree.cpp index 04fce801a..def97b834 100644 --- a/test/test_tree.cpp +++ b/test/test_tree.cpp @@ -967,28 +967,6 @@ TEST(Tree, operator_square_brackets_seq) EXPECT_EQ(cm[3].val(), "3"); EXPECT_EQ(cm[4].val(), "4"); // - EXPECT_TRUE(m[0] == "0"); - EXPECT_TRUE(m[1] == "1"); - EXPECT_TRUE(m[2] == "2"); - EXPECT_TRUE(m[3] == "3"); - EXPECT_TRUE(m[4] == "4"); - EXPECT_TRUE(cm[0] == "0"); - EXPECT_TRUE(cm[1] == "1"); - EXPECT_TRUE(cm[2] == "2"); - EXPECT_TRUE(cm[3] == "3"); - EXPECT_TRUE(cm[4] == "4"); - // - EXPECT_FALSE(m[0] != "0"); - EXPECT_FALSE(m[1] != "1"); - EXPECT_FALSE(m[2] != "2"); - EXPECT_FALSE(m[3] != "3"); - EXPECT_FALSE(m[4] != "4"); - EXPECT_FALSE(cm[0] != "0"); - EXPECT_FALSE(cm[1] != "1"); - EXPECT_FALSE(cm[2] != "2"); - EXPECT_FALSE(cm[3] != "3"); - EXPECT_FALSE(cm[4] != "4"); - // verify_assertion(t, [&](Tree const&){ return cm[m.capacity()]; }); verify_assertion(t, [&](Tree const&){ return cm[NONE]; }); verify_assertion(t, [&](Tree const&){ return cm[0][0]; }); @@ -1011,28 +989,6 @@ TEST(Tree, operator_square_brackets_map) EXPECT_EQ(cm["d"].val(), "3"); EXPECT_EQ(cm["e"].val(), "4"); // - EXPECT_TRUE(m["a"] == "0"); - EXPECT_TRUE(m["b"] == "1"); - EXPECT_TRUE(m["c"] == "2"); - EXPECT_TRUE(m["d"] == "3"); - EXPECT_TRUE(m["e"] == "4"); - EXPECT_TRUE(cm["a"] == "0"); - EXPECT_TRUE(cm["b"] == "1"); - EXPECT_TRUE(cm["c"] == "2"); - EXPECT_TRUE(cm["d"] == "3"); - EXPECT_TRUE(cm["e"] == "4"); - // - EXPECT_FALSE(m["a"] != "0"); - EXPECT_FALSE(m["b"] != "1"); - EXPECT_FALSE(m["c"] != "2"); - EXPECT_FALSE(m["d"] != "3"); - EXPECT_FALSE(m["e"] != "4"); - EXPECT_FALSE(cm["a"] != "0"); - EXPECT_FALSE(cm["b"] != "1"); - EXPECT_FALSE(cm["c"] != "2"); - EXPECT_FALSE(cm["d"] != "3"); - EXPECT_FALSE(cm["e"] != "4"); - // verify_assertion(t, [&](Tree const&){ return cm["f"]; }); verify_assertion(t, [&](Tree const&){ return cm["g"]["h"]; }); } @@ -1053,28 +1009,6 @@ TEST(Tree, noderef_at_seq) EXPECT_EQ(cm.at(3).val(), "3"); EXPECT_EQ(cm.at(4).val(), "4"); // - EXPECT_TRUE(m.at(0) == "0"); - EXPECT_TRUE(m.at(1) == "1"); - EXPECT_TRUE(m.at(2) == "2"); - EXPECT_TRUE(m.at(3) == "3"); - EXPECT_TRUE(m.at(4) == "4"); - EXPECT_TRUE(cm.at(0) == "0"); - EXPECT_TRUE(cm.at(1) == "1"); - EXPECT_TRUE(cm.at(2) == "2"); - EXPECT_TRUE(cm.at(3) == "3"); - EXPECT_TRUE(cm.at(4) == "4"); - // - EXPECT_FALSE(m.at(0) != "0"); - EXPECT_FALSE(m.at(1) != "1"); - EXPECT_FALSE(m.at(2) != "2"); - EXPECT_FALSE(m.at(3) != "3"); - EXPECT_FALSE(m.at(4) != "4"); - EXPECT_FALSE(cm.at(0) != "0"); - EXPECT_FALSE(cm.at(1) != "1"); - EXPECT_FALSE(cm.at(2) != "2"); - EXPECT_FALSE(cm.at(3) != "3"); - EXPECT_FALSE(cm.at(4) != "4"); - // EXPECT_EQ(cm.num_children(), 5); EXPECT_EQ(cm.num_children(), m.num_children()); // @@ -1125,28 +1059,6 @@ TEST(Tree, noderef_at_map) EXPECT_EQ(cm.at("d").val(), "3"); EXPECT_EQ(cm.at("e").val(), "4"); // - EXPECT_TRUE(m.at("a") == "0"); - EXPECT_TRUE(m.at("b") == "1"); - EXPECT_TRUE(m.at("c") == "2"); - EXPECT_TRUE(m.at("d") == "3"); - EXPECT_TRUE(m.at("e") == "4"); - EXPECT_TRUE(cm.at("a") == "0"); - EXPECT_TRUE(cm.at("b") == "1"); - EXPECT_TRUE(cm.at("c") == "2"); - EXPECT_TRUE(cm.at("d") == "3"); - EXPECT_TRUE(cm.at("e") == "4"); - // - EXPECT_FALSE(m.at("a") != "0"); - EXPECT_FALSE(m.at("b") != "1"); - EXPECT_FALSE(m.at("c") != "2"); - EXPECT_FALSE(m.at("d") != "3"); - EXPECT_FALSE(m.at("e") != "4"); - EXPECT_FALSE(cm.at("a") != "0"); - EXPECT_FALSE(cm.at("b") != "1"); - EXPECT_FALSE(cm.at("c") != "2"); - EXPECT_FALSE(cm.at("d") != "3"); - EXPECT_FALSE(cm.at("e") != "4"); - // verify_error(t, [&](Tree const&){ return cm.at(t.capacity()); }); verify_error(t, [&](Tree const&){ return cm.at(NONE); }); verify_error(t, [&](Tree const&){ return cm.at(cm.num_children()); }); @@ -1304,7 +1216,7 @@ foo: bar EXPECT_EQ(doc.is_stream(), doc.get()->m_type.is_stream()); EXPECT_EQ(keyval.is_stream(), keyval.get()->m_type.is_stream()); // - ASSERT_TRUE(t.docref(0)["none"].valid()); + ASSERT_TRUE(!t.docref(0)["none"].invalid()); ASSERT_TRUE(t.docref(0)["none"].is_seed()); ASSERT_FALSE(t.docref(0)["none"].readable()); verify_assertion(t, [&](Tree const&){ return t.docref(0)["none"].is_stream(); });