Адаптеры итераторов (Iterator adaptors)

Адаптеры итераторов (Iterator adaptors)

Обратные итераторы (Reverse iterators)

Двунаправленные итераторы и итераторы произвольного доступа имеют соответствующие адаптеры обратных итераторов, которые выполняют итерации через структуру данных в противоположном направлении.Они имеют те же самые сигнатуры, как и соответствующие итераторы. Фундаментальное соотношение между обратным итератором и его соответствующим итератором i установлено тождеством &*(reverse_iterator(i))==&*(i - 1). Это отображение продиктовано тем, что, в то время как после конца массива всегда есть указатель, может не быть допустимого указателя перед началом массива.

template ‹class BidirectionalIterator, class T, class Reference = T&, class Distance = ptrdiff_t›

class reverse_bidirectionaiIterator : public bidirectional_iterator‹T, Distance› {

 typedef reverse_bidirectional_iterator‹BidirectionalIterator, T, Reference, Distance› self;

 friend bool operator==(const self& х, const self& y);

protected:

 BidirectionalIterator current;

public:

 reverse_bidirectional_iterator() {}

 reverse_bidirectional_iterator(BidirectionalIterator х) : current(х) {}

 BidirectionalIterator base() {return current;}

 Reference operator*() const {

  BidirectionalIterator tmp = current;

  return *--tmp;

 }

 self& operator++() {

  --current;

  return *this;

 }

 self operator++(int) {

  self tmp = *this;

  --current;

  return tmp;

 }

 self& operator--() {

  ++current;

  return *this;

 }

 self operator--(int) {

  self tmp = *this;

  ++current;

  return tmp;

 }

};

template ‹class BidirectionalIterator, class T, class Reference, class Distance›

inline bool operator==(const reverse_bidirectional_iterator‹BidirectionalIterator, T, Reference, Distance›& x, const reverse_bidirectional_iterator‹BidirectionalIterator,

T, Reference, Distance›& y) {

 return x.current==y.current;

}

template ‹class RandomAccessIterator, class T, class Reference = T&, class Distance = ptrdiff_t›

class reverse_iterator: public random_access_iterator‹T, Distance› {

 typedef reverse_iterator‹RandomAccessIterator, T, Reference, Distance› self;

 friend bool operator==(const self& x, const self& y);

 friend bool operator‹(const self& x, const self& y);

 friend Distance operator-(const self& x, const self& y);

 friend self operator+(Distance n, const self& x);

protected:

 RandomAccessIterator current;

public:

 reverse_iterator() {}

 reverse_iterator(RandomAccessIterator x): current (x) {}

 RandomAccessIterator base() {return current;}

 Reference operator*() const {

  RandomAccessIterator tmp = current;

  return *--tmp;

 }

 self& operator++() {

  --current;

  return *this;

 }

 self operator++(int) {

  self tmp = *this;

  --current;

  return tmp;

 }

 self& operator--() {

  ++current;

  return *this;

 }

 self operator--(int) {

  self tmp = *this;

  ++current;

  return tmp;

 }

 self operator+(Distance n) const {

  return self(current - n);

 }

 self& operator+=(Distance n) {

  current -= n;

  return *this;

 }

 self operator-(Distance n) const {

  return self(current + n);

 }

 self operator-=(Distance n) {

  current += n;

  return *this;

 }

 Reference operator[](Distance n) {return *(*this + n);}

};

template ‹class RandomAccessIterator, class T, class Reference, class Distance›

inline bool operator==(const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& x, const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& y) {

 return x.current == y.current;

}

template ‹class RandomAccessIterator, class T, class Reference, class Distance›

inline bool operator‹(const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& x, const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& y) {

 return y.current ‹ x.current;

}

template ‹class RandomAccessIterator, class T, class Reference, class Distance›

inline Distance operator-(const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& х, const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& y) {

 return y.current - x.current;

}

template ‹class RandomAccessIterator, class T, class Reference, class Distance›

inline reverse_iterator‹RandomAccessIterator, T, Reference, Distance› operator+(Distance n, const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& x) {

 return reverse_iterator‹RandomAccessIterator, T, Reference, Distance›(x.current - n);

}