implement an duplicate-value filtering iterator

This commit is contained in:
Fischlurch 2010-01-06 06:19:30 +01:00
parent 0081b36793
commit ff2113e61f
3 changed files with 81 additions and 0 deletions

View file

@ -354,6 +354,37 @@ namespace lib {
}
/**
* Helper: predicate returning \c true
* whenever the argument value changes
* during a sequence of invocations.
*/
template<typename VAL>
class SkipRepetition
{
typedef wrapper::ItemWrapper<VAL> 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<class IT>
FilterIter<IT>
filterRepetitions (IT const& source)
{
typedef typename IT::value_type Val;
return filterIterator(source, SkipRepetition<Val>() );
}
} // namespace lib

View file

@ -173,6 +173,7 @@ namespace wrapper {
/* == copy and assignment == */
ItemWrapper (ItemWrapper const& ref)
: created_(false)
{
if (ref.isValid())
build (*ref);

View file

@ -30,6 +30,7 @@
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <cstdlib>
#include <vector>
@ -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<uint> numberz;
for (uint i=0; i<NUM_ELMS; ++i)
{
uint n = 1 + rand() % 100;
do numberz.push_back(i);
while (--n);
}
ASSERT (NUM_ELMS < numberz.size(), "no repetition in test data??");
typedef vector<uint>::iterator SrcIter;
typedef RangeIter<SrcIter> SeqIter;
typedef FilterIter<SeqIter> FilteredSeq;
SeqIter completeSequence (numberz.begin(), numberz.end());
FilteredSeq filtered = filterRepetitions (completeSequence);
uint num=0;
for (; num<NUM_ELMS && !isnil(filtered);
++num,
++filtered
)
ASSERT (num == *filtered);
ASSERT (num == NUM_ELMS && isnil(filtered));
}
static ulong addTwo (int i) { return i+2; }
static int negate (int i) { return -i; }