TreeExplorer: rework the solution to allow for arbitrary functor types
outift the Filter base class with the most generic form of the Functor wrapper, and rather wrap each functor argument individually. This allows then to combine various kinds of functors
This commit is contained in:
parent
90c0f43cfd
commit
be7f47d5b7
3 changed files with 67 additions and 18 deletions
|
|
@ -941,15 +941,41 @@ namespace lib {
|
|||
* original filter functor, under the assumption that both are roughly compatible. Moreover,
|
||||
* since we wrap the actual lambda into an adapter, allowing for generic lambdas to be used
|
||||
* as filter predicates, this setup allows for a lot of leeway regarding the concrete predicates.
|
||||
* @note whenever the filter is remoulded, the invariant is immediately [re-established](\ref Filter::pullFilter() )
|
||||
* @note whenever the filter is remoulded, the invariant is immediately
|
||||
* [re-established](\ref Filter::pullFilter() ), possibly forwarding the sequence
|
||||
* to the next element approved by the new version of the filter.
|
||||
* @remarks filter predicates can be specified in a wide variety of forms, and will be adapted
|
||||
* automatically. This flexibility also holds for any of the additional clauses provided
|
||||
* for remoulding the filter. Especially this means that functors of different kinds can
|
||||
* be mixed and combined. To allow for this flexibility, we need to drive the _base class_
|
||||
* with the most general form of a predicate functor, corresponding to `bool<SRC&>`.
|
||||
* Hereby we exploit the fact that the _wrapped filter,_ i.e. the Functor type constructed
|
||||
* in the _BoundFunctor traits, boils down to that most generic form, adapting the arguments
|
||||
* automatically. Thus the initial functor, the one passed to the ctor of this class, is
|
||||
* effectively wrapped twice, so it can be combined later on with any other form and
|
||||
* shape of functor. And since everything is inline, the compiler will remove any
|
||||
* overhead resulting from this redundant wrapping.
|
||||
*/
|
||||
template<class SRC, class FUN>
|
||||
class MutableFilter
|
||||
: public Filter<SRC,FUN>
|
||||
: public Filter<SRC, typename _BoundFunctor<FUN,SRC>::Functor>
|
||||
{
|
||||
using _Base = Filter<SRC,FUN>;
|
||||
using _Traits = _BoundFunctor<FUN,SRC>;
|
||||
using FilterPredicate = typename _Traits::Functor;
|
||||
using _Base = Filter<SRC,FilterPredicate>;
|
||||
|
||||
static_assert(can_IterForEach<SRC>::value, "Lumiera Iterator required as source");
|
||||
using Res = typename _Traits::Res;
|
||||
static_assert(std::is_constructible<bool, Res>::value, "Functor must be a predicate");
|
||||
|
||||
|
||||
public:
|
||||
using _Base::Filter;
|
||||
MutableFilter() =default;
|
||||
// inherited default copy operations
|
||||
|
||||
MutableFilter (SRC&& dataSrc, FUN&& filterFun)
|
||||
: _Base{move (dataSrc), FilterPredicate{forward<FUN> (filterFun)}}
|
||||
{ }
|
||||
|
||||
|
||||
public: /* === API to Remould the Filter condition underway === */
|
||||
|
|
@ -1073,13 +1099,13 @@ namespace lib {
|
|||
using Res = typename _ChainTraits::Res;
|
||||
static_assert(std::is_constructible<bool, Res>::value, "Chained Functor must be a predicate");
|
||||
|
||||
using FilterPredicate = typename _Base::FilterPredicate;
|
||||
using WrappedPredicate = typename _Base::FilterPredicate;
|
||||
using ChainPredicate = typename _ChainTraits::Functor;
|
||||
|
||||
FilterPredicate& firstClause = _Base::predicate_; // pick up the existing filter predicate
|
||||
WrappedPredicate& firstClause = _Base::predicate_; // pick up the existing filter predicate
|
||||
ChainPredicate chainClause{forward<COND> (additionalClause)}; // wrap the extension predicate in a similar way
|
||||
|
||||
_Base::predicate_ = FilterPredicate{buildCombinedClause (firstClause, chainClause)};
|
||||
_Base::predicate_ = WrappedPredicate{buildCombinedClause (firstClause, chainClause)};
|
||||
_Base::pullFilter(); // pull to re-establish the Invariant
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -888,16 +888,19 @@ namespace test{
|
|||
++seq;
|
||||
CHECK ( 3 == *seq);
|
||||
|
||||
// string buff{"."};
|
||||
// seq.andNotFilter ([&](CountDown& core)
|
||||
// {
|
||||
// buff += util::toString(core.p) + ".";
|
||||
// --core.p;
|
||||
// return core.p % 2;
|
||||
// });
|
||||
// cout << "URGS: "<<*seq<< " ..."<<buff<<endl;
|
||||
// cout << "URGS: "<<*seq<< " ..."<<buff<<endl;
|
||||
// cout << "URGS: "<<*seq<< " ..."<<buff<<endl;
|
||||
string buff{"."};
|
||||
seq.andNotFilter ([&](CountDown& core)
|
||||
{
|
||||
buff += util::toString(core.p) + ".";
|
||||
--core.p;
|
||||
return core.p % 2;
|
||||
});
|
||||
cout << "URGS: "<<*seq<< " ..."<<buff<<endl;
|
||||
++seq;
|
||||
cout << "URGS: "<<*seq<< " ..."<<buff<<endl;
|
||||
++seq;
|
||||
CHECK (isnil (seq));
|
||||
VERIFY_ERROR (ITER_EXHAUST, *seq );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31086,6 +31086,26 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1535919835337" ID="ID_984434298" MODIFIED="1535920192370" TEXT="Ausweg: doppelt wrappen?">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1535923167297" ID="ID_1611885187" MODIFIED="1535923219590" TEXT="Basis-Filter sieht unspezifische Form des Prädikates"/>
|
||||
<node CREATED="1535923237336" ID="ID_873685254" MODIFIED="1535923251434" TEXT="im Funktor steckt eingewickelt eine spezifische Form"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1535924949587" ID="ID_283543674" MODIFIED="1535925042250" TEXT="Lösung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1535924955458" ID="ID_257130301" MODIFIED="1535927205707" TEXT="Typ des gewrappten Funktors konstruieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1535924963017" ID="ID_1923686219" MODIFIED="1535927208519" TEXT="diesen schon in die Instanz der Basisklasse einfließen lassen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1535924983038" ID="ID_966924861" MODIFIED="1535927210570" TEXT="Konstruktor eigens definieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1535924991781" ID="ID_28842573" MODIFIED="1535927212273" TEXT="inline wrappen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1535925016969" ID="ID_214947623" MODIFIED="1535927239938" TEXT="der Rest müßte von selber funktionieren...">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -31116,7 +31136,7 @@
|
|||
</node>
|
||||
<node CREATED="1535893799799" ID="ID_706866636" MODIFIED="1535893804419" TEXT="Auswertungs-Stack">
|
||||
<node CREATED="1535893826972" ID="ID_352546105" MODIFIED="1535894073967" TEXT="aktueller Frame">
|
||||
<node CREATED="1535894074891" ID="ID_1972842519" MODIFIED="1535894075798" TEXT="== aktuel wirksamer Suchfilter"/>
|
||||
<node CREATED="1535894074891" ID="ID_1972842519" MODIFIED="1535923151832" TEXT="== aktuell wirksamer Suchfilter"/>
|
||||
<node CREATED="1535894076546" ID="ID_880245387" MODIFIED="1535894084445" TEXT="schießt Suchposition ein"/>
|
||||
</node>
|
||||
<node CREATED="1535893989214" ID="ID_875812160" MODIFIED="1535894010499">
|
||||
|
|
|
|||
Loading…
Reference in a new issue