This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Iterators wrappers?
Chris Jefferson wrote:
Hello,
I am currently working on some test cases for some functions in the
algorithm header. I wondered if there exists any "exact iterator
checkers",
Here's an input iterator I've used to test our algorithms. It lets
you wrap an ordinary pointer (not another iterator) into a sequence
of elements. We don't use container iterators (or any other parts
of the library) when testing algorithms to prevent bugs in those
areas from causing false negatives (or positives) in the tests.
Martin
template <class T>
struct InputIter
{
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef std::ptrdiff_t difference_type;
typedef std::input_iterator_tag iterator_category;
// body shared by all copies of the same InputIter specialization
// to detect algorithms that pass through the same interator more
// than once (disallowed by 24.1.1, p3)
struct Shared {
const value_type *cur_;
const value_type *end_;
int ref_;
Shared (const value_type *cur, const value_type *end)
: cur_ (cur), end_ (end), ref_ (1) { }
~Shared () {
end_ = cur_ = 0;
ref_ = -1;
}
private:
Shared (const Shared&); // not defined
void operator= (const Shared&); // not defined
};
// not default constructible
InputIter (const value_type *cur, const value_type *end)
: ptr_ (new Shared (cur, end)), cur_ (cur) { }
InputIter (const InputIter &rhs)
: ptr_ (rhs.ptr_), cur_ (rhs.cur_) {
++ptr_->ref_;
}
~InputIter () {
if (0 == --ptr_->ref_) // decrement the reference count
delete ptr_;
ptr_ = 0;
cur_ = 0;
}
InputIter& operator= (const InputIter &rhs) {
if (0 == --ptr_->ref_)
delete ptr_;
ptr_ = rhs.ptr_;
++ptr_->ref_;
cur_ = rhs.cur_;
return *this;
}
bool operator== (const InputIter &rhs) const {
return cur_ == rhs.cur_;
}
bool operator!= (const InputIter &rhs) const {
return !(*this == rhs);
}
// returning const-reference rather than a value in order
// not to impose the CopyConstructible requirement on T
// and to disallow constructs like *InputIter<T>() = T()
const value_type& operator* () const {
assert (cur_ && ptr_ && cur_ != ptr_->end_);
return *cur_;
}
const value_type* operator-> () const {
return &**this;
}
InputIter& operator++ () {
assert (ptr_ && ptr_->cur_ && ptr_->cur_ != ptr_->end_);
// verify that another copy of this iterator hasn't
// passed through this value yet
assert (ptr_->cur_ == cur_);
ptr_->cur_ = ++cur_;
return *this;
}
InputIter operator++ (int) {
return ++*this;
}
private:
Shared *ptr_;
const value_type *cur_; // past-the-end
};