27 Iterators library [iterators]

27.5 Iterator adaptors [predef.iterators]

27.5.1 Reverse iterators [reverse.iterators]

Шаблон класса reverse_­iterator - это адаптер итератора, который выполняет итерацию от конца последовательности, определенной его базовым итератором, до начала этой последовательности. Фундаментальное соотношение между обратным итератором и его соответствующим итератор i устанавливается идентичностью: &*(reverse_­iterator(i)) == &*(i - 1).

27.5.1.1 Class template reverse_­iterator [reverse.iterator]

namespace std {
  template <class Iterator>
  class reverse_iterator {
  public:
    using iterator_type     = Iterator;
    using iterator_category = typename iterator_traits<Iterator>::iterator_category;
    using value_type        = typename iterator_traits<Iterator>::value_type;
    using difference_type   = typename iterator_traits<Iterator>::difference_type;
    using pointer           = typename iterator_traits<Iterator>::pointer;
    using reference         = typename iterator_traits<Iterator>::reference;

    constexpr reverse_iterator();
    constexpr explicit reverse_iterator(Iterator x);
    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);

    constexpr Iterator base() const;      // explicit
    constexpr reference operator*() const;
    constexpr pointer   operator->() const;

    constexpr reverse_iterator& operator++();
    constexpr reverse_iterator  operator++(int);
    constexpr reverse_iterator& operator--();
    constexpr reverse_iterator  operator--(int);

    constexpr reverse_iterator  operator+ (difference_type n) const;
    constexpr reverse_iterator& operator+=(difference_type n);
    constexpr reverse_iterator  operator- (difference_type n) const;
    constexpr reverse_iterator& operator-=(difference_type n);
    constexpr unspecified operator[](difference_type n) const;
  protected:
    Iterator current;
  };

  template <class Iterator1, class Iterator2>
    constexpr bool operator==(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator!=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr auto operator-(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
  template <class Iterator>
    constexpr reverse_iterator<Iterator> operator+(
      typename reverse_iterator<Iterator>::difference_type n,
      const reverse_iterator<Iterator>& x);

  template <class Iterator>
    constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);
}

27.5.1.2 reverse_­iterator requirements [reverse.iter.requirements]

Параметр шаблона Iterator должен соответствовать всем требованиям a Bidirectional Iterator.

Кроме того, Iterator должен соответствовать требованиям a, random access iterator если какой-либо из членов operator+ ([reverse.iter.op+]), operator- ([reverse.iter.op-]), operator+= ([reverse.iter.op+=]), operator-= ([reverse.iter.op-=]), operator[] ([reverse.iter.opindex]) или операторов, не являющихся членами operator< ([reverse.iter.op<]), operator> ([reverse.iter.op>]),
operator<= ([reverse.iter.op<=]), operator>= ([reverse.iter.op>=]), operator- ([reverse.iter.opdiff]) или operator+ ([reverse.iter.opsum]) ссылаются таким образом, что требуется instantiation ([temp.inst]).

27.5.1.3 reverse_­iterator operations [reverse.iter.ops]

27.5.1.3.1 reverse_­iterator constructor [reverse.iter.cons]

constexpr reverse_iterator();

Effects: Значение инициализирует current. Операции итератора, применяемые к результирующему итератору, имеют определенное поведение тогда и только тогда, когда соответствующие операции определены в итераторе типа, инициализированном значением Iterator.

constexpr explicit reverse_iterator(Iterator x);

Effects: Инициализируется current с помощью x.

template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);

Effects: Инициализируется current с помощью u.current.

27.5.1.3.2 reverse_­iterator​::​operator= [reverse.iter.op=]

template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);

Effects: Присваивает u.base() текущему.

Returns: *this.

27.5.1.3.3 Conversion [reverse.iter.conv]

constexpr Iterator base() const; // explicit

Returns: current.

27.5.1.3.4 operator* [reverse.iter.op.star]

constexpr reference operator*() const;

Effects: Как будто по:

Iterator tmp = current;
return *--tmp;

27.5.1.3.5 operator-> [reverse.iter.opref]

constexpr pointer operator->() const;

Returns: addressof(operator*()).

27.5.1.3.6 operator++ [reverse.iter.op++]

