TreeExplorer: refactor Filter in a similar way
This commit is contained in:
parent
1e657acbff
commit
36d79be8b2
3 changed files with 77 additions and 64 deletions
|
|
@ -562,6 +562,24 @@ namespace lib {
|
|||
};
|
||||
|
||||
|
||||
template<typename FUN, typename SRC>
|
||||
inline void
|
||||
static_assert_isPredicate()
|
||||
{
|
||||
using Res = typename _FunTraits<FUN,SRC>::Res;
|
||||
static_assert(std::is_constructible<bool, Res>::value, "Functor must be a predicate");
|
||||
}
|
||||
|
||||
template<typename FUN, typename SRC>
|
||||
inline void
|
||||
static_assert_isSourceResultCompatible()
|
||||
{
|
||||
using ResIter = typename _DecoratorTraits<typename _FunTraits<FUN,SRC>::Res>::SrcIter;
|
||||
static_assert (std::is_convertible<typename ResIter::value_type, typename SRC::value_type>::value,
|
||||
"the iterator from the expansion must yield compatible values");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @internal Base of pipe processing decorator chain.
|
||||
|
|
@ -879,17 +897,14 @@ namespace lib {
|
|||
* The filter predicate and thus the source iterator is evaluated _eagerly_, to establish the
|
||||
* *invariant* of this class: _if a "current element" exists, it has already been approved._
|
||||
*/
|
||||
template<class SRC, class FUN>
|
||||
template<class SRC>
|
||||
class Filter
|
||||
: public SRC
|
||||
{
|
||||
static_assert(can_IterForEach<SRC>::value, "Lumiera Iterator required as source");
|
||||
using _Traits = _FunTraits<FUN,SRC>;
|
||||
using Res = typename _Traits::Res;
|
||||
static_assert(std::is_constructible<bool, Res>::value, "Functor must be a predicate");
|
||||
|
||||
protected:
|
||||
using FilterPredicate = typename _Traits::Functor;
|
||||
using FilterPredicate = function<bool(SRC&)>;
|
||||
|
||||
FilterPredicate predicate_;
|
||||
|
||||
|
|
@ -898,9 +913,10 @@ namespace lib {
|
|||
Filter() =default;
|
||||
// inherited default copy operations
|
||||
|
||||
template<typename FUN>
|
||||
Filter (SRC&& dataSrc, FUN&& filterFun)
|
||||
: SRC{move (dataSrc)}
|
||||
, predicate_{forward<FUN> (filterFun)}
|
||||
, predicate_{_FunTraits<FUN,SRC>::template adaptFunctor<SRC> (forward<FUN> (filterFun))}
|
||||
{
|
||||
pullFilter(); // initially pull to establish the invariant
|
||||
}
|
||||
|
|
@ -947,7 +963,7 @@ namespace lib {
|
|||
bool
|
||||
isDisabled() const
|
||||
{
|
||||
return not predicate_.boundFunction;
|
||||
return not bool{predicate_};
|
||||
}
|
||||
|
||||
/** @note establishes the invariant:
|
||||
|
|
@ -979,34 +995,22 @@ namespace lib {
|
|||
* @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 _FunTraits 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.
|
||||
* be mixed and combined.
|
||||
*/
|
||||
template<class SRC, class FUN>
|
||||
template<class SRC>
|
||||
class MutableFilter
|
||||
: public Filter<SRC, typename _FunTraits<FUN,SRC>::Functor>
|
||||
: public Filter<SRC>
|
||||
{
|
||||
using _Traits = _FunTraits<FUN,SRC>;
|
||||
using FilterPredicate = typename _Traits::Functor;
|
||||
using _Base = Filter<SRC,FilterPredicate>;
|
||||
|
||||
using _Filter = Filter<SRC>;
|
||||
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:
|
||||
MutableFilter() =default;
|
||||
// inherited default copy operations
|
||||
|
||||
template<typename FUN>
|
||||
MutableFilter (SRC&& dataSrc, FUN&& filterFun)
|
||||
: _Base{move (dataSrc), FilterPredicate{forward<FUN> (filterFun)}}
|
||||
: _Filter{move (dataSrc), forward<FUN> (filterFun)}
|
||||
{ }
|
||||
|
||||
|
||||
|
|
@ -1110,7 +1114,7 @@ namespace lib {
|
|||
void
|
||||
disableFilter()
|
||||
{
|
||||
_Base::predicate_.boundFunction = nullptr;
|
||||
_Filter::predicate_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1134,21 +1138,18 @@ namespace lib {
|
|||
void
|
||||
remouldFilter (COND&& additionalClause, COMB buildCombinedClause)
|
||||
{
|
||||
using _ChainTraits = _FunTraits<COND,SRC>;
|
||||
using Res = typename _ChainTraits::Res;
|
||||
static_assert(std::is_constructible<bool, Res>::value, "Chained Functor must be a predicate");
|
||||
static_assert_isPredicate<COND,SRC>();
|
||||
|
||||
using WrappedPredicate = typename _Base::FilterPredicate;
|
||||
using ChainPredicate = typename _ChainTraits::Functor;
|
||||
using WrappedPredicate = typename _Filter::FilterPredicate;
|
||||
|
||||
WrappedPredicate& firstClause = _Base::predicate_; // pick up the existing filter predicate
|
||||
ChainPredicate chainClause{forward<COND> (additionalClause)}; // wrap the extension predicate in a similar way
|
||||
|
||||
if (_Base::isDisabled())
|
||||
firstClause.boundFunction = ACCEPT_ALL;
|
||||
WrappedPredicate& firstClause = _Filter::predicate_; // pick up the existing filter predicate
|
||||
WrappedPredicate chainClause{_FunTraits<COND,SRC>::template adaptFunctor<SRC> (forward<COND> (additionalClause))};
|
||||
// wrap the extension predicate in a similar way
|
||||
if (_Filter::isDisabled())
|
||||
_Filter::predicate_ = ACCEPT_ALL;
|
||||
|
||||
_Base::predicate_ = WrappedPredicate{buildCombinedClause (firstClause, chainClause)};
|
||||
_Base::pullFilter(); // pull to re-establish the Invariant
|
||||
_Filter::predicate_ = buildCombinedClause (firstClause, chainClause);
|
||||
_Filter::pullFilter(); // pull to re-establish the Invariant
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1455,7 +1456,9 @@ namespace lib {
|
|||
auto
|
||||
filter (FUN&& filterPredicate)
|
||||
{
|
||||
using ResCore = iter_explorer::Filter<SRC, FUN>;
|
||||
iter_explorer::static_assert_isPredicate<FUN,SRC>();
|
||||
|
||||
using ResCore = iter_explorer::Filter<SRC>;
|
||||
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
|
||||
|
||||
return TreeExplorer<ResIter> (ResCore {move(*this), forward<FUN>(filterPredicate)});
|
||||
|
|
@ -1483,7 +1486,9 @@ namespace lib {
|
|||
auto
|
||||
mutableFilter (FUN&& filterPredicate)
|
||||
{
|
||||
using ResCore = iter_explorer::MutableFilter<SRC, FUN>;
|
||||
iter_explorer::static_assert_isPredicate<FUN,SRC>();
|
||||
|
||||
using ResCore = iter_explorer::MutableFilter<SRC>;
|
||||
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
|
||||
|
||||
return TreeExplorer<ResIter> (ResCore {move(*this), forward<FUN>(filterPredicate)});
|
||||
|
|
|
|||
|
|
@ -912,26 +912,26 @@ namespace test{
|
|||
|
||||
|
||||
// verify enabling and disabling...
|
||||
auto seq2 = treeExplore(CountDown{10})
|
||||
.mutableFilter(takeTrd);
|
||||
seq = treeExplore(CountDown{10})
|
||||
.mutableFilter(takeTrd);
|
||||
|
||||
CHECK (9 == *seq2);
|
||||
seq2.disableFilter();
|
||||
CHECK (9 == *seq2);
|
||||
++seq2;
|
||||
CHECK (8 == *seq2);
|
||||
seq2.andNotFilter (takeEve);
|
||||
CHECK (7 == *seq2);
|
||||
++seq2;
|
||||
CHECK (5 == *seq2);
|
||||
seq2.disableFilter();
|
||||
CHECK (5 == *seq2);
|
||||
++seq2;
|
||||
CHECK (4 == *seq2);
|
||||
++seq2;
|
||||
CHECK (3 == *seq2);
|
||||
seq2.flipFilter(); // everything rejected
|
||||
CHECK (isnil (seq2));
|
||||
CHECK (9 == *seq);
|
||||
seq.disableFilter();
|
||||
CHECK (9 == *seq);
|
||||
++seq;
|
||||
CHECK (8 == *seq);
|
||||
seq.andNotFilter (takeEve);
|
||||
CHECK (7 == *seq);
|
||||
++seq;
|
||||
CHECK (5 == *seq);
|
||||
seq.disableFilter();
|
||||
CHECK (5 == *seq);
|
||||
++seq;
|
||||
CHECK (4 == *seq);
|
||||
++seq;
|
||||
CHECK (3 == *seq);
|
||||
seq.flipFilter(); // everything rejected
|
||||
CHECK (isnil (seq));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31126,6 +31126,10 @@
|
|||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1536499475717" ID="ID_1987289240" MODIFIED="1536499534632" TEXT="Nach Refactoring TreeExplorer nun möglich">
|
||||
<arrowlink COLOR="#5cb3a1" DESTINATION="ID_1315131204" ENDARROW="Default" ENDINCLINATION="691;0;" ID="Arrow_ID_86390894" STARTARROW="None" STARTINCLINATION="167;37;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -31239,7 +31243,8 @@
|
|||
<node CREATED="1536420678842" ID="ID_1524886712" MODIFIED="1536420681830" TEXT="Ergebnis-Typ"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1536420803778" ID="ID_1315131204" MODIFIED="1536420809629" TEXT="Funktions-Signatur verbergen">
|
||||
<node CREATED="1536420803778" ID="ID_1315131204" MODIFIED="1536499525208" TEXT="Funktions-Signatur verbergen">
|
||||
<linktarget COLOR="#5cb3a1" DESTINATION="ID_1315131204" ENDARROW="Default" ENDINCLINATION="691;0;" ID="Arrow_ID_86390894" SOURCE="ID_1987289240" STARTARROW="None" STARTINCLINATION="167;37;"/>
|
||||
<node CREATED="1536420811265" ID="ID_1167994865" MODIFIED="1536420823683" TEXT="reduzieren auf res(SRC)"/>
|
||||
<node CREATED="1536420824983" ID="ID_784540518" MODIFIED="1536420836185" TEXT="konkrete Funktion in Adapter setzen"/>
|
||||
<node CREATED="1536420932944" ID="ID_512498364" MODIFIED="1536420940219" TEXT="ArgAccessor beim Aufruf">
|
||||
|
|
@ -31266,6 +31271,9 @@
|
|||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1536499557658" ID="ID_1939855291" MODIFIED="1536499572569" TEXT="dafür verschwindet konkreter Funktor-Typ vom Template">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -31370,11 +31378,11 @@
|
|||
</node>
|
||||
<node CREATED="1536455947209" ID="ID_1054869208" MODIFIED="1536455959131" TEXT="innerer Funktor ist aber direkt dort eingebettet"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1536453368676" ID="ID_1560078731" MODIFIED="1536453372397" TEXT="Filter">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1536453368676" ID="ID_1560078731" MODIFIED="1536499292336" TEXT="Filter">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1536453373605" ID="ID_1544724438" MODIFIED="1536453376828" TEXT="MutableFilter">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1536453373605" ID="ID_1544724438" MODIFIED="1536499295024" TEXT="MutableFilter">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1536453408359" ID="ID_63715215" MODIFIED="1536453414663" TEXT="Anpassen an Expander">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue