implement another wrapper to filter duplicates
This commit is contained in:
parent
a87889cbad
commit
c5e4725dcb
2 changed files with 102 additions and 5 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Reference in a new issue