constexpr reverse_iterator& operator++();

Effects: Как будто по: --current;

Returns: *this.

constexpr reverse_iterator operator++(int);

Effects: Как будто по:

reverse_iterator tmp = *this;
--current;
return tmp;

27.5.1.3.7 operator-- [reverse.iter.op--]

constexpr reverse_iterator& operator--();

Effects: Как будто мимо ++current.

Returns: *this.

constexpr reverse_iterator operator--(int);

Effects: Как будто по:

reverse_iterator tmp = *this;
++current;
return tmp;

27.5.1.3.8 operator+ [reverse.iter.op+]

constexpr reverse_iterator operator+(difference_type n) const;

Returns: reverse_­iterator(current-n).

27.5.1.3.9 operator+= [reverse.iter.op+=]

constexpr reverse_iterator& operator+=(difference_type n);

Effects: Как будто по: current -= n;

Returns: *this.

27.5.1.3.10 operator- [reverse.iter.op-]

constexpr reverse_iterator operator-(difference_type n) const;

Returns: reverse_­iterator(current+n).

27.5.1.3.11 operator-= [reverse.iter.op-=]

constexpr reverse_iterator& operator-=(difference_type n);

Effects: Как будто по: current += n;

Returns: *this.

27.5.1.3.12 operator[] [reverse.iter.opindex]

constexpr unspecified operator[](difference_type n) const;

Returns: current[-n-1].

27.5.1.3.13 operator== [reverse.iter.op==]

template <class Iterator1, class Iterator2> constexpr bool operator==( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);

Returns: x.current == y.current.

27.5.1.3.14 operator< [reverse.iter.op<]

template <class Iterator1, class Iterator2> constexpr bool operator<( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);

Returns: x.current > y.current.

27.5.1.3.15 operator!= [reverse.iter.op!=]

template <class Iterator1, class Iterator2> constexpr bool operator!=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);

Returns: x.current != y.current.

27.5.1.3.16 operator> [reverse.iter.op>]

template <class Iterator1, class Iterator2> constexpr bool operator>( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);

Returns: x.current < y.current.

27.5.1.3.17 operator>= [reverse.iter.op>=]

template <class Iterator1, class Iterator2> constexpr bool operator>=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);

Returns: x.current <= y.current.

27.5.1.3.18 operator<= [reverse.iter.op<=]

template <class Iterator1, class Iterator2> constexpr bool operator<=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);

Returns: x.current >= y.current.

27.5.1.3.19 operator- [reverse.iter.opdiff]

template <class Iterator1, class Iterator2> constexpr auto operator-( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());

Returns: y.current - x.current.

27.5.1.3.20 operator+ [reverse.iter.opsum]

template <class Iterator> constexpr reverse_iterator<Iterator> operator+( typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x);

Returns: reverse_­iterator<Iterator> (x.current - n).

27.5.1.3.21 Non-member function make_­reverse_­iterator() [reverse.iter.make]

template <class Iterator> constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);

Returns: reverse_­iterator<Iterator>(i).

27.5.2 Insert iterators [insert.iterators]

Чтобы можно было обрабатывать вставку так же, как запись в массив,insert iteratorsв библиотеке предусмотрен специальный вид адаптеров итератора, называемый . С обычными классами итераторов

while (first != last) *result++ = *first++;

вызывает [first, last) копирование диапазона в диапазон, начинающийся с результата. Тот же код, result который является итератором вставки, вставит соответствующие элементы в контейнер. Это устройство позволяет всем алгоритмам копирования в библиотеке работать в режиме, insert mode а не в regular overwrite режиме.

Итератор вставки создается из контейнера и, возможно, одного из его итераторов, указывающих на место вставки, если он не находится ни в начале, ни в конце контейнера. Итераторы вставки удовлетворяют требованиям итераторов вывода. operator* возвращает сам итератор вставки. Назначение operator=(const T& x) определяется на итераторах вставки, чтобы разрешить запись в них, оно вставляется x прямо перед тем местом, куда указывает итератор вставки. Другими словами, итератор вставки подобен курсору, указывающему на контейнер, в котором происходит вставка. back_­insert_­iterator вставляет элементы в конец контейнера, front_­insert_­iterator вставляет элементы в начало контейнера и insert_­iterator вставляет элементы, на которые указывает итератор в контейнере. back_­inserter, front_­inserterИ inserter три функции , делающие вставки итераторы из контейнера.

