diff --git a/src/lib/itertools.hpp b/src/lib/itertools.hpp index 09f92d8c3..80092d61b 100644 --- a/src/lib/itertools.hpp +++ b/src/lib/itertools.hpp @@ -354,6 +354,37 @@ namespace lib { } + /** + * Helper: predicate returning \c true + * whenever the argument value changes + * during a sequence of invocations. + */ + template + class SkipRepetition + { + typedef wrapper::ItemWrapper Item; + + Item prev_; + + public: + bool + operator() (VAL const& elm) + { + if (prev_ && + (*prev_ == elm)) + return false; + + // element differs from predecessor + prev_ = elm; + return true; + } + + typedef bool result_type; + }; + + + + @@ -509,6 +540,18 @@ namespace lib { } + /** filters away repeated values + * emitted by source iterator */ + template + FilterIter + filterRepetitions (IT const& source) + { + typedef typename IT::value_type Val; + return filterIterator(source, SkipRepetition() ); + } + + + } // namespace lib diff --git a/src/lib/wrapper.hpp b/src/lib/wrapper.hpp index 8b36f9b1e..918c9834a 100644 --- a/src/lib/wrapper.hpp +++ b/src/lib/wrapper.hpp @@ -173,6 +173,7 @@ namespace wrapper { /* == copy and assignment == */ ItemWrapper (ItemWrapper const& ref) + : created_(false) { if (ref.isValid()) build (*ref); diff --git a/tests/lib/itertools-test.cpp b/tests/lib/itertools-test.cpp index 850c8a03e..22aea64e1 100644 --- a/tests/lib/itertools-test.cpp +++ b/tests/lib/itertools-test.cpp @@ -30,6 +30,7 @@ #include #include +#include #include @@ -44,6 +45,7 @@ namespace test{ using std::vector; using std::cout; using std::endl; + using std::rand; @@ -105,6 +107,7 @@ namespace test{ Iter ii (source.begin()); ++++++ii; buildFilterIterator (ii); + verify_filterRepetitions(); buildTransformingIterator (source.begin()); } @@ -147,6 +150,40 @@ namespace test{ } + /** @test verify the helper to filter duplicate elements + * emitted by an source iterator. This test creates + * a sequence of numbers with random repetitions. + */ + void + verify_filterRepetitions () + { + vector numberz; + for (uint i=0; i::iterator SrcIter; + typedef RangeIter SeqIter; + typedef FilterIter FilteredSeq; + + SeqIter completeSequence (numberz.begin(), numberz.end()); + FilteredSeq filtered = filterRepetitions (completeSequence); + + uint num=0; + for (; num