TreeExplorer: cover expansion using a different result type

here using a lambda with side-effect and returning a reference to
a STL collection with the children, which is managed elsewhere.
This commit is contained in:
Fischlurch 2017-11-27 03:22:34 +01:00
parent 77c3226948
commit 86856390e1
3 changed files with 48 additions and 4 deletions

View file

@ -431,8 +431,8 @@ namespace lib {
{
REQUIRE (checkPoint(*this), "attempt to expand an empty explorer");
ResIter expanded = 0 < depth()? expandChildren_(*expansions_)
: expandChildren_(*this);
ResIter expanded{ 0 < depth()? expandChildren_(*expansions_)
: expandChildren_(*this)};
iterNext (*this); // consume current head element
if (not isnil(expanded))
expansions_.push (move(expanded));

View file

@ -288,7 +288,7 @@ namespace test{
/** @test use a preconfigured "expand" functor to recurse into children
/** @test use a preconfigured "expand" functor to recurse into children.
* The `expand()` builder function predefines a way how to _expand_ the current
* head element of the iteration. However, expansion does not happen automatically,
* rather, it needs to be invoked by the client, similar to increment of the iterator.
@ -298,6 +298,29 @@ namespace test{
* Conceptually, the evaluation _forks into the children of the expanded element_, before
* continuing with the successor of the expansion point. Obviously, expansion can be applied
* again on the result of the expansion, possibly leading to a tree of side evaluations.
*
* The expansion functor may be defined in various ways and will be adapted appropriately
* - it may follow the classical "monadic pattern", i.e. take individual _values_ and return
* a _"child monad"_, which is then "flat mapped" (integrated) into the resulting iteration
* - the resulting child collection may be returned as yet another iterator, which is then
* moved by the implementation into the stack of child sequences currently in evaluation
* - or alternatively the resulting child collection may be returned just as a "state core",
* which can be adapted into a _iterable state_ (see lib::IterStateWrapper).
* - or it may even return the reference to a STL collection existing elsewhere,
* which will then be iterated to yield the child elements
* - and, quite distinct to the aforementioned "monadic" usage, the expansion functor
* may alternatively be written in a way as to collaborate with the "state core" used
* when building the TreeExplorer. In this case, the functor typically takes a _reference_
* to this underlying state core or iterator. The purpose for this definition variant is
* to allow exploring a tree-like evaluation, without the need to disclose anything about
* the backing implementation; the expansion functor just happens to know the implementation
* type of the "state core" and manipulate it through its API to create a "derived core"
* representing a _child evaluation state_.
* - and finally, there is limited support for _generic lambdas._ In this case, the implementation
* will try to instantiate the passed lambda by using the concrete source iterator type as argument.
*
* @note expansion functor may use side-effects and indeed return something entirely different
* than the original sequence, as long as it is iterable and yields compatible values.
*/
void
verify_expandOperation()
@ -312,6 +335,25 @@ namespace test{
.expand([](uint j){ return NumberSequence{j-1}; })
);
// lambda with side-effect and a different return type
vector<vector<uint>> childBuffer;
auto expandIntoChildBuffer = [&](uint j) -> vector<uint>&
{
childBuffer.emplace_back();
vector<uint>& childNumbz = childBuffer.back();
for (size_t i=0; i<j-1; ++i)
childNumbz.push_back(j-1 - i);
return childNumbz;
};
verify_treeExpandingIterator(
treeExplore(CountDown{5})
.expand(expandIntoChildBuffer)
);
// test routine called the expansion functor five times
CHECK (5 == childBuffer.size());
verify_treeExpandingIterator(
treeExplore(CountDown{5})
.expand([](CountDown const& core){ return CountDown{ yield(core) - 1}; })

View file

@ -5357,7 +5357,9 @@
<node COLOR="#338800" CREATED="1511227824495" ID="ID_1299746114" MODIFIED="1511731959295" TEXT="Val -&gt; Iter&lt;Val&gt;">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1511571834032" ID="ID_1315469399" MODIFIED="1511571846898" TEXT="Val -&gt; collection&lt;Val&gt;"/>
<node COLOR="#338800" CREATED="1511571834032" ID="ID_1315469399" MODIFIED="1511754060610" TEXT="Val -&gt; collection&lt;Val&gt;">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1511227861867" ID="ID_1821706302" MODIFIED="1511571641506" TEXT="Fall-2 ">
<icon BUILTIN="flag-yellow"/>