diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index 49041c0c3..ce35330b0 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -487,6 +487,8 @@ namespace lib { BaseAdapter(SRC && src) : SRC(src) { } void expandChildren() { } + size_t depth() const { return 0; } + }; @@ -512,7 +514,7 @@ namespace lib { * @tparam SRC the wrapped source iterator, typically a TreeExplorer or nested decorator. * @tparam FUN the concrete type of the functor passed. Will be dissected to find the signature */ - template + template class Expander : public SRC { @@ -535,7 +537,9 @@ namespace lib { : SRC{move (parentExplorer)} // NOTE: slicing move to strip TreeExplorer (Builder) , expandChildren_{forward (expandFunctor)} , expansions_{} - { } + { + maybeExpandToExhaustion(); + } /** core operation: expand current head element */ @@ -551,6 +555,22 @@ namespace lib { expansions_.push (move(expanded)); } + void + maybeExpandToExhaustion() + { + if (not (expandToLeaf and this->checkPoint())) return; + + while (true) + { + ResIter expanded{ 0 < depth()? expandChildren_(*expansions_) + : expandChildren_(*this)}; + if (isnil(expanded)) + break; + iterate(); // consume current head element + expansions_.push (move(expanded)); + } + } + /** diagnostics: current level of nested child expansion */ size_t depth() const @@ -577,6 +597,13 @@ namespace lib { void iterNext() + { + iterate(); + maybeExpandToExhaustion(); + } + + void + iterate() { if (0 < depth()) { @@ -595,7 +622,7 @@ namespace lib { class AutoExpander : public SRC { - static_assert(is_StateCore::value, "need wrapped state as predecessor in pipeline"); + static_assert(is_StateCore::value, "need wrapped state core as predecessor in pipeline"); public: /** pass through ctor */ @@ -980,6 +1007,19 @@ namespace lib { } + /** @todo WIP 12/17 auto expand down to the leafs + */ + template + auto + expandLeaf (FUN&& expandFunctor) + { + using ResCore = iter_explorer::Expander; + using ResIter = typename _DecoratorTraits::SrcIter; + + return TreeExplorer (ResCore {move(*this), forward(expandFunctor)}); + } + + /** @todo WIP 12/17 auto expand all */ auto @@ -992,16 +1032,6 @@ namespace lib { } - /** @todo WIP 12/17 auto expand down to the leafs - */ - auto - expandLeaf() - { - UNIMPLEMENTED ("depth-first expand immediately, until reaching the leaf elements"); - return *this; - } - - /** adapt this TreeExplorer to pipe each result value through a transformation function. * Several "layers" of mapping can be piled on top of each other, possibly mixed with the * other types of adaptation, like the child-expanding operation, or a filter. Obviously, diff --git a/tests/library/iter-tree-explorer-test.cpp b/tests/library/iter-tree-explorer-test.cpp index 96597c831..da6b841f4 100644 --- a/tests/library/iter-tree-explorer-test.cpp +++ b/tests/library/iter-tree-explorer-test.cpp @@ -822,19 +822,19 @@ namespace test{ { uint val = get<0>(tup); uint sum = get<1>(tup); - return singleValIterator (Tu2{val-1, sum+val}); + return val? singleValIterator (Tu2{val-1, sum+val}) + : SingleValIter(); }; -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 cout << materialise( treeExplore(CountDown{4}) .transform([](uint i){ return Tu2{i,0}; }) -// .expand(summingExpander) //////////////////TODO why isn't that result iterator (singleValIterator) accepted? It should be - .expandLeaf() + .expandLeaf(summingExpander) .transform([](Tu2 res){ return get<1>(res); }) ) < + + + + + + + + + + + + + + + + + + + + + +