decision how to support tree exploration/reconstruction
initially the intention was to include a "bracketing construct" into the values returned by the iterator. After considering the various implementation and representation approaches, it seems more appropriate just to expose a measure for the depth-in-tree through the iterator itself, leaving any concerns about navigation and structure reconstruction to the usage site. As rationale we consider the full tree reconstruction as a very specialised use case, and as such the normal "just iteration" usage should not pay for this in terms of iterator size and implementation complexity. Once a "level" measure is exposed, the usage site can do precisely the same, with the help of the HierarchyOrientationIndicator.
This commit is contained in:
parent
8e8a67e6df
commit
6da0785d0a
2 changed files with 19 additions and 12 deletions
|
|
@ -428,6 +428,12 @@ namespace diff{
|
|||
scopes_.emplace_back(n);
|
||||
}
|
||||
|
||||
size_t
|
||||
depth() const
|
||||
{
|
||||
return scopes_.size();
|
||||
}
|
||||
|
||||
/* === Iteration control API for IterStateWrapper == */
|
||||
|
||||
friend bool
|
||||
|
|
@ -480,6 +486,8 @@ namespace diff{
|
|||
: IterStateWrapper<const GenNode, ScopeExplorer>
|
||||
{
|
||||
using IterStateWrapper<const GenNode, ScopeExplorer>::IterStateWrapper;
|
||||
|
||||
size_t level() const { return unConst(this)->stateCore().depth(); }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -285,12 +285,14 @@ namespace test{
|
|||
|
||||
|
||||
auto iter = n.begin();
|
||||
CHECK (!isnil (iter)); // initially the Record itself is exposed
|
||||
CHECK ("baked beans" == iter->idi.getSym());
|
||||
CHECK (!isnil (iter));
|
||||
CHECK (1 == iter.level());
|
||||
CHECK ("baked beans" == iter->idi.getSym()); // initially the Record itself is exposed
|
||||
CHECK (Rec::TYPE_NIL == iter->data.get<Rec>().getType());
|
||||
|
||||
++iter;
|
||||
CHECK ("hasSpam" == iter->idi.getSym()); // delve into the contents, starting with the attribute(s)
|
||||
CHECK (2 == iter.level()); // delve into the contents,
|
||||
CHECK ("hasSpam" == iter->idi.getSym()); // ...starting with the attribute(s)
|
||||
CHECK (true == iter->data.get<bool>());
|
||||
CHECK ("GenNode-ID(\"hasSpam\")-DataCap|«bool»|1" == string(*iter));
|
||||
|
||||
|
|
@ -311,6 +313,7 @@ namespace test{
|
|||
CHECK ("ham" == iter->data.get<Rec>().getType());
|
||||
|
||||
++iter;
|
||||
CHECK (3 == iter.level());
|
||||
CHECK ("eggs" == iter->data.get<string>()); // contents of the nested ("spam") object's scope
|
||||
|
||||
++iter;
|
||||
|
|
@ -318,20 +321,16 @@ namespace test{
|
|||
|
||||
++iter;
|
||||
CHECK ("spam" == iter->data.get<string>());
|
||||
CHECK (3 == iter.level());
|
||||
|
||||
++iter;
|
||||
CHECK ("_END_spam" == iter->idi.getSym()); // bracketing construct to close the nested scope
|
||||
|
||||
++iter;
|
||||
CHECK (2 == iter.level()); // decreasing level indicates we left nested scope
|
||||
CHECK (!iter->isNamed()); // next item in the enclosing scope
|
||||
CHECK (42 == iter->data.get<int64_t>());
|
||||
CHECK (2 == iter.level());
|
||||
|
||||
++iter;
|
||||
CHECK ("_END_baked beans" == iter->idi.getSym()); // bracketing returns to top level
|
||||
CHECK (isSameObject(n.data.get<Rec>(), iter->data.get<Rec>()));
|
||||
CHECK (Ref(n) == *iter); // actually this is a RecordRef to the original object
|
||||
|
||||
++iter;
|
||||
++iter; // nothing more on top level beyond the initial Record
|
||||
CHECK (0 == iter.level());
|
||||
CHECK (isnil (iter));
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue