implement an duplicate-value filtering iterator
This commit is contained in:
parent
0081b36793
commit
ff2113e61f
3 changed files with 81 additions and 0 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ namespace wrapper {
|
|||
/* == copy and assignment == */
|
||||
|
||||
ItemWrapper (ItemWrapper const& ref)
|
||||
: created_(false)
|
||||
{
|
||||
if (ref.isValid())
|
||||
build (*ref);
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue