[deque]

# 23 Containers library [[containers]](./#containers)

## 23.3 Sequence containers [[sequences]](sequences#deque)

### 23.3.5 Class template deque [deque]

#### [23.3.5.1](#overview) Overview [[deque.overview]](deque.overview)

[1](#overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6466)

Adeque is a sequence container that supports [random access iterators](random.access.iterators "24.3.5.7 Random access iterators [random.access.iterators]")[.](#overview-1.sentence-1)

In addition, it supports constant time insert and erase operations at the beginning or the end;
insert and erase in the middle take linear time[.](#overview-1.sentence-2)

That is, a deque is especially optimized for pushing and popping elements at the beginning and end[.](#overview-1.sentence-3)

Storage management is handled automatically[.](#overview-1.sentence-4)

[2](#overview-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6476)

A deque meets all of the requirements
of a container ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")),
of a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3 Reversible container requirements")),
of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")), and
of a sequence container,
including the optional sequence container requirements ([[sequence.reqmts]](sequence.reqmts "23.2.4 Sequence containers"))[.](#overview-2.sentence-1)

Descriptions are provided here only for operations ondeque that are not described in one of these tables
or for operations where there is additional semantic information[.](#overview-2.sentence-2)

[3](#overview-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6488)

The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#overview-3.sentence-1)

namespace std {template<class T, class Allocator = allocator<T>>class deque {public:// typesusing 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]](container.requirements "23.2 Requirements")using difference_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; // [[deque.cons]](#cons "23.3.5.2 Constructors, copy, and assignment"), construct/copy/destroyconstexpr deque() : deque(Allocator()) { }constexpr explicit deque(const Allocator&); constexpr explicit deque(size_type n, const Allocator& = Allocator()); constexpr deque(size_type n, const T& value, const Allocator& = Allocator()); template<class InputIterator>constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator()); constexpr deque(const deque& x); constexpr deque(deque&&); constexpr deque(const deque&, const type_identity_t<Allocator>&); constexpr deque(deque&&, const type_identity_t<Allocator>&); constexpr deque(initializer_list<T>, const Allocator& = Allocator()); constexpr ~deque(); constexpr deque& operator=(const deque& x); constexpr deque& operator=(deque&& x)noexcept(allocator_traits<Allocator>::is_always_equal::value); constexpr deque& operator=(initializer_list<T>); template<class InputIterator>constexpr void assign(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>constexpr void assign_range(R&& rg); constexpr void assign(size_type n, const T& t); constexpr void assign(initializer_list<T>); constexpr allocator_type get_allocator() const noexcept; // iteratorsconstexpr 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; // [[deque.capacity]](#capacity "23.3.5.3 Capacity"), capacityconstexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; constexpr void resize(size_type sz); constexpr void resize(size_type sz, const T& c); constexpr void shrink_to_fit(); // element accessconstexpr 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; // [[deque.modifiers]](#modifiers "23.3.5.4 Modifiers"), modifierstemplate<class... Args> constexpr reference emplace_front(Args&&... args); template<class... Args> constexpr reference emplace_back(Args&&... args); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); constexpr void push_front(const T& x); constexpr void push_front(T&& x); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>constexpr void prepend_range(R&& rg); constexpr void push_back(const T& x); constexpr void push_back(T&& x); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>constexpr void append_range(R&& rg); constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator>constexpr iterator insert(const_iterator position,
 InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<T>); constexpr void pop_front(); constexpr void pop_back(); constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(deque&)noexcept(allocator_traits<Allocator>::is_always_equal::value); constexpr void clear() noexcept; }; template<class InputIterator, class Allocator = allocator<*iter-value-type*<InputIterator>>> deque(InputIterator, InputIterator, Allocator = Allocator())-> deque<*iter-value-type*<InputIterator>, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Allocator = allocator<ranges::range_value_t<R>>> deque(from_range_t, R&&, Allocator = Allocator())-> deque<ranges::range_value_t<R>, Allocator>;}

#### [23.3.5.2](#cons) Constructors, copy, and assignment [[deque.cons]](deque.cons)

[ð](#lib:deque,constructor)

`constexpr explicit deque(const Allocator&);
`

[1](#cons-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6624)

*Effects*: Constructs an emptydeque,
using the specified allocator[.](#cons-1.sentence-1)

[2](#cons-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6630)

*Complexity*: Constant[.](#cons-2.sentence-1)

[ð](#lib:deque,constructor_)

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

[3](#cons-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6641)

*Preconditions*: T is *Cpp17DefaultInsertable* into deque[.](#cons-3.sentence-1)

[4](#cons-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6645)

*Effects*: Constructs a deque withn default-inserted elements using the specified allocator[.](#cons-4.sentence-1)

[5](#cons-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6650)

*Complexity*: Linear in n[.](#cons-5.sentence-1)

[ð](#lib:deque,constructor__)

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

[6](#cons-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6661)

*Preconditions*: T is *Cpp17CopyInsertable* into deque[.](#cons-6.sentence-1)

[7](#cons-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6665)

*Effects*: Constructs adeque with n copies of value,
using the specified allocator[.](#cons-7.sentence-1)

[8](#cons-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6672)

*Complexity*: Linear in n[.](#cons-8.sentence-1)

[ð](#lib:deque,constructor___)

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

[9](#cons-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6684)

*Effects*: Constructs adeque equal to the range
[first, last),
using the specified allocator[.](#cons-9.sentence-1)

[10](#cons-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6692)

*Complexity*: Linear in distance(first, last)[.](#cons-10.sentence-1)

[ð](#lib:deque,constructor____)

`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>
  constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator());
`

[11](#cons-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6704)

*Effects*: Constructs a deque with the elements of the range rg,
using the specified allocator[.](#cons-11.sentence-1)

[12](#cons-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6709)

*Complexity*: Linear in ranges​::​distance(rg)[.](#cons-12.sentence-1)

#### [23.3.5.3](#capacity) Capacity [[deque.capacity]](deque.capacity)

[ð](#lib:resize,deque)

`constexpr void resize(size_type sz);
`

[1](#capacity-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6722)

*Preconditions*: T is *Cpp17MoveInsertable* and *Cpp17DefaultInsertable* into deque[.](#capacity-1.sentence-1)

[2](#capacity-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6726)

*Effects*: If sz < size(), erases the last size() - sz elements
from the sequence[.](#capacity-2.sentence-1)

Otherwise,
appends sz - size() default-inserted elements to the sequence[.](#capacity-2.sentence-2)

[ð](#lib:resize,deque_)

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

[3](#capacity-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6739)

*Preconditions*: T is *Cpp17CopyInsertable* into deque[.](#capacity-3.sentence-1)

[4](#capacity-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6743)

*Effects*: If sz < size(), erases the last size() - sz elements
from the sequence[.](#capacity-4.sentence-1)

Otherwise,
appends sz - size() copies of c to the sequence[.](#capacity-4.sentence-2)

[ð](#lib:shrink_to_fit,deque)

`constexpr void shrink_to_fit();
`

[5](#capacity-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6756)

*Preconditions*: T is *Cpp17MoveInsertable* into deque[.](#capacity-5.sentence-1)

[6](#capacity-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6760)

*Effects*: shrink_to_fit is a non-binding request to reduce memory use
but does not change the size of the sequence[.](#capacity-6.sentence-1)

[*Note [1](#capacity-note-1)*:

The request is non-binding to allow latitude for
implementation-specific optimizations[.](#capacity-6.sentence-2)

â *end note*]

If the size is equal to the old capacity, or
if an exception is thrown other than by the move constructor
of a non-*Cpp17CopyInsertable* T,
then there are no effects[.](#capacity-6.sentence-3)

[7](#capacity-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6773)

*Complexity*: If the size is not equal to the old capacity,
linear in the size of the sequence;
otherwise constant[.](#capacity-7.sentence-1)

[8](#capacity-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6779)

*Remarks*: If the size is not equal to the old capacity,
then invalidates all the references, pointers, and iterators
referring to the elements in the sequence,
as well as the past-the-end iterator[.](#capacity-8.sentence-1)

#### [23.3.5.4](#modifiers) Modifiers [[deque.modifiers]](deque.modifiers)

[ð](#lib:insert,deque)

`constexpr iterator insert(const_iterator position, const T& x);
constexpr iterator insert(const_iterator position, T&& x);
constexpr iterator insert(const_iterator position, size_type n, const T& x);
template<class InputIterator>
  constexpr iterator insert(const_iterator position,
                            InputIterator first, InputIterator last);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>
  constexpr iterator insert_range(const_iterator position, R&& rg);
constexpr iterator insert(const_iterator position, initializer_list<T>);

template<class... Args> constexpr reference emplace_front(Args&&... args);
template<class... Args> constexpr reference emplace_back(Args&&... args);
template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
constexpr void push_front(const T& x);
constexpr void push_front(T&& x);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>
  constexpr void prepend_range(R&& rg);
constexpr void push_back(const T& x);
constexpr void push_back(T&& x);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<T> R>
  constexpr void append_range(R&& rg);
`

[1](#modifiers-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6818)

*Effects*: An insertion in the middle of the deque invalidates all the iterators and
references to elements of the deque[.](#modifiers-1.sentence-1)

An insertion at either end of the
deque invalidates all the iterators to the deque, but has no effect on
the validity of references to elements of the deque[.](#modifiers-1.sentence-2)

[2](#modifiers-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6826)

*Complexity*: The complexity is linear in the number of elements inserted plus the lesser
of the distances to the beginning and end of the deque[.](#modifiers-2.sentence-1)

Inserting a single element at either the beginning or end of a deque always takes constant time
and causes a single call to a constructor ofT[.](#modifiers-2.sentence-2)

[3](#modifiers-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6834)

*Remarks*: If an exception is thrown other than by the
copy constructor, move constructor,
assignment operator, or move assignment operator ofT,
there are no effects[.](#modifiers-3.sentence-1)

If an exception is thrown while inserting a single element at either end,
there are no effects[.](#modifiers-3.sentence-2)

Otherwise, if an exception is thrown by the move constructor of a
non-*Cpp17CopyInsertable*T, the effects are unspecified[.](#modifiers-3.sentence-3)

[ð](#lib:erase,deque)

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

[4](#modifiers-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6857)

*Effects*: An erase operation that erases the last element of a deque invalidates only the past-the-end iterator
and all iterators and references to the erased elements[.](#modifiers-4.sentence-1)

An erase operation that erases the first
element of a deque but not the last element invalidates only iterators
and references to the erased elements[.](#modifiers-4.sentence-2)

An erase operation
that erases neither the first element nor the last element of a deque invalidates the past-the-end
iterator and all iterators and references to all the elements of the deque[.](#modifiers-4.sentence-3)

[*Note [1](#modifiers-note-1)*:

pop_front and pop_back are erase operations[.](#modifiers-4.sentence-4)

â *end note*]

[5](#modifiers-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6869)

*Throws*: Nothing unless an exception is thrown by the assignment operator ofT[.](#modifiers-5.sentence-1)

[6](#modifiers-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6874)

*Complexity*: The number of calls to the destructor of T is the same as the
number of elements erased, but the number of calls to the assignment operator of T is
no more than the lesser of the number of elements before the erased elements and the number of elements after the erased elements[.](#modifiers-6.sentence-1)

#### [23.3.5.5](#erasure) Erasure [[deque.erasure]](deque.erasure)

[ð](#lib:erase,deque_)

`template<class T, class Allocator, class U = T>
  constexpr typename deque<T, Allocator>::size_type
    erase(deque<T, Allocator>& c, const U& value);
`

[1](#erasure-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6891)

*Effects*: Equivalent to:auto it = remove(c.begin(), c.end(), value);auto r = distance(it, c.end());
c.erase(it, c.end());return r;

[ð](#lib:erase_if,deque)

`template<class T, class Allocator, class Predicate>
  constexpr typename deque<T, Allocator>::size_type
    erase_if(deque<T, Allocator>& c, Predicate pred);
`

[2](#erasure-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L6910)

*Effects*: Equivalent to:auto it = remove_if(c.begin(), c.end(), pred);auto r = distance(it, c.end());
c.erase(it, c.end());return r;
