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.... :-)
This commit is contained in:
Fischlurch 2018-09-13 15:48:51 +02:00
parent 10f21f77f8
commit 29d2c151b3
3 changed files with 88 additions and 12 deletions

View file

@ -177,9 +177,8 @@ namespace iter {
* it is _possible_ to build a step which _extends_ or sharpens the preceding condition.
*/
template<typename FUN>
disable_if<is_convertible<FUN, Value>,
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<typename FUN>
disable_if<is_convertible<FUN, Value>,
IterChainSearch&& >
search (FUN&& filterPredicate)
{
addStep ([predicate{forward<FUN> (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);
}

View file

@ -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_>() <<endl;
#define SHOW_EXPR(_XX_) \
cout << "Probe " << STRINGIFY(_XX_) << " ? = " << _XX_ <<endl;
/** Diagnostic helper: join all the elements from a _copy_ of the iterator */
template<class II>
inline string
materialise (II&& ii)
{
return util::join (std::forward<II> (ii), "-");
}
///////////////////////////////////////////////////TODO WIP
@ -108,9 +117,6 @@ namespace test{
.search("bacon")
.search("tomato");
///////////////////////////////////////////////////TODO WIP
cout << "search[0]=" <<*search<<endl;
///////////////////////////////////////////////////TODO WIP
CHECK (search);
CHECK (not isnil(search));
CHECK ("tomato" == *search);
@ -142,6 +148,11 @@ namespace test{
void
chainedIteration ()
{
auto search = chainSearch(SPAM)
.search([](string const& str){ return startsWith (str, "s"); });
///////////////////////////////////////////////////TODO WIP
cout << materialise (search) <<endl;
///////////////////////////////////////////////////TODO WIP
}

View file

@ -32163,6 +32163,56 @@
<node COLOR="#338800" CREATED="1536358204137" ID="ID_1724606451" MODIFIED="1536716878774" TEXT="verwirft den sonstigen Stack komplett"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1536792181982" ID="ID_548701484" MODIFIED="1536792260764" TEXT="search direkt per Pr&#xe4;dikat">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...d.h. direkt das Pr&#228;dikat, und nicht eine Funktion, die den Filter konfiguriert
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1536792241949" ID="ID_613611906" MODIFIED="1536792249583" TEXT="setzt direkt nur ein neues Pr&#xe4;dikat"/>
<node CREATED="1536792250124" ID="ID_10955924" MODIFIED="1536792257390" TEXT="spart viel Syntax ein">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#435e98" CREATED="1536845264898" ID="ID_1033092941" MODIFIED="1536845289109" TEXT="Problem: capture forward">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1536845290596" ID="ID_1184113483" MODIFIED="1536845467915" TEXT="Lamda soll eine &quot;universelle referenz&quot; capturen">
<icon BUILTIN="yes"/>
</node>
<node COLOR="#338800" CREATED="1536845309386" ID="ID_1593606355" MODIFIED="1536845460398" TEXT="Ausweg: forward-into captured value">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1536845374585" ID="ID_794602132" LINK="https://stackoverflow.com/a/20669290" MODIFIED="1536845438985" TEXT="geht seit C++14"/>
<node CREATED="1536845439219" ID="ID_372370252" MODIFIED="1536845455950" TEXT="nur Eclipse / CDT mault herum">
<icon BUILTIN="smily_bad"/>
<node CREATED="1536845496960" ID="ID_1490455562" MODIFIED="1536845539474" TEXT="und deshalb...">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...habe ich noch gar nicht gemerkt, da&#223; das geht,
</p>
<p>
und manchen komischen Workaround implementiert.
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1536845594971" ID="ID_1942437093" MODIFIED="1536845602373" TEXT="Eclipse updaten?">
<icon BUILTIN="hourglass"/>
</node>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1536018420398" ID="ID_41628967" MODIFIED="1536326452308" TEXT="Adaptieren der Quell-Datensequenz">