27.5.2.1 Class template back_­insert_­iterator [back.insert.iterator]

namespace std {
  template <class Container>
  class back_insert_iterator {
  protected:
    Container* container;

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    explicit back_insert_iterator(Container& x);
    back_insert_iterator& operator=(const typename Container::value_type& value);
    back_insert_iterator& operator=(typename Container::value_type&& value);

    back_insert_iterator& operator*();
    back_insert_iterator& operator++();
    back_insert_iterator  operator++(int);
  };

  template <class Container>
    back_insert_iterator<Container> back_inserter(Container& x);
}

27.5.2.2 back_­insert_­iterator operations [back.insert.iter.ops]

27.5.2.2.1 back_­insert_­iterator constructor [back.insert.iter.cons]

explicit back_insert_iterator(Container& x);

Effects: Инициализируется container с помощью addressof(x).

27.5.2.2.2 back_­insert_­iterator​::​operator= [back.insert.iter.op=]

back_insert_iterator& operator=(const typename Container::value_type& value);

Effects: Как будто по: container->push_­back(value);

Returns: *this.

back_insert_iterator& operator=(typename Container::value_type&& value);

Effects: Как будто по: container->push_­back(std​::​move(value));

Returns: *this.

27.5.2.2.3 back_­insert_­iterator​::​operator* [back.insert.iter.op*]

back_insert_iterator& operator*();

Returns: *this.

27.5.2.2.4 back_­insert_­iterator​::​operator++ [back.insert.iter.op++]

back_insert_iterator& operator++(); back_insert_iterator operator++(int);

Returns: *this.

27.5.2.2.5 back_­inserter [back.inserter]

template <class Container> back_insert_iterator<Container> back_inserter(Container& x);

Returns: back_­insert_­iterator<Container>(x).

27.5.2.3 Class template front_­insert_­iterator [front.insert.iterator]

namespace std {
  template <class Container>
  class front_insert_iterator {
  protected:
    Container* container;

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    explicit front_insert_iterator(Container& x);
    front_insert_iterator& operator=(const typename Container::value_type& value);
    front_insert_iterator& operator=(typename Container::value_type&& value);

    front_insert_iterator& operator*();
    front_insert_iterator& operator++();
    front_insert_iterator  operator++(int);
  };

  template <class Container>
    front_insert_iterator<Container> front_inserter(Container& x);
}

27.5.2.4 front_­insert_­iterator operations [front.insert.iter.ops]

27.5.2.4.1 front_­insert_­iterator constructor [front.insert.iter.cons]

explicit front_insert_iterator(Container& x);

Effects: Инициализируется container с помощью addressof(x).

27.5.2.4.2 front_­insert_­iterator​::​operator= [front.insert.iter.op=]

front_insert_iterator& operator=(const typename Container::value_type& value);

Effects: Как будто по: container->push_­front(value);

Returns: *this.

front_insert_iterator& operator=(typename Container::value_type&& value);

Effects: Как будто по: container->push_­front(std​::​move(value));

Returns: *this.

27.5.2.4.3 front_­insert_­iterator​::​operator* [front.insert.iter.op*]

front_insert_iterator& operator*();

Returns: *this.

27.5.2.4.4 front_­insert_­iterator​::​operator++ [front.insert.iter.op++]

front_insert_iterator& operator++(); front_insert_iterator operator++(int);

Returns: *this.

27.5.2.4.5 front_­inserter [front.inserter]

template <class Container> front_insert_iterator<Container> front_inserter(Container& x);

Returns: front_­insert_­iterator<Container>(x).

27.5.2.5 Class template insert_­iterator [insert.iterator]

namespace std {
  template <class Container>
  class insert_iterator {
  protected:
    Container* container;
    typename Container::iterator iter;

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    insert_iterator(Container& x, typename Container::iterator i);
    insert_iterator& operator=(const typename Container::value_type& value);
    insert_iterator& operator=(typename Container::value_type&& value);

