From c0b8b63df037e6f68f42eae5809446fb2ef3166f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 7 Sep 2018 20:44:25 +0200 Subject: [PATCH] ChainSearch: ensure to pass current state without spurious copy It is essential that we pass the current state of the filter into the expand functor, where it needs to be copied (once!) to create a child state, which can then be augmented. This augmented state is then pushed onto a stack, to enable backtracking. Due to the flexible adapters and the wrapping into the TreeExplorer builder, we ended up performing several spurious copies on the current state --- src/lib/iter-chain-search.hpp | 21 +++++--- src/lib/iter-tree-explorer.hpp | 10 ++++ wiki/thinkPad.ichthyo.mm | 93 ++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 6 deletions(-) diff --git a/src/lib/iter-chain-search.hpp b/src/lib/iter-chain-search.hpp index 01e957cd7..6c661abc5 100644 --- a/src/lib/iter-chain-search.hpp +++ b/src/lib/iter-chain-search.hpp @@ -92,11 +92,19 @@ namespace iter { template struct _IterChainSetup { - using Filter = decltype( buildSearchFilter (std::declval()) ); - - using StepFunctor = typename iter_explorer::_BoundFunctor::Functor; + using Filter = decltype( buildSearchFilter(std::declval()).asIterator() ); + using StepFunctor = std::function; + using StepWrapper = typename iter_explorer::_BoundFunctor::Functor; + // ^^^^^^^^^^^^^ used as argument on generic lambda using Pipeline = decltype( buildExplorer (std::declval(), std::declval()) ); + + static Pipeline + configurePipeline (SRC&& dataSource, StepFunctor step) + { + return buildExplorer(forward (dataSource), move (step)); + } + }; }//(End)type construction helpers @@ -122,7 +130,7 @@ namespace iter { using Value = typename _Base::value_type; using Filter = typename _Trait::Filter; - using Step = typename _Trait::StepFunctor; + using Step = typename _Trait::StepWrapper; std::vector stepChain_; @@ -136,8 +144,8 @@ namespace iter { template explicit IterChainSearch (SEQ&& srcData) - : _Base{move (buildExplorer (forward (srcData) - ,Step{[this](Filter const& curr){ return configureFilterChain(curr); }}))} + : _Base{_Trait::configurePipeline (forward (srcData) + ,[this](Filter const& curr){ return configureFilterChain(curr); })} { } // inherited default ctor and standard copy operations @@ -165,6 +173,7 @@ namespace iter { search (FUN&& configureSearchStep) { stepChain_.emplace_back (Step{forward (configureSearchStep)}); + this->iterNext(); // establish invariant: expand to leaf and forward to first match return move(*this); } diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index be4590e2c..a7f5c5686 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -1474,6 +1474,16 @@ namespace lib { { return IterExploreSource {move(*this)}; } + + + /** _terminal builder_ to strip the TreeExplorer and expose the built Pipeline. + * @return a »Lumiera Forward iterator« incorporating the complete pipeline logic. + */ + SRC + asIterator() + { + return SRC {move(*this)}; + } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 92ac0c48a..4b7f561ef 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -31215,6 +31215,99 @@ + + + + + + + + + + + + + + + + + + + + + + +

+ ...d.h. die einzelnen Steps in der Pipeline direkt wrappen. +

+

+ Dann ist außen herum keine Anpassung der Argumente mehr notwendig, +

+

+ und man kann die Expand-Funktion direkt als std::function-Objekt durchgeben +

+ + +
+ +
+
+ + + + + + +

+ ...um den Expand-Funktor zu zwingen, eine Kopie zu machen; +

+

+ es sollte die Filter-Konfiguration auf der Kopie manipuliert werden, +

+

+ während das Original auf dem Auswertungs-Stack liegen bleibt, +

+

+ für späteres Backtracking... +

+ + +
+
+ + + + + + + + +

+ ...damit man stets weitere Builder-Funktionen auf der Pipeline aufrufen kann +

+ + +
+
+ + + + + + +

+ weil wir diesen manipulieren +

+ + +
+
+ + + + +
+