implement another wrapper to filter duplicates

This commit is contained in:
Fischlurch 2010-04-02 01:46:48 +02:00
parent a87889cbad
commit c5e4725dcb
2 changed files with 102 additions and 5 deletions

View file

@ -82,6 +82,44 @@ namespace iter_stl {
};
template<typename IT>
class DistinctIter
: public lib::BoolCheckable<DistinctIter<IT> >
{
public:
typedef typename IT::value_type value_type;
typedef typename IT::reference reference;
typedef typename IT::pointer pointer;
private:
IT i_;
pointer prev_;
void memorise() { if (i_) prev_ = &(*i_); }
public:
DistinctIter() : i_(), prev_() { }
DistinctIter(IT const& i) : i_(i),prev_() { memorise(); }
pointer operator->() const { return i_; }
reference operator*() const { return *i_; }
bool isValid() const { return i_; }
DistinctIter&
operator++()
{
do ++i_;
while (i_ && prev_ && *prev_ == *i_ );
memorise();
return *this;
}
friend bool operator== (DistinctIter const& i1, DistinctIter const& i2) { return i1.i_ == i2.i_; }
friend bool operator!= (DistinctIter const& i1, DistinctIter const& i2) { return i1.i_ != i2.i_; }
};
namespace { // traits and helpers...
template<class MAP>
@ -117,8 +155,8 @@ namespace iter_stl {
typedef KeyType& reference;
typedef KeyType* pointer;
PickKeyIter () : WrapI() {}
PickKeyIter (EntryIter iter) : WrapI(iter) {}
PickKeyIter () : WrapI() {}
PickKeyIter (EntryIter const& iter) : WrapI(iter) {}
pointer operator->() const { return &(WrapI::get()->first); }
reference operator* () const { return (WrapI::get()->first); }
@ -130,8 +168,8 @@ namespace iter_stl {
typedef ValType& reference;
typedef ValType* pointer;
PickValIter () : WrapI() {}
PickValIter (EntryIter iter) : WrapI(iter) {}
PickValIter () : WrapI() {}
PickValIter (EntryIter const& iter) : WrapI(iter) {}
pointer operator->() const { return &(WrapI::get()->second); }
reference operator* () const { return (WrapI::get()->second); }
@ -140,6 +178,24 @@ namespace iter_stl {
typedef RangeIter<PickKeyIter> KeyIter;
typedef RangeIter<PickValIter> ValIter;
};
template<class SEQ>
struct _SeqT
{
typedef typename SEQ::iterator Iter;
typedef RangeIter<Iter> Range;
typedef DistinctIter<Range> DistinctVals;
};
template<class SEQ>
struct _SeqT<const SEQ>
{
typedef typename SEQ::const_iterator Iter;
typedef RangeIter<Iter> Range;
typedef DistinctIter<Range> DistinctVals;
};
}
@ -173,6 +229,20 @@ namespace iter_stl {
}
/** build a Lumiera Forward Iterator to suppress
* any repetitions in the given sequence.
*/
template<class SEQ>
inline typename _SeqT<SEQ>::DistinctVals
eachDistinct (SEQ& seq)
{
typedef typename _SeqT<SEQ>::Range Range;
typedef typename _SeqT<SEQ>::DistinctVals DistinctValues;
return DistinctValues (Range (seq.begin(), seq.end()));
}
/**
*/
template<class MAP>

View file

@ -93,6 +93,7 @@ namespace test{
{
if (0 < arg.size()) NUM_ELMS = lexical_cast<uint> (arg[0]);
checkDistinctValIter();
iterateMapKeyVal (getTestMap_int<MapII> (NUM_ELMS));
}
@ -107,8 +108,34 @@ namespace test{
TEST_ITER (iter::eachVal, (map));
TEST_ITER (iter::eachDistinctKey, (map));
}
void
checkDistinctValIter()
{
PRINT_FUNC (filter-distinct-values, VecI);
VecI vec;
TEST_ITER(iter::eachDistinct, (vec));
vec.push_back (1);
vec.push_back (1);
vec.push_back (1);
TEST_ITER(iter::eachDistinct, (vec));
vec.push_back (2);
vec.push_back (3);
vec.push_back (3);
vec.push_back (1);
TEST_ITER(iter::eachDistinct, (vec));
vec.push_back (1);
vec.push_back (1);
vec.push_back (1);
vec.push_back (1);
vec.push_back (1);
TEST_ITER(iter::eachDistinct, (vec));
}
};
LAUNCHER (IterAdapterSTL_test, "unit common");