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:
Fischlurch 2018-09-03 00:27:21 +02:00
parent 90c0f43cfd
commit be7f47d5b7
3 changed files with 67 additions and 18 deletions

View file

@ -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
}
};

View file

@ -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 );
}

View file

@ -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&#xe4;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&#xf6;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&#xdf;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&#xfc;&#xdf;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&#xdf;t Suchposition ein"/>
</node>
<node CREATED="1535893989214" ID="ID_875812160" MODIFIED="1535894010499">