    insert_iterator& operator*();
    insert_iterator& operator++();
    insert_iterator& operator++(int);
  };

  template <class Container>
    insert_iterator<Container> inserter(Container& x, typename Container::iterator i);
}

27.5.2.6 insert_­iterator operations [insert.iter.ops]

27.5.2.6.1 insert_­iterator constructor [insert.iter.cons]

insert_iterator(Container& x, typename Container::iterator i);

Effects: Инициализируется container с помощью addressof(x) и iter с помощью i.

27.5.2.6.2 insert_­iterator​::​operator= [insert.iter.op=]

insert_iterator& operator=(const typename Container::value_type& value);

Effects: Как будто по:

iter = container->insert(iter, value);
++iter;

Returns: *this.

insert_iterator& operator=(typename Container::value_type&& value);

Effects: Как будто по:

iter = container->insert(iter, std::move(value));
++iter;

Returns: *this.

27.5.2.6.3 insert_­iterator​::​operator* [insert.iter.op*]

insert_iterator& operator*();

Returns: *this.

27.5.2.6.4 insert_­iterator​::​operator++ [insert.iter.op++]

insert_iterator& operator++(); insert_iterator& operator++(int);

Returns: *this.

27.5.2.6.5 inserter [inserter]

template <class Container> insert_iterator<Container> inserter(Container& x, typename Container::iterator i);

Returns: insert_­iterator<Container>(x, i).

27.5.3 Move iterators [move.iterators]

Шаблон класса move_­iterator - это адаптер итератора с таким же поведением, что и базовый итератор, за исключением того, что его оператор косвенного обращения неявно преобразует значение, возвращаемое оператором косвенного обращения базового итератора, в rvalue. Некоторые общие алгоритмы можно вызывать с итераторами перемещения, чтобы заменить копирование перемещением.

[Example:

list<string> s;
// populate the list s
vector<string> v1(s.begin(), s.end());          // copies strings into v1
vector<string> v2(make_move_iterator(s.begin()),
                  make_move_iterator(s.end())); // moves strings into v2

end example]

27.5.3.1 Class template move_­iterator [move.iterator]

namespace std {
  template <class Iterator>
  class move_iterator {
  public:
    using iterator_type     = Iterator;
    using iterator_category = typename iterator_traits<Iterator>::iterator_category;
    using value_type        = typename iterator_traits<Iterator>::value_type;
    using difference_type   = typename iterator_traits<Iterator>::difference_type;
    using pointer           = Iterator;
    using reference         = see below;

    constexpr move_iterator();
    constexpr explicit move_iterator(Iterator i);
    template <class U> constexpr move_iterator(const move_iterator<U>& u);
    template <class U> constexpr move_iterator& operator=(const move_iterator<U>& u);

    constexpr iterator_type base() const;
    constexpr reference operator*() const;
    constexpr pointer operator->() const;

    constexpr move_iterator& operator++();
    constexpr move_iterator operator++(int);
    constexpr move_iterator& operator--();
    constexpr move_iterator operator--(int);

    constexpr move_iterator operator+(difference_type n) const;
    constexpr move_iterator& operator+=(difference_type n);
    constexpr move_iterator operator-(difference_type n) const;
    constexpr move_iterator& operator-=(difference_type n);
    constexpr unspecified operator[](difference_type n) const;

  private:
    Iterator current;   // exposition only
  };

