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:
parent
10f21f77f8
commit
29d2c151b3
3 changed files with 88 additions and 12 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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ädikat">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...d.h. direkt das Prä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ä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 "universelle referenz" 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ß 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">
|
||||
|
|
|
|||
Loading…
Reference in a new issue