diff --git a/src/lib/diff/gen-node.hpp b/src/lib/diff/gen-node.hpp index e75b266e5..4a2309da7 100644 --- a/src/lib/diff/gen-node.hpp +++ b/src/lib/diff/gen-node.hpp @@ -192,6 +192,18 @@ namespace diff{ X& get(); template X const& get() const; + + + /** visit _children_ of a nested `Record` */ + Rec::scopeIter + childIter() const + { + const Rec* rec = unConst(this)->maybeGet(); + if (!rec) + return Rec::scopeIter(); + else + return rec->scope(); + } }; @@ -262,7 +274,7 @@ namespace diff{ - /** @internal diagnostics helper. Include format-helper.cpp on use */ + /** @internal diagnostics helper */ operator string() const { return "GenNode-"+string(idi)+"-"+string(data); @@ -310,6 +322,27 @@ namespace diff{ iterator end() const; + using ChildDataIter = TransformIter; + + /** visit the _data_ of nested child elements + * @return an iterator over the DataCap elements of all children, + * in case this GenNode actually holds a Record. + * Otherwise an empty iterator. + * @note this iterator visits _only_ the children, which are + * by definition unnamed. It does _not_ visit attributes. + */ + friend ChildDataIter + childData (GenNode const& n) + { + return ChildDataIter{ n.data.childIter() + , [](GenNode const& child) ->DataCap const& + { + return child.data; + } + }; + } + + friend string name (GenNode const& node) { diff --git a/tests/library/diff/gen-node-basic-test.cpp b/tests/library/diff/gen-node-basic-test.cpp index 92a131372..31d569756 100644 --- a/tests/library/diff/gen-node-basic-test.cpp +++ b/tests/library/diff/gen-node-basic-test.cpp @@ -76,7 +76,7 @@ namespace test{ * - object-like elements can be represented by using a diff:Record * as payload. Obviously, the resulting data structure type is recursive. * - a shortcut is provided to simplify defining empty baseline objects - * - there is a special notation to create "id references", which can + * - a special notation is provided to create "id references", which * can be used to stand-in for an "object" (Record). This shortcut * notation is relevant for the tree diff language -- used within * Lumiera as "External Tree Description" of object networks. @@ -222,7 +222,7 @@ namespace test{ CHECK (hamID.getHash() == ham.idi.getHash()); CHECK (contains (string(hamID), "spam")); // Lovely spam! - Ref ref1("egg bacon sausage and spam"); + Ref ref1("egg bacon sausage and spam"); // empty placeholder Ref ref2(ham); CHECK (ref1.idi == ham.idi); @@ -328,6 +328,32 @@ namespace test{ CHECK (0 == iter.level()); CHECK (isnil (iter)); + + + // another kind of iteration: shallow child data sequence + // note: exposing the DataCap of each child + auto child = childData(n); + CHECK (!isnil (child)); + CHECK ('*' == child->get()); + + ++child; + CHECK ("★" == child->get()); + + ++child; + CHECK (almostEqual (PI, child->get())); + + ++child; + CHECK ("ham" == child->get().getType()); + CHECK ("eggs" == child->get().child(0).data.get()); + + ++child; + CHECK (TimeSpan(Time::ZERO, FSecs(23,25)) == child->get()); + + ++child; + CHECK (42 == child->get()); + + ++child; + CHECK (isnil (child)); }