1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| // tag
struct input_iterator_tag { };
struct output_iterator_tag { };
struct forward_iterator_tag : public input_iterator_tag { };
struct bidirectional_iterator_tag : public forward_iterator_tag { };
struct random_access_iterator_tag : public bidirectional_iterator_tag { };
// iterators
template <class Diff, class T, class Ptr, class Ref, class Cat>
struct iterator {
typedef Diff difference_type;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef Cat iterator_category;
iterator(pointer p = nullptr): m_ptr(p) { }
template <class U, class UCat>
iterator(const iterator<Diff, U, U*, U&, UCat>& it): iterator(it.ptr()) { }
value_type operator*() const { return *ptr() };
value_type operator->() const { return *ptr() };
template <class U, class UCat>
bool operator==(iterator<Diff, U, U*, U&, UCat> it) { return ptr() == it->ptr(); }
template <class U, class UCat>
bool operator!=(iterator<Diff, U, U*, U&, UCat> it) { return !it == *this; }
protected:
virtual ~iterator() { }
pointer& ptr() { return m_ptr; };
pointer ptr() const { return m_ptr; };
private:
pointer m_ptr;
};
template <class Diff, class T, class Ptr, class Ref, class Cat, class Iter>
struct input_iterator: public iterator<Diff, T, Ptr, Ref, Cat> {
input_iterator(pointer p = nullptr): iterator(p) { }
template <class U, class UCat, class Iter2> // TODO virer UCat ?
input_iterator(const input_iterator<Diff, U, U*, U&, UCat, Iter2>& it): input_iterator(it.ptr()) { }
Iter& operator++() { inc(); return *ptr(); };
void operator++(int) { inc(); };
protected:
virtual ~input_iterator() { }
virtual void inc() = 0;
};
// TODO output_iterator
template <class Diff, class T, class Ptr, class Ref, class Cat, class Iter>
struct forward_iterator: public input_iterator<Diff, T, Ptr, Ref, Cat, Iter> {
forward_iterator(pointer p = nullptr): input_iterator(p) { }
template <class U, class UCat, class Iter2> // TODO virer UCat ?
forward_iterator(const forward_iterator<Diff, U, U*, U&, UCat, Iter2>& it): forward_iterator(it.ptr()) { }
Iter operator++(int) { Iter it(*this); inc(); return it; };
protected:
virtual ~forward_iterator() { }
};
template <class Diff, class T, class Ptr, class Ref, class Cat, class Iter>
struct bidirectional_iterator: public forward_iterator<Diff, T, Ptr, Ref, Cat, Iter> {
bidirectional_iterator(pointer p = nullptr): forward_iterator(p) { }
template <class U, class UCat, class Iter2> // TODO virer UCat ?
bidirectional_iterator(const bidirectional_iterator<Diff, U, U*, U&, UCat, Iter2>& it):
bidirectional_iterator(it.ptr()) { }
Iter& operator--() { dec(); return *ptr(); };
Iter operator--(int) { Iter it(*this); dec(); return it; };
protected:
virtual ~bidirectional_iterator() { }
virtual void dec() = 0;
};
template <class Diff, class T, class Ptr, class Ref, class Cat, class Iter>
struct random_access_iterator: public bidirectional_iterator<Diff, T, Ptr, Ref, Cat, Iter> {
random_access_iterator(pointer p = nullptr): bidirectional_iterator(p) { }
template <class U, class UCat, class Iter2> // TODO virer UCat ?
random_access_iterator(const random_access_iterator<Diff, U, U*, U&, UCat, Iter2>& it):
random_access_iterator(it.ptr()) { }
Iter& operator+=(difference_type n) { add(n); return *this; }
Iter& operator-=(difference_type n) { sub(n); return *this; }
Iter operator+(difference_type n) const { Iter it(*this); it.add(n); return it; }
friend Iter operator+(difference_type n, Iter it) { return it + n; }
Iter operator-(difference_type n) const { Iter it(*this); it.sub(n); return it; }
friend Iter operator-(difference_type n, Iter it) { return it - n; }
difference_type operator+(Iter it) const { return static_cast<difference_type>(ptr() + it.ptr()); } // TODO extract method
difference_type operator-(Iter it) const { return static_cast<difference_type>(ptr() - it.ptr()); }
reference operator[](difference_type n) const { return *((*this) + n); }
protected:
virtual ~random_access_iterator() { }
virtual void add(difference_type) = 0;
virtual void sub(difference_type) = 0;
}; |
Partager