From 130bc095d9848a7528cba5ad5de765cf6fe7504a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 22 Jun 2023 20:23:55 +0200 Subject: [PATCH] the new design takes the old name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The second design from 2017, based on a pipeline builder, is now renamed `TreeExplorer` ⟼ `IterExplorer` and uses the memorable entrance point `lib::explore()` ✔ --- src/lib/iter-adapter.hpp | 2 +- src/lib/iter-chain-search.hpp | 10 +- ...er-tree-explorer.hpp => iter-explorer.hpp} | 197 ++++++++---------- src/stage/interact/ui-coord-resolver.cpp | 1 - src/stage/interact/ui-coord-resolver.hpp | 4 +- src/stage/timeline/track-presenter.hpp | 2 +- src/stage/timeline/track-profile.hpp | 6 +- src/steam/engine/job-planning.hpp | 4 +- tests/12metaprogramming.tests | 11 +- .../engine/job-planning-pipeline-test.cpp | 12 +- tests/core/steam/engine/mock-support-test.cpp | 2 +- ...plorer-test.cpp => iter-explorer-test.cpp} | 130 ++++++------ .../library/meta/value-type-binding-test.cpp | 2 +- tests/library/verb-visitor-dispatch-test.cpp | 4 +- tests/stage/gen-node-location-query.hpp | 4 +- .../stage/interact/ui-coord-resolver-test.cpp | 2 +- tests/stage/model/canvas-hook-test.cpp | 4 +- tests/stage/model/view-hook-test.cpp | 4 +- 18 files changed, 187 insertions(+), 214 deletions(-) rename src/lib/{iter-tree-explorer.hpp => iter-explorer.hpp} (91%) rename tests/library/{iter-tree-explorer-test.cpp => iter-explorer-test.cpp} (94%) diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index 7015f7be2..581613611 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -330,7 +330,7 @@ namespace lib { * The resulting iterator will hold an instance of ST, which thus * needs to be copyable and default constructible to the extent * this is required for the iterator as such. - * @see IterExplorer an iterator monad built on top of IterStateWrapper + * @see IterExplorer a pipeline builder framework on top of IterStateWrapper * @see iter-explorer-test.hpp * @see iter-adaptor-test.cpp */ diff --git a/src/lib/iter-chain-search.hpp b/src/lib/iter-chain-search.hpp index 2b364628e..475d81b1a 100644 --- a/src/lib/iter-chain-search.hpp +++ b/src/lib/iter-chain-search.hpp @@ -59,7 +59,7 @@ ** capture extended facilities within the scope _enclosing_ the pipeline, as long ** as this scope remains intact during the whole usage time of the pipeline. ** - the resulting entity, an instantiation of the IterChainSearch template, is - ** not a generic TreeExplorer (builder). Be careful when using any builder + ** not a generic IterExplorer (builder). Be careful when using any builder ** functions still accessible. The only functions meant to be used in ** builder style are the IterChainSearch::search() variations. ** - if you copy, the embedded state is copied alongside, but not @@ -78,7 +78,7 @@ #include "lib/error.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/meta/util.hpp" #include @@ -102,7 +102,7 @@ namespace iter { auto buildSearchFilter (SRC&& dataSource) { - return treeExplore (forward (dataSource)) + return explore (forward (dataSource)) .mutableFilter(); } @@ -116,7 +116,7 @@ namespace iter { /** * @internal helper to rebind on inferred types. - * @remark we use the TreeExplorer framework to assemble the processing pipeline + * @remark we use the IterExplorer framework to assemble the processing pipeline * from suitable building blocks configured with some lambdas. However, we * also want to _inherit_ from this filter pipeline, so to expose the typical * iterator operations without much ado. Thus we use some (static) helper function @@ -304,7 +304,7 @@ namespace iter { * container, or a [»State Core«](\ref lib::IterStateWrapper) object. * @warning if you capture the result of this call by an auto variable, * be sure to understand that invoking any further builder operation on - * TreeExplorer will invalidate that variable (by moving it into the + * IterExplorer will invalidate that variable (by moving it into the * augmented iterator returned from such builder call). */ template diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-explorer.hpp similarity index 91% rename from src/lib/iter-tree-explorer.hpp rename to src/lib/iter-explorer.hpp index 35d818d54..8e9a88dcb 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-explorer.hpp @@ -1,5 +1,5 @@ /* - ITER-TREE-EXPLORER.hpp - building blocks for iterator evaluation strategies + ITER-EXPLORER.hpp - building blocks for iterator evaluation strategies Copyright (C) Lumiera.org 2017, Hermann Vosseler @@ -20,9 +20,9 @@ */ -/** @file iter-tree-explorer.hpp +/** @file iter-explorer.hpp ** Building tree expanding and backtracking evaluations within hierarchical scopes. - ** Based on the *Lumiera Forward Iterator* concept and using the basic IterAdaptor templates, + ** Based on the *Lumiera Forward Iterator* concept and using the basic IterAdapter templates, ** these components allow to implement typical evaluation strategies, like conditional expanding ** or depth-first exploration of a hierarchical structure. Since the access to this structure is ** abstracted through the underlying iterator, what we effectively get is a functional datastructure. @@ -30,39 +30,26 @@ ** itself (value semantics) -- similar to the IterStateWrapper, which is one of the basic helper templates ** provided by iter-adapter.hpp. ** - ** @remark as of 2017, this template, as well as the initial IterExplorer (draft from 2012) can be - ** seen as steps towards designing a framework of building blocks for tree expanding and - ** backtracking algorithms. Due to the nature of Lumiera's design, we repeatedly encounter - ** this kind of computation pattern, when it comes to matching flexible configuration against - ** a likewise hierarchical and rules based model. To keep the code base maintainable, - ** we deem it crucial to reduce the inherent complexity in such algorithms by clearly - ** separate the _mechanics of evaluation_ from the actual logic of the target domain. + ** @remark historically, this template, as well as the initial IterExplorer (draft from 2012) can be + ** seen as steps towards a framework of building blocks for tree expanding and backtracking + ** algorithms — driven by a persistent need for this computation pattern, which lies in the + ** nature of Lumiera's design: matching flexible configuration against a likewise hierarchical + ** and rules based model. ** - ** # Iterators as Monad + ** # Background: Iterators as Monad ** The fundamental idea behind the implementation technique used here is the _Monad pattern_ ** known from functional programming. A Monad is a container holding some arbitrarily typed base value; the monad can - ** be seen as "amplifying" and enhancing the contained base value by attaching additional properties or capabilities + ** be seen as „amplifying“ and enhancing the contained base value by attaching additional properties or capabilities ** This is a rather detached concept with a wide variety of applications (things like IO state, parsers, combinators, ** calculations with exception handling but also simple data structures like lists or trees). The key point with any ** monad is the ability to _bind a function_ into the monad; this function will work on the _contained base values_ ** and produce a modified new monad instance. In the simple case of a list, "binding" a function basically means - ** to _map the function onto_ the elements in the list. (actually it means the `flatMap` operation) - ** - ** ## Rationale - ** The primary benefit of using the monad pattern is to separate the transforming operation completely from - ** the mechanics of applying that operation and combining the results. More specifically, we rely on an iterator - ** to represent an abstracted source of data and we expose the combined and transformed results again as such - ** an abstracted data sequence. While the transformation to apply can be selected at runtime (as a functor), - ** the monad pattern defines a sane way to represent partial evaluation state without requiring a container - ** for intermediary results. This is especially helpful when - ** - a flexible and unspecific source data structure needs to be processed - ** - and this evaluation needs to be done asynchronously and in parallel (no locking, immutable data) - ** - and a partial evaluation needs to be stored as continuation (not relying on the stack for partial results) + ** to _map the function onto_ the elements in the list. (strictly speaking, it means the `flatMap` operation) ** ** # A Pipeline builder - ** Based on such concepts, structures and evaluation patterns, the TreeExplorer serves the purpose to provide + ** Based on such concepts, structures and evaluation patterns, the IterExplorer serves the purpose to provide ** building blocks to assemble a _processing pipeline_, where processing will happen _on demand,_ while iterating. - ** TreeExplorer itself is both a Lumiera Forward Iterator based on some wrapped data source, and at the same time + ** IterExplorer itself is both a Lumiera Forward Iterator based on some wrapped data source, and at the same time ** it is a builder to chain up processing steps to work on the data pulled from that source. These processing steps ** are attached as _decorators_ wrapping the source, in the order the corresponding builder functions were invoked. ** - the *expand operation* installs a function to consume one element and replace it by the sequence of elements @@ -75,12 +62,20 @@ ** - in concert, expand- and transform operation allow to build hierarchy evaluation algorithms without exposing ** any knowledge regarding the concrete hierarchy used and explored as data source. ** - ** In itself, the TreeExplorer is an iterator with implementation defined type (all operations being inlined). + ** In itself, the IterExplorer is an iterator with implementation defined type (all operations being inlined). ** But it is possible to package this structure behind a conventional iteration interface with virtual functions. - ** By invoking the terminal builder function TreeExplorer::asIterSource(), the iterator compound type, as created + ** By invoking the terminal builder function IterExplorer::asIterSource(), the iterator compound type, as created ** thus far, will be moved into a heap allocation, returning a front-end based on IterSource. In addition, the ** actually returned type, IterExplorerSource, exposes the `expandChildren()` operation as discussed above. ** + ** ## Rationale + ** This design leads to a complete separation of the transforming operation from the mechanics how to apply that + ** operation and combine the results. More specifically, we rely on an iterator to represent an abstracted source + ** of data and we expose the combined and transformed results again as such an abstracted data sequence. Thereby, + ** a trend towards separation of concerns is introduced; the data source remains opaque, while the manipulation + ** to apply can be selected at runtime or written inline as Lambda. The iterator itself is a self-contained + ** value and represents partial evaluation state without requiring a container for intermediary results. + ** ** ## some implementation details ** The builder operations assemble a heavily nested type, each builder call thereby adding yet another layer of ** subclassing. The templates involved into this build process are _specialised_, as driven by the actual functor @@ -94,22 +89,19 @@ ** of the newly built subclass object. The previously existing pipeline is defunct after that ** move; if you captured it into a variable, be sure to capture the _result_ of the new ** builder operation as well and don't use the old variable anymore. Moreover, it should - ** be ensured that any "state core" used within TreeExplorer has an efficient move ctor; + ** be ensured that any "state core" used within IterExplorer has an efficient move ctor; ** including RVO, the compiler is typically able to optimise such move calls away altogether. ** - ** @see IterTreeExplorer_test + ** @see IterExplorer_test ** @see iter-adapter.hpp ** @see itertools.hpp ** @see IterSource (completely opaque iterator) - ** - ** @warning as of 4/2023 the alternative Monad-style iterator framework "iter-explorer" will be retracted - ** and replaced by this design here, which will then be renamed into IterExplorer //////////////////////////////TICKET #1276 ** */ -#ifndef LIB_ITER_TREE_EXPLORER_H -#define LIB_ITER_TREE_EXPLORER_H +#ifndef LIB_ITER_EXPLORER_H +#define LIB_ITER_EXPLORER_H #include "lib/error.hpp" @@ -333,7 +325,7 @@ namespace lib { - namespace { // TreeExplorer traits + namespace { // IterExplorer traits using meta::enable_if; using meta::disable_if; @@ -394,11 +386,11 @@ namespace lib { }; - /** decide how to adapt and embed the source sequence into the resulting TreeExplorer */ + /** decide how to adapt and embed the source sequence into the resulting IterExplorer */ template struct _DecoratorTraits { - static_assert (!sizeof(SRC), "Can not build TreeExplorer: Unable to figure out how to iterate the given SRC type."); + static_assert (!sizeof(SRC), "Can not build IterExplorer: Unable to figure out how to iterate the given SRC type."); }; template @@ -473,7 +465,7 @@ namespace lib { using pointer = typename ValueTypeBinding::pointer; }; - }//(End) TreeExplorer traits + }//(End) IterExplorer traits @@ -484,12 +476,12 @@ namespace lib { constexpr auto ACCEPT_ALL = [](auto){return true;}; /** - * @internal technical details of binding a functor into the TreeExplorer. + * @internal technical details of binding a functor into the IterExplorer. * Notably, this happens when adapting an _"expansion functor"_ to allow expanding a given element * from the TreeExploer (iterator) into a sequence of child elements. A quite similar situation * arises when binding a _transformation function_ to be mapped onto each result element. * - * The TreeExplorer::expand() operation accepts various flavours of functors, and depending on + * The IterExplorer::expand() operation accepts various flavours of functors, and depending on * the signature of such a functor, an appropriate adapter will be constructed here, allowing to * write a generic Expander::expandChildren() operation. The following details are handled here: * - detect if the passed functor is generic, or a regular "function-like" entity. @@ -602,7 +594,7 @@ namespace lib { /** * @internal Base of pipe processing decorator chain. - * TreeExplorer allows to create a stack out of various decorating processors + * IterExplorer allows to create a stack out of various decorating processors * - each decorator is itself a _"state core"_, adding some on-demand processing * - each wraps and adapts a source iterator, attaching to and passing-on the iteration logic * Typically each such layer is configured with actual functionality provided as lambda or functor. @@ -611,7 +603,7 @@ namespace lib { * call, where some "expansion layer" consumes the current element and replaces it by an expanded * series of new elements. Other layers might need to sync to this operation, and thus it is passed * down the chain. For that reason, we need a dedicated BaseAdapter to adsorb such chained calls. - * @remark when building the TreeExplorer, the to-be-wrapped source is fed down into its place + * @remark when building the IterExplorer, the to-be-wrapped source is fed down into its place * within BaseAdapter. For that reason, it is not sufficient just to lift the copy ctors * of the base (as inheriting the base class ctors would do). Rather, we need dedicated * further copy ctors to clone and move from the _undecorated base type._ @@ -630,7 +622,7 @@ namespace lib { /** - * @internal Decorator for TreeExplorer adding the ability to "expand children". + * @internal Decorator for IterExplorer adding the ability to "expand children". * The expandChildren() operation is the key element of a depth-first evaluation: it consumes * one element and performs a preconfigured _expansion functor_ on that element to yield * its "children". These are given in the form of another iterator, which needs to be @@ -652,7 +644,7 @@ namespace lib { * bindings of the passed raw functor, one to work on the source sequence, and the other * one to work on the result sequence of a recursive child expansions; these two sequences * need not be implemented in the same way, which simplifies the definition of algorithms. - * @tparam SRC the wrapped source iterator, typically a TreeExplorer or nested decorator. + * @tparam SRC the wrapped source iterator, typically a IterExplorer or nested decorator. * @tparam FUN the concrete type of the functor passed. Will be dissected to find the signature */ template @@ -677,7 +669,7 @@ namespace lib { template Expander (SRC&& parentExplorer, FUN&& expandFunctor) - : SRC{move (parentExplorer)} // NOTE: slicing move to strip TreeExplorer (Builder) + : SRC{move (parentExplorer)} // NOTE: slicing move to strip IterExplorer (Builder) , expandRoot_ {_FunTraits ::adaptFunctor (forward (expandFunctor))} // adapt to accept SRC& , expandChild_{_FunTraits::adaptFunctor (forward (expandFunctor))} // adapt to accept RES& , expansions_{} @@ -867,7 +859,7 @@ namespace lib { /** - * @internal Decorator for TreeExplorer to map a transformation function on all results. + * @internal Decorator for IterExplorer to map a transformation function on all results. * The transformation function is invoked on demand, and only once per item to be treated, * storing the treated result into an universal value holder buffer. The given functor * is adapted in a similar way as the "expand functor", so to detect and convert the @@ -896,7 +888,7 @@ namespace lib { template Transformer (SRC&& dataSrc, FUN&& transformFunctor) - : SRC{move (dataSrc)} // NOTE: slicing move to strip TreeExplorer (Builder) + : SRC{move (dataSrc)} // NOTE: slicing move to strip IterExplorer (Builder) , trafo_{_FunTraits::adaptFunctor (forward (transformFunctor))} { } @@ -953,7 +945,7 @@ namespace lib { /** - * @internal Decorator for TreeExplorer to filter elements based on a predicate. + * @internal Decorator for IterExplorer to filter elements based on a predicate. * Similar to the Transformer, the given functor is adapted as appropriate. However, * we require the functor's result type to be convertible to bool, to serve as approval test. * The filter predicate and thus the source iterator is evaluated _eagerly_, to establish the @@ -1215,7 +1207,7 @@ namespace lib { /** - * @internal Decorator for TreeExplorer to cut iteration once a predicate ceases to be true. + * @internal Decorator for IterExplorer to cut iteration once a predicate ceases to be true. * Similar to Filter, the given functor is adapted as appropriate, yet is required to yield * a bool convertible result. The functor will be evaluated whenever the »exhausted« state * of the resulting iterator is checked, on each access and before iteration; this evaluation @@ -1262,7 +1254,7 @@ namespace lib { /** * Interface to indicate and expose the ability for _child expansion_. - * This interface is used when packaging a TreeExplorer pipeline opaquely into IterSource. + * This interface is used when packaging a IterExplorer pipeline opaquely into IterSource. * @remark the depth() call indicates the depth of the child expansion tree. This information * can be used by a "downstream" consumer to react according to a nested scope structure. * @todo expandChildren() should not return the value pointer. @@ -1282,22 +1274,22 @@ namespace lib { }; /** - * @internal Decorator to package a whole TreeExplorer pipeline suitably to be handled through - * an IterSource based front-end. Such packaging is performed by the TreeExplorer::asIterSource() + * @internal Decorator to package a whole IterExplorer pipeline suitably to be handled through + * an IterSource based front-end. Such packaging is performed by the IterExplorer::asIterSource() * terminal builder function. In addition to [wrapping the iterator](\ref WrappedLumieraIter), * the `expandChildren()` operation is exposed as virtual function, to allow invocation through * the type-erased front-end, without any knowledge about the concrete implementation type * of the wrapped TreeIterator pipeline. */ template - class PackagedTreeExplorerSource + class PackagedIterExplorerSource : public WrappedLumieraIter , public ChildExpandableSource { using Parent = WrappedLumieraIter; using Val = typename SRC::value_type; ///////////////////////////////////TICKET #1125 : get rid of Val - ~PackagedTreeExplorerSource() { } + ~PackagedIterExplorerSource() { } public: using Parent::Parent; @@ -1323,12 +1315,12 @@ namespace lib { /** - * Iterator front-end to manage and operate a TreeExplorer pipeline opaquely. + * Iterator front-end to manage and operate a IterExplorer pipeline opaquely. * In addition to the usual iterator functions, this front-end also exposes an * `expandChildren()`-function, to activate the _expansion functor_ installed - * through TreeExplorer::expand(). + * through IterExplorer::expand(). * @remarks A iterator pipeline is assembled through invocation of the builder functions - * on TreeExplorer -- this way creating a complex implementation defined iterator type. + * on IterExplorer — thereby creating a complex implementation defined iterator type. * This front-end manages such a pipeline in heap allocated storage (by shared_ptr), while * exposing only a simple conventional interface (templated to the resulting value type `VAL`). * This allows to pass it over interfaces as "unspecified data source", without disclosing @@ -1366,13 +1358,13 @@ namespace lib { private: template - friend class TreeExplorer; + friend class IterExplorer; template IterExploreSource (IT&& opaqueSrcPipeline) : IterSource::iterator { IterSource::build ( - new iter_explorer::PackagedTreeExplorerSource { + new iter_explorer::PackagedIterExplorerSource { move (opaqueSrcPipeline)})} { } @@ -1380,7 +1372,7 @@ namespace lib { expandableSource() const { if (not this->source()) - throw error::State ("operating on a disabled default constructed TreeExplorer" + throw error::State ("operating on a disabled default constructed IterExplorer" ,error::LUMIERA_ERROR_BOTTOM_VALUE); auto source = unConst(this)->source().get(); @@ -1392,7 +1384,7 @@ namespace lib { - /* ======= TreeExplorer pipeline builder and iterator ======= */ + /* ======= IterExplorer pipeline builder and iterator ======= */ /** * Adapter to build a demand-driven tree expanding and exploring computation @@ -1406,16 +1398,16 @@ namespace lib { * into an instance of the iter_explorer::BaseAdapter template * * \par usage - * TreeExplorer is meant to be used as *Builder* for a processing pipeline. + * IterExplorer is meant to be used as *Builder* for a processing pipeline. * For this to work, it is essential to pick the `SRC` baseclass properly. - * - to build a TreeExplorer, use the treeExplore() free function, + * - to build a IterExplorer, use the \ref explore() free function, * which cares to pick up and possibly adapt the given iteration source - * - to add processing layers, invoke the builder operations on TreeExplorer + * - to add processing layers, invoke the builder operations on IterExplorer * in a chained fashion, thereby binding functors or lambdas. Capture the * final result with an auto variable. * - the result is iterable in accordance to »Lumiera Forward Iterator« * - * @warning deliberately, the builder functions exposed on TreeExplorer will + * @warning deliberately, the builder functions exposed on IterExplorer will * _move_ the old object into the new, augmented iterator. This is * possibly dangerous, since one might be tempted to invoke such a * builder function on an existing iterator variable captured by auto. @@ -1425,7 +1417,7 @@ namespace lib { * builder API and unleashes or slices down to the iterator instead. */ template - class TreeExplorer + class IterExplorer : public SRC { static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); @@ -1443,7 +1435,7 @@ namespace lib { /* ==== Builder functions ==== */ - /** preconfigure this TreeExplorer to allow for _"expansion of children"_. + /** preconfigure this IterExplorer to allow for _"expansion of children"_. * The resulting iterator exposes an `expandChildren()` function, which consumes * the current head element of this iterator and feeds it through the * _expansion functor_, which was provided to this builder function here. @@ -1466,10 +1458,10 @@ namespace lib { * reason, the functor may take its argument by reference, and a produced * new "child state core" may likewise collaborate with that original * data source or state core behind the scenes; the latter is guaranteed - * to exist during the whole lifetime of this TreeExplorer. + * to exist during the whole lifetime of this IterExplorer. * @note there is limited support for generic lambdas, but only for the second case. * The reason is, we can not "probe" a template or generic lambda for possible - * argument and result types. Thus, if you provide a generic lambda, TreeExplorer + * argument and result types. Thus, if you provide a generic lambda, IterExplorer * tries to pass it a `SrcIter &` (reference to the embedded original iterator). * For any other cases, please provide a lambda or functor with a single, explicitly * typed argument. Obviously, argument and result type should also make sense for @@ -1486,7 +1478,7 @@ namespace lib { using ResCore = iter_explorer::Expander; using ResIter = typename _DecoratorTraits::SrcIter; - return TreeExplorer (ResCore {move(*this), forward(expandFunctor)}); + return IterExplorer (ResCore {move(*this), forward(expandFunctor)}); } @@ -1507,7 +1499,7 @@ namespace lib { using ResCore = iter_explorer::AutoExpander; using ResIter = typename _DecoratorTraits::SrcIter; - return TreeExplorer (ResCore {move(*this)}); + return IterExplorer (ResCore {move(*this)}); } /** shortcut notation to invoke \ref expand(expandFunctor) followed by \ref expandAll() */ @@ -1535,11 +1527,11 @@ namespace lib { using ResCore = iter_explorer::ScheduledExpander; using ResIter = typename _DecoratorTraits::SrcIter; - return TreeExplorer (ResCore {move(*this)}); + return IterExplorer (ResCore {move(*this)}); } - /** adapt this TreeExplorer to pipe each result value through a transformation function. + /** adapt this IterExplorer 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, * when building such processing pipelines, the input and output types of the functors @@ -1558,11 +1550,11 @@ namespace lib { using ResCore = iter_explorer::Transformer; using ResIter = typename _DecoratorTraits::SrcIter; - return TreeExplorer (ResCore {move(*this), forward(transformFunctor)}); + return IterExplorer (ResCore {move(*this), forward(transformFunctor)}); } - /** adapt this TreeExplorer to iterate only as long as a condition holds true. + /** adapt this IterExplorer to iterate only as long as a condition holds true. * @return processing pipeline with attached [stop condition](\ref iter_explorer::StopTrigger) */ template @@ -1574,11 +1566,11 @@ namespace lib { using ResCore = iter_explorer::StopTrigger; using ResIter = typename _DecoratorTraits::SrcIter; - return TreeExplorer (ResCore {move(*this), forward(whileCond)}); + return IterExplorer (ResCore {move(*this), forward(whileCond)}); } - /** adapt this TreeExplorer to iterate until a condition becomes first true. + /** adapt this IterExplorer to iterate until a condition becomes first true. * @return processing pipeline with attached [stop condition](\ref iter_explorer::StopTrigger) */ template @@ -1591,7 +1583,7 @@ namespace lib { using ResIter = typename _DecoratorTraits::SrcIter; using ArgType = typename iter_explorer::_FunTraits::Arg; - return TreeExplorer (ResCore { move(*this) + return IterExplorer (ResCore { move(*this) ,[whileCond = forward(untilCond)](ArgType val) { return not whileCond(val); @@ -1600,7 +1592,7 @@ namespace lib { } - /** adapt this TreeExplorer to filter results, by invoking the given functor to approve them. + /** adapt this IterExplorer to filter results, by invoking the given functor to approve them. * The previously created source layers will be "pulled" to fast-forward immediately to the * next element confirmed this way by the bound functor. If none of the source elements * is acceptable, the iterator will transition to exhausted state immediately. @@ -1615,7 +1607,7 @@ namespace lib { using ResCore = iter_explorer::Filter; using ResIter = typename _DecoratorTraits::SrcIter; - return TreeExplorer (ResCore {move(*this), forward(filterPredicate)}); + return IterExplorer (ResCore {move(*this), forward(filterPredicate)}); } @@ -1628,7 +1620,7 @@ namespace lib { * possibly causing the underlying iterator to be pulled until an element matching the condition * is found. * @return processing pipeline with attached [special MutableFilter](\ref iter_explorer::MutableFilter) decorator - * @see \ref IterTreeExplorer_test::verify_FilterChanges() + * @see \ref IterIterExplorer_test::verify_FilterChanges() * @see \ref iter_explorer::MutableFilter::andFilter() * @see \ref iter_explorer::MutableFilter::andNotFilter() * @see \ref iter_explorer::MutableFilter::orFilter() @@ -1645,7 +1637,7 @@ namespace lib { using ResCore = iter_explorer::MutableFilter; using ResIter = typename _DecoratorTraits::SrcIter; - return TreeExplorer (ResCore {move(*this), forward(filterPredicate)}); + return IterExplorer (ResCore {move(*this), forward(filterPredicate)}); } @@ -1666,7 +1658,7 @@ namespace lib { * which for the consumer side behave like `iterNext()` calls. If a layer needs to do something special for * `iterNext()`, it needs to perform a similar action for `expandChildren()`. * - it must be behave like a default-constructible, copyable value object - * @return augmented TreeExplorer, incorporating and adapting the injected layer + * @return augmented IterExplorer, incorporating and adapting the injected layer */ template class LAY> auto @@ -1675,7 +1667,7 @@ namespace lib { using ResCore = LAY; using ResIter = typename _DecoratorTraits::SrcIter; - return TreeExplorer (ResCore {move(*this)}); + return IterExplorer (ResCore {move(*this)}); } @@ -1695,7 +1687,7 @@ namespace lib { } - /** _terminal builder_ to strip the TreeExplorer and expose the built Pipeline. + /** _terminal builder_ to strip the IterExplorer and expose the built Pipeline. * @return a »Lumiera Forward iterator« incorporating the complete pipeline logic. */ SRC @@ -1714,14 +1706,15 @@ namespace lib { /* ==== convenient builder free functions ==== */ - /** start building a TreeExplorer + /** start building a IterExplorer * by suitably wrapping the given iterable source. * @return a TreeEplorer, which is an Iterator to yield all the source elements, * but may also be used to build up a complex processing pipeline. * @warning if you capture the result of this call by an auto variable, * be sure to understand that invoking any further builder operation on - * TreeExplorer will invalidate that variable (by moving it into the + * IterExplorer will invalidate that variable (by moving it into the * augmented iterator returned from such builder call). + * @todo this framework should be retrofitted to fit in with C++20 pipelines * * # Usage * @@ -1735,23 +1728,23 @@ namespace lib { * be iterated as "Lumiera Forward Iterator". Any object with suitable extension * points and behaviour can be used, as explained [here](\ref lib::IterStateWrapper). * - * The resulting TreeExplorer instance can directly be used as "Lumiera Forward Iterator". + * The resulting IterExplorer instance can directly be used as "Lumiera Forward Iterator". * However, typically you might want to invoke the builder functions to configure further * processing steps in a processing pipeline... - * - to [filter](\ref TreeExplorer::filter) the results with a predicate (functor) - * - to [transform](\ref TreeExplorer::transform) the yielded results - * - to bind and configure a [child expansion operation](\ref TreeExplorer::expand), which + * - to [filter](\ref IterExplorer::filter) the results with a predicate (functor) + * - to [transform](\ref IterExplorer::transform) the yielded results + * - to bind and configure a [child expansion operation](\ref IterExplorer::expand), which * can then be triggered by explicitly invoking [.expandChildren()](\ref iter_explorer::Expander::expandChildren) * on the resulting pipeline; the generated child sequence is "flat mapped" into the results * (a *Monad* style usage). - * - to [package](\ref TreeExplorer::asIterSource) the pipeline built thus far behind an opaque + * - to [package](\ref IterExplorer::asIterSource) the pipeline built thus far behind an opaque * interface and move the implementation into heap memory. * * A typical usage might be... * \code * auto multiply = [](int v){ return 2*v; }; * - * auto ii = treeExplore (CountDown{7,4}) + * auto ii = explore (CountDown{7,4}) * .transform(multiply); * * CHECK (14 == *ii); @@ -1763,24 +1756,14 @@ namespace lib { */ template inline auto - treeExplore (IT&& srcSeq) + explore (IT&& srcSeq) { using SrcIter = typename _DecoratorTraits::SrcIter; using Base = iter_explorer::BaseAdapter; - return TreeExplorer (std::forward (srcSeq)); - } - - /** synonym for #treeExplore. - * @remark this might become an extension to C++20 pipelines - */ - template - inline auto - explore (IT&& srcSeq) - { - return treeExplore (std::forward (srcSeq)); + return IterExplorer (std::forward (srcSeq)); } } // namespace lib -#endif /* LIB_ITER_TREE_EXPLORER_H */ +#endif /* LIB_ITER_EXPLORER_H */ diff --git a/src/stage/interact/ui-coord-resolver.cpp b/src/stage/interact/ui-coord-resolver.cpp index ba767374b..b1cb227e8 100644 --- a/src/stage/interact/ui-coord-resolver.cpp +++ b/src/stage/interact/ui-coord-resolver.cpp @@ -33,7 +33,6 @@ using util::isnil; using lib::Symbol; -using lib::treeExplore; namespace stage { diff --git a/src/stage/interact/ui-coord-resolver.hpp b/src/stage/interact/ui-coord-resolver.hpp index 7c1d04c8b..5ab3617cb 100644 --- a/src/stage/interact/ui-coord-resolver.hpp +++ b/src/stage/interact/ui-coord-resolver.hpp @@ -119,7 +119,7 @@ #include "lib/symbol.hpp" #include "lib/format-string.hpp" #include "stage/interact/ui-coord.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/iter-source.hpp" #include "lib/depend.hpp" #include "lib/util.hpp" @@ -177,7 +177,7 @@ namespace interact { static auto buildIterator (TreeStructureNavigator* source) { - return lib::treeExplore (source) + return lib::explore (source) .expand([](TreeStructureNavigator& parent){ return parent.expandChildren(); }); } }; diff --git a/src/stage/timeline/track-presenter.hpp b/src/stage/timeline/track-presenter.hpp index 4858694b9..fbdf929de 100644 --- a/src/stage/timeline/track-presenter.hpp +++ b/src/stage/timeline/track-presenter.hpp @@ -106,7 +106,7 @@ #include "stage/timeline/track-head-widget.hpp" #include "stage/timeline/track-body.hpp" #include "lib/time/timevalue.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/util-coll.hpp" #include "lib/nocopy.hpp" diff --git a/src/stage/timeline/track-profile.hpp b/src/stage/timeline/track-profile.hpp index 002a12927..28fab5ddb 100644 --- a/src/stage/timeline/track-profile.hpp +++ b/src/stage/timeline/track-profile.hpp @@ -41,7 +41,7 @@ #include "stage/gtk-base.hpp" #include "lib/verb-visitor.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/symbol.hpp" #include "lib/util.hpp" @@ -207,8 +207,8 @@ namespace timeline { }; - return lib::treeExplore(elements) - .filter(CountingFilter{pinnedPrefixCnt, selectPrefixPart}); + return lib::explore (elements) + .filter (CountingFilter{pinnedPrefixCnt, selectPrefixPart}); } }; diff --git a/src/steam/engine/job-planning.hpp b/src/steam/engine/job-planning.hpp index 66fb823ca..0dd3ce457 100644 --- a/src/steam/engine/job-planning.hpp +++ b/src/steam/engine/job-planning.hpp @@ -46,14 +46,14 @@ ** must be complete before the main frame job can be started. Since the Job-Planning pipeline is ** generic, this kind of detail dependency is modelled as _prerequisite JobTicket,_ leading to ** an possibly extended depth-first tree expansion, starting from the »master frame ticket« at - ** the root. This _tree exploration_ is implemented by the TreeExplorer::Expander building block, + ** the root. This _tree exploration_ is implemented by the IterExplorer::Expander building block, ** which obviously has to maintain a stack of expanded child dependencies. This leads to the ** observation, that at any point of this dependency processing, for the complete path from the ** child prerequisite up to the root tick there is a sequence of JobPlanning instances placed ** into this stack in the Explorer object (each level in this stack is actually an iterator ** and handles one level of child prerequisites). The deadline calculation directly exploits ** this known arrangement, insofar each JobPlanning has a pointer to its parent (sitting in - ** the stack level above). See the [IterExplorer unit test](\ref lib::IterTreeExplorer_test::verify_expandOperation) + ** the stack level above). See the [IterExplorer unit test](\ref lib::IterExplorer_test::verify_expandOperation) ** to understand this recursive on-demand processing in greater detail. ** ** @see JobPlanning_test diff --git a/tests/12metaprogramming.tests b/tests/12metaprogramming.tests index 735cd3b53..f9ff786a5 100644 --- a/tests/12metaprogramming.tests +++ b/tests/12metaprogramming.tests @@ -328,16 +328,7 @@ return: 0 END -TEST "Iterator monad variations (1st draft)" IterExplorer_test <timeOf (frameNr); }) - ) + ) == "200ms-240ms-280ms-320ms-360ms-400ms-440ms-480ms"_expect); @@ -326,7 +326,7 @@ namespace test { CHECK (visualise(pipeline) == "J(11|200ms⧐1s180ms)"_expect); // first job in pipeline: nominal t=200ms, // .... 10ms engine latency + 10ms job runtime ⟶ deadline 1s180ms CHECK (materialise( - treeExplore(move(pipeline)) + explore(move(pipeline)) .transform(visualise) ) == "J(11|200ms⧐1s180ms)-J(22|200ms⧐1s150ms)-J(33|200ms⧐1s110ms)-" // ... -(10+10) | -(10+10)-(10+20) | -(10+10)-(10+20)-(10+30) diff --git a/tests/core/steam/engine/mock-support-test.cpp b/tests/core/steam/engine/mock-support-test.cpp index df2002b20..dd907f791 100644 --- a/tests/core/steam/engine/mock-support-test.cpp +++ b/tests/core/steam/engine/mock-support-test.cpp @@ -29,7 +29,7 @@ #include "lib/test/test-helper.hpp" #include "steam/engine/mock-dispatcher.hpp" #include "vault/engine/nop-job-functor.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/util-tuple.hpp" #include "lib/util.hpp" diff --git a/tests/library/iter-tree-explorer-test.cpp b/tests/library/iter-explorer-test.cpp similarity index 94% rename from tests/library/iter-tree-explorer-test.cpp rename to tests/library/iter-explorer-test.cpp index 94f1969d2..8f199c3b2 100644 --- a/tests/library/iter-tree-explorer-test.cpp +++ b/tests/library/iter-explorer-test.cpp @@ -1,5 +1,5 @@ /* - IterTreeExplorer(Test) - verify tree expanding and backtracking iterator + IterExplorer(Test) - verify tree expanding and backtracking iterator Copyright (C) Lumiera.org 2017, Hermann Vosseler @@ -59,7 +59,7 @@ #include "lib/itertools.hpp" #include "lib/util.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/meta/trait.hpp" #include @@ -216,11 +216,11 @@ namespace test{ /*******************************************************************//** * @test use a simple source iterator yielding numbers * to build various functional evaluation pipelines, - * based on the \ref TreeExplorer template. + * based on the \ref IterExplorer template. * - the adapter to wrap the source, which can either * [be a state core](\ref verify_wrappedState() ), or can * [be a Lumiera Forward Iterator](\ref verify_wrappedIterator() ) - * - the defining use case for TreeExplorer is to build a + * - the defining use case for IterExplorer is to build a * [pipeline for depth-first exploration](\ref verify_expandOperation() ) * of a (functional) tree structure. This "tree" is created by invoking * a "expand functor", which can be defined in various ways. @@ -256,10 +256,10 @@ namespace test{ * It is up to the monad to decide if, and when those processing steps are applied to the * embedded values and how to combine the results into a new monad. * - * @see TreeExplorer + * @see IterExplorer * @see IterAdapter */ - class IterTreeExplorer_test : public Test + class IterExplorer_test : public Test { virtual void @@ -287,12 +287,12 @@ namespace test{ /** @test without using any extra functionality, - * TreeExplorer just wraps an iterable state. + * IterExplorer just wraps an iterable state. */ void verify_wrappedState() { - auto ii = treeExplore (CountDown{5,0}); + auto ii = explore (CountDown{5,0}); CHECK (!isnil (ii)); CHECK (5 == *ii); ++ii; @@ -304,17 +304,17 @@ namespace test{ VERIFY_ERROR (ITER_EXHAUST, *ii ); VERIFY_ERROR (ITER_EXHAUST, ++ii ); - ii = treeExplore (CountDown{5}); + ii = explore (CountDown{5}); CHECK (materialise(ii) == "5-4-3-2-1"); - ii = treeExplore (CountDown{7,4}); + ii = explore (CountDown{7,4}); CHECK (materialise(ii) == "7-6-5"); - ii = treeExplore (CountDown{}); + ii = explore (CountDown{}); CHECK ( isnil (ii)); CHECK (!ii); } - /** @test TreeExplorer is able to wrap any _Lumiera Forward Iterator_ */ + /** @test IterExplorer is able to wrap any _Lumiera Forward Iterator_ */ void verify_wrappedIterator() { @@ -325,7 +325,7 @@ namespace test{ ++ii; CHECK (-2 == *ii); - auto jj = treeExplore(ii); + auto jj = explore(ii); CHECK (!isnil (jj)); CHECK (-2 == *jj); ++jj; @@ -338,7 +338,7 @@ namespace test{ CHECK (materialise(jj) == "3--5-8--13"); // can even adapt STL container automatically - auto kk = treeExplore(numz); + auto kk = explore(numz); CHECK (!isnil (kk)); CHECK (1 == *kk); CHECK (materialise(kk) == "1--2-3--5-8--13"); @@ -368,7 +368,7 @@ namespace test{ * 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_ + * when building the IterExplorer. 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 @@ -386,12 +386,12 @@ namespace test{ /* == "monadic flatMap" == */ verify_treeExpandingIterator( - treeExplore(CountDown{5}) + explore(CountDown{5}) .expand([](uint j){ return CountDown{j-1}; }) // expand-functor: Val > StateCore ); verify_treeExpandingIterator( - treeExplore(CountDown{5}) + explore(CountDown{5}) .expand([](uint j){ return NumberSequence{j-1}; }) // expand-functor: Val > Iter ); // NOTE: different Iterator type than the source! @@ -407,7 +407,7 @@ namespace test{ }; verify_treeExpandingIterator( - treeExplore(CountDown{5}) + explore(CountDown{5}) .expand(expandIntoChildBuffer) // expand-functor: Val > STL-container& ); @@ -419,22 +419,22 @@ namespace test{ /* == "state manipulation" use cases == */ verify_treeExpandingIterator( - treeExplore(CountDown{5}) + explore(CountDown{5}) .expand([](CountDown const& core){ return CountDown{ core.yield() - 1}; }) // expand-functor: StateCore const& -> StateCore ); verify_treeExpandingIterator( - treeExplore(CountDown{5}) + explore(CountDown{5}) .expand([](CountDown core){ return NumberSequence{ core.yield() - 1}; }) // expand-functor: StateCore -> Iter ); verify_treeExpandingIterator( - treeExplore(CountDown{5}) + explore(CountDown{5}) .expand([](auto & it){ return CountDown{ *it - 1}; }) // generic Lambda: Iter& -> StateCore ); verify_treeExpandingIterator( - treeExplore(CountDown{5}) + explore(CountDown{5}) .expand([](auto it){ return decltype(it){ *it - 1}; }) // generic Lambda: Iter -> Iter ); } @@ -496,7 +496,7 @@ namespace test{ void verify_expand_rootCurrent() { - auto tree = treeExplore(CountDown{25}) + auto tree = explore(CountDown{25}) .expand([](uint j){ return CountDown{j-1}; }); CHECK (materialise(tree) == "25-24-23-22-21-20-19-18-17-16-15-14-13-12-11-10-9-8-7-6-5-4-3-2-1"); @@ -557,7 +557,7 @@ namespace test{ auto formatify = [&](auto it){ return string{embrace % *it}; }; // generic lambda: assumed to take an Iterator& - auto ii = treeExplore (CountDown{7,4}) + auto ii = explore(CountDown{7,4}) .transform(multiply) ; @@ -577,14 +577,14 @@ namespace test{ // demonstrate chaining of several transformation layers vector numz{1,-2,3,-5,8,-13}; - CHECK ("≺1≻-≺-2≻-≺3≻-≺-5≻-≺8≻-≺-13≻" == materialise (treeExplore(numz) + CHECK ("≺1≻-≺-2≻-≺3≻-≺-5≻-≺8≻-≺-13≻" == materialise (explore(numz) .transform(formatify)) ); - CHECK ("≺2≻-≺-4≻-≺6≻-≺-10≻-≺16≻-≺-26≻" == materialise (treeExplore(numz) + CHECK ("≺2≻-≺-4≻-≺6≻-≺-10≻-≺16≻-≺-26≻" == materialise (explore(numz) .transform(multiply) .transform(formatify)) ); - CHECK ("≺≺4≻≻-≺≺-8≻≻-≺≺12≻≻-≺≺-20≻≻-≺≺32≻≻-≺≺-52≻≻" == materialise (treeExplore(numz) + CHECK ("≺≺4≻≻-≺≺-8≻≻-≺≺12≻≻-≺≺-20≻≻-≺≺32≻≻-≺≺-52≻≻" == materialise (explore(numz) .transform(multiply) .transform(multiply) .transform(formatify) @@ -594,7 +594,7 @@ namespace test{ // demonstrate the functor is evaluated only once per step int fact = 3; - auto jj = treeExplore (CountDown{4}) + auto jj = explore (CountDown{4}) .transform([&](int v) { v *=fact; @@ -638,7 +638,7 @@ namespace test{ // demonstrate a transformer accessing the source state core... // should not be relevant in practice, but works due to the generic adapters - auto kk = treeExplore(CountDown{9,4}) + auto kk = explore (CountDown{9,4}) .transform([](CountDown& core) { uint delta = core.p - core.e; @@ -659,7 +659,7 @@ namespace test{ /** @test combine the recursion into children with a tail mapping operation. - * Wile basically this is just the layering structure of TreeExplorer put into action, + * Wile basically this is just the layering structure of IterExplorer put into action, * you should note one specific twist: the iter_explorer::Expander::expandChildren() call * is meant to be issued from ``downstream'', from the consumer side. Yet the consumer at * that point might well see the items as processed by a transforming step layered on top. @@ -683,7 +683,7 @@ namespace test{ void verify_combinedExpandTransform() { - auto ii = treeExplore(CountDown{5}) + auto ii = explore(CountDown{5}) .expand([](uint j){ return CountDown{j-1}; }) .transform([](int v){ return 2*v; }) ; @@ -700,7 +700,7 @@ namespace test{ // how intermediary processing steps may interact CHECK (materialise ( - treeExplore(CountDown{5}) + explore(CountDown{5}) .expand([](uint j){ return CountDown{j-1}; }) .transform([](int v){ return 2*v; }) .transform([](auto& it) @@ -748,13 +748,13 @@ namespace test{ verify_customProcessingLayer() { CHECK (materialise( - treeExplore(CountDown{7}) + explore(CountDown{7}) .processingLayer() ) == "7-5-3-1"); CHECK (materialise( - treeExplore(CountDown{7}) + explore(CountDown{7}) .transform([](uint v){ return 2*v; }) .processingLayer() .filter([](int v){ return v % 3; }) @@ -771,12 +771,12 @@ namespace test{ * Such is especially relevant when searching for a locally or global maximal solution, which * is rather simple to implement with an additional filtering layer -- and this approach requires * us to deliver all partial solutions for the filter layer to act on. Obviously this functionality - * leads to additional state and thus is provided as optional layer in the TreeExplorer builder. + * leads to additional state and thus is provided as optional layer in the IterExplorer builder. */ void verify_scheduledExpansion() { - auto ii = treeExplore(CountDown{6}) + auto ii = explore(CountDown{6}) .expand([](uint j){ return CountDown{j-2}; }) .expandOnIteration(); @@ -833,25 +833,25 @@ namespace test{ verify_untilStopTrigger() { CHECK (materialise ( - treeExplore(CountDown{10}) + explore (CountDown{10}) .iterUntil([](uint j){ return j < 5; }) ) == "10-9-8-7-6-5"_expect); CHECK (materialise ( - treeExplore(CountDown{10}) + explore (CountDown{10}) .iterWhile([](uint j){ return j > 5; }) ) == "10-9-8-7-6"_expect); CHECK (materialise ( - treeExplore(CountDown{10}) + explore (CountDown{10}) .iterWhile([](int j){ return j > -5; }) ) == "10-9-8-7-6-5-4-3-2-1"_expect); CHECK (materialise ( - treeExplore(CountDown{10}) + explore (CountDown{10}) .iterWhile([](uint j){ return j > 25; }) ) == ""_expect); @@ -870,14 +870,14 @@ namespace test{ { // canonical example, using a clean side-effect free predicate based on element values CHECK (materialise ( - treeExplore(CountDown{10}) + explore(CountDown{10}) .filter([](uint j){ return j % 2; }) ) == "9-7-5-3-1"_expect); // Filter may lead to consuming util exhaustion... - auto ii = treeExplore(CountDown{10}) + auto ii = explore(CountDown{10}) .filter([](int j){ return j > 9; }); CHECK (not isnil (ii)); @@ -888,7 +888,7 @@ namespace test{ // none of the source elements can be approved here... - auto jj = treeExplore(CountDown{5}) + auto jj = explore(CountDown{5}) .filter([](int j){ return j > 9; }); CHECK (isnil (jj)); @@ -901,7 +901,7 @@ namespace test{ // uint to float, but the filter interacts directly with the core and thus // judges based on the original values CHECK (materialise ( - treeExplore(CountDown{10,4}) + explore(CountDown{10,4}) .transform([](float f){ return 0.55 + 2*f; }) .filter([](CountDown& core){ return core.p % 2; }) ) @@ -912,7 +912,7 @@ namespace test{ // contrived example to verify interplay of filtering and child expansion; // especially note that the filter is re-evaluated after expansion happened. CHECK (materialise ( - treeExplore(CountDown{10}) + explore(CountDown{10}) .expand([](uint i){ return CountDown{i%4==0? i-1 : 0}; }) // generate subtree at 8 and 4 ==> 10-9-8-7-6-5-4-3-2-1-3-2-1-7-6-5-4-3-2-1-3-2-1 .filter([](uint i){ return i%2 == 0; }) .expandAll() // Note: sends the expandChildren down through the filter @@ -927,7 +927,7 @@ namespace test{ // - accepting the iterator to trigger child expansion // - which also causes re-evaluation of the preceding transformer bool toggle = false; - auto kk = treeExplore(CountDown{10,5}) + auto kk = explore(CountDown{10,5}) .expand([](uint j){ return CountDown{j-1}; }) .transform([](int v){ return 2*v; }) .filter([&](auto& it) @@ -955,7 +955,7 @@ namespace test{ CHECK (materialise(kk.filter([](long i){ return i % 7; })) == "12-10-8-6-4-2-12"_expect); // Explanation: - // Since the original TreeExplorer was assigned to variable kk, + // Since the original IterExplorer was assigned to variable kk, // the materialise()-Function got a lvalue-ref and thus made a copy // of the whole compound. For that reason, the original state within // kk still rests at 7 -- because the filter evaluates eagerly, the @@ -977,7 +977,7 @@ namespace test{ void verify_FilterChanges() { - auto seq = treeExplore(CountDown{20}) + auto seq = explore(CountDown{20}) .mutableFilter(); auto takeEve = [](uint i){ return i%2 == 0; }; @@ -1036,7 +1036,7 @@ namespace test{ // verify enabling and disabling... - seq = treeExplore(CountDown{10}) + seq = explore(CountDown{10}) .mutableFilter(takeTrd); CHECK (9 == *seq); @@ -1063,7 +1063,7 @@ namespace test{ /** @test package the resulting Iterator as automatically managed, * polymorphic opaque entity implementing the IterSource interface. - * The builder operations on TreeExplorer each generate a distinct, implementation + * The builder operations on IterExplorer each generate a distinct, implementation * defined type, which is meant to be captured by `auto`. However, the terminal builder * function `asIterSource()` moves the whole compound iterator object, as generated by * preceding builder steps, into a heap allocation and exposes a simplified front-end, @@ -1088,7 +1088,7 @@ namespace test{ IterSource::iterator sequence; // note `sequence` is polymorphic CHECK (isnil (sequence)); - sequence = treeExplore(CountDown{20,10}) + sequence = explore(CountDown{20,10}) .filter([](uint i){ return i % 2; }) .asIterSource(); // note this terminal builder function // moves the whole pipeline onto the heap @@ -1097,7 +1097,7 @@ namespace test{ // use one sequence as source to build another one - sequence = treeExplore(sequence) + sequence = explore(sequence) .transform([](uint i){ return i*2; }) .asIterSource(); @@ -1117,7 +1117,7 @@ namespace test{ IterExploreSource exploreIter; CHECK (isnil (exploreIter)); - exploreIter = treeExplore(CountDown{20,10}) + exploreIter = explore(CountDown{20,10}) .filter([](uint i){ return i % 2; }) .transform([](uint i){ return i*2; }) .filter([](int i){ return i>25; }) @@ -1144,7 +1144,7 @@ namespace test{ * Contrary to the preceding test case, here the point is to _base the whole pipeline_ * on a data source accessible through the IterSource (VTable based) interface. The notable * point with this technique is the ability to use some _extended sub interface of IterSource_ - * and to rely on this interface to implement some functor bound into the TreeExplorer pipeline. + * and to rely on this interface to implement some functor bound into the IterExplorer pipeline. * Especially this allows to delegate the "child expansion" through such an interface and just * return a compatible IterSource as result. This way, the opaque implementation gains total * freedom regarding the concrete implementation of the "child series" iterator. In fact, @@ -1185,14 +1185,14 @@ namespace test{ // simple standard case: create a new heap allocated IterSource implementation. - // TreeExplorer will take ownership (by smart-ptr) and build a Lumiera Iterator front-End + // IterExplorer will take ownership (by smart-ptr) and build a Lumiera Iterator front-End CHECK ("7-6-5-4-3-2-1" == materialise ( - treeExplore(new VerySpecificIter{7}))); + explore (new VerySpecificIter{7}))); // missing source detected PrivateSource* niente = nullptr; - CHECK (isnil (treeExplore(niente))); + CHECK (isnil (explore (niente))); // attach to an IterSource living here in local scope... @@ -1201,7 +1201,7 @@ namespace test{ // ...and build a child expansion on top, which calls through the PrivateSource-API // Effectively this means we do not know the concrete type of the "expanded children" iterator, // only that it adheres to the same IterSource sub-interface as used on the base iterator. - auto ii = treeExplore(vsit) + auto ii = explore(vsit) .expand ([](PrivateSource& source){ return source.expandChildren(); }); CHECK (not isnil (ii)); @@ -1258,7 +1258,7 @@ namespace test{ verify_depthFirstExploration() { CHECK (materialise( - treeExplore(CountDown{4}) + explore(CountDown{4}) .expand([](uint j){ return CountDown{j-1}; }) .expandAll() .transform([](int i){ return i*10; }) @@ -1277,7 +1277,7 @@ namespace test{ }; CHECK (materialise( - treeExplore(CountDown{4}) + explore(CountDown{4}) .transform([](uint i){ return Tu2{i,0}; }) .expand(summingExpander) .expandAll() @@ -1289,7 +1289,7 @@ namespace test{ /** @test Demonstration how to build complex algorithms by layered tree expanding iteration - * @remarks this is the actual use case which inspired the design of TreeExplorer: + * @remarks this is the actual use case which inspired the design of IterExplorer: * Search with backtracking over an opaque (abstracted), tree-shaped search space. * - the first point to note is that the search algorithm knows nothing about its * data source, beyond its ability to delve down (expand) into child nodes @@ -1316,7 +1316,7 @@ namespace test{ { // Layer-1: the search space with "hidden" implementation using DataSrc = IterExploreSource; - DataSrc searchSpace = treeExplore(RandomSeq{-1}) + DataSrc searchSpace = explore(RandomSeq{-1}) .expand([](char){ return RandomSeq{15}; }) .asIterSource(); @@ -1370,10 +1370,10 @@ namespace test{ // Layer-3: Evaluation pipeline to drive search - string toFind = util::join (treeExplore (RandomSeq{5}), ""); + string toFind = util::join (explore (RandomSeq{5}), ""); cout << "Search in random tree: toFind = "<src.depth() < it->toFind.size() - 1 @@ -1392,7 +1392,7 @@ namespace test{ - LAUNCHER (IterTreeExplorer_test, "unit common"); + LAUNCHER (IterExplorer_test, "unit common"); }} // namespace lib::test diff --git a/tests/library/meta/value-type-binding-test.cpp b/tests/library/meta/value-type-binding-test.cpp index 462e58716..61aa81b79 100644 --- a/tests/library/meta/value-type-binding-test.cpp +++ b/tests/library/meta/value-type-binding-test.cpp @@ -75,7 +75,7 @@ namespace test{ * * @see value-type-binding.hpp * @see lib::RangeIter - * @see lib::TreeExplorer::transform() + * @see lib::IterExplorer::transform() */ class ValueTypeBinding_test : public Test diff --git a/tests/library/verb-visitor-dispatch-test.cpp b/tests/library/verb-visitor-dispatch-test.cpp index bd50835f6..7d14791fe 100644 --- a/tests/library/verb-visitor-dispatch-test.cpp +++ b/tests/library/verb-visitor-dispatch-test.cpp @@ -32,7 +32,7 @@ #include "lib/format-cout.hpp" #include "lib/format-util.hpp" #include "lib/meta/tuple-helper.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include #include @@ -200,7 +200,7 @@ namespace test{ DiagnosticRenderer diagnostic; auto render = [&](Receiver& renderer) { - return join (lib::treeExplore(tokens) + return join (lib::explore(tokens) .transform ([&](Token tok) { return tok.applyTo (renderer); diff --git a/tests/stage/gen-node-location-query.hpp b/tests/stage/gen-node-location-query.hpp index fde51f26d..db0bbd779 100644 --- a/tests/stage/gen-node-location-query.hpp +++ b/tests/stage/gen-node-location-query.hpp @@ -52,7 +52,7 @@ ** if this implementation can be used beyond this limited purpose ** ** @see UICoordResolver_test - ** @see IterTreeExplorer_test + ** @see IterExplorer_test ** @see ui-coord-resolver.hpp ** @see navigator.hpp */ @@ -66,7 +66,7 @@ #include "stage/interact/ui-coord-resolver.hpp" #include "lib/diff/gen-node.hpp" #include "lib/format-string.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/iter-source.hpp" #include "lib/itertools.hpp" #include "lib/util.hpp" diff --git a/tests/stage/interact/ui-coord-resolver-test.cpp b/tests/stage/interact/ui-coord-resolver-test.cpp index 65dd502a4..cccc0e858 100644 --- a/tests/stage/interact/ui-coord-resolver-test.cpp +++ b/tests/stage/interact/ui-coord-resolver-test.cpp @@ -145,7 +145,7 @@ namespace test { * UI this would of course not be a configurable property of the * LocationQuery, but rather just reflect the transient window * state and return the currently activated window - * @see IterTreeExplorer_test::verify_IterSource() regarding "child exploration"... + * @see IterExplorer_test::verify_IterSource() regarding "child exploration"... */ void verify_backingQuery() diff --git a/tests/stage/model/canvas-hook-test.cpp b/tests/stage/model/canvas-hook-test.cpp index c223427a9..20a8aab50 100644 --- a/tests/stage/model/canvas-hook-test.cpp +++ b/tests/stage/model/canvas-hook-test.cpp @@ -29,7 +29,7 @@ #include "lib/test/test-helper.hpp" #include "stage/model/canvas-hook.hpp" #include "lib/scoped-collection.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/iter-adapter-stl.hpp" #include "lib/util.hpp" @@ -84,7 +84,7 @@ namespace test { auto allWidgetIDs() const { - return lib::treeExplore(widgets_) + return lib::explore(widgets_) .transform([](Attachment const& entry) { return entry.widget.i; diff --git a/tests/stage/model/view-hook-test.cpp b/tests/stage/model/view-hook-test.cpp index 92c7315e5..cc7a76107 100644 --- a/tests/stage/model/view-hook-test.cpp +++ b/tests/stage/model/view-hook-test.cpp @@ -29,7 +29,7 @@ #include "lib/test/test-helper.hpp" #include "stage/model/view-hook.hpp" #include "lib/scoped-collection.hpp" -#include "lib/iter-tree-explorer.hpp" +#include "lib/iter-explorer.hpp" #include "lib/iter-adapter-stl.hpp" #include "lib/util.hpp" @@ -77,7 +77,7 @@ namespace test { auto allWidgetIDs() const { - return lib::treeExplore(widgets_) + return lib::explore(widgets_) .transform([](DummyWidget const& entry) { return entry.i;