augment extensible filter to add the obvious variations
that is - allow also for a disjunctive extension - allow for negated conditions - allow to flip the current condition unit test PASS
This commit is contained in:
parent
0e41555402
commit
6659a7dee1
3 changed files with 118 additions and 11 deletions
|
|
@ -358,6 +358,20 @@ namespace lib {
|
|||
* modified, current head of iteration gets re-evaluated
|
||||
* and possible fast-forwarded to the next element
|
||||
* satisfying the now extended filter condition.
|
||||
* @note changing the condition modifies a given iterator in place.
|
||||
* Superficially this might look as if the storage remains
|
||||
* the same, but in fact we're adding a lambda closure,
|
||||
* which the runtime usually allocates on the heap,
|
||||
* holding the previous functor and a second functor
|
||||
* for the added clause.
|
||||
* @warning the addition of disjunctive and negated clauses might
|
||||
* actually weaken the filter condition. Yet still there is
|
||||
* \em no reset of the source iterator, i.e. we don't
|
||||
* re-evaluate from start, but just from current head.
|
||||
* Which means we might miss elements in the already consumed
|
||||
* part of the source sequence, which theoretically would
|
||||
* pass the now altered filter condition.
|
||||
* @see IterTools_test::verify_filterExtension
|
||||
*/
|
||||
template<class IT>
|
||||
class ExtensibleFilterIter
|
||||
|
|
@ -396,6 +410,64 @@ namespace lib {
|
|||
reEvaluate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename COND>
|
||||
ExtensibleFilterIter&
|
||||
andNotFilter (COND conjunctiveClause)
|
||||
{
|
||||
function<bool(Val)>& filter = this->core_.predicate_;
|
||||
|
||||
filter = [=](Val val)
|
||||
{
|
||||
return filter(val)
|
||||
and not conjunctiveClause(val);
|
||||
};
|
||||
reEvaluate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename COND>
|
||||
ExtensibleFilterIter&
|
||||
orFilter (COND disjunctiveClause)
|
||||
{
|
||||
function<bool(Val)>& filter = this->core_.predicate_;
|
||||
|
||||
filter = [=](Val val)
|
||||
{
|
||||
return filter(val)
|
||||
or disjunctiveClause(val);
|
||||
};
|
||||
reEvaluate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename COND>
|
||||
ExtensibleFilterIter&
|
||||
orNotFilter (COND disjunctiveClause)
|
||||
{
|
||||
function<bool(Val)>& filter = this->core_.predicate_;
|
||||
|
||||
filter = [=](Val val)
|
||||
{
|
||||
return filter(val)
|
||||
or not disjunctiveClause(val);
|
||||
};
|
||||
reEvaluate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExtensibleFilterIter&
|
||||
flipFilter ()
|
||||
{
|
||||
function<bool(Val)>& filter = this->core_.predicate_;
|
||||
|
||||
filter = [=](Val val)
|
||||
{
|
||||
return not filter(val);
|
||||
};
|
||||
reEvaluate();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -206,15 +206,18 @@ END
|
|||
|
||||
|
||||
TEST "Lumiera Iterator Tools" IterTools_test 20 <<END
|
||||
out: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
|
||||
out: ::20::18::16::14::12::10::8::6::4::2
|
||||
out: ::19::17::15::13::11::9::7::5::3::1
|
||||
out: ::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
|
||||
out: ::16::14::12::10::8::6::4::2
|
||||
out: ::17::15::13::11::9::7::5::3::1
|
||||
out: ::10::9::8::7::6::5::4::3::2::1
|
||||
out: ::-10::-9::-8::-7::-6::-5::-4::-3::-2::-1
|
||||
out: ::12::11::10::9::8::7::6::5::4::3
|
||||
out-lit: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
|
||||
out-lit: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
|
||||
out-lit: ::20::18::16::14::12::10::8::6::4::2
|
||||
out-lit: ::19::17::15::13::11::9::7::5::3::1
|
||||
out-lit: ::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
|
||||
out-lit: ::16::14::12::10::8::6::4::2
|
||||
out-lit: ::17::15::13::11::9::7::5::3::1
|
||||
out-lit: ::12::18::24::30::36::42::48::54
|
||||
out-lit: ::13::17::19::23::25::29::31::35::37::41::43::47::49::53::55::59
|
||||
out-lit: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
|
||||
out-lit: ::-20::-19::-18::-17::-16::-15::-14::-13::-12::-11::-10::-9::-8::-7::-6::-5::-4::-3::-2::-1
|
||||
out-lit: ::22::21::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3
|
||||
END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,12 @@ namespace test{
|
|||
* while in the middle of an ongoing iteration.
|
||||
* Typically this means sharpening the filter condition
|
||||
* and thus making the filter more restrictive, filtering
|
||||
* away more elements of the source stream.
|
||||
* away more elements of the source stream. But through
|
||||
* the ability to add disjunctive and negated clauses,
|
||||
* it is also possible to weaken the filter condition
|
||||
* @note in case of a weakened filter condition, there is
|
||||
* \em no reset of the source iterator, i.e. we don't
|
||||
* re-evaluate from start, but just from current head.
|
||||
*/
|
||||
void
|
||||
verify_filterExtension ()
|
||||
|
|
@ -189,14 +194,41 @@ namespace test{
|
|||
++filterIter;
|
||||
CHECK (4 == *filterIter);
|
||||
|
||||
// sharpen the condition...
|
||||
filterIter.andFilter(takeTrd);
|
||||
CHECK (!isnil (filterIter));
|
||||
CHECK (6 == *filterIter);
|
||||
CHECK (6 == *filterIter); // divisible by two and by three
|
||||
++filterIter;
|
||||
CHECK (12 == *filterIter);
|
||||
|
||||
verifyComparisons (filterIter);
|
||||
pullOut (filterIter);
|
||||
|
||||
// adding a disjunctive clause actually weakens the filter...
|
||||
filterIter = {completeSequence, takeTrd};
|
||||
CHECK (!isnil (filterIter));
|
||||
CHECK (0 == *filterIter);
|
||||
++filterIter;
|
||||
CHECK (3 == *filterIter);
|
||||
|
||||
filterIter.orFilter(takeEve);
|
||||
CHECK (3 == *filterIter);
|
||||
++filterIter;
|
||||
CHECK (4 == *filterIter);
|
||||
++filterIter;
|
||||
CHECK (6 == *filterIter);
|
||||
verifyComparisons (filterIter);
|
||||
|
||||
// flip filter logic
|
||||
filterIter.flipFilter();
|
||||
CHECK (7 == *filterIter); // not even and not divisible by three
|
||||
++filterIter;
|
||||
CHECK (11 == *filterIter);
|
||||
++filterIter;
|
||||
CHECK (13 == *filterIter);
|
||||
|
||||
verifyComparisons (filterIter);
|
||||
pullOut (filterIter);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue