26 Containers library [containers]

26.3 Sequence containers [sequences]

26.3.1 In general [sequences.general]

Заголовки <array>, <deque>, <forward_­list>, <list>, и <vector> определить шаблоны классов , которые отвечают требования , предъявляемые к последовательным контейнерам.

26.3.2 Header <array> synopsis [array.syn]

#include <initializer_list>

namespace std {
  // [array], class template array
  template <class T, size_t N> struct array;
  template <class T, size_t N>
    bool operator==(const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator!=(const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator< (const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator> (const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator<=(const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator>=(const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));

  template <class T> class tuple_size;
  template <size_t I, class T> class tuple_element;
  template <class T, size_t N>
    struct tuple_size<array<T, N>>;
  template <size_t I, class T, size_t N>
    struct tuple_element<I, array<T, N>>;
  template <size_t I, class T, size_t N>
    constexpr T& get(array<T, N>&) noexcept;
  template <size_t I, class T, size_t N>
    constexpr T&& get(array<T, N>&&) noexcept;
  template <size_t I, class T, size_t N>
    constexpr const T& get(const array<T, N>&) noexcept;
  template <size_t I, class T, size_t N>
    constexpr const T&& get(const array<T, N>&&) noexcept;
}

26.3.3 Header <deque> synopsis [deque.syn]

#include <initializer_list>

namespace std {
  // [deque], class template deque
  template <class T, class Allocator = allocator<T>> class deque;
  template <class T, class Allocator>
    bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  namespace pmr {
    template <class T>
      using deque = std::deque<T, polymorphic_allocator<T>>;
  }
}

26.3.4 Header <forward_­list> synopsis [forward_list.syn]

#include <initializer_list>

namespace std {
  // [forwardlist], class template forward_­list
  template <class T, class Allocator = allocator<T>> class forward_list;
  template <class T, class Allocator>
    bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  namespace pmr {
    template <class T>
      using forward_list = std::forward_list<T, polymorphic_allocator<T>>;
  }
}

26.3.5 Header <list> synopsis [list.syn]

#include <initializer_list>

namespace std {
  // [list], class template list
  template <class T, class Allocator = allocator<T>> class list;
  template <class T, class Allocator>
    bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    void swap(list<T, Allocator>& x, list<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  namespace pmr {
    template <class T>
      using list = std::list<T, polymorphic_allocator<T>>;
  }
}

26.3.6 Header <vector> synopsis [vector.syn]

#include <initializer_list>

namespace std {
  // [vector], class template vector
  template <class T, class Allocator = allocator<T>> class vector;
  template <class T, class Allocator>
    bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  // [vector.bool], class vector<bool>
  template <class Allocator> class vector<bool, Allocator>;

  // hash support
  template <class T> struct hash;
  template <class Allocator> struct hash<vector<bool, Allocator>>;

  namespace pmr {
    template <class T>
      using vector = std::vector<T, polymorphic_allocator<T>>;
  }
}

26.3.7 Class template array [array]

26.3.7.1 Class template array overview [array.overview]

Заголовок <array> определяет шаблон класса для хранения последовательностей объектов фиксированного размера. An array - это contiguous container. Экземпляр array<T, N> хранит N элементы типа T, так что size() == N это инвариант.

An array - это объект, aggregate который может быть инициализирован списком до N элементов, типы которых могут быть преобразованы T.

Объект array удовлетворяет всем требованиям контейнера и обратимого контейнера ([container.requirements]), за исключением того, что созданный по умолчанию array объект не является пустым и swap не имеет постоянной сложности. An array удовлетворяет некоторым требованиям a sequence container. Здесь описаны только операции array , не описанные в одной из этих таблиц, а также операции, для которых имеется дополнительная семантическая информация.

namespace std {
  template <class T, size_t N>
  struct array {
    //  types:
    using value_type             = T;
    using pointer                = T*;
    using const_pointer          = const T*;
    using reference              = T&;
    using const_reference        = const T&;
    using size_type              = size_t;
    using difference_type        = ptrdiff_t;
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // no explicit construct/copy/destroy for aggregate type

    void fill(const T& u);
    void swap(array&) noexcept(is_nothrow_swappable_v<T>);

    // iterators:
    constexpr iterator               begin() noexcept;
    constexpr const_iterator         begin() const noexcept;
    constexpr iterator               end() noexcept;
    constexpr const_iterator         end() const noexcept;

    constexpr reverse_iterator       rbegin() noexcept;
    constexpr const_reverse_iterator rbegin() const noexcept;
    constexpr reverse_iterator       rend() noexcept;
    constexpr const_reverse_iterator rend() const noexcept;

    constexpr const_iterator         cbegin() const noexcept;
    constexpr const_iterator         cend() const noexcept;
    constexpr const_reverse_iterator crbegin() const noexcept;
    constexpr const_reverse_iterator crend() const noexcept;

    // capacity:
    constexpr bool      empty() const noexcept;
    constexpr size_type size() const noexcept;
    constexpr size_type max_size() const noexcept;

    // element access:
    constexpr reference       operator[](size_type n);
    constexpr const_reference operator[](size_type n) const;
    constexpr reference       at(size_type n);
    constexpr const_reference at(size_type n) const;
    constexpr reference       front();
    constexpr const_reference front() const;
    constexpr reference       back();
    constexpr const_reference back() const;

    constexpr T *       data() noexcept;
    constexpr const T * data() const noexcept;
  };

  template<class T, class... U>
    array(T, U...) -> array<T, 1 + sizeof...(U)>;
}

26.3.7.2 array constructors, copy, and assignment [array.cons]

Условия для aggregate . Класс array опирается на неявно объявленные специальные функции - члены ([class.ctor], [class.dtor]и [class.copy]) , чтобы соответствовать требованиям таблицы контейнера в [container.requirements]. В дополнение к требованиям, указанным в таблице требований к контейнеру, неявный конструктор перемещения и оператор присваивания перемещения для array require that T be MoveConstructible или MoveAssignable, соответственно.

template<class T, class... U> array(T, U...) -> array<T, 1 + sizeof...(U)>;

Requires: (is_­same_­v<T, U> && ...) есть true. В противном случае программа будет некорректной.

26.3.7.3 array specialized algorithms [array.special]

template <class T, size_t N> void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));

Remarks: Эта функция не будет участвовать в разрешении перегрузки , если N == 0 или is_­swappable_­v<T> нет true.

Effects: Как будто мимо x.swap(y).

Complexity: Линейный вход N.

26.3.7.4 array​::​size [array.size]

template <class T, size_t N> constexpr size_type array<T, N>::size() const noexcept;

Returns: N.

26.3.7.5 array​::​data [array.data]

constexpr T* data() noexcept; constexpr const T* data() const noexcept;

Returns: Указатель, такой, что data() == addressof(front())и [data(), data() + size()) является допустимым диапазоном.

26.3.7.6 array​::​fill [array.fill]

void fill(const T& u);

Effects: Как будто мимо fill_­n(begin(), N, u).

26.3.7.7 array​::​swap [array.swap]

void swap(array& y) noexcept(is_nothrow_swappable_v<T>);

Effects: Эквивалентно swap_­ranges(begin(), end(), y.begin()).

[ Note: В отличие от swap функции для других контейнеров, array​::​swap требует линейного времени, может завершиться через исключение и не приводит к связыванию итераторов с другим контейнером. ] end note

26.3.7.8 Zero sized arrays [array.zero]

array обеспечивает поддержку в частном случае N == 0.

В случае N == 0, begin() == end() == уникальное значение. Возвращаемое значение data() не указано.

Эффект вызова front() или back() для массива нулевого размера не определен.

Функция-член swap() должна иметь спецификацию исключения исключения.

26.3.7.9 Tuple interface to class template array [array.tuple]

template <class T, size_t N> struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };

tuple_element<I, array<T, N>>::type

Requires: I < N. Программа некорректно сформирована, если I выходит за пределы допустимого диапазона.

Value: Тип T.

template <size_t I, class T, size_t N> constexpr T& get(array<T, N>& a) noexcept; template <size_t I, class T, size_t N> constexpr T&& get(array<T, N>&& a) noexcept; template <size_t I, class T, size_t N> constexpr const T& get(const array<T, N>& a) noexcept; template <size_t I, class T, size_t N> constexpr const T&& get(const array<T, N>&& a) noexcept;

Requires: I < N. Программа некорректно сформирована, если I выходит за пределы допустимого диапазона.

Returns: Ссылка на Ith элемент a, где индексирование начинается с нуля.

26.3.8 Class template deque [deque]

26.3.8.1 Class template deque overview [deque.overview]

A deque - это контейнер последовательности, который поддерживает итераторы произвольного доступа ([random.access.iterators]). Кроме того, он поддерживает операции вставки и стирания с постоянным временем в начале или в конце; вставка и стирание в середине занимают линейное время. То есть двухсторонняя очередь особенно оптимизирована для нажатия и выталкивания элементов в начале и в конце. Управление хранилищем осуществляется автоматически.

A deque удовлетворяет всем требованиям, предъявляемым к a container, к reversible контейнеру, к контейнеру последовательности, включая optional sequence container requirements, и к allocator-aware container. Здесь описаны только операции deque , не описанные в одной из этих таблиц, или операции, в которых есть дополнительная семантическая информация.

namespace std {
  template <class T, class Allocator = allocator<T>>
  class deque {
  public:
    // types:
    using value_type             = T;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // [deque.cons], construct/copy/destroy
    deque() : deque(Allocator()) { }
    explicit deque(const Allocator&);
    explicit deque(size_type n, const Allocator& = Allocator());
    deque(size_type n, const T& value, const Allocator& = Allocator());
    template <class InputIterator>
      deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
    deque(const deque& x);
    deque(deque&&);
    deque(const deque&, const Allocator&);
    deque(deque&&, const Allocator&);
    deque(initializer_list<T>, const Allocator& = Allocator());

    ~deque();
    deque& operator=(const deque& x);
    deque& operator=(deque&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    deque& operator=(initializer_list<T>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const T& t);
    void assign(initializer_list<T>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;
    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [deque.capacity], capacity
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    void      resize(size_type sz);
    void      resize(size_type sz, const T& c);
    void      shrink_to_fit();

    // element access:
    reference       operator[](size_type n);
    const_reference operator[](size_type n) const;
    reference       at(size_type n);
    const_reference at(size_type n) const;
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;

    // [deque.modifiers], modifiers
    template <class... Args> reference emplace_front(Args&&... args);
    template <class... Args> reference emplace_back(Args&&... args);
    template <class... Args> iterator emplace(const_iterator position, Args&&... args);

    void push_front(const T& x);
    void push_front(T&& x);
    void push_back(const T& x);
    void push_back(T&& x);

    iterator insert(const_iterator position, const T& x);
    iterator insert(const_iterator position, T&& x);
    iterator insert(const_iterator position, size_type n, const T& x);
    template <class InputIterator>
      iterator insert(const_iterator position, InputIterator first, InputIterator last);
    iterator insert(const_iterator position, initializer_list<T>);

    void pop_front();
    void pop_back();

    iterator erase(const_iterator position);
    iterator erase(const_iterator first, const_iterator last);
    void     swap(deque&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    void     clear() noexcept;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    deque(InputIterator, InputIterator, Allocator = Allocator())
      -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;

  template <class T, class Allocator>
    bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);

  // [deque.special], specialized algorithms
  template <class T, class Allocator>
    void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

26.3.8.2 deque constructors, copy, and assignment [deque.cons]

explicit deque(const Allocator&);

Effects: Создает пустой deque, используя указанный распределитель.

Complexity: Постоянный.

explicit deque(size_type n, const Allocator& = Allocator());

Effects: Создает deque со n вставленными по умолчанию элементами с использованием указанного распределителя.

Requires: T должен быть DefaultInsertable в *this.

Complexity: Линейный вход n.

deque(size_type n, const T& value, const Allocator& = Allocator());

Effects: Создает deque с n копиями value, используя указанный распределитель.

Requires: T должен быть CopyInsertable в *this.

Complexity: Линейный вход n.

template <class InputIterator> deque(InputIterator first, InputIterator last, const Allocator& = Allocator());

Effects: Создает значение, deque равное диапазону [first, last), используя указанный распределитель.

Complexity: Линейный вход distance(first, last).

26.3.8.3 deque capacity [deque.capacity]

void resize(size_type sz);

Effects: Если sz < size(), стирает последние size() - sz элементы из последовательности. В противном случае добавляет sz - size() в последовательность элементы, вставленные по умолчанию.

Requires: T должно быть MoveInsertable и DefaultInsertable в *this.

void resize(size_type sz, const T& c);

Effects: Если sz < size(), стирает последние size() - sz элементы из последовательности. В противном случае добавляет к последовательности sz - size() копии c .

Requires: T должен быть CopyInsertable в *this.

void shrink_to_fit();

Requires: T должен быть MoveInsertable в *this.

Effects: shrink_­to_­fit является необязательным запросом на уменьшение использования памяти, но не меняет размер последовательности. [ Note: Запрос не является обязывающим, чтобы дать свободу для оптимизации, зависящей от реализации. ] Если исключение вызвано другим, чем конструктором перемещения объекта non- , никаких эффектов не возникает. end noteCopyInsertable T

Complexity: Линейный по размеру последовательности.

Remarks: shrink_­to_­fit делает недействительными все ссылки, указатели и итераторы, ссылающиеся на элементы в последовательности, а также на итератор, прошедший за конец.

26.3.8.4 deque modifiers [deque.modifiers]

iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); template <class InputIterator> iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list<T>); template <class... Args> reference emplace_front(Args&&... args); template <class... Args> reference emplace_back(Args&&... args); template <class... Args> iterator emplace(const_iterator position, Args&&... args); void push_front(const T& x); void push_front(T&& x); void push_back(const T& x); void push_back(T&& x);

Effects: Вставка в середине двухсторонней очереди делает недействительными все итераторы и ссылки на элементы двухсторонней очереди. Вставка на любом конце двухсторонней очереди делает недействительными все итераторы двухсторонней очереди, но не влияет на достоверность ссылок на элементы двухсторонней очереди.

Remarks: Если исключение создается не конструктором копирования, конструктором перемещения, оператором присваивания или оператором присваивания перемещения, T эффекты отсутствуют. Если при вставке одного элемента с любого конца возникнет исключение, никаких эффектов не будет. В противном случае, если конструктор перемещения не-CopyInsertable T, генерирует исключение , эффекты не определены.

Complexity: Сложность линейна в зависимости от количества вставленных элементов плюс меньшее из расстояний до начала и конца двухсторонней очереди. Вставка одного элемента в начало или конец двухсторонней очереди всегда занимает постоянное время и вызывает единственный вызов конструктора T.

iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void pop_front(); void pop_back();

Effects: Операция стирания, которая стирает последний элемент двухсторонней очереди, делает недействительными только последний итератор, а также все итераторы и ссылки на стертые элементы. Операция стирания, которая стирает первый элемент двухсторонней очереди, но не последний элемент, делает недействительными только итераторы и ссылки на удаленные элементы. Операция стирания, которая не стирает ни первый элемент, ни последний элемент двухсторонней очереди, делает недействительными итератор, прошедший за конец, и все итераторы и ссылки на все элементы двухсторонней очереди. [ Note: pop_­front и pop_­back являются операциями стирания. ] end note

Complexity: Количество вызовов деструктора T такое же, как и количество стертых элементов, но количество вызовов оператора присваивания T не больше, чем меньшее из количества элементов перед стертыми элементами и количества элементов после стертые элементы.

Throws: Ничего, кроме случаев, когда конструктором копирования, конструктором перемещения, оператором присваивания или оператором присваивания перемещения для T.

26.3.8.5 deque specialized algorithms [deque.special]

template <class T, class Allocator> void swap(deque<T, Allocator>& x, deque<T, Allocator>& y) noexcept(noexcept(x.swap(y)));

Effects: Как будто мимо x.swap(y).

26.3.9 Class template forward_­list [forwardlist]

26.3.9.1 Class template forward_­list overview [forwardlist.overview]

A forward_­list - это контейнер, который поддерживает прямые итераторы и позволяет выполнять операции вставки и стирания с постоянным временем в любом месте последовательности с автоматическим управлением хранилищем. Быстрый произвольный доступ к элементам списка не поддерживается. [ Note: Предполагается, что forward_­list у него нулевые объемные или временные накладные расходы по сравнению с рукописным односвязным списком в стиле C. Функции, которые противоречили бы этой цели, были опущены. ]end note

A forward_­list удовлетворяет всем требованиям a container, за исключением того, что size() функция-член не предоставляется и operator== имеет линейную сложность. A forward_­list также удовлетворяет всем требованиям для allocator-aware container. Кроме того, a forward_­list предоставляет assign функции-члены (таблица 87) и некоторые из optional container requirements. Здесь приведены описания только для операций forward_­list , не описанных в этой таблице, или для операций, для которых имеется дополнительная семантическая информация.

[ Note: Изменение любого списка требует доступа к элементу, предшествующему первому интересующему элементу, но в a forward_­list нет постоянного способа доступа к предыдущему элементу. По этой причине изменяемые диапазоны, например диапазоны, предоставленные для erase и splice, должны быть открыты в начале. ] end note

namespace std {
  template <class T, class Allocator = allocator<T>>
  class forward_list {
  public:
    // types:
    using value_type      = T;
    using allocator_type  = Allocator;
    using pointer         = typename allocator_traits<Allocator>::pointer;
    using const_pointer   = typename allocator_traits<Allocator>::const_pointer;
    using reference       = value_type&;
    using const_reference = const value_type&;
    using size_type       = implementation-defined; // see [container.requirements]
    using difference_type = implementation-defined; // see [container.requirements]
    using iterator        = implementation-defined; // see [container.requirements]
    using const_iterator  = implementation-defined; // see [container.requirements]

    // [forwardlist.cons], construct/copy/destroy
    forward_list() : forward_list(Allocator()) { }
    explicit forward_list(const Allocator&);
    explicit forward_list(size_type n, const Allocator& = Allocator());
    forward_list(size_type n, const T& value,
                 const Allocator& = Allocator());
    template <class InputIterator>
      forward_list(InputIterator first, InputIterator last,
                   const Allocator& = Allocator());
    forward_list(const forward_list& x);
    forward_list(forward_list&& x);
    forward_list(const forward_list& x, const Allocator&);
    forward_list(forward_list&& x, const Allocator&);
    forward_list(initializer_list<T>, const Allocator& = Allocator());
    ~forward_list();
    forward_list& operator=(const forward_list& x);
    forward_list& operator=(forward_list&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    forward_list& operator=(initializer_list<T>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const T& t);
    void assign(initializer_list<T>);
    allocator_type get_allocator() const noexcept;

    // [forwardlist.iter], iterators
    iterator before_begin() noexcept;
    const_iterator before_begin() const noexcept;
    iterator begin() noexcept;
    const_iterator begin() const noexcept;
    iterator end() noexcept;
    const_iterator end() const noexcept;

    const_iterator cbegin() const noexcept;
    const_iterator cbefore_begin() const noexcept;
    const_iterator cend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type max_size() const noexcept;

    // [forwardlist.access], element access
    reference front();
    const_reference front() const;

    // [forwardlist.modifiers], modifiers
    template <class... Args> reference emplace_front(Args&&... args);
    void push_front(const T& x);
    void push_front(T&& x);
    void pop_front();

    template <class... Args> iterator emplace_after(const_iterator position, Args&&... args);
    iterator insert_after(const_iterator position, const T& x);
    iterator insert_after(const_iterator position, T&& x);

    iterator insert_after(const_iterator position, size_type n, const T& x);
    template <class InputIterator>
      iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
    iterator insert_after(const_iterator position, initializer_list<T> il);

    iterator erase_after(const_iterator position);
    iterator erase_after(const_iterator position, const_iterator last);
    void swap(forward_list&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);

    void resize(size_type sz);
    void resize(size_type sz, const value_type& c);
    void clear() noexcept;

    // [forwardlist.ops], forward_­list operations
    void splice_after(const_iterator position, forward_list& x);
    void splice_after(const_iterator position, forward_list&& x);
    void splice_after(const_iterator position, forward_list& x,
                      const_iterator i);
    void splice_after(const_iterator position, forward_list&& x,
                      const_iterator i);
    void splice_after(const_iterator position, forward_list& x,
                      const_iterator first, const_iterator last);
    void splice_after(const_iterator position, forward_list&& x,
                      const_iterator first, const_iterator last);

    void remove(const T& value);
    template <class Predicate> void remove_if(Predicate pred);

    void unique();
    template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);

    void merge(forward_list& x);
    void merge(forward_list&& x);
    template <class Compare> void merge(forward_list& x, Compare comp);
    template <class Compare> void merge(forward_list&& x, Compare comp);

    void sort();
    template <class Compare> void sort(Compare comp);

    void reverse() noexcept;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    forward_list(InputIterator, InputIterator, Allocator = Allocator())
      -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>;

  template <class T, class Allocator>
    bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);

  // [forwardlist.spec], specialized algorithms
  template <class T, class Allocator>
    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

Неполный тип T может использоваться при forward_­list создании экземпляра, если распределитель удовлетворяет требованиям allocator completeness requirements. T заполняется до того, как будет сделана forward_­list ссылка на какой-либо член результирующей специализации .

26.3.9.2 forward_­list constructors, copy, assignment [forwardlist.cons]

explicit forward_list(const Allocator&);

Effects: Создает пустой forward_­list объект, используя указанный распределитель.

Complexity: Постоянный.

explicit forward_list(size_type n, const Allocator& = Allocator());

Effects: Создает forward_­list объект со n вставленными по умолчанию элементами, используя указанный распределитель.

Requires: T должен быть DefaultInsertable в *this.

Complexity: Линейный вход n.

forward_list(size_type n, const T& value, const Allocator& = Allocator());

Effects: Создает forward_­list объект с n копиями с value использованием указанного распределителя.

Requires: T должен быть CopyInsertable в *this.

Complexity: Линейный вход n.

template <class InputIterator> forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());

Effects: Создает forward_­list объект, равный диапазону [first, last).

Complexity: Линейный вход distance(first, last).

26.3.9.3 forward_­list iterators [forwardlist.iter]

iterator before_begin() noexcept; const_iterator before_begin() const noexcept; const_iterator cbefore_begin() const noexcept;

Returns: Итератор без разыменования, который при увеличении равен итератору, возвращаемому begin().

Effects: cbefore_­begin() эквивалентно const_­cast<forward_­list const&>(*this).before_­begin().

Remarks: before_­begin() == end() равны false.

26.3.9.4 forward_­list element access [forwardlist.access]

reference front(); const_reference front() const;

Returns: *begin()

26.3.9.5 forward_­list modifiers [forwardlist.modifiers]

Ни одна из перегрузок insert_­after не должна влиять на действительность итераторов и ссылок, и erase_­after должна делать недействительными только итераторы и ссылки на стертые элементы. Если во время сгенерировано исключение insert_­after , никакого эффекта не будет. Вставка n элементов в a forward_­list линейна по n, а количество вызовов конструктора копирования или перемещения T точно равно n. Стирание n элементов из a forward_­list линейно по, n и количество вызовов деструктора типа T точно равно n.

template <class... Args> reference emplace_front(Args&&... args);

Effects: Вставляет объект типа, созданного value_­type с помощью, value_­type(std​::​forward<Args>(​args)...) в начало списка.

void push_front(const T& x); void push_front(T&& x);

Effects: Вставляет копию x в начало списка.

void pop_front();

Effects: Как будто мимо erase_­after(before_­begin()).

iterator insert_after(const_iterator position, const T& x); iterator insert_after(const_iterator position, T&& x);

Requires: position является before_­begin() или является разыменяемым итератором в диапазоне [begin(), end()).

Effects: Вставляет копию x после position.

Returns: Итератор, указывающий на копию x.

iterator insert_after(const_iterator position, size_type n, const T& x);

Requires: position является before_­begin() или является разыменяемым итератором в диапазоне [begin(), end()).

Effects: Вставляет n копии x после position.

Returns: Итератор, указывающий на последнюю вставленную копию x или position if n == 0.

template <class InputIterator> iterator insert_after(const_iterator position, InputIterator first, InputIterator last);

Requires: position является before_­begin() или является разыменяемым итератором в диапазоне [begin(), end()). first и last не являются итераторами в *this.

Effects: Вставляет копии элементов в [first, last) after position.

Returns: Итератор, указывающий на последний вставленный элемент или position if first == last.

iterator insert_after(const_iterator position, initializer_list<T> il);

Effects: insert_­after(p, il.begin(), il.end()).

Returns: Итератор, указывающий на последний вставленный элемент или position если il он пуст.

template <class... Args> iterator emplace_after(const_iterator position, Args&&... args);

Requires: position является before_­begin() или является разыменяемым итератором в диапазоне [begin(), end()).

Effects: Вставляет объект типа, созданного value_­type с помощью value_­type(std​::​forward<Args>(​args)...) after position.

Returns: Итератор, указывающий на новый объект.

iterator erase_after(const_iterator position);

Requires: Следующий итератор position можно разыменовать.

Effects: Удаляет элемент, на который указывает следующий итератор position.

Returns: Итератор, указывающий на элемент, следующий за тем, который был удален, или end() если такой элемент не существует.

Throws: Ничего такого.

iterator erase_after(const_iterator position, const_iterator last);

Requires: Все итераторы в диапазоне (position, last) можно разыменовать.

Effects: Стирает элементы в диапазоне (position, last).

Returns: last.

Throws: Ничего такого.

void resize(size_type sz);

Effects: Если sz < distance(begin(), end()), стирает последние distance(begin(), end()) - sz элементы из списка. В противном случае sz - distance(begin(), end()) вставляет элементы, вставленные по умолчанию, в конец списка.

Requires: T должен быть DefaultInsertable в *this.

void resize(size_type sz, const value_type& c);

Effects: Если sz < distance(begin(), end()), стирает последние distance(begin(), end()) - sz элементы из списка. В противном случае вставляет sz - distance(begin(), end()) копии c в конец списка.

Requires: T должен быть CopyInsertable в *this.

void clear() noexcept;

Effects: Удаляет все элементы в диапазоне [begin(), end()).

Remarks: Не делает недействительными итераторы, прошедшие мимо конца.

26.3.9.6 forward_­list operations [forwardlist.ops]

void splice_after(const_iterator position, forward_list& x); void splice_after(const_iterator position, forward_list&& x);

Requires: position является before_­begin() или является разыменяемым итератором в диапазоне [begin(), end()). get_­allocator() == x.get_­allocator(). &x != this.

Effects: Вставляет содержимое x после positionи x становится пустым. Указатели и ссылки на перемещенные элементы x теперь относятся к тем же элементам, но как к членам *this. Итераторы, относящиеся к перемещенным элементам, будут продолжать ссылаться на свои элементы, но теперь они ведут себя как итераторы в *this, а не в x.

Throws: Ничего такого.

Complexity: O(distance(x.begin(), x.end()))

void splice_after(const_iterator position, forward_list& x, const_iterator i); void splice_after(const_iterator position, forward_list&& x, const_iterator i);

Requires: position является before_­begin() или является разыменяемым итератором в диапазоне [begin(), end()). Следующий итератор i - это итератор с возможностью разыменования в x. get_­allocator() == x.get_­allocator().

Effects: Вставки элемент следующие i в *thisпосле position, и удаляет его из x. Результат не меняется, если position == i или position == ++i. Указатели и ссылки, чтобы *++i продолжать ссылаться на тот же элемент, но как на член *this. Итераторы *++i продолжают ссылаться на тот же элемент, но теперь ведут себя как итераторы в *this, а не в x.

Throws: Ничего такого.

Complexity: O(1)

void splice_after(const_iterator position, forward_list& x, const_iterator first, const_iterator last); void splice_after(const_iterator position, forward_list&& x, const_iterator first, const_iterator last);

Requires: position является before_­begin() или является разыменяемым итератором в диапазоне [begin(), end()). (first, last) - допустимый диапазон в x, и все итераторы в этом диапазоне (first, last) можно разыменовать. position не является итератором в диапазоне (first, last). get_­allocator() == x.get_­allocator().

Effects: Вставляет элементы в диапазон (first, last) после position и удаляет элементы из x. Указатели и ссылки на перемещенные элементы x теперь относятся к тем же элементам, но как к членам *this. Итераторы, относящиеся к перемещенным элементам, будут продолжать ссылаться на свои элементы, но теперь они ведут себя как итераторы в *this, а не в x.

Complexity: O(distance(first, last))

void remove(const T& value); template <class Predicate> void remove_if(Predicate pred);

Effects: Удаляет все элементы в списке, на которые ссылается итератор списка, i для которых выполняются следующие условия: *i == value (for remove()), pred(*i) is true (for remove_­if()). Делает недействительными только итераторы и ссылки на удаленные элементы.

Throws: Ничего, если сравнение равенства или предикат не вызывает исключения.

Remarks: Stable.

Complexity: Точно distance(begin(), end()) применения соответствующего предиката.

void unique(); template <class BinaryPredicate> void unique(BinaryPredicate pred);

Effects: Удаляет все элементы, кроме первого, из каждой последовательной группы равных элементов, на которую ссылается итератор i в диапазоне, [first + 1, last) для которого *i == *(i-1) (для версии без аргументов) или pred(*i, *(i - 1)) (для версии с аргументом предиката) выполняется. Делает недействительными только итераторы и ссылки на удаленные элементы.

Throws: Ничего, если сравнение равенства или предикат не вызывает исключения.

Complexity: Если диапазон [first, last) не пуст, то это точно (last - first) - 1 применения соответствующего предиката, в противном случае - никакие применения предиката.

void merge(forward_list& x); void merge(forward_list&& x); template <class Compare> void merge(forward_list& x, Compare comp); template <class Compare> void merge(forward_list&& x, Compare comp);

Requires: comp определяет strict weak orderingи *this и x оба сортируются в соответствии с этим порядком. get_­allocator() == x.get_­allocator().

Effects: Объединяет два отсортированных диапазона [begin(), end()) и [x.begin(), x.end()). x после слияния пусто. Если исключение выбрасывается иначе, чем путем сравнения, нет никаких эффектов. Указатели и ссылки на перемещенные элементы x теперь относятся к тем же элементам, но как к членам *this. Итераторы, относящиеся к перемещенным элементам, будут продолжать ссылаться на свои элементы, но теперь они ведут себя как итераторы в *this, а не в x.

Remarks: Stable. Поведение не определено, если get_­allocator() != x.get_­allocator().

Complexity: Максимум distance(begin(), end()) + distance(x.begin(), x.end()) - 1 сравнений.

void sort(); template <class Compare> void sort(Compare comp);

Requires: operator< (для версии без аргументов) или comp (для версии с аргументом сравнения) определяет strict weak ordering.

Effects: Сортирует список по объекту функции operator< или comp . Если выбрасывается исключение, порядок элементов в нем *this не указан. Не влияет на валидность итераторов и ссылок.

Remarks: Stable.

Complexity: Примерно NlogN сравнения, где N есть distance(begin(), end()).

void reverse() noexcept;

Effects: Меняет порядок элементов в списке на обратный. Не влияет на валидность итераторов и ссылок.

Complexity: Линейное время.

26.3.9.7 forward_­list specialized algorithms [forwardlist.spec]

template <class T, class Allocator> void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) noexcept(noexcept(x.swap(y)));

Effects: Как будто мимо x.swap(y).

26.3.10 Class template list [list]

26.3.10.1 Class template list overview [list.overview]

A list - это контейнер последовательности, который поддерживает двунаправленные итераторы и позволяет выполнять операции вставки и стирания с постоянным временем в любом месте последовательности с автоматическим управлением хранением. В отличие от vectors и deques, быстрый произвольный доступ к элементам списка не поддерживается, но многим алгоритмам в любом случае нужен только последовательный доступ.

A list удовлетворяет всем требованиям контейнера, обратимого контейнера (приведенного в двух таблицах [container.requirements]), контейнера последовательности, включая большую часть optional sequence container requirements, и файла allocator-aware container. Исключением являются функции-членыoperator[] и at, которые не предусмотрены.258 Здесь описаны только операции list , не описанные в одной из этих таблиц, или операции, в которых есть дополнительная семантическая информация.

namespace std {
  template <class T, class Allocator = allocator<T>>
  class list {
  public:
    // types:
    using value_type             = T;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // [list.cons], construct/copy/destroy
    list() : list(Allocator()) { }
    explicit list(const Allocator&);
    explicit list(size_type n, const Allocator& = Allocator());
    list(size_type n, const T& value, const Allocator& = Allocator());
    template <class InputIterator>
      list(InputIterator first, InputIterator last, const Allocator& = Allocator());
    list(const list& x);
    list(list&& x);
    list(const list&, const Allocator&);
    list(list&&, const Allocator&);
    list(initializer_list<T>, const Allocator& = Allocator());
    ~list();
    list& operator=(const list& x);
    list& operator=(list&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    list& operator=(initializer_list<T>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const T& t);
    void assign(initializer_list<T>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;
    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [list.capacity], capacity
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    void      resize(size_type sz);
    void      resize(size_type sz, const T& c);

    // element access:
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;

    // [list.modifiers], modifiers
    template <class... Args> reference emplace_front(Args&&... args);
    template <class... Args> reference emplace_back(Args&&... args);
    void push_front(const T& x);
    void push_front(T&& x);
    void pop_front();
    void push_back(const T& x);
    void push_back(T&& x);
    void pop_back();

    template <class... Args> iterator emplace(const_iterator position, Args&&... args);
    iterator insert(const_iterator position, const T& x);
    iterator insert(const_iterator position, T&& x);
    iterator insert(const_iterator position, size_type n, const T& x);
    template <class InputIterator>
      iterator insert(const_iterator position, InputIterator first,
                      InputIterator last);
    iterator insert(const_iterator position, initializer_list<T> il);

    iterator erase(const_iterator position);
    iterator erase(const_iterator position, const_iterator last);
    void     swap(list&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    void     clear() noexcept;

    // [list.ops], list operations
    void splice(const_iterator position, list& x);
    void splice(const_iterator position, list&& x);
    void splice(const_iterator position, list& x, const_iterator i);
    void splice(const_iterator position, list&& x, const_iterator i);
    void splice(const_iterator position, list& x,
                const_iterator first, const_iterator last);
    void splice(const_iterator position, list&& x,
                const_iterator first, const_iterator last);

    void remove(const T& value);
    template <class Predicate> void remove_if(Predicate pred);

    void unique();
    template <class BinaryPredicate>
      void unique(BinaryPredicate binary_pred);

    void merge(list& x);
    void merge(list&& x);
    template <class Compare> void merge(list& x, Compare comp);
    template <class Compare> void merge(list&& x, Compare comp);

    void sort();
    template <class Compare> void sort(Compare comp);

    void reverse() noexcept;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    list(InputIterator, InputIterator, Allocator = Allocator())
      -> list<typename iterator_traits<InputIterator>::value_type, Allocator>;

  template <class T, class Allocator>
    bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const list<T, Allocator>& x, const list<T, Allocator>& y);

  // [list.special], specialized algorithms
  template <class T, class Allocator>
    void swap(list<T, Allocator>& x, list<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

Неполный тип T может использоваться при list создании экземпляра, если распределитель удовлетворяет требованиям allocator completeness requirements. T заполняется до того, как будет сделана list ссылка на какой-либо член результирующей специализации .

Эти функции-члены предоставляются только контейнерами, итераторы которых являются итераторами с произвольным доступом.

26.3.10.2 list constructors, copy, and assignment [list.cons]

explicit list(const Allocator&);

Effects: Создает пустой список, используя указанный распределитель.

Complexity: Постоянный.

explicit list(size_type n, const Allocator& = Allocator());

Effects: Создает list со n вставленными по умолчанию элементами с использованием указанного распределителя.

Requires: T должен быть DefaultInsertable в *this.

Complexity: Линейный вход n.

list(size_type n, const T& value, const Allocator& = Allocator());

Effects: Создает list с n копиями value, используя указанный распределитель.

Requires: T должен быть CopyInsertable в *this.

Complexity: Линейный вход n.

template <class InputIterator> list(InputIterator first, InputIterator last, const Allocator& = Allocator());

Effects: Создает list равный диапазону [first, last).

Complexity: Линейный вход distance(first, last).

26.3.10.3 list capacity [list.capacity]

void resize(size_type sz);

Effects: Если size() < sz, добавляет sz - size() в последовательность элементы, вставленные по умолчанию. Если sz <= size()эквивалентно:

list<T>::iterator it = begin();
advance(it, sz);
erase(it, end());

Requires: T должен быть DefaultInsertable в *this.

void resize(size_type sz, const T& c);

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

if (sz > size())
  insert(end(), sz-size(), c);
else if (sz < size()) {
  iterator i = begin();
  advance(i, sz);
  erase(i, end());
}
else
  ;                 // do nothing

Requires: T должен быть CopyInsertable в *this.

26.3.10.4 list modifiers [list.modifiers]

iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); template <class InputIterator> iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list<T>); template <class... Args> reference emplace_front(Args&&... args); template <class... Args> reference emplace_back(Args&&... args); template <class... Args> iterator emplace(const_iterator position, Args&&... args); void push_front(const T& x); void push_front(T&& x); void push_back(const T& x); void push_back(T&& x);

Remarks: Не влияет на валидность итераторов и ссылок. Если выбрано исключение, никаких эффектов нет.

Complexity: Вставка одного элемента в список занимает постоянное время и ровно один вызов конструктора T. Вставка нескольких элементов в список линейна по количеству вставленных элементов, а количество вызовов конструктора копирования или конструктора перемещения T точно равно количеству вставленных элементов.

iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void pop_front(); void pop_back(); void clear() noexcept;

Effects: Делает недействительными только итераторы и ссылки на удаленные элементы.

Throws: Ничего такого.

Complexity: Стирание одного элемента - это постоянная операция по времени с одним вызовом деструктора T. Стирание диапазона в списке происходит за линейное время по размеру диапазона, а количество вызовов деструктора типа T в точности равно размеру диапазона.

26.3.10.5 list operations [list.ops]

Поскольку списки позволяют быстро вставлять и стирать из середины списка, определенные операции предусмотрены специально для них.259

list предоставляет три операции соединения, которые разрушающе перемещают элементы из одного списка в другой. Поведение операций соединения не определено, если get_­allocator() != x.get_­allocator().

void splice(const_iterator position, list& x); void splice(const_iterator position, list&& x);

Requires: &x != this.

Effects: Вставляет содержимое x до position и x становится пустым. Указатели и ссылки на перемещенные элементы x теперь относятся к тем же элементам, но как к членам *this. Итераторы, относящиеся к перемещенным элементам, будут продолжать ссылаться на свои элементы, но теперь они ведут себя как итераторы в *this, а не в x.

Throws: Ничего такого.

Complexity: Постоянное время.

void splice(const_iterator position, list& x, const_iterator i); void splice(const_iterator position, list&& x, const_iterator i);

Requires: i - допустимый разыменяемый итератор для x.

Effects: Вставляет элемент , на который указывает i из списка ,x прежде чем position и удаляет элемент из x. Результат не меняется, если position == i или position == ++i. Указатели и ссылки, чтобы *i продолжать ссылаться на этот же элемент, но как на член *this. Итераторы *i (включая i себя) продолжают ссылаться на один и тот же элемент, но теперь ведут себя как итераторы в *this, а не в x.

Throws: Ничего такого.

Complexity: Постоянное время.

void splice(const_iterator position, list& x, const_iterator first, const_iterator last); void splice(const_iterator position, list&& x, const_iterator first, const_iterator last);

Requires: [first, last) допустимый диапазон в x. Программа имеет неопределенное поведение, если position является итератором в диапазоне [first, last).

Effects: Вставляет элементы в диапазон [first, last) до position и удаляет элементы из x. Указатели и ссылки на перемещенные элементы x теперь относятся к тем же элементам, но как к членам *this. Итераторы, относящиеся к перемещенным элементам, будут продолжать ссылаться на свои элементы, но теперь они ведут себя как итераторы в *this, а не в x.

Throws: Ничего такого.

Complexity: Постоянное время, если &x == this; в противном случае - линейное время.

void remove(const T& value); template <class Predicate> void remove_if(Predicate pred);

Effects: Удаляет все элементы в списке, на которые ссылается итератор списка, i для которого выполняются следующие условия: *i == value, pred(*i) != false. Делает недействительными только итераторы и ссылки на удаленные элементы.

Throws: Ничего, если исключение не вызвано *i == value или pred(*i) != false.

Remarks: Stable.

Complexity: Точно size() применения соответствующего предиката.

void unique(); template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);

Effects: Удаляет все элементы, кроме первого, из каждой последовательной группы равных элементов, на которую ссылается итератор i в диапазоне, [first + 1, last) для которого *i == *(i-1) (для версии unique без аргументов) или pred(*i, *(i - 1)) (для версии unique с аргументом предиката) выполняется. Делает недействительными только итераторы и ссылки на удаленные элементы.

Throws: Ничего, если исключение не вызвано *i == *(i-1) или pred(*i, *(i - 1))

Complexity: Если диапазон [first, last) не пуст, то это точно (last - first) - 1 применения соответствующего предиката, в противном случае - никакие применения предиката.

void merge(list& x); void merge(list&& x); template <class Compare> void merge(list& x, Compare comp); template <class Compare> void merge(list&& x, Compare comp);

Requires: comp должен определять a strict weak ordering, и как список, так и список аргументов должны быть отсортированы в соответствии с этим порядком.

Effects: Если (&x == this) ничего не делает; в противном случае объединяет два отсортированных диапазона [begin(), end()) и [x.​begin(), x.end()). Результатом является диапазон, в котором элементы будут отсортированы в неубывающем порядке в соответствии с порядком, определенным с помощью comp; то есть для каждого итератора iв диапазоне, отличном от первого, условие comp(*i, *(i - 1)) будет false. Указатели и ссылки на перемещенные элементы x теперь относятся к тем же элементам, но как к членам *this. Итераторы, относящиеся к перемещенным элементам, будут продолжать ссылаться на свои элементы, но теперь они ведут себя как итераторы в *this, а не в x.

Remarks: Stable. Если после слияния (&x != this) диапазон [x.begin(), x.end())пуст. Эта операция не копирует никакие элементы. Поведение не определено, если get_­allocator() != x.get_­allocator().

Complexity: В большинстве size() + x.size() - 1 приложений comp if (&x != this); в противном случае приложения comp не выполняются. Если исключение выбрасывается иначе, чем путем сравнения, нет никаких эффектов.

void reverse() noexcept;

Effects: Меняет порядок элементов в списке на обратный. Не влияет на валидность итераторов и ссылок.

Complexity: Линейное время.

void sort(); template <class Compare> void sort(Compare comp);

Requires: operator< (для первой версии) или comp (для второй версии) должен определять файл strict weak ordering.

Effects: Сортирует список по объекту operator< или Compare функции. Если выбрасывается исключение, порядок элементов в нем *this не указан. Не влияет на валидность итераторов и ссылок.

Remarks: Stable.

Complexity: Примерно NlogN сравнения, где N == size().

Как указано в [allocator.requirements], требования этого пункта применяются только к спискам, распределители которых сравниваются одинаково.

26.3.10.6 list specialized algorithms [list.special]

template <class T, class Allocator> void swap(list<T, Allocator>& x, list<T, Allocator>& y) noexcept(noexcept(x.swap(y)));

Effects: Как будто мимо x.swap(y).

26.3.11 Class template vector [vector]

26.3.11.1 Class template vector overview [vector.overview]

A vector - это контейнер последовательности, который поддерживает (амортизированные) операции вставки и стирания с постоянным временем в конце; вставка и стирание в середине занимают линейное время. Управление хранилищем осуществляется автоматически, хотя могут быть даны подсказки для повышения эффективности.

A vector удовлетворяет все требования , предъявляемые к container и от в reversible контейнере, из контейнера последовательности, в том числе большинства из optional sequence container requirements, с концентрацией allocator-aware container, а для типа элемента , отличного bool, в А contiguous container. Исключением являются функции-члены push_­front, pop_­frontи emplace_­front , которые не предусмотрены. Здесь описаны только операции vector , не описанные в одной из этих таблиц, или операции, в которых есть дополнительная семантическая информация.

namespace std {
  template <class T, class Allocator = allocator<T>>
  class vector {
  public:
    // types:
    using value_type             = T;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // [vector.cons], construct/copy/destroy
    vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { }
    explicit vector(const Allocator&) noexcept;
    explicit vector(size_type n, const Allocator& = Allocator());
    vector(size_type n, const T& value, const Allocator& = Allocator());
    template <class InputIterator>
      vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
    vector(const vector& x);
    vector(vector&&) noexcept;
    vector(const vector&, const Allocator&);
    vector(vector&&, const Allocator&);
    vector(initializer_list<T>, const Allocator& = Allocator());
    ~vector();
    vector& operator=(const vector& x);
    vector& operator=(vector&& x)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    vector& operator=(initializer_list<T>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const T& u);
    void assign(initializer_list<T>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;
    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [vector.capacity], capacity
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    size_type capacity() const noexcept;
    void      resize(size_type sz);
    void      resize(size_type sz, const T& c);
    void      reserve(size_type n);
    void      shrink_to_fit();

    // element access:
    reference       operator[](size_type n);
    const_reference operator[](size_type n) const;
    const_reference at(size_type n) const;
    reference       at(size_type n);
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;

    // [vector.data], data access
    T*       data() noexcept;
    const T* data() const noexcept;

    // [vector.modifiers], modifiers
    template <class... Args> reference emplace_back(Args&&... args);
    void push_back(const T& x);
    void push_back(T&& x);
    void pop_back();

    template <class... Args> iterator emplace(const_iterator position, Args&&... args);
    iterator insert(const_iterator position, const T& x);
    iterator insert(const_iterator position, T&& x);
    iterator insert(const_iterator position, size_type n, const T& x);
    template <class InputIterator>
      iterator insert(const_iterator position, InputIterator first, InputIterator last);
    iterator insert(const_iterator position, initializer_list<T> il);
    iterator erase(const_iterator position);
    iterator erase(const_iterator first, const_iterator last);
    void     swap(vector&)
      noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    void     clear() noexcept;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    vector(InputIterator, InputIterator, Allocator = Allocator())
      -> vector<typename iterator_traits<InputIterator>::value_type, Allocator>;

  template <class T, class Allocator>
    bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);

  // [vector.special], specialized algorithms
  template <class T, class Allocator>
    void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

Неполный тип T может использоваться при vector создании экземпляра, если распределитель удовлетворяет требованиям allocator completeness requirements. T заполняется до того, как будет сделана vector ссылка на какой-либо член результирующей специализации .

26.3.11.2 vector constructors, copy, and assignment [vector.cons]

explicit vector(const Allocator&);

Effects: Создает пустой vector, используя указанный распределитель.

Complexity: Постоянный.

explicit vector(size_type n, const Allocator& = Allocator());

Effects: Создает vector со n вставленными по умолчанию элементами с использованием указанного распределителя.

Requires: T должен быть DefaultInsertable в *this.

Complexity: Линейный вход n.

vector(size_type n, const T& value, const Allocator& = Allocator());

Effects: Создает vector с n копиями value, используя указанный распределитель.

Requires: T должен быть CopyInsertable в *this.

Complexity: Линейный вход n.

template <class InputIterator> vector(InputIterator first, InputIterator last, const Allocator& = Allocator());

Effects: Создает значение, vector равное диапазону [first, last), используя указанный распределитель.

Complexity: Выполняет только N вызовы конструктора копирования T (где N - расстояние между first и last) и не выполняет перераспределения, если итераторы first и last относятся к категориям прямого, двунаправленного или произвольного доступа. Он выполняет упорядоченные N вызовы конструктора копирования T и упорядочивает logN перераспределения, если они являются просто итераторами ввода.

26.3.11.3 vector capacity [vector.capacity]

size_type capacity() const noexcept;

Returns: Общее количество элементов, которые вектор может содержать без необходимости перераспределения.

void reserve(size_type n);

Requires: T должен быть MoveInsertable в *this.

Effects: Директива, которая информирует vector о планируемом изменении размера, чтобы он мог соответствующим образом управлять распределением хранилища. После того, какreserve(), capacity() больше или равен аргументу ,reserve если Перераспределение происходит; и равно предыдущему значению в capacity() противном случае. Перераспределение происходит в этот момент тогда и только тогда, когда текущая емкость меньше аргумента reserve(). Если исключение выбрасывается не конструктором перемещения не-CopyInsertable типа, не будет никаких эффектов.

Complexity: Он не изменяет размер последовательности и занимает самое большее линейное время в размере последовательности.

Throws: length_­error если n > max_­size().260

Remarks: Перераспределение делает недействительными все ссылки, указатели и итераторы, относящиеся к элементам в последовательности. Никакое перераспределение не должно происходить во время вставок, которые происходят после вызова, reserve() до того момента, когда вставка сделает размер вектора больше, чем значение capacity().

void shrink_to_fit();

Requires: T должен быть MoveInsertable в *this.

Effects: shrink_­to_­fit является необязательным запросом для сокращения capacity() до size(). [ Note: Запрос не является обязывающим, чтобы дать свободу для оптимизации, зависящей от реализации. ] Он не увеличивается , но может уменьшаться , вызывая перераспределение. Если исключение вызвано другим, чем конструктором перемещения объекта non- , никаких эффектов не возникает. end note capacity() capacity()CopyInsertable T

Complexity: Линейный по размеру последовательности.

Remarks: Перераспределение делает недействительными все ссылки, указатели и итераторы, относящиеся к элементам в последовательности, а также к итератору, прошедшему конец. Если перераспределения не происходит, они остаются в силе.

void swap(vector& x) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);

Effects: Обмены содержания и capacity() о *this с у x.

Complexity: Постоянное время.

void resize(size_type sz);

Effects: Если sz < size(), стирает последние size() - sz элементы из последовательности. В противном случае добавляет sz - size() в последовательность элементы, вставленные по умолчанию.

Requires: T должно быть MoveInsertable и DefaultInsertable в *this.

Remarks: Если исключение вызвано другим, чем конструктором перемещения объекта non-CopyInsertable T , никаких эффектов не возникает.

void resize(size_type sz, const T& c);

Effects: Если sz < size(), стирает последние size() - sz элементы из последовательности. В противном случае добавляет к последовательности sz - size() копии c .

Requires: T должен быть CopyInsertable в *this.

Remarks: Если выбрано исключение, никаких эффектов нет.

reserve() использования, Allocator​::​allocate() которые могут вызвать соответствующее исключение.

26.3.11.4 vector data [vector.data]

T* data() noexcept; const T* data() const noexcept;

Returns: Указатель, [data(), data() + size()) представляющий собой допустимый диапазон. Для непустого вектора data() == addressof(front()).

Complexity: Постоянное время.

26.3.11.5 vector modifiers [vector.modifiers]

iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); template <class InputIterator> iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list<T>); template <class... Args> reference emplace_back(Args&&... args); template <class... Args> iterator emplace(const_iterator position, Args&&... args); void push_back(const T& x); void push_back(T&& x);

Remarks: Вызывает перераспределение, если новый размер больше старого. Перераспределение делает недействительными все ссылки, указатели и итераторы, относящиеся к элементам в последовательности. Если перераспределения не происходит, все итераторы и ссылки до точки вставки остаются действительными. Если исключение создается не конструктором копирования, конструктором перемещения, оператором присваивания или оператором присваивания перемещения T или какой-либо InputIterator операцией, эффекты отсутствуют. Если при вставке одного элемента в конце возникает исключение, которое T есть CopyInsertable или is_­nothrow_­move_­constructible_­v<T> есть true, никаких эффектов нет. В противном случае, если конструктор перемещения не-CopyInsertable T, генерирует исключение , эффекты не определены.

Complexity: Сложность линейна по количеству вставленных элементов плюс расстояние до конца вектора.

iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void pop_back();

Effects: Делает недействительными итераторы и ссылки в точке стирания или после нее.

Complexity: Деструктором объекта T называется количество раз, равное количеству стертых элементов, а оператором присваивания T вызывается количество раз, равное количеству элементов в векторе после стертых элементов.

Throws: Ничего, если оператор присваивания или оператор присваивания перемещения не генерирует исключение T.

26.3.11.6 vector specialized algorithms [vector.special]

template <class T, class Allocator> void swap(vector<T, Allocator>& x, vector<T, Allocator>& y) noexcept(noexcept(x.swap(y)));

Effects: Как будто мимо x.swap(y).

26.3.12 Class vector<bool> [vector.bool]

Для оптимизации распределения пространства предусмотрена специализация вектора для bool элементов:

namespace std {
  template <class Allocator>
  class vector<bool, Allocator> {
  public:
    // types:
    using value_type             = bool;
    using allocator_type         = Allocator;
    using pointer                = implementation-defined;
    using const_pointer          = implementation-defined;
    using const_reference        = bool;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // bit reference:
    class reference {
      friend class vector;
      reference() noexcept;
    public:
      ~reference();
      operator bool() const noexcept;
      reference& operator=(const bool x) noexcept;
      reference& operator=(const reference& x) noexcept;
      void flip() noexcept;     // flips the bit
    };

    // construct/copy/destroy:
    vector() : vector(Allocator()) { }
    explicit vector(const Allocator&);
    explicit vector(size_type n, const Allocator& = Allocator());
    vector(size_type n, const bool& value,
           const Allocator& = Allocator());
    template <class InputIterator>
      vector(InputIterator first, InputIterator last,
             const Allocator& = Allocator());
    vector(const vector<bool, Allocator>& x);
    vector(vector<bool, Allocator>&& x);
    vector(const vector&, const Allocator&);
    vector(vector&&, const Allocator&);
    vector(initializer_list<bool>, const Allocator& = Allocator()));
    ~vector();
    vector<bool, Allocator>& operator=(const vector<bool, Allocator>& x);
    vector<bool, Allocator>& operator=(vector<bool, Allocator>&& x);
    vector& operator=(initializer_list<bool>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const bool& t);
    void assign(initializer_list<bool>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;
    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    size_type capacity() const noexcept;
    void      resize(size_type sz, bool c = false);
    void      reserve(size_type n);
    void      shrink_to_fit();

    // element access:
    reference       operator[](size_type n);
    const_reference operator[](size_type n) const;
    const_reference at(size_type n) const;
    reference       at(size_type n);
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;

    // modifiers:
    template <class... Args> reference emplace_back(Args&&... args);
    void push_back(const bool& x);
    void pop_back();
    template <class... Args> iterator emplace(const_iterator position, Args&&... args);
    iterator insert(const_iterator position, const bool& x);
    iterator insert(const_iterator position, size_type n, const bool& x);
    template <class InputIterator>
      iterator insert(const_iterator position,
                      InputIterator first, InputIterator last);
    iterator insert(const_iterator position, initializer_list<bool> il);

    iterator erase(const_iterator position);
    iterator erase(const_iterator first, const_iterator last);
    void swap(vector<bool, Allocator>&);
    static void swap(reference x, reference y) noexcept;
    void flip() noexcept;       // flips all bits
    void clear() noexcept;
  };
}

Если не описано ниже, все операции имеют те же требования и семантику, что и основной vector шаблон, за исключением того, что операции, работающие с bool типом значения, сопоставляются с битовыми значениями в хранилище контейнера и allocator_­traits​::​construct не используются для создания этих значений.

Нет требования, чтобы данные хранились как непрерывное распределение bool значений. Вместо этого рекомендуется оптимизированное по пространству представление битов.

reference - это класс, моделирующий поведение ссылок одного бита в vector<bool>. Функция преобразования возвращается, true когда бит установлен, и в false противном случае. Оператор присваивания устанавливает бит, когда аргумент (преобразовывается в), true и очищает его в противном случае. flip меняет состояние долота.

void flip() noexcept;

Effects: Заменяет каждый элемент в контейнере его дополнением.

static void swap(reference x, reference y) noexcept;

Effects: Меняет содержимое x и y как будто:

bool b = x;
x = y;
y = b;

template <class Allocator> struct hash<vector<bool, Allocator>>;

Специализация включена ([unord.hash]).