From 94da0f627f3af36d09ef92cdd2ca87ce70f7b6ac Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 2 Sep 2018 18:42:58 +0200 Subject: [PATCH] TreeExplorer: draft ability to remould the filter The intention is to switch from the itertools-based filter to the filter available in the TreeExplorer framework. Thus "basically" we just need to copy the solution over, since both are conceptually equivalent. However...... :-( The TreeExplorer framework is designed to be way more generic and accepts basically everything as argument and tries to adapt apropriately. This means we have to use a lot of intricate boilerplate code, just to get the same effect that was possible in Itertools with a simple and elegant in-place lambda assignment --- src/lib/iter-tree-explorer.hpp | 27 +++- tests/library/iter-tree-explorer-test.cpp | 23 ++++ wiki/thinkPad.ichthyo.mm | 149 +++++++++++++++++++++- 3 files changed, 197 insertions(+), 2 deletions(-) diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index 650db48cc..9e4227c5f 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -526,7 +526,7 @@ namespace lib { template Res - operator() (ARG& arg) + operator() (ARG& arg) const { auto accessArg = ArgAccessor::build(); @@ -910,6 +910,31 @@ namespace lib { pullFilter(); } + + /* === Remould the Filter condition underway === */ + + template + void + andFilter (COND conjunctiveClause) + { + using _ChainTraits = _BoundFunctor; + using Res = typename _ChainTraits::Res; + static_assert(std::is_constructible::value, "Chained Functor must be a predicate"); + + using ChainPredicate = typename _ChainTraits::Functor; + + FilterPredicate& firstClause = this->predicate_; + ChainPredicate chainClause{forward (conjunctiveClause)}; + + + predicate_ = FilterPredicate{[firstClause, chainClause] (auto val) + { + return firstClause(val) + and chainClause(val); + } }; + pullFilter(); + } + private: SRC& srcIter() const diff --git a/tests/library/iter-tree-explorer-test.cpp b/tests/library/iter-tree-explorer-test.cpp index 39e9e08d3..5ef65bf60 100644 --- a/tests/library/iter-tree-explorer-test.cpp +++ b/tests/library/iter-tree-explorer-test.cpp @@ -276,6 +276,7 @@ namespace test{ verify_combinedExpandTransform(); verify_scheduledExpansion(); verify_FilterIterator(); + verify_FilterChanges(); verify_asIterSource(); verify_IterSource(); @@ -847,6 +848,28 @@ namespace test{ + /** @test the filter layer can be re-configured on the fly */ + void + verify_FilterChanges() + { + auto seq = treeExplore(CountDown{20}) + .filter([](uint){ return true; }); + + auto takeEve = [](uint i){ return i%2 == 0; }; + auto takeTrd = [](uint i){ return i%3 == 0; }; + + CHECK (20 == *seq); + ++seq; + CHECK (19 == *seq); + CHECK (19 == *seq); + + seq.andFilter (takeEve); + CHECK (18 == *seq); + } + + + + /** @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 diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index c4a24a536..cff9e76e8 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -30840,7 +30840,8 @@ - + + @@ -30855,6 +30856,152 @@ + + + + + + + + + + + + + + +

+ ...und das hängt an einem hauchdünnen Faden, +

+

+ und ist subtil bis zum geht nicht mehr.... +

+

+ +

+

+ Wenn man das Lambda einfach per [=] schreibt, und das Feld this->predicate_ verwendet, +

+

+ dann wird this gecaptured (und das ist effektiv per Referenz). Wenn ich dann den +

+

+ konstruierten Funktor an this->predicate_ zuweise, haben wir eine Endlos-Rekursion. +

+

+ +

+

+ Lösung: man muß im lokalen Frame eine Referenz auf this->predicate definieren und binden. +

+

+ Diese wird dann per Value gecaptured, was die gewünschte Kopie bewirkt. +

+ + +
+
+ + + + + + +

+ ...muß den Chain-Funktor aus dem Template-Argument erzeugen, +

+

+ und ihn dann in die per-Value-Closure des erzeugten neuen Lambda binden (=Kopie). +

+

+ +

+

+ Erst ab C++17 kann man Lambda-Captures pre move machen +

+

+ (und auch dafür ist die Syntax grausam) +

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

+ ...es soll bloß einfach funktionieren!!!!!!!!!!! +

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

+ keine gute Idee. +

+

+ Dann verwenden wir im einen Funktor-Framework eine Filter-Komponente +

+

+ aus dem anderen Framework, obwohl es direkt hier auch eine Filter-Komponente gäbe. +

+

+ +

+

+ Außerdem habe ich immer noch die Hoffnung, irgendwann mal +

+

+ die Itertools komplett durch den TreeExplorer ablösen zu können +

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

+ ...so daß es nur noch wenige Zugangs-Punkte zum unterliegenden Iterator gibt +

+ + +
+