  template <class Iterator1, class Iterator2>
    constexpr bool operator==(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator!=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

  template <class Iterator1, class Iterator2>
    constexpr auto operator-(
      const move_iterator<Iterator1>& x,
      const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
  template <class Iterator>
    constexpr move_iterator<Iterator> operator+(
      typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
  template <class Iterator>
    constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
}

Пусть R обозначают iterator_­traits<Iterator>​::​reference. Если is_­reference_­v<R> есть true, то специализация шаблона move_­iterator<Iterator> определяет вложенный тип имени reference как синоним remove_­reference_­t<R>&&, иначе как синоним R.

27.5.3.2 move_­iterator requirements [move.iter.requirements]

Параметр шаблона Iterator должен соответствовать требованиям для input iterator. Кроме того, если реализуется какая-либо из функций обхода с двунаправленным или произвольным доступом, параметр шаблона должен соответствовать требованиям для a Bidirectional Iterator или a Random Access Iterator, соответственно.

27.5.3.3 move_­iterator operations [move.iter.ops]

27.5.3.3.1 move_­iterator constructors [move.iter.op.const]

constexpr move_iterator();

Effects: Создает объект move_­iterator, инициализирующий значение current. Операции итератора, применяемые к результирующему итератору, имеют определенное поведение тогда и только тогда, когда соответствующие операции определены в итераторе типа, инициализированном значением Iterator.

constexpr explicit move_iterator(Iterator i);

Effects: Создаёт move_­iterator, инициализируется current с i.

template <class U> constexpr move_iterator(const move_iterator<U>& u);

Effects: Создаёт move_­iterator, инициализируется current с u.base().

Requires: U конвертируется в Iterator.

27.5.3.3.2 move_­iterator​::​operator= [move.iter.op=]

template <class U> constexpr move_iterator& operator=(const move_iterator<U>& u);

Effects: Назначает u.base() в current.

Requires: U конвертируется в Iterator.

27.5.3.3.3 move_­iterator conversion [move.iter.op.conv]

constexpr Iterator base() const;

Returns: current.

27.5.3.3.4 move_­iterator​::​operator* [move.iter.op.star]

constexpr reference operator*() const;

Returns: static_­cast<reference>(*current).

27.5.3.3.5 move_­iterator​::​operator-> [move.iter.op.ref]

constexpr pointer operator->() const;

Returns: current.

27.5.3.3.6 move_­iterator​::​operator++ [move.iter.op.incr]

constexpr move_iterator& operator++();

Effects: Как будто мимо ++current.

Returns: *this.

constexpr move_iterator operator++(int);

Effects: Как будто по:

move_iterator tmp = *this;
++current;
return tmp;

27.5.3.3.7 move_­iterator​::​operator-- [move.iter.op.decr]

constexpr move_iterator& operator--();

Effects: Как будто мимо --current.

Returns: *this.

constexpr move_iterator operator--(int);

Effects: Как будто по:

move_iterator tmp = *this;
--current;
return tmp;

27.5.3.3.8 move_­iterator​::​operator+ [move.iter.op.+]

constexpr move_iterator operator+(difference_type n) const;

Returns: move_­iterator(current + n).

27.5.3.3.9 move_­iterator​::​operator+= [move.iter.op.+=]

constexpr move_iterator& operator+=(difference_type n);

Effects: Как будто по: current += n;

Returns: *this.

27.5.3.3.10 move_­iterator​::​operator- [move.iter.op.-]

constexpr move_iterator operator-(difference_type n) const;

Returns: move_­iterator(current - n).

27.5.3.3.11 move_­iterator​::​operator-= [move.iter.op.-=]

constexpr move_iterator& operator-=(difference_type n);

Effects: Как будто по: current -= n;

Returns: *this.

27.5.3.3.12 move_­iterator​::​operator[] [move.iter.op.index]

constexpr unspecified operator[](difference_type n) const;

Returns: std​::​move(current[n]).

27.5.3.3.13 move_­iterator comparisons [move.iter.op.comp]

template <class Iterator1, class Iterator2> constexpr bool operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

Returns: x.base() == y.base().

template <class Iterator1, class Iterator2> constexpr bool operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

Returns: !(x == y).

template <class Iterator1, class Iterator2> constexpr bool operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

Returns: x.base() < y.base().

template <class Iterator1, class Iterator2> constexpr bool operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

Returns: !(y < x).

template <class Iterator1, class Iterator2> constexpr bool operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

Returns: y < x.

template <class Iterator1, class Iterator2> constexpr bool operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

Returns: !(x < y).

27.5.3.3.14 move_­iterator non-member functions [move.iter.nonmember]

template <class Iterator1, class Iterator2> constexpr auto operator-( const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());

Returns: x.base() - y.base().

template <class Iterator> constexpr move_iterator<Iterator> operator+( typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);

Returns: x + n.

template <class Iterator> constexpr move_iterator<Iterator> make_move_iterator(Iterator i);

Returns: move_­iterator<Iterator>(i).