From 6659a7dee11599a25e1125df72b7ec7aa3f7c747 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 5 Dec 2015 02:00:44 +0100 Subject: [PATCH] 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 --- src/lib/itertools.hpp | 72 ++++++++++++++++++++++++++++++++ tests/12metaprogramming.tests | 21 ++++++---- tests/library/itertools-test.cpp | 36 +++++++++++++++- 3 files changed, 118 insertions(+), 11 deletions(-) diff --git a/src/lib/itertools.hpp b/src/lib/itertools.hpp index 47b91f797..fa925977f 100644 --- a/src/lib/itertools.hpp +++ b/src/lib/itertools.hpp @@ -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 ExtensibleFilterIter @@ -396,6 +410,64 @@ namespace lib { reEvaluate(); return *this; } + + template + ExtensibleFilterIter& + andNotFilter (COND conjunctiveClause) + { + function& filter = this->core_.predicate_; + + filter = [=](Val val) + { + return filter(val) + and not conjunctiveClause(val); + }; + reEvaluate(); + return *this; + } + + template + ExtensibleFilterIter& + orFilter (COND disjunctiveClause) + { + function& filter = this->core_.predicate_; + + filter = [=](Val val) + { + return filter(val) + or disjunctiveClause(val); + }; + reEvaluate(); + return *this; + } + + template + ExtensibleFilterIter& + orNotFilter (COND disjunctiveClause) + { + function& filter = this->core_.predicate_; + + filter = [=](Val val) + { + return filter(val) + or not disjunctiveClause(val); + }; + reEvaluate(); + return *this; + } + + ExtensibleFilterIter& + flipFilter () + { + function& filter = this->core_.predicate_; + + filter = [=](Val val) + { + return not filter(val); + }; + reEvaluate(); + return *this; + } }; diff --git a/tests/12metaprogramming.tests b/tests/12metaprogramming.tests index 39bce4b62..ca708eb61 100644 --- a/tests/12metaprogramming.tests +++ b/tests/12metaprogramming.tests @@ -206,15 +206,18 @@ END TEST "Lumiera Iterator Tools" IterTools_test 20 <