From 29d2c151b3e6137d93faca2d8fff53c73d05b689 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 13 Sep 2018 15:48:51 +0200 Subject: [PATCH] ChainSearch: add builder function just to replace the filter Up to now, we had a very simplistic configuration option just to search for a match, and we had the complete full-blown reconfiguration builder option, which accepts a functor to work on and reconfigure the embedded Filter chain. It occurred to me that in many cases you'd rather want some intermediary level of flexibility: you want to replace the filter predicate entirely by some explicitly given functor, yet you don't need the full ability to re-shape the Filter chain as a whole. In fact the intended use case for IterChainSearch (which is the EventLog I am about to augment with backtracking capabilities) will only ever need that intermediate level. Thus wer're adding this intermediary level of configurability now. The only twist is that doing so requires us to pass an "arbitrary function like thing" (captured by universal reference) through a "layer of lambdas". Which means, we have to capture an "arbitrary thingie" by value. Fortunately, as I just found out today, C++14 allows something which comes close to that requirement: the value capture of a lambda is allowe to have an intialiser. Which means, we can std::forward into the value captured by the intermediary lambda. I just hope I never need to know or understand the actual type this captured "value" takes on.... :-) --- src/lib/iter-chain-search.hpp | 33 +++++++++++----- tests/library/iter-chain-search-test.cpp | 17 ++++++-- wiki/thinkPad.ichthyo.mm | 50 ++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/src/lib/iter-chain-search.hpp b/src/lib/iter-chain-search.hpp index b1eec1949..3de00ddea 100644 --- a/src/lib/iter-chain-search.hpp +++ b/src/lib/iter-chain-search.hpp @@ -177,9 +177,8 @@ namespace iter { * it is _possible_ to build a step which _extends_ or sharpens the preceding condition. */ template - disable_if, - IterChainSearch&& > - search (FUN&& configureSearchStep) + IterChainSearch&& + addStep (FUN&& configureSearchStep) { if (not this->empty()) { @@ -196,18 +195,34 @@ namespace iter { return move(*this); } + /** attach additional search with the given filter predicate. + * After successfully searching for all the conditions currently in the filter chain, + * the embedded iterator will finally be pulled until matching the given target value. + * @remarks adds a new layer on the stack of search conditions with a _copy_ of the + * previously used iterator, and installs the given filter predicate therein. + */ + template + disable_if, + IterChainSearch&& > + search (FUN&& filterPredicate) + { + addStep ([predicate{forward (filterPredicate)}] + (Filter filter) // note: filter taken by value + { + filter.setNewFilter (predicate); + return filter; // return copy of the original state with changed filter + }); + return move(*this); + } + /** attach additional direct search for a given value. * After successfully searching for all the conditions currently in the filter chain, - * the underlying iterator will finally be pulled until matching the given target value. + * the embedded iterator will finally be pulled until matching the given target value. */ IterChainSearch&& search (Value target) { - search ([=](Filter filter) // note: filter taken by value - { - filter.setNewFilter ([target](Value const& currVal) { return currVal == target; }); - return filter; // return copy of the original state with changed filter - }); + search ([target](Value const& currVal) { return currVal == target; }); return move(*this); } diff --git a/tests/library/iter-chain-search-test.cpp b/tests/library/iter-chain-search-test.cpp index e1688776f..a62b165b6 100644 --- a/tests/library/iter-chain-search-test.cpp +++ b/tests/library/iter-chain-search-test.cpp @@ -45,6 +45,7 @@ namespace test{ using ::Test; using util::join; using util::isnil; + using util::startsWith; using util::isSameObject; using std::vector; using std::string; @@ -76,6 +77,14 @@ namespace test{ cout << "typeof( " << STRINGIFY(_TY_) << " )= " << lib::meta::typeStr<_TY_>() < + + + + + + +

+ ...d.h. direkt das Prädikat, und nicht eine Funktion, die den Filter konfiguriert +

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

+ ...habe ich noch gar nicht gemerkt, daß das geht, +

+

+ und manchen komischen Workaround implementiert. +

+ + +
+
+ + + +
+
+