26 Containers library [containers]

26.3 Sequence containers [sequences]

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 noteCopyInsertableT

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).