xref: /freebsd/contrib/llvm-project/libcxx/include/deque (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_DEQUE
110b57cec5SDimitry Andric#define _LIBCPP_DEQUE
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    deque synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andrictemplate <class T, class Allocator = allocator<T> >
200b57cec5SDimitry Andricclass deque
210b57cec5SDimitry Andric{
220b57cec5SDimitry Andricpublic:
230b57cec5SDimitry Andric    // types:
240b57cec5SDimitry Andric    typedef T value_type;
250b57cec5SDimitry Andric    typedef Allocator allocator_type;
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric    typedef typename allocator_type::reference       reference;
280b57cec5SDimitry Andric    typedef typename allocator_type::const_reference const_reference;
290b57cec5SDimitry Andric    typedef implementation-defined                   iterator;
300b57cec5SDimitry Andric    typedef implementation-defined                   const_iterator;
310b57cec5SDimitry Andric    typedef typename allocator_type::size_type       size_type;
320b57cec5SDimitry Andric    typedef typename allocator_type::difference_type difference_type;
330b57cec5SDimitry Andric
340b57cec5SDimitry Andric    typedef typename allocator_type::pointer         pointer;
350b57cec5SDimitry Andric    typedef typename allocator_type::const_pointer   const_pointer;
360b57cec5SDimitry Andric    typedef std::reverse_iterator<iterator>          reverse_iterator;
370b57cec5SDimitry Andric    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric    // construct/copy/destroy:
400b57cec5SDimitry Andric    deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);
410b57cec5SDimitry Andric    explicit deque(const allocator_type& a);
420b57cec5SDimitry Andric    explicit deque(size_type n);
430b57cec5SDimitry Andric    explicit deque(size_type n, const allocator_type& a); // C++14
440b57cec5SDimitry Andric    deque(size_type n, const value_type& v);
450b57cec5SDimitry Andric    deque(size_type n, const value_type& v, const allocator_type& a);
460b57cec5SDimitry Andric    template <class InputIterator>
470b57cec5SDimitry Andric        deque(InputIterator f, InputIterator l);
480b57cec5SDimitry Andric    template <class InputIterator>
490b57cec5SDimitry Andric        deque(InputIterator f, InputIterator l, const allocator_type& a);
500b57cec5SDimitry Andric    deque(const deque& c);
510b57cec5SDimitry Andric    deque(deque&& c)
520b57cec5SDimitry Andric        noexcept(is_nothrow_move_constructible<allocator_type>::value);
530b57cec5SDimitry Andric    deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
540b57cec5SDimitry Andric    deque(const deque& c, const allocator_type& a);
550b57cec5SDimitry Andric    deque(deque&& c, const allocator_type& a);
560b57cec5SDimitry Andric    ~deque();
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric    deque& operator=(const deque& c);
590b57cec5SDimitry Andric    deque& operator=(deque&& c)
600b57cec5SDimitry Andric        noexcept(
610b57cec5SDimitry Andric             allocator_type::propagate_on_container_move_assignment::value &&
620b57cec5SDimitry Andric             is_nothrow_move_assignable<allocator_type>::value);
630b57cec5SDimitry Andric    deque& operator=(initializer_list<value_type> il);
640b57cec5SDimitry Andric
650b57cec5SDimitry Andric    template <class InputIterator>
660b57cec5SDimitry Andric        void assign(InputIterator f, InputIterator l);
670b57cec5SDimitry Andric    void assign(size_type n, const value_type& v);
680b57cec5SDimitry Andric    void assign(initializer_list<value_type> il);
690b57cec5SDimitry Andric
700b57cec5SDimitry Andric    allocator_type get_allocator() const noexcept;
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric    // iterators:
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric    iterator       begin() noexcept;
750b57cec5SDimitry Andric    const_iterator begin() const noexcept;
760b57cec5SDimitry Andric    iterator       end() noexcept;
770b57cec5SDimitry Andric    const_iterator end() const noexcept;
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric    reverse_iterator       rbegin() noexcept;
800b57cec5SDimitry Andric    const_reverse_iterator rbegin() const noexcept;
810b57cec5SDimitry Andric    reverse_iterator       rend() noexcept;
820b57cec5SDimitry Andric    const_reverse_iterator rend() const noexcept;
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric    const_iterator         cbegin() const noexcept;
850b57cec5SDimitry Andric    const_iterator         cend() const noexcept;
860b57cec5SDimitry Andric    const_reverse_iterator crbegin() const noexcept;
870b57cec5SDimitry Andric    const_reverse_iterator crend() const noexcept;
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric    // capacity:
900b57cec5SDimitry Andric    size_type size() const noexcept;
910b57cec5SDimitry Andric    size_type max_size() const noexcept;
920b57cec5SDimitry Andric    void resize(size_type n);
930b57cec5SDimitry Andric    void resize(size_type n, const value_type& v);
940b57cec5SDimitry Andric    void shrink_to_fit();
950b57cec5SDimitry Andric    bool empty() const noexcept;
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric    // element access:
980b57cec5SDimitry Andric    reference operator[](size_type i);
990b57cec5SDimitry Andric    const_reference operator[](size_type i) const;
1000b57cec5SDimitry Andric    reference at(size_type i);
1010b57cec5SDimitry Andric    const_reference at(size_type i) const;
1020b57cec5SDimitry Andric    reference front();
1030b57cec5SDimitry Andric    const_reference front() const;
1040b57cec5SDimitry Andric    reference back();
1050b57cec5SDimitry Andric    const_reference back() const;
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric    // modifiers:
1080b57cec5SDimitry Andric    void push_front(const value_type& v);
1090b57cec5SDimitry Andric    void push_front(value_type&& v);
1100b57cec5SDimitry Andric    void push_back(const value_type& v);
1110b57cec5SDimitry Andric    void push_back(value_type&& v);
1120b57cec5SDimitry Andric    template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
1130b57cec5SDimitry Andric    template <class... Args> reference emplace_back(Args&&... args);   // reference in C++17
1140b57cec5SDimitry Andric    template <class... Args> iterator emplace(const_iterator p, Args&&... args);
1150b57cec5SDimitry Andric    iterator insert(const_iterator p, const value_type& v);
1160b57cec5SDimitry Andric    iterator insert(const_iterator p, value_type&& v);
1170b57cec5SDimitry Andric    iterator insert(const_iterator p, size_type n, const value_type& v);
1180b57cec5SDimitry Andric    template <class InputIterator>
1190b57cec5SDimitry Andric        iterator insert(const_iterator p, InputIterator f, InputIterator l);
1200b57cec5SDimitry Andric    iterator insert(const_iterator p, initializer_list<value_type> il);
1210b57cec5SDimitry Andric    void pop_front();
1220b57cec5SDimitry Andric    void pop_back();
1230b57cec5SDimitry Andric    iterator erase(const_iterator p);
1240b57cec5SDimitry Andric    iterator erase(const_iterator f, const_iterator l);
1250b57cec5SDimitry Andric    void swap(deque& c)
1260b57cec5SDimitry Andric        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
1270b57cec5SDimitry Andric    void clear() noexcept;
1280b57cec5SDimitry Andric};
1290b57cec5SDimitry Andric
1300b57cec5SDimitry Andrictemplate <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
1310b57cec5SDimitry Andric   deque(InputIterator, InputIterator, Allocator = Allocator())
132349cc55cSDimitry Andric   -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andrictemplate <class T, class Allocator>
1350b57cec5SDimitry Andric    bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1360b57cec5SDimitry Andrictemplate <class T, class Allocator>
1370b57cec5SDimitry Andric    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1380b57cec5SDimitry Andrictemplate <class T, class Allocator>
1390b57cec5SDimitry Andric    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1400b57cec5SDimitry Andrictemplate <class T, class Allocator>
1410b57cec5SDimitry Andric    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1420b57cec5SDimitry Andrictemplate <class T, class Allocator>
1430b57cec5SDimitry Andric    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1440b57cec5SDimitry Andrictemplate <class T, class Allocator>
1450b57cec5SDimitry Andric    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andric// specialized algorithms:
1480b57cec5SDimitry Andrictemplate <class T, class Allocator>
1490b57cec5SDimitry Andric    void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
1500b57cec5SDimitry Andric         noexcept(noexcept(x.swap(y)));
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andrictemplate <class T, class Allocator, class U>
1535ffd83dbSDimitry Andric    typename deque<T, Allocator>::size_type
1545ffd83dbSDimitry Andric    erase(deque<T, Allocator>& c, const U& value);       // C++20
1550b57cec5SDimitry Andrictemplate <class T, class Allocator, class Predicate>
1565ffd83dbSDimitry Andric    typename deque<T, Allocator>::size_type
1575ffd83dbSDimitry Andric    erase_if(deque<T, Allocator>& c, Predicate pred);    // C++20
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric}  // std
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric*/
1620b57cec5SDimitry Andric
16381ad6265SDimitry Andric#include <__algorithm/copy.h>
16481ad6265SDimitry Andric#include <__algorithm/copy_backward.h>
16581ad6265SDimitry Andric#include <__algorithm/equal.h>
16681ad6265SDimitry Andric#include <__algorithm/fill_n.h>
16781ad6265SDimitry Andric#include <__algorithm/lexicographical_compare.h>
16881ad6265SDimitry Andric#include <__algorithm/min.h>
16981ad6265SDimitry Andric#include <__algorithm/remove.h>
17081ad6265SDimitry Andric#include <__algorithm/remove_if.h>
17181ad6265SDimitry Andric#include <__algorithm/unwrap_iter.h>
17281ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
1730b57cec5SDimitry Andric#include <__config>
17481ad6265SDimitry Andric#include <__format/enable_insertable.h>
175349cc55cSDimitry Andric#include <__iterator/iterator_traits.h>
17681ad6265SDimitry Andric#include <__iterator/next.h>
17781ad6265SDimitry Andric#include <__iterator/prev.h>
17881ad6265SDimitry Andric#include <__iterator/reverse_iterator.h>
179*bdd1243dSDimitry Andric#include <__iterator/segmented_iterator.h>
180*bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h>
181*bdd1243dSDimitry Andric#include <__memory/pointer_traits.h>
182*bdd1243dSDimitry Andric#include <__memory/temp_value.h>
183*bdd1243dSDimitry Andric#include <__memory/unique_ptr.h>
184*bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h>
1850b57cec5SDimitry Andric#include <__split_buffer>
186*bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h>
187fe6060f1SDimitry Andric#include <__utility/forward.h>
18881ad6265SDimitry Andric#include <__utility/move.h>
18981ad6265SDimitry Andric#include <__utility/swap.h>
190fe6060f1SDimitry Andric#include <limits>
1910b57cec5SDimitry Andric#include <stdexcept>
192fe6060f1SDimitry Andric#include <type_traits>
1930b57cec5SDimitry Andric#include <version>
1940b57cec5SDimitry Andric
19581ad6265SDimitry Andric// standard-mandated includes
19681ad6265SDimitry Andric
19781ad6265SDimitry Andric// [iterator.range]
19881ad6265SDimitry Andric#include <__iterator/access.h>
19981ad6265SDimitry Andric#include <__iterator/data.h>
20081ad6265SDimitry Andric#include <__iterator/empty.h>
20181ad6265SDimitry Andric#include <__iterator/reverse_access.h>
20281ad6265SDimitry Andric#include <__iterator/size.h>
20381ad6265SDimitry Andric
20481ad6265SDimitry Andric// [deque.syn]
20581ad6265SDimitry Andric#include <compare>
20681ad6265SDimitry Andric#include <initializer_list>
20781ad6265SDimitry Andric
2080b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2090b57cec5SDimitry Andric#  pragma GCC system_header
2100b57cec5SDimitry Andric#endif
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
2130b57cec5SDimitry Andric#include <__undef_macros>
2140b57cec5SDimitry Andric
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andrictemplate <class _ValueType, class _DiffType>
2210b57cec5SDimitry Andricstruct __deque_block_size {
2220b57cec5SDimitry Andric  static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
2230b57cec5SDimitry Andric};
2240b57cec5SDimitry Andric
2250b57cec5SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
2260b57cec5SDimitry Andric          class _DiffType, _DiffType _BS =
2270b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
2280b57cec5SDimitry Andric// Keep template parameter to avoid changing all template declarations thoughout
2290b57cec5SDimitry Andric// this file.
2300b57cec5SDimitry Andric                               0
2310b57cec5SDimitry Andric#else
2320b57cec5SDimitry Andric                               __deque_block_size<_ValueType, _DiffType>::value
2330b57cec5SDimitry Andric#endif
2340b57cec5SDimitry Andric          >
2350b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __deque_iterator
2360b57cec5SDimitry Andric{
2370b57cec5SDimitry Andric    typedef _MapPointer __map_iterator;
2380b57cec5SDimitry Andricpublic:
2390b57cec5SDimitry Andric    typedef _Pointer  pointer;
2400b57cec5SDimitry Andric    typedef _DiffType difference_type;
2410b57cec5SDimitry Andricprivate:
2420b57cec5SDimitry Andric    __map_iterator __m_iter_;
2430b57cec5SDimitry Andric    pointer        __ptr_;
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric    static const difference_type __block_size;
2460b57cec5SDimitry Andricpublic:
2470b57cec5SDimitry Andric    typedef _ValueType                  value_type;
2480b57cec5SDimitry Andric    typedef random_access_iterator_tag  iterator_category;
2490b57cec5SDimitry Andric    typedef _Reference                  reference;
2500b57cec5SDimitry Andric
251*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT
2520b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
2530b57cec5SDimitry Andric     : __m_iter_(nullptr), __ptr_(nullptr)
2540b57cec5SDimitry Andric#endif
2550b57cec5SDimitry Andric     {}
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric    template <class _Pp, class _Rp, class _MP>
258*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2590b57cec5SDimitry Andric    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
2600b57cec5SDimitry Andric                typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
2610b57cec5SDimitry Andric        : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
2620b57cec5SDimitry Andric
263*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI reference operator*() const {return *__ptr_;}
264*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI pointer operator->() const {return __ptr_;}
2650b57cec5SDimitry Andric
266*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++()
2670b57cec5SDimitry Andric    {
2680b57cec5SDimitry Andric        if (++__ptr_ - *__m_iter_ == __block_size)
2690b57cec5SDimitry Andric        {
2700b57cec5SDimitry Andric            ++__m_iter_;
2710b57cec5SDimitry Andric            __ptr_ = *__m_iter_;
2720b57cec5SDimitry Andric        }
2730b57cec5SDimitry Andric        return *this;
2740b57cec5SDimitry Andric    }
2750b57cec5SDimitry Andric
276*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int)
2770b57cec5SDimitry Andric    {
2780b57cec5SDimitry Andric        __deque_iterator __tmp = *this;
2790b57cec5SDimitry Andric        ++(*this);
2800b57cec5SDimitry Andric        return __tmp;
2810b57cec5SDimitry Andric    }
2820b57cec5SDimitry Andric
283*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--()
2840b57cec5SDimitry Andric    {
2850b57cec5SDimitry Andric        if (__ptr_ == *__m_iter_)
2860b57cec5SDimitry Andric        {
2870b57cec5SDimitry Andric            --__m_iter_;
2880b57cec5SDimitry Andric            __ptr_ = *__m_iter_ + __block_size;
2890b57cec5SDimitry Andric        }
2900b57cec5SDimitry Andric        --__ptr_;
2910b57cec5SDimitry Andric        return *this;
2920b57cec5SDimitry Andric    }
2930b57cec5SDimitry Andric
294*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int)
2950b57cec5SDimitry Andric    {
2960b57cec5SDimitry Andric        __deque_iterator __tmp = *this;
2970b57cec5SDimitry Andric        --(*this);
2980b57cec5SDimitry Andric        return __tmp;
2990b57cec5SDimitry Andric    }
3000b57cec5SDimitry Andric
301*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n)
3020b57cec5SDimitry Andric    {
3030b57cec5SDimitry Andric        if (__n != 0)
3040b57cec5SDimitry Andric        {
3050b57cec5SDimitry Andric            __n += __ptr_ - *__m_iter_;
3060b57cec5SDimitry Andric            if (__n > 0)
3070b57cec5SDimitry Andric            {
3080b57cec5SDimitry Andric                __m_iter_ += __n / __block_size;
3090b57cec5SDimitry Andric                __ptr_ = *__m_iter_ + __n % __block_size;
3100b57cec5SDimitry Andric            }
3110b57cec5SDimitry Andric            else // (__n < 0)
3120b57cec5SDimitry Andric            {
3130b57cec5SDimitry Andric                difference_type __z = __block_size - 1 - __n;
3140b57cec5SDimitry Andric                __m_iter_ -= __z / __block_size;
3150b57cec5SDimitry Andric                __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
3160b57cec5SDimitry Andric            }
3170b57cec5SDimitry Andric        }
3180b57cec5SDimitry Andric        return *this;
3190b57cec5SDimitry Andric    }
3200b57cec5SDimitry Andric
321*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n)
3220b57cec5SDimitry Andric    {
3230b57cec5SDimitry Andric        return *this += -__n;
3240b57cec5SDimitry Andric    }
3250b57cec5SDimitry Andric
326*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const
3270b57cec5SDimitry Andric    {
3280b57cec5SDimitry Andric        __deque_iterator __t(*this);
3290b57cec5SDimitry Andric        __t += __n;
3300b57cec5SDimitry Andric        return __t;
3310b57cec5SDimitry Andric    }
3320b57cec5SDimitry Andric
333*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const
3340b57cec5SDimitry Andric    {
3350b57cec5SDimitry Andric        __deque_iterator __t(*this);
3360b57cec5SDimitry Andric        __t -= __n;
3370b57cec5SDimitry Andric        return __t;
3380b57cec5SDimitry Andric    }
3390b57cec5SDimitry Andric
340*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3410b57cec5SDimitry Andric    friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
3420b57cec5SDimitry Andric        {return __it + __n;}
3430b57cec5SDimitry Andric
344*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3450b57cec5SDimitry Andric    friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
3460b57cec5SDimitry Andric    {
3470b57cec5SDimitry Andric        if (__x != __y)
3480b57cec5SDimitry Andric            return (__x.__m_iter_ - __y.__m_iter_) * __block_size
3490b57cec5SDimitry Andric                 + (__x.__ptr_ - *__x.__m_iter_)
3500b57cec5SDimitry Andric                 - (__y.__ptr_ - *__y.__m_iter_);
3510b57cec5SDimitry Andric        return 0;
3520b57cec5SDimitry Andric    }
3530b57cec5SDimitry Andric
354*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const
3550b57cec5SDimitry Andric        {return *(*this + __n);}
3560b57cec5SDimitry Andric
357*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3580b57cec5SDimitry Andric        bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
3590b57cec5SDimitry Andric        {return __x.__ptr_ == __y.__ptr_;}
3600b57cec5SDimitry Andric
361*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3620b57cec5SDimitry Andric        bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
3630b57cec5SDimitry Andric        {return !(__x == __y);}
3640b57cec5SDimitry Andric
365*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3660b57cec5SDimitry Andric        bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
3670b57cec5SDimitry Andric        {return __x.__m_iter_ < __y.__m_iter_ ||
3680b57cec5SDimitry Andric               (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
3690b57cec5SDimitry Andric
370*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3710b57cec5SDimitry Andric        bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
3720b57cec5SDimitry Andric        {return __y < __x;}
3730b57cec5SDimitry Andric
374*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3750b57cec5SDimitry Andric        bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
3760b57cec5SDimitry Andric        {return !(__y < __x);}
3770b57cec5SDimitry Andric
378*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3790b57cec5SDimitry Andric        bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
3800b57cec5SDimitry Andric        {return !(__x < __y);}
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andricprivate:
383*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
3840b57cec5SDimitry Andric        : __m_iter_(__m), __ptr_(__p) {}
3850b57cec5SDimitry Andric
3860b57cec5SDimitry Andric    template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque;
3870b57cec5SDimitry Andric    template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
3880b57cec5SDimitry Andric        friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
3890b57cec5SDimitry Andric
390*bdd1243dSDimitry Andric    template <class>
391*bdd1243dSDimitry Andric    friend struct __segmented_iterator_traits;
392*bdd1243dSDimitry Andric};
3930b57cec5SDimitry Andric
394*bdd1243dSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize>
395*bdd1243dSDimitry Andricstruct __segmented_iterator_traits<
396*bdd1243dSDimitry Andric    __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > {
397*bdd1243dSDimitry Andricprivate:
398*bdd1243dSDimitry Andric  using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>;
3990b57cec5SDimitry Andric
400*bdd1243dSDimitry Andricpublic:
401*bdd1243dSDimitry Andric  using __is_segmented_iterator = true_type;
402*bdd1243dSDimitry Andric  using __segment_iterator = _MapPointer;
403*bdd1243dSDimitry Andric  using __local_iterator = _Pointer;
4040b57cec5SDimitry Andric
405*bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; }
406*bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; }
407*bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; }
4080b57cec5SDimitry Andric
409*bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
410*bdd1243dSDimitry Andric        return *__iter + _Iterator::__block_size;
411*bdd1243dSDimitry Andric  }
4120b57cec5SDimitry Andric
413*bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) {
414*bdd1243dSDimitry Andric        if (__local == __end(__segment)) {
415*bdd1243dSDimitry Andric            ++__segment;
416*bdd1243dSDimitry Andric            return _Iterator(__segment, *__segment);
417*bdd1243dSDimitry Andric        }
418*bdd1243dSDimitry Andric        return _Iterator(__segment, __local);
419*bdd1243dSDimitry Andric  }
4200b57cec5SDimitry Andric};
4210b57cec5SDimitry Andric
4220b57cec5SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
4230b57cec5SDimitry Andric          class _DiffType, _DiffType _BlockSize>
4240b57cec5SDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
4250b57cec5SDimitry Andric                                 _DiffType, _BlockSize>::__block_size =
4260b57cec5SDimitry Andric    __deque_block_size<_ValueType, _DiffType>::value;
4270b57cec5SDimitry Andric
428*bdd1243dSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/>
429*bdd1243dSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque
4300b57cec5SDimitry Andric{
4310b57cec5SDimitry Andricpublic:
432*bdd1243dSDimitry Andric    // types:
433e40139ffSDimitry Andric
434*bdd1243dSDimitry Andric  using value_type = _Tp;
4350b57cec5SDimitry Andric
436*bdd1243dSDimitry Andric  static_assert((is_same<typename _Allocator::value_type, value_type>::value),
437*bdd1243dSDimitry Andric                "Allocator::value_type must be same type as value_type");
4380b57cec5SDimitry Andric
439*bdd1243dSDimitry Andric  using allocator_type = _Allocator;
440*bdd1243dSDimitry Andric  using __alloc_traits = allocator_traits<allocator_type>;
4410b57cec5SDimitry Andric
442*bdd1243dSDimitry Andric  using size_type       = typename __alloc_traits::size_type;
443*bdd1243dSDimitry Andric  using difference_type = typename __alloc_traits::difference_type;
4440b57cec5SDimitry Andric
445*bdd1243dSDimitry Andric  using pointer       = typename __alloc_traits::pointer;
446*bdd1243dSDimitry Andric  using const_pointer = typename __alloc_traits::const_pointer;
447*bdd1243dSDimitry Andric
448*bdd1243dSDimitry Andric  using __pointer_allocator       = __rebind_alloc<__alloc_traits, pointer>;
449*bdd1243dSDimitry Andric  using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>;
450*bdd1243dSDimitry Andric  using __map                     = __split_buffer<pointer, __pointer_allocator>;
451*bdd1243dSDimitry Andric  using __map_alloc_traits        = allocator_traits<__pointer_allocator>;
452*bdd1243dSDimitry Andric  using __map_pointer             = typename __map_alloc_traits::pointer;
453*bdd1243dSDimitry Andric  using __map_const_pointer       = typename allocator_traits<__const_pointer_allocator>::const_pointer;
454*bdd1243dSDimitry Andric
455*bdd1243dSDimitry Andric  using reference       = value_type&;
456*bdd1243dSDimitry Andric  using const_reference = const value_type&;
457*bdd1243dSDimitry Andric
458*bdd1243dSDimitry Andric  using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>;
459*bdd1243dSDimitry Andric  using const_iterator =
460*bdd1243dSDimitry Andric      __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>;
461*bdd1243dSDimitry Andric  using reverse_iterator       = std::reverse_iterator<iterator>;
462*bdd1243dSDimitry Andric  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
463*bdd1243dSDimitry Andric
464*bdd1243dSDimitry Andric  static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
465*bdd1243dSDimitry Andric                "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
466*bdd1243dSDimitry Andric                "original allocator");
467*bdd1243dSDimitry Andric  static_assert(is_nothrow_default_constructible<allocator_type>::value ==
468*bdd1243dSDimitry Andric                    is_nothrow_default_constructible<__pointer_allocator>::value,
469*bdd1243dSDimitry Andric                "rebinding an allocator should not change excpetion guarantees");
470*bdd1243dSDimitry Andric  static_assert(is_nothrow_move_constructible<allocator_type>::value ==
471*bdd1243dSDimitry Andric                    is_nothrow_move_constructible<typename __map::allocator_type>::value,
472*bdd1243dSDimitry Andric                "rebinding an allocator should not change excpetion guarantees");
473*bdd1243dSDimitry Andric
474*bdd1243dSDimitry Andricprivate:
475e40139ffSDimitry Andric  struct __deque_block_range {
476*bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI
477*bdd1243dSDimitry Andric    __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {}
478e40139ffSDimitry Andric    const pointer __begin_;
479e40139ffSDimitry Andric    const pointer __end_;
480e40139ffSDimitry Andric  };
481e40139ffSDimitry Andric
482e40139ffSDimitry Andric  struct __deque_range {
483e40139ffSDimitry Andric    iterator __pos_;
484e40139ffSDimitry Andric    const iterator __end_;
485e40139ffSDimitry Andric
486*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT
487e40139ffSDimitry Andric      : __pos_(__pos), __end_(__e) {}
488e40139ffSDimitry Andric
489*bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT {
490e40139ffSDimitry Andric      return __pos_ != __end_;
491e40139ffSDimitry Andric    }
492e40139ffSDimitry Andric
493*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range begin() const {
494e40139ffSDimitry Andric      return *this;
495e40139ffSDimitry Andric    }
496e40139ffSDimitry Andric
497*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range end() const {
498e40139ffSDimitry Andric      return __deque_range(__end_, __end_);
499e40139ffSDimitry Andric    }
500*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT {
501e40139ffSDimitry Andric        if (__pos_.__m_iter_ == __end_.__m_iter_) {
502e40139ffSDimitry Andric        return __deque_block_range(__pos_.__ptr_, __end_.__ptr_);
503e40139ffSDimitry Andric      }
504e40139ffSDimitry Andric      return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size);
505e40139ffSDimitry Andric    }
506e40139ffSDimitry Andric
507*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT {
508e40139ffSDimitry Andric      if (__pos_.__m_iter_ == __end_.__m_iter_) {
509e40139ffSDimitry Andric        __pos_ = __end_;
510e40139ffSDimitry Andric      } else {
511e40139ffSDimitry Andric        ++__pos_.__m_iter_;
512e40139ffSDimitry Andric        __pos_.__ptr_ = *__pos_.__m_iter_;
513e40139ffSDimitry Andric      }
514e40139ffSDimitry Andric      return *this;
515e40139ffSDimitry Andric    }
516e40139ffSDimitry Andric
517e40139ffSDimitry Andric
518*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) {
519e40139ffSDimitry Andric      return __lhs.__pos_ == __rhs.__pos_;
520e40139ffSDimitry Andric    }
521*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) {
522e40139ffSDimitry Andric      return !(__lhs == __rhs);
523e40139ffSDimitry Andric    }
524e40139ffSDimitry Andric  };
525e40139ffSDimitry Andric
526e40139ffSDimitry Andric  struct _ConstructTransaction {
527*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r)
528e40139ffSDimitry Andric      : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {}
529e40139ffSDimitry Andric
530e40139ffSDimitry Andric
531*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
532*bdd1243dSDimitry Andric      __base_->__size() += (__pos_ - __begin_);
533e40139ffSDimitry Andric    }
534e40139ffSDimitry Andric
535e40139ffSDimitry Andric    pointer __pos_;
536e40139ffSDimitry Andric    const pointer __end_;
537e40139ffSDimitry Andric  private:
538e40139ffSDimitry Andric    const pointer __begin_;
539*bdd1243dSDimitry Andric    deque* const __base_;
540e40139ffSDimitry Andric  };
541e40139ffSDimitry Andric
542*bdd1243dSDimitry Andric  static const difference_type __block_size;
543*bdd1243dSDimitry Andric
5440b57cec5SDimitry Andric  __map __map_;
5450b57cec5SDimitry Andric  size_type __start_;
5460b57cec5SDimitry Andric  __compressed_pair<size_type, allocator_type> __size_;
5470b57cec5SDimitry Andric
5480b57cec5SDimitry Andricpublic:
549*bdd1243dSDimitry Andric
550*bdd1243dSDimitry Andric    // construct/copy/destroy:
551*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
552*bdd1243dSDimitry Andric    deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
553*bdd1243dSDimitry Andric        : __start_(0), __size_(0, __default_init_tag()) {}
554*bdd1243dSDimitry Andric
555*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~deque() {
556*bdd1243dSDimitry Andric      clear();
557*bdd1243dSDimitry Andric      typename __map::iterator __i = __map_.begin();
558*bdd1243dSDimitry Andric      typename __map::iterator __e = __map_.end();
559*bdd1243dSDimitry Andric      for (; __i != __e; ++__i)
560*bdd1243dSDimitry Andric          __alloc_traits::deallocate(__alloc(), *__i, __block_size);
561*bdd1243dSDimitry Andric    }
562*bdd1243dSDimitry Andric
563*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a)
564*bdd1243dSDimitry Andric        : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
565*bdd1243dSDimitry Andric
566*bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n);
567*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER > 11
568*bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a);
569*bdd1243dSDimitry Andric#endif
570*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v);
571*bdd1243dSDimitry Andric
572*bdd1243dSDimitry Andric    template <class = __enable_if_t<__is_allocator<_Allocator>::value> >
573*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a)
574*bdd1243dSDimitry Andric        : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
575*bdd1243dSDimitry Andric    {
576*bdd1243dSDimitry Andric        if (__n > 0)
577*bdd1243dSDimitry Andric            __append(__n, __v);
578*bdd1243dSDimitry Andric    }
579*bdd1243dSDimitry Andric
580*bdd1243dSDimitry Andric    template <class _InputIter>
581*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l,
582*bdd1243dSDimitry Andric              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
583*bdd1243dSDimitry Andric    template <class _InputIter>
584*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
585*bdd1243dSDimitry Andric              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
586*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(const deque& __c);
587*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a);
588*bdd1243dSDimitry Andric
589*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c);
5900b57cec5SDimitry Andric
5910b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
592*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il);
593*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a);
594*bdd1243dSDimitry Andric
595*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
596*bdd1243dSDimitry Andric    deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
597*bdd1243dSDimitry Andric
598*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
599*bdd1243dSDimitry Andric    deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
600*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
601*bdd1243dSDimitry Andric    deque(deque&& __c, const __type_identity_t<allocator_type>& __a);
602*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
603*bdd1243dSDimitry Andric    deque& operator=(deque&& __c)
604*bdd1243dSDimitry Andric        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
605*bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value);
606*bdd1243dSDimitry Andric
607*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
608*bdd1243dSDimitry Andric    void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
6090b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
6100b57cec5SDimitry Andric
611*bdd1243dSDimitry Andric    template <class _InputIter>
612*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l,
613*bdd1243dSDimitry Andric                    typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
614*bdd1243dSDimitry Andric                                      !__is_cpp17_random_access_iterator<_InputIter>::value>::type* = 0);
615*bdd1243dSDimitry Andric    template <class _RAIter>
616*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l,
617*bdd1243dSDimitry Andric                    typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
618*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
619*bdd1243dSDimitry Andric
620*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
621*bdd1243dSDimitry Andric    allocator_type get_allocator() const _NOEXCEPT;
622*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); }
623*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); }
624*bdd1243dSDimitry Andric
625*bdd1243dSDimitry Andric  // iterators:
626*bdd1243dSDimitry Andric
627*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
628*bdd1243dSDimitry Andric      __map_pointer __mp = __map_.begin() + __start_ / __block_size;
629*bdd1243dSDimitry Andric      return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
630*bdd1243dSDimitry Andric  }
631*bdd1243dSDimitry Andric
632*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
633*bdd1243dSDimitry Andric      __map_const_pointer __mp =
634*bdd1243dSDimitry Andric          static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
635*bdd1243dSDimitry Andric      return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
636*bdd1243dSDimitry Andric  }
637*bdd1243dSDimitry Andric
638*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
639*bdd1243dSDimitry Andric      size_type __p      = size() + __start_;
640*bdd1243dSDimitry Andric      __map_pointer __mp = __map_.begin() + __p / __block_size;
641*bdd1243dSDimitry Andric      return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
642*bdd1243dSDimitry Andric  }
643*bdd1243dSDimitry Andric
644*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
645*bdd1243dSDimitry Andric      size_type __p            = size() + __start_;
646*bdd1243dSDimitry Andric      __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
647*bdd1243dSDimitry Andric      return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
648*bdd1243dSDimitry Andric  }
649*bdd1243dSDimitry Andric
650*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
651*bdd1243dSDimitry Andric    reverse_iterator       rbegin() _NOEXCEPT
652*bdd1243dSDimitry Andric        {return       reverse_iterator(end());}
653*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
654*bdd1243dSDimitry Andric    const_reverse_iterator rbegin() const _NOEXCEPT
655*bdd1243dSDimitry Andric        {return const_reverse_iterator(end());}
656*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
657*bdd1243dSDimitry Andric    reverse_iterator       rend() _NOEXCEPT
658*bdd1243dSDimitry Andric        {return       reverse_iterator(begin());}
659*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
660*bdd1243dSDimitry Andric    const_reverse_iterator rend()   const _NOEXCEPT
661*bdd1243dSDimitry Andric        {return const_reverse_iterator(begin());}
662*bdd1243dSDimitry Andric
663*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
664*bdd1243dSDimitry Andric    const_iterator         cbegin()  const _NOEXCEPT
665*bdd1243dSDimitry Andric        {return begin();}
666*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
667*bdd1243dSDimitry Andric    const_iterator         cend()    const _NOEXCEPT
668*bdd1243dSDimitry Andric        {return end();}
669*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
670*bdd1243dSDimitry Andric    const_reverse_iterator crbegin() const _NOEXCEPT
671*bdd1243dSDimitry Andric        {return const_reverse_iterator(end());}
672*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
673*bdd1243dSDimitry Andric    const_reverse_iterator crend()   const _NOEXCEPT
674*bdd1243dSDimitry Andric        {return const_reverse_iterator(begin());}
675*bdd1243dSDimitry Andric
676*bdd1243dSDimitry Andric    // capacity:
677*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
678*bdd1243dSDimitry Andric    size_type size() const _NOEXCEPT {return __size();}
679*bdd1243dSDimitry Andric
680*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); }
681*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); }
682*bdd1243dSDimitry Andric
683*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
684*bdd1243dSDimitry Andric    size_type max_size() const _NOEXCEPT
685*bdd1243dSDimitry Andric        {return _VSTD::min<size_type>(
686*bdd1243dSDimitry Andric            __alloc_traits::max_size(__alloc()),
687*bdd1243dSDimitry Andric            numeric_limits<difference_type>::max());}
688*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
689*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
690*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
691*bdd1243dSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
692*bdd1243dSDimitry Andric    bool empty() const _NOEXCEPT {return size() == 0;}
693*bdd1243dSDimitry Andric
694*bdd1243dSDimitry Andric    // element access:
695*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
696*bdd1243dSDimitry Andric    reference operator[](size_type __i) _NOEXCEPT;
697*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
698*bdd1243dSDimitry Andric    const_reference operator[](size_type __i) const _NOEXCEPT;
699*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
700*bdd1243dSDimitry Andric    reference at(size_type __i);
701*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
702*bdd1243dSDimitry Andric    const_reference at(size_type __i) const;
703*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
704*bdd1243dSDimitry Andric    reference front() _NOEXCEPT;
705*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
706*bdd1243dSDimitry Andric    const_reference front() const _NOEXCEPT;
707*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
708*bdd1243dSDimitry Andric    reference back() _NOEXCEPT;
709*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
710*bdd1243dSDimitry Andric    const_reference back() const _NOEXCEPT;
711*bdd1243dSDimitry Andric
712*bdd1243dSDimitry Andric    // 23.2.2.3 modifiers:
713*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
714*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v);
715*bdd1243dSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
716*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER > 14
717*bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
718*bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args);
719*bdd1243dSDimitry Andric#else
720*bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI void      emplace_front(_Args&&... __args);
721*bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI void      emplace_back (_Args&&... __args);
722*bdd1243dSDimitry Andric#endif
723*bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args);
724*bdd1243dSDimitry Andric
725*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
726*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v);
727*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v);
728*bdd1243dSDimitry Andric
729*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
730*bdd1243dSDimitry Andric    iterator insert(const_iterator __p, initializer_list<value_type> __il)
731*bdd1243dSDimitry Andric        {return insert(__p, __il.begin(), __il.end());}
732*bdd1243dSDimitry Andric#endif // _LIBCPP_CXX03_LANG
733*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v);
734*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v);
735*bdd1243dSDimitry Andric    template <class _InputIter>
736*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
737*bdd1243dSDimitry Andric                         typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type* = 0);
738*bdd1243dSDimitry Andric    template <class _ForwardIterator>
739*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
740*bdd1243dSDimitry Andric                        typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
741*bdd1243dSDimitry Andric    template <class _BiIter>
742*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
743*bdd1243dSDimitry Andric                         typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0);
744*bdd1243dSDimitry Andric
745*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void pop_front();
746*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void pop_back();
747*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
748*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
749*bdd1243dSDimitry Andric
750*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
751*bdd1243dSDimitry Andric    void swap(deque& __c)
7520b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
7530b57cec5SDimitry Andric        _NOEXCEPT;
7540b57cec5SDimitry Andric#else
7550b57cec5SDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
7560b57cec5SDimitry Andric                   __is_nothrow_swappable<allocator_type>::value);
7570b57cec5SDimitry Andric#endif
758*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
7590b57cec5SDimitry Andric    void clear() _NOEXCEPT;
7600b57cec5SDimitry Andric
761*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
762*bdd1243dSDimitry Andric    bool __invariants() const {
7630b57cec5SDimitry Andric        if (!__map_.__invariants())
7640b57cec5SDimitry Andric            return false;
7650b57cec5SDimitry Andric        if (__map_.size() >= size_type(-1) / __block_size)
7660b57cec5SDimitry Andric            return false;
7670b57cec5SDimitry Andric        for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
7680b57cec5SDimitry Andric            __i != __e; ++__i)
7690b57cec5SDimitry Andric            if (*__i == nullptr)
7700b57cec5SDimitry Andric                return false;
7710b57cec5SDimitry Andric        if (__map_.size() != 0)
7720b57cec5SDimitry Andric        {
7730b57cec5SDimitry Andric            if (size() >= __map_.size() * __block_size)
7740b57cec5SDimitry Andric                return false;
7750b57cec5SDimitry Andric            if (__start_ >= __map_.size() * __block_size - size())
7760b57cec5SDimitry Andric                return false;
7770b57cec5SDimitry Andric        }
7780b57cec5SDimitry Andric        else
7790b57cec5SDimitry Andric        {
7800b57cec5SDimitry Andric            if (size() != 0)
7810b57cec5SDimitry Andric                return false;
7820b57cec5SDimitry Andric            if (__start_ != 0)
7830b57cec5SDimitry Andric                return false;
7840b57cec5SDimitry Andric        }
7850b57cec5SDimitry Andric        return true;
7860b57cec5SDimitry Andric    }
7870b57cec5SDimitry Andric
788*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
789*bdd1243dSDimitry Andric    void __move_assign_alloc(deque& __c)
790*bdd1243dSDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
791*bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value)
792*bdd1243dSDimitry Andric        {__move_assign_alloc(__c, integral_constant<bool,
793*bdd1243dSDimitry Andric                      __alloc_traits::propagate_on_container_move_assignment::value>());}
794*bdd1243dSDimitry Andric
795*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
796*bdd1243dSDimitry Andric    void __move_assign_alloc(deque& __c, true_type)
797*bdd1243dSDimitry Andric        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
7980b57cec5SDimitry Andric        {
799*bdd1243dSDimitry Andric            __alloc() = _VSTD::move(__c.__alloc());
8000b57cec5SDimitry Andric        }
8010b57cec5SDimitry Andric
802*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
803*bdd1243dSDimitry Andric    void __move_assign_alloc(deque&, false_type) _NOEXCEPT
8040b57cec5SDimitry Andric        {}
8054824e7fdSDimitry Andric
806*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
807*bdd1243dSDimitry Andric    void __move_assign(deque& __c)
808*bdd1243dSDimitry Andric        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
809*bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value)
8104824e7fdSDimitry Andric    {
811*bdd1243dSDimitry Andric        __map_ = _VSTD::move(__c.__map_);
812*bdd1243dSDimitry Andric        __start_ = __c.__start_;
813*bdd1243dSDimitry Andric        __size() = __c.size();
814*bdd1243dSDimitry Andric        __move_assign_alloc(__c);
815*bdd1243dSDimitry Andric        __c.__start_ = __c.__size() = 0;
8164824e7fdSDimitry Andric    }
8174824e7fdSDimitry Andric
818*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8190b57cec5SDimitry Andric    static size_type __recommend_blocks(size_type __n)
8200b57cec5SDimitry Andric    {
821*bdd1243dSDimitry Andric        return __n / __block_size + (__n % __block_size != 0);
8220b57cec5SDimitry Andric    }
823*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8240b57cec5SDimitry Andric    size_type __capacity() const
8250b57cec5SDimitry Andric    {
826*bdd1243dSDimitry Andric        return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1;
8270b57cec5SDimitry Andric    }
828*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
829e40139ffSDimitry Andric    size_type __block_count() const
830e40139ffSDimitry Andric    {
831*bdd1243dSDimitry Andric        return __map_.size();
832e40139ffSDimitry Andric    }
833e40139ffSDimitry Andric
834*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8350b57cec5SDimitry Andric    size_type __front_spare() const
8360b57cec5SDimitry Andric    {
837*bdd1243dSDimitry Andric        return __start_;
8380b57cec5SDimitry Andric    }
839*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
840e40139ffSDimitry Andric    size_type __front_spare_blocks() const {
841*bdd1243dSDimitry Andric      return __front_spare() / __block_size;
842e40139ffSDimitry Andric    }
843*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8440b57cec5SDimitry Andric    size_type __back_spare() const
8450b57cec5SDimitry Andric    {
846*bdd1243dSDimitry Andric        return __capacity() - (__start_ + size());
8470b57cec5SDimitry Andric    }
848*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
849e40139ffSDimitry Andric    size_type __back_spare_blocks() const {
850*bdd1243dSDimitry Andric      return __back_spare() / __block_size;
851e40139ffSDimitry Andric    }
852e40139ffSDimitry Andric
853e40139ffSDimitry Andric private:
854*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
855e40139ffSDimitry Andric    bool __maybe_remove_front_spare(bool __keep_one = true) {
856e40139ffSDimitry Andric      if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {
857*bdd1243dSDimitry Andric        __alloc_traits::deallocate(__alloc(), __map_.front(),
858*bdd1243dSDimitry Andric                                   __block_size);
859*bdd1243dSDimitry Andric        __map_.pop_front();
860*bdd1243dSDimitry Andric        __start_ -= __block_size;
861e40139ffSDimitry Andric        return true;
862e40139ffSDimitry Andric      }
863e40139ffSDimitry Andric      return false;
864e40139ffSDimitry Andric    }
865e40139ffSDimitry Andric
866*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
867e40139ffSDimitry Andric    bool __maybe_remove_back_spare(bool __keep_one = true) {
868e40139ffSDimitry Andric      if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {
869*bdd1243dSDimitry Andric        __alloc_traits::deallocate(__alloc(), __map_.back(),
870*bdd1243dSDimitry Andric                                   __block_size);
871*bdd1243dSDimitry Andric        __map_.pop_back();
872e40139ffSDimitry Andric        return true;
873e40139ffSDimitry Andric      }
874e40139ffSDimitry Andric      return false;
875e40139ffSDimitry Andric    }
8760b57cec5SDimitry Andric
8770b57cec5SDimitry Andric    template <class _InpIter>
878*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l,
879753f127fSDimitry Andric                 typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type* = 0);
8800b57cec5SDimitry Andric    template <class _ForIter>
881*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l,
882480093f4SDimitry Andric                      typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0);
883*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
884*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v);
885*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f);
886*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_front_capacity();
887*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n);
888*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_back_capacity();
889*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n);
890*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r,
8910b57cec5SDimitry Andric                              const_pointer& __vt);
892*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
8930b57cec5SDimitry Andric                                       const_pointer& __vt);
894*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l,
8950b57cec5SDimitry Andric                                    iterator __r, const_pointer& __vt);
896*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_construct_backward_and_check(iterator __f, iterator __l,
8970b57cec5SDimitry Andric                                             iterator __r, const_pointer& __vt);
8980b57cec5SDimitry Andric
899*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9000b57cec5SDimitry Andric    void __copy_assign_alloc(const deque& __c)
9010b57cec5SDimitry Andric        {__copy_assign_alloc(__c, integral_constant<bool,
9020b57cec5SDimitry Andric                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
9030b57cec5SDimitry Andric
904*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9050b57cec5SDimitry Andric    void __copy_assign_alloc(const deque& __c, true_type)
9060b57cec5SDimitry Andric        {
907*bdd1243dSDimitry Andric            if (__alloc() != __c.__alloc())
9080b57cec5SDimitry Andric            {
9090b57cec5SDimitry Andric                clear();
9100b57cec5SDimitry Andric                shrink_to_fit();
9110b57cec5SDimitry Andric            }
912*bdd1243dSDimitry Andric            __alloc() = __c.__alloc();
913*bdd1243dSDimitry Andric            __map_.__alloc() = __c.__map_.__alloc();
9140b57cec5SDimitry Andric        }
9150b57cec5SDimitry Andric
916*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9170b57cec5SDimitry Andric    void __copy_assign_alloc(const deque&, false_type)
9180b57cec5SDimitry Andric        {}
9190b57cec5SDimitry Andric
920*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type)
9210b57cec5SDimitry Andric        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
922*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type);
9230b57cec5SDimitry Andric};
9240b57cec5SDimitry Andric
925*bdd1243dSDimitry Andrictemplate <class _Tp, class _Alloc>
926*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size =
927*bdd1243dSDimitry Andric    __deque_block_size<value_type, difference_type>::value;
928*bdd1243dSDimitry Andric
929349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17
9300b57cec5SDimitry Andrictemplate<class _InputIterator,
931fe6060f1SDimitry Andric         class _Alloc = allocator<__iter_value_type<_InputIterator>>,
932349cc55cSDimitry Andric         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
933349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Alloc>::value>
9340b57cec5SDimitry Andric         >
9350b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator)
936fe6060f1SDimitry Andric  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
9370b57cec5SDimitry Andric
9380b57cec5SDimitry Andrictemplate<class _InputIterator,
9390b57cec5SDimitry Andric         class _Alloc,
940349cc55cSDimitry Andric         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
941349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Alloc>::value>
9420b57cec5SDimitry Andric         >
9430b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc)
944fe6060f1SDimitry Andric  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
9450b57cec5SDimitry Andric#endif
9460b57cec5SDimitry Andric
9470b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
9480b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n)
949*bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
9500b57cec5SDimitry Andric{
9510b57cec5SDimitry Andric    if (__n > 0)
9520b57cec5SDimitry Andric        __append(__n);
9530b57cec5SDimitry Andric}
9540b57cec5SDimitry Andric
9550b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
9560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
9570b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
958*bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
9590b57cec5SDimitry Andric{
9600b57cec5SDimitry Andric    if (__n > 0)
9610b57cec5SDimitry Andric        __append(__n);
9620b57cec5SDimitry Andric}
9630b57cec5SDimitry Andric#endif
9640b57cec5SDimitry Andric
9650b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
9660b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
967*bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
9680b57cec5SDimitry Andric{
9690b57cec5SDimitry Andric    if (__n > 0)
9700b57cec5SDimitry Andric        __append(__n, __v);
9710b57cec5SDimitry Andric}
9720b57cec5SDimitry Andric
9730b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
9740b57cec5SDimitry Andrictemplate <class _InputIter>
9750b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
976480093f4SDimitry Andric              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
977*bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
9780b57cec5SDimitry Andric{
9790b57cec5SDimitry Andric    __append(__f, __l);
9800b57cec5SDimitry Andric}
9810b57cec5SDimitry Andric
9820b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
9830b57cec5SDimitry Andrictemplate <class _InputIter>
9840b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
985480093f4SDimitry Andric              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
986*bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
9870b57cec5SDimitry Andric{
9880b57cec5SDimitry Andric    __append(__f, __l);
9890b57cec5SDimitry Andric}
9900b57cec5SDimitry Andric
9910b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
9920b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c)
993*bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))),
994*bdd1243dSDimitry Andric      __start_(0),
995*bdd1243dSDimitry Andric      __size_(0, __map_.__alloc())
9960b57cec5SDimitry Andric{
9970b57cec5SDimitry Andric    __append(__c.begin(), __c.end());
9980b57cec5SDimitry Andric}
9990b57cec5SDimitry Andric
10000b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
100181ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a)
1002*bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
10030b57cec5SDimitry Andric{
10040b57cec5SDimitry Andric    __append(__c.begin(), __c.end());
10050b57cec5SDimitry Andric}
10060b57cec5SDimitry Andric
10070b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
10080b57cec5SDimitry Andricdeque<_Tp, _Allocator>&
10090b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator=(const deque& __c)
10100b57cec5SDimitry Andric{
1011349cc55cSDimitry Andric    if (this != _VSTD::addressof(__c))
10120b57cec5SDimitry Andric    {
10130b57cec5SDimitry Andric        __copy_assign_alloc(__c);
10140b57cec5SDimitry Andric        assign(__c.begin(), __c.end());
10150b57cec5SDimitry Andric    }
10160b57cec5SDimitry Andric    return *this;
10170b57cec5SDimitry Andric}
10180b57cec5SDimitry Andric
10190b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10200b57cec5SDimitry Andric
10210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
10220b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
1023*bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
10240b57cec5SDimitry Andric{
10250b57cec5SDimitry Andric    __append(__il.begin(), __il.end());
10260b57cec5SDimitry Andric}
10270b57cec5SDimitry Andric
10280b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
10290b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
1030*bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
10310b57cec5SDimitry Andric{
10320b57cec5SDimitry Andric    __append(__il.begin(), __il.end());
10330b57cec5SDimitry Andric}
10340b57cec5SDimitry Andric
10350b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
10360b57cec5SDimitry Andricinline
10370b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(deque&& __c)
1038*bdd1243dSDimitry Andric    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
1039*bdd1243dSDimitry Andric    : __map_(std::move(__c.__map_)), __start_(std::move(__c.__start_)), __size_(std::move(__c.__size_))
10400b57cec5SDimitry Andric{
1041*bdd1243dSDimitry Andric  __c.__start_ = 0;
1042*bdd1243dSDimitry Andric  __c.__size() = 0;
10430b57cec5SDimitry Andric}
10440b57cec5SDimitry Andric
10450b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
10460b57cec5SDimitry Andricinline
104781ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a)
1048*bdd1243dSDimitry Andric    : __map_(std::move(__c.__map_), __pointer_allocator(__a)),
1049*bdd1243dSDimitry Andric      __start_(std::move(__c.__start_)),
1050*bdd1243dSDimitry Andric      __size_(std::move(__c.__size()), __a)
10510b57cec5SDimitry Andric{
1052*bdd1243dSDimitry Andric    if (__a == __c.__alloc())
10530b57cec5SDimitry Andric    {
1054*bdd1243dSDimitry Andric        __c.__start_ = 0;
1055*bdd1243dSDimitry Andric        __c.__size() = 0;
1056*bdd1243dSDimitry Andric    }
1057*bdd1243dSDimitry Andric    else
1058*bdd1243dSDimitry Andric    {
1059*bdd1243dSDimitry Andric        __map_.clear();
1060*bdd1243dSDimitry Andric        __start_ = 0;
1061*bdd1243dSDimitry Andric        __size() = 0;
10620b57cec5SDimitry Andric        typedef move_iterator<iterator> _Ip;
10630b57cec5SDimitry Andric        assign(_Ip(__c.begin()), _Ip(__c.end()));
10640b57cec5SDimitry Andric    }
10650b57cec5SDimitry Andric}
10660b57cec5SDimitry Andric
10670b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
10680b57cec5SDimitry Andricinline
10690b57cec5SDimitry Andricdeque<_Tp, _Allocator>&
10700b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator=(deque&& __c)
10710b57cec5SDimitry Andric        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
10720b57cec5SDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value)
10730b57cec5SDimitry Andric{
10740b57cec5SDimitry Andric    __move_assign(__c, integral_constant<bool,
10750b57cec5SDimitry Andric          __alloc_traits::propagate_on_container_move_assignment::value>());
10760b57cec5SDimitry Andric    return *this;
10770b57cec5SDimitry Andric}
10780b57cec5SDimitry Andric
10790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
10800b57cec5SDimitry Andricvoid
10810b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
10820b57cec5SDimitry Andric{
1083*bdd1243dSDimitry Andric    if (__alloc() != __c.__alloc())
10840b57cec5SDimitry Andric    {
10850b57cec5SDimitry Andric        typedef move_iterator<iterator> _Ip;
10860b57cec5SDimitry Andric        assign(_Ip(__c.begin()), _Ip(__c.end()));
10870b57cec5SDimitry Andric    }
10880b57cec5SDimitry Andric    else
10890b57cec5SDimitry Andric        __move_assign(__c, true_type());
10900b57cec5SDimitry Andric}
10910b57cec5SDimitry Andric
10920b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
10930b57cec5SDimitry Andricvoid
10940b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
10950b57cec5SDimitry Andric    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
10960b57cec5SDimitry Andric{
10970b57cec5SDimitry Andric    clear();
10980b57cec5SDimitry Andric    shrink_to_fit();
1099*bdd1243dSDimitry Andric    __move_assign(__c);
11000b57cec5SDimitry Andric}
11010b57cec5SDimitry Andric
11020b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
11030b57cec5SDimitry Andric
11040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
11050b57cec5SDimitry Andrictemplate <class _InputIter>
11060b57cec5SDimitry Andricvoid
11070b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
1108480093f4SDimitry Andric                               typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
1109480093f4SDimitry Andric                                                 !__is_cpp17_random_access_iterator<_InputIter>::value>::type*)
11100b57cec5SDimitry Andric{
1111*bdd1243dSDimitry Andric    iterator __i = begin();
1112*bdd1243dSDimitry Andric    iterator __e = end();
11130b57cec5SDimitry Andric    for (; __f != __l && __i != __e; ++__f, (void) ++__i)
11140b57cec5SDimitry Andric        *__i = *__f;
11150b57cec5SDimitry Andric    if (__f != __l)
11160b57cec5SDimitry Andric        __append(__f, __l);
11170b57cec5SDimitry Andric    else
11180b57cec5SDimitry Andric        __erase_to_end(__i);
11190b57cec5SDimitry Andric}
11200b57cec5SDimitry Andric
11210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
11220b57cec5SDimitry Andrictemplate <class _RAIter>
11230b57cec5SDimitry Andricvoid
11240b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
1125480093f4SDimitry Andric                               typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
11260b57cec5SDimitry Andric{
1127*bdd1243dSDimitry Andric    if (static_cast<size_type>(__l - __f) > size())
11280b57cec5SDimitry Andric    {
1129*bdd1243dSDimitry Andric        _RAIter __m = __f + size();
1130*bdd1243dSDimitry Andric        _VSTD::copy(__f, __m, begin());
11310b57cec5SDimitry Andric        __append(__m, __l);
11320b57cec5SDimitry Andric    }
11330b57cec5SDimitry Andric    else
1134*bdd1243dSDimitry Andric        __erase_to_end(_VSTD::copy(__f, __l, begin()));
11350b57cec5SDimitry Andric}
11360b57cec5SDimitry Andric
11370b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
11380b57cec5SDimitry Andricvoid
11390b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
11400b57cec5SDimitry Andric{
1141*bdd1243dSDimitry Andric    if (__n > size())
11420b57cec5SDimitry Andric    {
1143*bdd1243dSDimitry Andric        _VSTD::fill_n(begin(), size(), __v);
1144*bdd1243dSDimitry Andric        __n -= size();
11450b57cec5SDimitry Andric        __append(__n, __v);
11460b57cec5SDimitry Andric    }
11470b57cec5SDimitry Andric    else
1148*bdd1243dSDimitry Andric        __erase_to_end(_VSTD::fill_n(begin(), __n, __v));
11490b57cec5SDimitry Andric}
11500b57cec5SDimitry Andric
11510b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
11520b57cec5SDimitry Andricinline
11530b57cec5SDimitry Andric_Allocator
11540b57cec5SDimitry Andricdeque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
11550b57cec5SDimitry Andric{
1156*bdd1243dSDimitry Andric    return __alloc();
11570b57cec5SDimitry Andric}
11580b57cec5SDimitry Andric
11590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
11600b57cec5SDimitry Andricvoid
11610b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n)
11620b57cec5SDimitry Andric{
1163*bdd1243dSDimitry Andric    if (__n > size())
1164*bdd1243dSDimitry Andric        __append(__n - size());
1165*bdd1243dSDimitry Andric    else if (__n < size())
1166*bdd1243dSDimitry Andric        __erase_to_end(begin() + __n);
11670b57cec5SDimitry Andric}
11680b57cec5SDimitry Andric
11690b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
11700b57cec5SDimitry Andricvoid
11710b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
11720b57cec5SDimitry Andric{
1173*bdd1243dSDimitry Andric    if (__n > size())
1174*bdd1243dSDimitry Andric        __append(__n - size(), __v);
1175*bdd1243dSDimitry Andric    else if (__n < size())
1176*bdd1243dSDimitry Andric        __erase_to_end(begin() + __n);
11770b57cec5SDimitry Andric}
11780b57cec5SDimitry Andric
11790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
11800b57cec5SDimitry Andricvoid
11810b57cec5SDimitry Andricdeque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
11820b57cec5SDimitry Andric{
1183*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
11840b57cec5SDimitry Andric    if (empty())
11850b57cec5SDimitry Andric    {
1186*bdd1243dSDimitry Andric        while (__map_.size() > 0)
11870b57cec5SDimitry Andric        {
1188*bdd1243dSDimitry Andric            __alloc_traits::deallocate(__a, __map_.back(), __block_size);
1189*bdd1243dSDimitry Andric            __map_.pop_back();
11900b57cec5SDimitry Andric        }
1191*bdd1243dSDimitry Andric        __start_ = 0;
11920b57cec5SDimitry Andric    }
11930b57cec5SDimitry Andric    else
11940b57cec5SDimitry Andric    {
1195e40139ffSDimitry Andric      __maybe_remove_front_spare(/*__keep_one=*/false);
1196e40139ffSDimitry Andric      __maybe_remove_back_spare(/*__keep_one=*/false);
11970b57cec5SDimitry Andric    }
1198*bdd1243dSDimitry Andric    __map_.shrink_to_fit();
11990b57cec5SDimitry Andric}
12000b57cec5SDimitry Andric
12010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12020b57cec5SDimitry Andricinline
12030b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
12040b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT
12050b57cec5SDimitry Andric{
1206*bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1207*bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
12080b57cec5SDimitry Andric}
12090b57cec5SDimitry Andric
12100b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12110b57cec5SDimitry Andricinline
12120b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
12130b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT
12140b57cec5SDimitry Andric{
1215*bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1216*bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
12170b57cec5SDimitry Andric}
12180b57cec5SDimitry Andric
12190b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12200b57cec5SDimitry Andricinline
12210b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
12220b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i)
12230b57cec5SDimitry Andric{
1224*bdd1243dSDimitry Andric    if (__i >= size())
1225349cc55cSDimitry Andric        _VSTD::__throw_out_of_range("deque");
1226*bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1227*bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
12280b57cec5SDimitry Andric}
12290b57cec5SDimitry Andric
12300b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12310b57cec5SDimitry Andricinline
12320b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
12330b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i) const
12340b57cec5SDimitry Andric{
1235*bdd1243dSDimitry Andric    if (__i >= size())
1236349cc55cSDimitry Andric        _VSTD::__throw_out_of_range("deque");
1237*bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1238*bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
12390b57cec5SDimitry Andric}
12400b57cec5SDimitry Andric
12410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12420b57cec5SDimitry Andricinline
12430b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
12440b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() _NOEXCEPT
12450b57cec5SDimitry Andric{
1246*bdd1243dSDimitry Andric    return *(*(__map_.begin() + __start_ / __block_size)
1247*bdd1243dSDimitry Andric                                    + __start_ % __block_size);
12480b57cec5SDimitry Andric}
12490b57cec5SDimitry Andric
12500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12510b57cec5SDimitry Andricinline
12520b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
12530b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() const _NOEXCEPT
12540b57cec5SDimitry Andric{
1255*bdd1243dSDimitry Andric    return *(*(__map_.begin() + __start_ / __block_size)
1256*bdd1243dSDimitry Andric                                      + __start_ % __block_size);
12570b57cec5SDimitry Andric}
12580b57cec5SDimitry Andric
12590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12600b57cec5SDimitry Andricinline
12610b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
12620b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() _NOEXCEPT
12630b57cec5SDimitry Andric{
1264*bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
1265*bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
12660b57cec5SDimitry Andric}
12670b57cec5SDimitry Andric
12680b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12690b57cec5SDimitry Andricinline
12700b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
12710b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() const _NOEXCEPT
12720b57cec5SDimitry Andric{
1273*bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
1274*bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
12750b57cec5SDimitry Andric}
12760b57cec5SDimitry Andric
12770b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12780b57cec5SDimitry Andricvoid
12790b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(const value_type& __v)
12800b57cec5SDimitry Andric{
1281*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
12820b57cec5SDimitry Andric    if (__back_spare() == 0)
12830b57cec5SDimitry Andric        __add_back_capacity();
12840b57cec5SDimitry Andric    // __back_spare() >= 1
1285*bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v);
1286*bdd1243dSDimitry Andric    ++__size();
12870b57cec5SDimitry Andric}
12880b57cec5SDimitry Andric
12890b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
12900b57cec5SDimitry Andricvoid
12910b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(const value_type& __v)
12920b57cec5SDimitry Andric{
1293*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
12940b57cec5SDimitry Andric    if (__front_spare() == 0)
12950b57cec5SDimitry Andric        __add_front_capacity();
12960b57cec5SDimitry Andric    // __front_spare() >= 1
1297*bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v);
1298*bdd1243dSDimitry Andric    --__start_;
1299*bdd1243dSDimitry Andric    ++__size();
13000b57cec5SDimitry Andric}
13010b57cec5SDimitry Andric
13020b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
13030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13040b57cec5SDimitry Andricvoid
13050b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(value_type&& __v)
13060b57cec5SDimitry Andric{
1307*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
13080b57cec5SDimitry Andric    if (__back_spare() == 0)
13090b57cec5SDimitry Andric        __add_back_capacity();
13100b57cec5SDimitry Andric    // __back_spare() >= 1
1311*bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v));
1312*bdd1243dSDimitry Andric    ++__size();
13130b57cec5SDimitry Andric}
13140b57cec5SDimitry Andric
13150b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13160b57cec5SDimitry Andrictemplate <class... _Args>
13170b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
13180b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
13190b57cec5SDimitry Andric#else
13200b57cec5SDimitry Andricvoid
13210b57cec5SDimitry Andric#endif
13220b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
13230b57cec5SDimitry Andric{
1324*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
13250b57cec5SDimitry Andric    if (__back_spare() == 0)
13260b57cec5SDimitry Andric        __add_back_capacity();
13270b57cec5SDimitry Andric    // __back_spare() >= 1
1328*bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*end()),
13290b57cec5SDimitry Andric                              _VSTD::forward<_Args>(__args)...);
1330*bdd1243dSDimitry Andric    ++__size();
13310b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
1332*bdd1243dSDimitry Andric    return *--end();
13330b57cec5SDimitry Andric#endif
13340b57cec5SDimitry Andric}
13350b57cec5SDimitry Andric
13360b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13370b57cec5SDimitry Andricvoid
13380b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(value_type&& __v)
13390b57cec5SDimitry Andric{
1340*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
13410b57cec5SDimitry Andric    if (__front_spare() == 0)
13420b57cec5SDimitry Andric        __add_front_capacity();
13430b57cec5SDimitry Andric    // __front_spare() >= 1
1344*bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v));
1345*bdd1243dSDimitry Andric    --__start_;
1346*bdd1243dSDimitry Andric    ++__size();
13470b57cec5SDimitry Andric}
13480b57cec5SDimitry Andric
13490b57cec5SDimitry Andric
13500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13510b57cec5SDimitry Andrictemplate <class... _Args>
13520b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
13530b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
13540b57cec5SDimitry Andric#else
13550b57cec5SDimitry Andricvoid
13560b57cec5SDimitry Andric#endif
13570b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
13580b57cec5SDimitry Andric{
1359*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
13600b57cec5SDimitry Andric    if (__front_spare() == 0)
13610b57cec5SDimitry Andric        __add_front_capacity();
13620b57cec5SDimitry Andric    // __front_spare() >= 1
1363*bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...);
1364*bdd1243dSDimitry Andric    --__start_;
1365*bdd1243dSDimitry Andric    ++__size();
13660b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
1367*bdd1243dSDimitry Andric    return *begin();
13680b57cec5SDimitry Andric#endif
13690b57cec5SDimitry Andric}
13700b57cec5SDimitry Andric
13710b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13720b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
13730b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
13740b57cec5SDimitry Andric{
1375*bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1376*bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1377*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
13780b57cec5SDimitry Andric    if (__pos < __to_end)
13790b57cec5SDimitry Andric    {   // insert by shifting things backward
13800b57cec5SDimitry Andric        if (__front_spare() == 0)
13810b57cec5SDimitry Andric            __add_front_capacity();
13820b57cec5SDimitry Andric        // __front_spare() >= 1
13830b57cec5SDimitry Andric        if (__pos == 0)
13840b57cec5SDimitry Andric        {
1385*bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v));
1386*bdd1243dSDimitry Andric            --__start_;
1387*bdd1243dSDimitry Andric            ++__size();
13880b57cec5SDimitry Andric        }
13890b57cec5SDimitry Andric        else
13900b57cec5SDimitry Andric        {
1391*bdd1243dSDimitry Andric            iterator __b = begin();
13920b57cec5SDimitry Andric            iterator __bm1 = _VSTD::prev(__b);
13930b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1394*bdd1243dSDimitry Andric            --__start_;
1395*bdd1243dSDimitry Andric            ++__size();
13960b57cec5SDimitry Andric            if (__pos > 1)
13970b57cec5SDimitry Andric                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
13980b57cec5SDimitry Andric            *__b = _VSTD::move(__v);
13990b57cec5SDimitry Andric        }
14000b57cec5SDimitry Andric    }
14010b57cec5SDimitry Andric    else
14020b57cec5SDimitry Andric    {   // insert by shifting things forward
14030b57cec5SDimitry Andric        if (__back_spare() == 0)
14040b57cec5SDimitry Andric            __add_back_capacity();
14050b57cec5SDimitry Andric        // __back_capacity >= 1
1406*bdd1243dSDimitry Andric        size_type __de = size() - __pos;
14070b57cec5SDimitry Andric        if (__de == 0)
14080b57cec5SDimitry Andric        {
1409*bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v));
1410*bdd1243dSDimitry Andric            ++__size();
14110b57cec5SDimitry Andric        }
14120b57cec5SDimitry Andric        else
14130b57cec5SDimitry Andric        {
1414*bdd1243dSDimitry Andric            iterator __e = end();
14150b57cec5SDimitry Andric            iterator __em1 = _VSTD::prev(__e);
14160b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
1417*bdd1243dSDimitry Andric            ++__size();
14180b57cec5SDimitry Andric            if (__de > 1)
14190b57cec5SDimitry Andric                __e = _VSTD::move_backward(__e - __de, __em1, __e);
14200b57cec5SDimitry Andric            *--__e = _VSTD::move(__v);
14210b57cec5SDimitry Andric        }
14220b57cec5SDimitry Andric    }
1423*bdd1243dSDimitry Andric    return begin() + __pos;
14240b57cec5SDimitry Andric}
14250b57cec5SDimitry Andric
14260b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14270b57cec5SDimitry Andrictemplate <class... _Args>
14280b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
14290b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
14300b57cec5SDimitry Andric{
1431*bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1432*bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1433*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
14340b57cec5SDimitry Andric    if (__pos < __to_end)
14350b57cec5SDimitry Andric    {   // insert by shifting things backward
14360b57cec5SDimitry Andric        if (__front_spare() == 0)
14370b57cec5SDimitry Andric            __add_front_capacity();
14380b57cec5SDimitry Andric        // __front_spare() >= 1
14390b57cec5SDimitry Andric        if (__pos == 0)
14400b57cec5SDimitry Andric        {
1441*bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...);
1442*bdd1243dSDimitry Andric            --__start_;
1443*bdd1243dSDimitry Andric            ++__size();
14440b57cec5SDimitry Andric        }
14450b57cec5SDimitry Andric        else
14460b57cec5SDimitry Andric        {
1447*bdd1243dSDimitry Andric            __temp_value<value_type, _Allocator> __tmp(__alloc(), _VSTD::forward<_Args>(__args)...);
1448*bdd1243dSDimitry Andric            iterator __b = begin();
14490b57cec5SDimitry Andric            iterator __bm1 = _VSTD::prev(__b);
14500b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1451*bdd1243dSDimitry Andric            --__start_;
1452*bdd1243dSDimitry Andric            ++__size();
14530b57cec5SDimitry Andric            if (__pos > 1)
14540b57cec5SDimitry Andric                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
14550b57cec5SDimitry Andric            *__b = _VSTD::move(__tmp.get());
14560b57cec5SDimitry Andric        }
14570b57cec5SDimitry Andric    }
14580b57cec5SDimitry Andric    else
14590b57cec5SDimitry Andric    {   // insert by shifting things forward
14600b57cec5SDimitry Andric        if (__back_spare() == 0)
14610b57cec5SDimitry Andric            __add_back_capacity();
14620b57cec5SDimitry Andric        // __back_capacity >= 1
1463*bdd1243dSDimitry Andric        size_type __de = size() - __pos;
14640b57cec5SDimitry Andric        if (__de == 0)
14650b57cec5SDimitry Andric        {
1466*bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::forward<_Args>(__args)...);
1467*bdd1243dSDimitry Andric            ++__size();
14680b57cec5SDimitry Andric        }
14690b57cec5SDimitry Andric        else
14700b57cec5SDimitry Andric        {
1471*bdd1243dSDimitry Andric            __temp_value<value_type, _Allocator> __tmp(__alloc(), _VSTD::forward<_Args>(__args)...);
1472*bdd1243dSDimitry Andric            iterator __e = end();
14730b57cec5SDimitry Andric            iterator __em1 = _VSTD::prev(__e);
14740b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
1475*bdd1243dSDimitry Andric            ++__size();
14760b57cec5SDimitry Andric            if (__de > 1)
14770b57cec5SDimitry Andric                __e = _VSTD::move_backward(__e - __de, __em1, __e);
14780b57cec5SDimitry Andric            *--__e = _VSTD::move(__tmp.get());
14790b57cec5SDimitry Andric        }
14800b57cec5SDimitry Andric    }
1481*bdd1243dSDimitry Andric    return begin() + __pos;
14820b57cec5SDimitry Andric}
14830b57cec5SDimitry Andric
14840b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
14850b57cec5SDimitry Andric
14860b57cec5SDimitry Andric
14870b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14880b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
14890b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
14900b57cec5SDimitry Andric{
1491*bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1492*bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1493*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
14940b57cec5SDimitry Andric    if (__pos < __to_end)
14950b57cec5SDimitry Andric    {   // insert by shifting things backward
14960b57cec5SDimitry Andric        if (__front_spare() == 0)
14970b57cec5SDimitry Andric            __add_front_capacity();
14980b57cec5SDimitry Andric        // __front_spare() >= 1
14990b57cec5SDimitry Andric        if (__pos == 0)
15000b57cec5SDimitry Andric        {
1501*bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v);
1502*bdd1243dSDimitry Andric            --__start_;
1503*bdd1243dSDimitry Andric            ++__size();
15040b57cec5SDimitry Andric        }
15050b57cec5SDimitry Andric        else
15060b57cec5SDimitry Andric        {
15070b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1508*bdd1243dSDimitry Andric            iterator __b = begin();
15090b57cec5SDimitry Andric            iterator __bm1 = _VSTD::prev(__b);
15100b57cec5SDimitry Andric            if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
15110b57cec5SDimitry Andric                __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
15120b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1513*bdd1243dSDimitry Andric            --__start_;
1514*bdd1243dSDimitry Andric            ++__size();
15150b57cec5SDimitry Andric            if (__pos > 1)
15160b57cec5SDimitry Andric                __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);
15170b57cec5SDimitry Andric            *__b = *__vt;
15180b57cec5SDimitry Andric        }
15190b57cec5SDimitry Andric    }
15200b57cec5SDimitry Andric    else
15210b57cec5SDimitry Andric    {   // insert by shifting things forward
15220b57cec5SDimitry Andric        if (__back_spare() == 0)
15230b57cec5SDimitry Andric            __add_back_capacity();
15240b57cec5SDimitry Andric        // __back_capacity >= 1
1525*bdd1243dSDimitry Andric        size_type __de = size() - __pos;
15260b57cec5SDimitry Andric        if (__de == 0)
15270b57cec5SDimitry Andric        {
1528*bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v);
1529*bdd1243dSDimitry Andric            ++__size();
15300b57cec5SDimitry Andric        }
15310b57cec5SDimitry Andric        else
15320b57cec5SDimitry Andric        {
15330b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1534*bdd1243dSDimitry Andric            iterator __e = end();
15350b57cec5SDimitry Andric            iterator __em1 = _VSTD::prev(__e);
15360b57cec5SDimitry Andric            if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
15370b57cec5SDimitry Andric                __vt = pointer_traits<const_pointer>::pointer_to(*__e);
15380b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
1539*bdd1243dSDimitry Andric            ++__size();
15400b57cec5SDimitry Andric            if (__de > 1)
15410b57cec5SDimitry Andric                __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
15420b57cec5SDimitry Andric            *--__e = *__vt;
15430b57cec5SDimitry Andric        }
15440b57cec5SDimitry Andric    }
1545*bdd1243dSDimitry Andric    return begin() + __pos;
15460b57cec5SDimitry Andric}
15470b57cec5SDimitry Andric
15480b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
15490b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
15500b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
15510b57cec5SDimitry Andric{
1552*bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1553*bdd1243dSDimitry Andric    size_type __to_end = __size() - __pos;
1554*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
15550b57cec5SDimitry Andric    if (__pos < __to_end)
15560b57cec5SDimitry Andric    {   // insert by shifting things backward
15570b57cec5SDimitry Andric        if (__n > __front_spare())
15580b57cec5SDimitry Andric            __add_front_capacity(__n - __front_spare());
15590b57cec5SDimitry Andric        // __n <= __front_spare()
1560*bdd1243dSDimitry Andric        iterator __old_begin = begin();
15610b57cec5SDimitry Andric        iterator __i = __old_begin;
15620b57cec5SDimitry Andric        if (__n > __pos)
15630b57cec5SDimitry Andric        {
1564*bdd1243dSDimitry Andric            for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size())
15650b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);
15660b57cec5SDimitry Andric            __n = __pos;
15670b57cec5SDimitry Andric        }
15680b57cec5SDimitry Andric        if (__n > 0)
15690b57cec5SDimitry Andric        {
15700b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
15710b57cec5SDimitry Andric            iterator __obn = __old_begin + __n;
15720b57cec5SDimitry Andric            __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
15730b57cec5SDimitry Andric            if (__n < __pos)
15740b57cec5SDimitry Andric                __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
15750b57cec5SDimitry Andric            _VSTD::fill_n(__old_begin, __n, *__vt);
15760b57cec5SDimitry Andric        }
15770b57cec5SDimitry Andric    }
15780b57cec5SDimitry Andric    else
15790b57cec5SDimitry Andric    {   // insert by shifting things forward
15800b57cec5SDimitry Andric        size_type __back_capacity = __back_spare();
15810b57cec5SDimitry Andric        if (__n > __back_capacity)
15820b57cec5SDimitry Andric            __add_back_capacity(__n - __back_capacity);
15830b57cec5SDimitry Andric        // __n <= __back_capacity
1584*bdd1243dSDimitry Andric        iterator __old_end = end();
15850b57cec5SDimitry Andric        iterator __i = __old_end;
1586*bdd1243dSDimitry Andric        size_type __de = size() - __pos;
15870b57cec5SDimitry Andric        if (__n > __de)
15880b57cec5SDimitry Andric        {
1589*bdd1243dSDimitry Andric            for (size_type __m = __n - __de; __m; --__m, (void) ++__i, ++__size())
15900b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
15910b57cec5SDimitry Andric            __n = __de;
15920b57cec5SDimitry Andric        }
15930b57cec5SDimitry Andric        if (__n > 0)
15940b57cec5SDimitry Andric        {
15950b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
15960b57cec5SDimitry Andric            iterator __oen = __old_end - __n;
15970b57cec5SDimitry Andric            __move_construct_and_check(__oen, __old_end, __i, __vt);
15980b57cec5SDimitry Andric            if (__n < __de)
15990b57cec5SDimitry Andric                __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
16000b57cec5SDimitry Andric            _VSTD::fill_n(__old_end - __n, __n, *__vt);
16010b57cec5SDimitry Andric        }
16020b57cec5SDimitry Andric    }
1603*bdd1243dSDimitry Andric    return begin() + __pos;
16040b57cec5SDimitry Andric}
16050b57cec5SDimitry Andric
16060b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16070b57cec5SDimitry Andrictemplate <class _InputIter>
16080b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
16090b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
1610753f127fSDimitry Andric                               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type*)
16110b57cec5SDimitry Andric{
1612*bdd1243dSDimitry Andric    __split_buffer<value_type, allocator_type&> __buf(__alloc());
16130b57cec5SDimitry Andric    __buf.__construct_at_end(__f, __l);
16140b57cec5SDimitry Andric    typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
16150b57cec5SDimitry Andric    return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
16160b57cec5SDimitry Andric}
16170b57cec5SDimitry Andric
16180b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16190b57cec5SDimitry Andrictemplate <class _ForwardIterator>
16200b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
16210b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
1622753f127fSDimitry Andric                               typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
16230b57cec5SDimitry Andric{
16240b57cec5SDimitry Andric    size_type __n = _VSTD::distance(__f, __l);
1625*bdd1243dSDimitry Andric    __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc());
16260b57cec5SDimitry Andric    __buf.__construct_at_end(__f, __l);
16270b57cec5SDimitry Andric    typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
16280b57cec5SDimitry Andric    return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
16290b57cec5SDimitry Andric}
16300b57cec5SDimitry Andric
16310b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16320b57cec5SDimitry Andrictemplate <class _BiIter>
16330b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
16340b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
1635480093f4SDimitry Andric                               typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type*)
16360b57cec5SDimitry Andric{
16370b57cec5SDimitry Andric    size_type __n = _VSTD::distance(__f, __l);
1638*bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1639*bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1640*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
16410b57cec5SDimitry Andric    if (__pos < __to_end)
16420b57cec5SDimitry Andric    {   // insert by shifting things backward
16430b57cec5SDimitry Andric        if (__n > __front_spare())
16440b57cec5SDimitry Andric            __add_front_capacity(__n - __front_spare());
16450b57cec5SDimitry Andric        // __n <= __front_spare()
1646*bdd1243dSDimitry Andric        iterator __old_begin = begin();
16470b57cec5SDimitry Andric        iterator __i = __old_begin;
16480b57cec5SDimitry Andric        _BiIter __m = __f;
16490b57cec5SDimitry Andric        if (__n > __pos)
16500b57cec5SDimitry Andric        {
16510b57cec5SDimitry Andric            __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);
1652*bdd1243dSDimitry Andric            for (_BiIter __j = __m; __j != __f; --__start_, ++__size())
16530b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);
16540b57cec5SDimitry Andric            __n = __pos;
16550b57cec5SDimitry Andric        }
16560b57cec5SDimitry Andric        if (__n > 0)
16570b57cec5SDimitry Andric        {
16580b57cec5SDimitry Andric            iterator __obn = __old_begin + __n;
16590b57cec5SDimitry Andric            for (iterator __j = __obn; __j != __old_begin;)
16600b57cec5SDimitry Andric            {
16610b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));
1662*bdd1243dSDimitry Andric                --__start_;
1663*bdd1243dSDimitry Andric                ++__size();
16640b57cec5SDimitry Andric            }
16650b57cec5SDimitry Andric            if (__n < __pos)
16660b57cec5SDimitry Andric                __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);
16670b57cec5SDimitry Andric            _VSTD::copy(__m, __l, __old_begin);
16680b57cec5SDimitry Andric        }
16690b57cec5SDimitry Andric    }
16700b57cec5SDimitry Andric    else
16710b57cec5SDimitry Andric    {   // insert by shifting things forward
16720b57cec5SDimitry Andric        size_type __back_capacity = __back_spare();
16730b57cec5SDimitry Andric        if (__n > __back_capacity)
16740b57cec5SDimitry Andric            __add_back_capacity(__n - __back_capacity);
16750b57cec5SDimitry Andric        // __n <= __back_capacity
1676*bdd1243dSDimitry Andric        iterator __old_end = end();
16770b57cec5SDimitry Andric        iterator __i = __old_end;
16780b57cec5SDimitry Andric        _BiIter __m = __l;
1679*bdd1243dSDimitry Andric        size_type __de = size() - __pos;
16800b57cec5SDimitry Andric        if (__n > __de)
16810b57cec5SDimitry Andric        {
16820b57cec5SDimitry Andric            __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
1683*bdd1243dSDimitry Andric            for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__size())
16840b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
16850b57cec5SDimitry Andric            __n = __de;
16860b57cec5SDimitry Andric        }
16870b57cec5SDimitry Andric        if (__n > 0)
16880b57cec5SDimitry Andric        {
16890b57cec5SDimitry Andric            iterator __oen = __old_end - __n;
1690*bdd1243dSDimitry Andric            for (iterator __j = __oen; __j != __old_end; ++__i, (void) ++__j, ++__size())
16910b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));
16920b57cec5SDimitry Andric            if (__n < __de)
16930b57cec5SDimitry Andric                __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);
16940b57cec5SDimitry Andric            _VSTD::copy_backward(__f, __m, __old_end);
16950b57cec5SDimitry Andric        }
16960b57cec5SDimitry Andric    }
1697*bdd1243dSDimitry Andric    return begin() + __pos;
16980b57cec5SDimitry Andric}
16990b57cec5SDimitry Andric
17000b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17010b57cec5SDimitry Andrictemplate <class _InpIter>
17020b57cec5SDimitry Andricvoid
17030b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
1704753f127fSDimitry Andric                                 typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type*)
17050b57cec5SDimitry Andric{
17060b57cec5SDimitry Andric    for (; __f != __l; ++__f)
17070b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
17080b57cec5SDimitry Andric        push_back(*__f);
17090b57cec5SDimitry Andric#else
17100b57cec5SDimitry Andric        emplace_back(*__f);
17110b57cec5SDimitry Andric#endif
17120b57cec5SDimitry Andric}
17130b57cec5SDimitry Andric
17140b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17150b57cec5SDimitry Andrictemplate <class _ForIter>
17160b57cec5SDimitry Andricvoid
17170b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
1718480093f4SDimitry Andric                                 typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type*)
17190b57cec5SDimitry Andric{
17200b57cec5SDimitry Andric    size_type __n = _VSTD::distance(__f, __l);
1721*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17220b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
17230b57cec5SDimitry Andric    if (__n > __back_capacity)
17240b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
17250b57cec5SDimitry Andric    // __n <= __back_capacity
1726*bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
1727e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
1728e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {
1729e8d8bef9SDimitry Andric        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f);
1730e40139ffSDimitry Andric      }
1731e40139ffSDimitry Andric    }
17320b57cec5SDimitry Andric}
17330b57cec5SDimitry Andric
17340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17350b57cec5SDimitry Andricvoid
17360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n)
17370b57cec5SDimitry Andric{
1738*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17390b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
17400b57cec5SDimitry Andric    if (__n > __back_capacity)
17410b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
17420b57cec5SDimitry Andric    // __n <= __back_capacity
1743*bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
1744e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
1745e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
1746e8d8bef9SDimitry Andric        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_));
1747e40139ffSDimitry Andric      }
1748e40139ffSDimitry Andric    }
17490b57cec5SDimitry Andric}
17500b57cec5SDimitry Andric
17510b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17520b57cec5SDimitry Andricvoid
17530b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
17540b57cec5SDimitry Andric{
1755*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17560b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
17570b57cec5SDimitry Andric    if (__n > __back_capacity)
17580b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
17590b57cec5SDimitry Andric    // __n <= __back_capacity
1760*bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
1761e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
1762e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
1763e8d8bef9SDimitry Andric        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v);
1764e40139ffSDimitry Andric      }
1765e40139ffSDimitry Andric    }
1766e40139ffSDimitry Andric
17670b57cec5SDimitry Andric}
17680b57cec5SDimitry Andric
17690b57cec5SDimitry Andric// Create front capacity for one block of elements.
17700b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
17710b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17720b57cec5SDimitry Andricvoid
17730b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity()
17740b57cec5SDimitry Andric{
1775*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
1776*bdd1243dSDimitry Andric    if (__back_spare() >= __block_size)
17770b57cec5SDimitry Andric    {
1778*bdd1243dSDimitry Andric        __start_ += __block_size;
1779*bdd1243dSDimitry Andric        pointer __pt = __map_.back();
1780*bdd1243dSDimitry Andric        __map_.pop_back();
1781*bdd1243dSDimitry Andric        __map_.push_front(__pt);
17820b57cec5SDimitry Andric    }
1783*bdd1243dSDimitry Andric    // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer
1784*bdd1243dSDimitry Andric    else if (__map_.size() < __map_.capacity())
17850b57cec5SDimitry Andric    {   // we can put the new buffer into the map, but don't shift things around
17860b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
17870b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
1788*bdd1243dSDimitry Andric        if (__map_.__front_spare() > 0)
1789*bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
17900b57cec5SDimitry Andric        else
17910b57cec5SDimitry Andric        {
1792*bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
17930b57cec5SDimitry Andric            // Done allocating, reorder capacity
1794*bdd1243dSDimitry Andric            pointer __pt = __map_.back();
1795*bdd1243dSDimitry Andric            __map_.pop_back();
1796*bdd1243dSDimitry Andric            __map_.push_front(__pt);
17970b57cec5SDimitry Andric        }
1798*bdd1243dSDimitry Andric        __start_ = __map_.size() == 1 ?
1799*bdd1243dSDimitry Andric                               __block_size / 2 :
1800*bdd1243dSDimitry Andric                               __start_ + __block_size;
18010b57cec5SDimitry Andric    }
18020b57cec5SDimitry Andric    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
18030b57cec5SDimitry Andric    else
18040b57cec5SDimitry Andric    {
1805*bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
1806*bdd1243dSDimitry Andric            __buf(std::max<size_type>(2 * __map_.capacity(), 1),
1807*bdd1243dSDimitry Andric                  0, __map_.__alloc());
18080b57cec5SDimitry Andric
18090b57cec5SDimitry Andric        typedef __allocator_destructor<_Allocator> _Dp;
18100b57cec5SDimitry Andric        unique_ptr<pointer, _Dp> __hold(
1811*bdd1243dSDimitry Andric            __alloc_traits::allocate(__a, __block_size),
1812*bdd1243dSDimitry Andric                _Dp(__a, __block_size));
18130b57cec5SDimitry Andric        __buf.push_back(__hold.get());
18140b57cec5SDimitry Andric        __hold.release();
18150b57cec5SDimitry Andric
1816*bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.begin();
1817*bdd1243dSDimitry Andric                __i != __map_.end(); ++__i)
18180b57cec5SDimitry Andric            __buf.push_back(*__i);
1819*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__first_, __buf.__first_);
1820*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__begin_, __buf.__begin_);
1821*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_, __buf.__end_);
1822*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
1823*bdd1243dSDimitry Andric        __start_ = __map_.size() == 1 ?
1824*bdd1243dSDimitry Andric                               __block_size / 2 :
1825*bdd1243dSDimitry Andric                               __start_ + __block_size;
18260b57cec5SDimitry Andric    }
18270b57cec5SDimitry Andric}
18280b57cec5SDimitry Andric
18290b57cec5SDimitry Andric// Create front capacity for __n elements.
18300b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
18310b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
18320b57cec5SDimitry Andricvoid
18330b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
18340b57cec5SDimitry Andric{
1835*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
1836*bdd1243dSDimitry Andric    size_type __nb = __recommend_blocks(__n + __map_.empty());
18370b57cec5SDimitry Andric    // Number of unused blocks at back:
1838*bdd1243dSDimitry Andric    size_type __back_capacity = __back_spare() / __block_size;
18390b57cec5SDimitry Andric    __back_capacity = _VSTD::min(__back_capacity, __nb);  // don't take more than you need
18400b57cec5SDimitry Andric    __nb -= __back_capacity;  // number of blocks need to allocate
18410b57cec5SDimitry Andric    // If __nb == 0, then we have sufficient capacity.
18420b57cec5SDimitry Andric    if (__nb == 0)
18430b57cec5SDimitry Andric    {
1844*bdd1243dSDimitry Andric        __start_ += __block_size * __back_capacity;
18450b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
18460b57cec5SDimitry Andric        {
1847*bdd1243dSDimitry Andric            pointer __pt = __map_.back();
1848*bdd1243dSDimitry Andric            __map_.pop_back();
1849*bdd1243dSDimitry Andric            __map_.push_front(__pt);
18500b57cec5SDimitry Andric        }
18510b57cec5SDimitry Andric    }
18520b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
1853*bdd1243dSDimitry Andric    else if (__nb <= __map_.capacity() - __map_.size())
18540b57cec5SDimitry Andric    {   // we can put the new buffers into the map, but don't shift things around
18550b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
18560b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
1857*bdd1243dSDimitry Andric        for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1))
18580b57cec5SDimitry Andric        {
1859*bdd1243dSDimitry Andric            if (__map_.__front_spare() == 0)
18600b57cec5SDimitry Andric                break;
1861*bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
18620b57cec5SDimitry Andric        }
18630b57cec5SDimitry Andric        for (; __nb > 0; --__nb, ++__back_capacity)
1864*bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
18650b57cec5SDimitry Andric        // Done allocating, reorder capacity
1866*bdd1243dSDimitry Andric        __start_ += __back_capacity * __block_size;
18670b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
18680b57cec5SDimitry Andric        {
1869*bdd1243dSDimitry Andric            pointer __pt = __map_.back();
1870*bdd1243dSDimitry Andric            __map_.pop_back();
1871*bdd1243dSDimitry Andric            __map_.push_front(__pt);
18720b57cec5SDimitry Andric        }
18730b57cec5SDimitry Andric    }
18740b57cec5SDimitry Andric    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
18750b57cec5SDimitry Andric    else
18760b57cec5SDimitry Andric    {
1877*bdd1243dSDimitry Andric        size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty();
1878*bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
1879*bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(),
1880*bdd1243dSDimitry Andric                                      __nb + __map_.size()),
1881*bdd1243dSDimitry Andric                  0, __map_.__alloc());
18820b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
18830b57cec5SDimitry Andric        try
18840b57cec5SDimitry Andric        {
18850b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS
18860b57cec5SDimitry Andric            for (; __nb > 0; --__nb)
1887*bdd1243dSDimitry Andric                __buf.push_back(__alloc_traits::allocate(__a, __block_size));
18880b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
18890b57cec5SDimitry Andric        }
18900b57cec5SDimitry Andric        catch (...)
18910b57cec5SDimitry Andric        {
1892*bdd1243dSDimitry Andric            for (__map_pointer __i = __buf.begin();
18930b57cec5SDimitry Andric                    __i != __buf.end(); ++__i)
1894*bdd1243dSDimitry Andric                __alloc_traits::deallocate(__a, *__i, __block_size);
18950b57cec5SDimitry Andric            throw;
18960b57cec5SDimitry Andric        }
18970b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS
18980b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
18990b57cec5SDimitry Andric        {
1900*bdd1243dSDimitry Andric            __buf.push_back(__map_.back());
1901*bdd1243dSDimitry Andric            __map_.pop_back();
19020b57cec5SDimitry Andric        }
1903*bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.begin();
1904*bdd1243dSDimitry Andric                __i != __map_.end(); ++__i)
19050b57cec5SDimitry Andric            __buf.push_back(*__i);
1906*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__first_, __buf.__first_);
1907*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__begin_, __buf.__begin_);
1908*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_, __buf.__end_);
1909*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
1910*bdd1243dSDimitry Andric        __start_ += __ds;
19110b57cec5SDimitry Andric    }
19120b57cec5SDimitry Andric}
19130b57cec5SDimitry Andric
19140b57cec5SDimitry Andric// Create back capacity for one block of elements.
19150b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
19160b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
19170b57cec5SDimitry Andricvoid
19180b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity()
19190b57cec5SDimitry Andric{
1920*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
1921*bdd1243dSDimitry Andric    if (__front_spare() >= __block_size)
19220b57cec5SDimitry Andric    {
1923*bdd1243dSDimitry Andric        __start_ -= __block_size;
1924*bdd1243dSDimitry Andric        pointer __pt = __map_.front();
1925*bdd1243dSDimitry Andric        __map_.pop_front();
1926*bdd1243dSDimitry Andric        __map_.push_back(__pt);
19270b57cec5SDimitry Andric    }
19280b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
1929*bdd1243dSDimitry Andric    else if (__map_.size() < __map_.capacity())
19300b57cec5SDimitry Andric    {   // we can put the new buffer into the map, but don't shift things around
19310b57cec5SDimitry Andric        // until it is allocated.  If we throw, we don't need to fix
19320b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
1933*bdd1243dSDimitry Andric        if (__map_.__back_spare() != 0)
1934*bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
19350b57cec5SDimitry Andric        else
19360b57cec5SDimitry Andric        {
1937*bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
19380b57cec5SDimitry Andric            // Done allocating, reorder capacity
1939*bdd1243dSDimitry Andric            pointer __pt = __map_.front();
1940*bdd1243dSDimitry Andric            __map_.pop_front();
1941*bdd1243dSDimitry Andric            __map_.push_back(__pt);
19420b57cec5SDimitry Andric        }
19430b57cec5SDimitry Andric    }
19440b57cec5SDimitry Andric    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
19450b57cec5SDimitry Andric    else
19460b57cec5SDimitry Andric    {
1947*bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
1948*bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(), 1),
1949*bdd1243dSDimitry Andric                  __map_.size(),
1950*bdd1243dSDimitry Andric                  __map_.__alloc());
19510b57cec5SDimitry Andric
19520b57cec5SDimitry Andric        typedef __allocator_destructor<_Allocator> _Dp;
19530b57cec5SDimitry Andric        unique_ptr<pointer, _Dp> __hold(
1954*bdd1243dSDimitry Andric            __alloc_traits::allocate(__a, __block_size),
1955*bdd1243dSDimitry Andric                _Dp(__a, __block_size));
19560b57cec5SDimitry Andric        __buf.push_back(__hold.get());
19570b57cec5SDimitry Andric        __hold.release();
19580b57cec5SDimitry Andric
1959*bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.end();
1960*bdd1243dSDimitry Andric                __i != __map_.begin();)
19610b57cec5SDimitry Andric            __buf.push_front(*--__i);
1962*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__first_, __buf.__first_);
1963*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__begin_, __buf.__begin_);
1964*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_, __buf.__end_);
1965*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
19660b57cec5SDimitry Andric    }
19670b57cec5SDimitry Andric}
19680b57cec5SDimitry Andric
19690b57cec5SDimitry Andric// Create back capacity for __n elements.
19700b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
19710b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
19720b57cec5SDimitry Andricvoid
19730b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
19740b57cec5SDimitry Andric{
1975*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
1976*bdd1243dSDimitry Andric    size_type __nb = __recommend_blocks(__n + __map_.empty());
19770b57cec5SDimitry Andric    // Number of unused blocks at front:
1978*bdd1243dSDimitry Andric    size_type __front_capacity = __front_spare() / __block_size;
19790b57cec5SDimitry Andric    __front_capacity = _VSTD::min(__front_capacity, __nb);  // don't take more than you need
19800b57cec5SDimitry Andric    __nb -= __front_capacity;  // number of blocks need to allocate
19810b57cec5SDimitry Andric    // If __nb == 0, then we have sufficient capacity.
19820b57cec5SDimitry Andric    if (__nb == 0)
19830b57cec5SDimitry Andric    {
1984*bdd1243dSDimitry Andric        __start_ -= __block_size * __front_capacity;
19850b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
19860b57cec5SDimitry Andric        {
1987*bdd1243dSDimitry Andric            pointer __pt = __map_.front();
1988*bdd1243dSDimitry Andric            __map_.pop_front();
1989*bdd1243dSDimitry Andric            __map_.push_back(__pt);
19900b57cec5SDimitry Andric        }
19910b57cec5SDimitry Andric    }
19920b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
1993*bdd1243dSDimitry Andric    else if (__nb <= __map_.capacity() - __map_.size())
19940b57cec5SDimitry Andric    {   // we can put the new buffers into the map, but don't shift things around
19950b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
19960b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
19970b57cec5SDimitry Andric        for (; __nb > 0; --__nb)
19980b57cec5SDimitry Andric        {
1999*bdd1243dSDimitry Andric            if (__map_.__back_spare() == 0)
20000b57cec5SDimitry Andric                break;
2001*bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
20020b57cec5SDimitry Andric        }
2003*bdd1243dSDimitry Andric        for (; __nb > 0; --__nb, ++__front_capacity, __start_ +=
2004*bdd1243dSDimitry Andric                                 __block_size - (__map_.size() == 1))
2005*bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
20060b57cec5SDimitry Andric        // Done allocating, reorder capacity
2007*bdd1243dSDimitry Andric        __start_ -= __block_size * __front_capacity;
20080b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
20090b57cec5SDimitry Andric        {
2010*bdd1243dSDimitry Andric            pointer __pt = __map_.front();
2011*bdd1243dSDimitry Andric            __map_.pop_front();
2012*bdd1243dSDimitry Andric            __map_.push_back(__pt);
20130b57cec5SDimitry Andric        }
20140b57cec5SDimitry Andric    }
20150b57cec5SDimitry Andric    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
20160b57cec5SDimitry Andric    else
20170b57cec5SDimitry Andric    {
2018*bdd1243dSDimitry Andric        size_type __ds = __front_capacity * __block_size;
2019*bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2020*bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(),
2021*bdd1243dSDimitry Andric                                      __nb + __map_.size()),
2022*bdd1243dSDimitry Andric                  __map_.size() - __front_capacity,
2023*bdd1243dSDimitry Andric                  __map_.__alloc());
20240b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
20250b57cec5SDimitry Andric        try
20260b57cec5SDimitry Andric        {
20270b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS
20280b57cec5SDimitry Andric            for (; __nb > 0; --__nb)
2029*bdd1243dSDimitry Andric                __buf.push_back(__alloc_traits::allocate(__a, __block_size));
20300b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
20310b57cec5SDimitry Andric        }
20320b57cec5SDimitry Andric        catch (...)
20330b57cec5SDimitry Andric        {
2034*bdd1243dSDimitry Andric            for (__map_pointer __i = __buf.begin();
20350b57cec5SDimitry Andric                    __i != __buf.end(); ++__i)
2036*bdd1243dSDimitry Andric                __alloc_traits::deallocate(__a, *__i, __block_size);
20370b57cec5SDimitry Andric            throw;
20380b57cec5SDimitry Andric        }
20390b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS
20400b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
20410b57cec5SDimitry Andric        {
2042*bdd1243dSDimitry Andric            __buf.push_back(__map_.front());
2043*bdd1243dSDimitry Andric            __map_.pop_front();
20440b57cec5SDimitry Andric        }
2045*bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.end();
2046*bdd1243dSDimitry Andric                __i != __map_.begin();)
20470b57cec5SDimitry Andric            __buf.push_front(*--__i);
2048*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__first_, __buf.__first_);
2049*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__begin_, __buf.__begin_);
2050*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_, __buf.__end_);
2051*bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
2052*bdd1243dSDimitry Andric        __start_ -= __ds;
20530b57cec5SDimitry Andric    }
20540b57cec5SDimitry Andric}
20550b57cec5SDimitry Andric
20560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
20570b57cec5SDimitry Andricvoid
20580b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_front()
20590b57cec5SDimitry Andric{
2060*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2061*bdd1243dSDimitry Andric    __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() +
2062*bdd1243dSDimitry Andric                                                    __start_ / __block_size) +
2063*bdd1243dSDimitry Andric                                                    __start_ % __block_size));
2064*bdd1243dSDimitry Andric    --__size();
2065*bdd1243dSDimitry Andric    ++__start_;
2066e40139ffSDimitry Andric    __maybe_remove_front_spare();
20670b57cec5SDimitry Andric}
20680b57cec5SDimitry Andric
20690b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
20700b57cec5SDimitry Andricvoid
20710b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_back()
20720b57cec5SDimitry Andric{
2073fe6060f1SDimitry Andric    _LIBCPP_ASSERT(!empty(), "deque::pop_back called on an empty deque");
2074*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2075*bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
2076*bdd1243dSDimitry Andric    __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() +
2077*bdd1243dSDimitry Andric                                                    __p / __block_size) +
2078*bdd1243dSDimitry Andric                                                    __p % __block_size));
2079*bdd1243dSDimitry Andric    --__size();
2080e40139ffSDimitry Andric    __maybe_remove_back_spare();
20810b57cec5SDimitry Andric}
20820b57cec5SDimitry Andric
20830b57cec5SDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)).
20840b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
20850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
20860b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
20870b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
20880b57cec5SDimitry Andric                                         const_pointer& __vt)
20890b57cec5SDimitry Andric{
20900b57cec5SDimitry Andric    // as if
20910b57cec5SDimitry Andric    //   for (; __f != __l; ++__f, ++__r)
20920b57cec5SDimitry Andric    //       *__r = _VSTD::move(*__f);
20930b57cec5SDimitry Andric    difference_type __n = __l - __f;
20940b57cec5SDimitry Andric    while (__n > 0)
20950b57cec5SDimitry Andric    {
20960b57cec5SDimitry Andric        pointer __fb = __f.__ptr_;
2097*bdd1243dSDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
20980b57cec5SDimitry Andric        difference_type __bs = __fe - __fb;
20990b57cec5SDimitry Andric        if (__bs > __n)
21000b57cec5SDimitry Andric        {
21010b57cec5SDimitry Andric            __bs = __n;
21020b57cec5SDimitry Andric            __fe = __fb + __bs;
21030b57cec5SDimitry Andric        }
21040b57cec5SDimitry Andric        if (__fb <= __vt && __vt < __fe)
21050b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
21060b57cec5SDimitry Andric        __r = _VSTD::move(__fb, __fe, __r);
21070b57cec5SDimitry Andric        __n -= __bs;
21080b57cec5SDimitry Andric        __f += __bs;
21090b57cec5SDimitry Andric    }
21100b57cec5SDimitry Andric    return __r;
21110b57cec5SDimitry Andric}
21120b57cec5SDimitry Andric
21130b57cec5SDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
21140b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt.
21150b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
21160b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
21170b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
21180b57cec5SDimitry Andric                                                  const_pointer& __vt)
21190b57cec5SDimitry Andric{
21200b57cec5SDimitry Andric    // as if
21210b57cec5SDimitry Andric    //   while (__f != __l)
21220b57cec5SDimitry Andric    //       *--__r = _VSTD::move(*--__l);
21230b57cec5SDimitry Andric    difference_type __n = __l - __f;
21240b57cec5SDimitry Andric    while (__n > 0)
21250b57cec5SDimitry Andric    {
21260b57cec5SDimitry Andric        --__l;
21270b57cec5SDimitry Andric        pointer __lb = *__l.__m_iter_;
21280b57cec5SDimitry Andric        pointer __le = __l.__ptr_ + 1;
21290b57cec5SDimitry Andric        difference_type __bs = __le - __lb;
21300b57cec5SDimitry Andric        if (__bs > __n)
21310b57cec5SDimitry Andric        {
21320b57cec5SDimitry Andric            __bs = __n;
21330b57cec5SDimitry Andric            __lb = __le - __bs;
21340b57cec5SDimitry Andric        }
21350b57cec5SDimitry Andric        if (__lb <= __vt && __vt < __le)
21360b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
21370b57cec5SDimitry Andric        __r = _VSTD::move_backward(__lb, __le, __r);
21380b57cec5SDimitry Andric        __n -= __bs;
21390b57cec5SDimitry Andric        __l -= __bs - 1;
21400b57cec5SDimitry Andric    }
21410b57cec5SDimitry Andric    return __r;
21420b57cec5SDimitry Andric}
21430b57cec5SDimitry Andric
21440b57cec5SDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)).
21450b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt.
21460b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
21470b57cec5SDimitry Andricvoid
21480b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
21490b57cec5SDimitry Andric                                                   iterator __r, const_pointer& __vt)
21500b57cec5SDimitry Andric{
2151*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
21520b57cec5SDimitry Andric    // as if
2153*bdd1243dSDimitry Andric    //   for (; __f != __l; ++__r, ++__f, ++__size())
21540b57cec5SDimitry Andric    //       __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));
21550b57cec5SDimitry Andric    difference_type __n = __l - __f;
21560b57cec5SDimitry Andric    while (__n > 0)
21570b57cec5SDimitry Andric    {
21580b57cec5SDimitry Andric        pointer __fb = __f.__ptr_;
2159*bdd1243dSDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
21600b57cec5SDimitry Andric        difference_type __bs = __fe - __fb;
21610b57cec5SDimitry Andric        if (__bs > __n)
21620b57cec5SDimitry Andric        {
21630b57cec5SDimitry Andric            __bs = __n;
21640b57cec5SDimitry Andric            __fe = __fb + __bs;
21650b57cec5SDimitry Andric        }
21660b57cec5SDimitry Andric        if (__fb <= __vt && __vt < __fe)
21670b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
2168*bdd1243dSDimitry Andric        for (; __fb != __fe; ++__fb, ++__r, ++__size())
21690b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
21700b57cec5SDimitry Andric        __n -= __bs;
21710b57cec5SDimitry Andric        __f += __bs;
21720b57cec5SDimitry Andric    }
21730b57cec5SDimitry Andric}
21740b57cec5SDimitry Andric
21750b57cec5SDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
21760b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
21770b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
21780b57cec5SDimitry Andricvoid
21790b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
21800b57cec5SDimitry Andric                                                            iterator __r, const_pointer& __vt)
21810b57cec5SDimitry Andric{
2182*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
21830b57cec5SDimitry Andric    // as if
21840b57cec5SDimitry Andric    //   for (iterator __j = __l; __j != __f;)
21850b57cec5SDimitry Andric    //   {
21860b57cec5SDimitry Andric    //       __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));
2187*bdd1243dSDimitry Andric    //       --__start_;
2188*bdd1243dSDimitry Andric    //       ++__size();
21890b57cec5SDimitry Andric    //   }
21900b57cec5SDimitry Andric    difference_type __n = __l - __f;
21910b57cec5SDimitry Andric    while (__n > 0)
21920b57cec5SDimitry Andric    {
21930b57cec5SDimitry Andric        --__l;
21940b57cec5SDimitry Andric        pointer __lb = *__l.__m_iter_;
21950b57cec5SDimitry Andric        pointer __le = __l.__ptr_ + 1;
21960b57cec5SDimitry Andric        difference_type __bs = __le - __lb;
21970b57cec5SDimitry Andric        if (__bs > __n)
21980b57cec5SDimitry Andric        {
21990b57cec5SDimitry Andric            __bs = __n;
22000b57cec5SDimitry Andric            __lb = __le - __bs;
22010b57cec5SDimitry Andric        }
22020b57cec5SDimitry Andric        if (__lb <= __vt && __vt < __le)
22030b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
22040b57cec5SDimitry Andric        while (__le != __lb)
22050b57cec5SDimitry Andric        {
22060b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
2207*bdd1243dSDimitry Andric            --__start_;
2208*bdd1243dSDimitry Andric            ++__size();
22090b57cec5SDimitry Andric        }
22100b57cec5SDimitry Andric        __n -= __bs;
22110b57cec5SDimitry Andric        __l -= __bs - 1;
22120b57cec5SDimitry Andric    }
22130b57cec5SDimitry Andric}
22140b57cec5SDimitry Andric
22150b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22160b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
22170b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f)
22180b57cec5SDimitry Andric{
2219*bdd1243dSDimitry Andric    iterator __b = begin();
22200b57cec5SDimitry Andric    difference_type __pos = __f - __b;
22210b57cec5SDimitry Andric    iterator __p = __b + __pos;
2222*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2223*bdd1243dSDimitry Andric    if (static_cast<size_t>(__pos) <= (size() - 1) / 2)
22240b57cec5SDimitry Andric    {   // erase from front
22250b57cec5SDimitry Andric        _VSTD::move_backward(__b, __p, _VSTD::next(__p));
22260b57cec5SDimitry Andric        __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
2227*bdd1243dSDimitry Andric        --__size();
2228*bdd1243dSDimitry Andric        ++__start_;
2229e40139ffSDimitry Andric        __maybe_remove_front_spare();
22300b57cec5SDimitry Andric    }
22310b57cec5SDimitry Andric    else
22320b57cec5SDimitry Andric    {   // erase from back
2233*bdd1243dSDimitry Andric        iterator __i = _VSTD::move(_VSTD::next(__p), end(), __p);
22340b57cec5SDimitry Andric        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2235*bdd1243dSDimitry Andric        --__size();
2236e40139ffSDimitry Andric        __maybe_remove_back_spare();
22370b57cec5SDimitry Andric    }
2238*bdd1243dSDimitry Andric    return begin() + __pos;
22390b57cec5SDimitry Andric}
22400b57cec5SDimitry Andric
22410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22420b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
22430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
22440b57cec5SDimitry Andric{
22450b57cec5SDimitry Andric    difference_type __n = __l - __f;
2246*bdd1243dSDimitry Andric    iterator __b = begin();
22470b57cec5SDimitry Andric    difference_type __pos = __f - __b;
22480b57cec5SDimitry Andric    iterator __p = __b + __pos;
22490b57cec5SDimitry Andric    if (__n > 0)
22500b57cec5SDimitry Andric    {
2251*bdd1243dSDimitry Andric        allocator_type& __a = __alloc();
2252*bdd1243dSDimitry Andric        if (static_cast<size_t>(__pos) <= (size() - __n) / 2)
22530b57cec5SDimitry Andric        {   // erase from front
22540b57cec5SDimitry Andric            iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
22550b57cec5SDimitry Andric            for (; __b != __i; ++__b)
22560b57cec5SDimitry Andric                __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
2257*bdd1243dSDimitry Andric            __size() -= __n;
2258*bdd1243dSDimitry Andric            __start_ += __n;
2259e40139ffSDimitry Andric            while (__maybe_remove_front_spare()) {
22600b57cec5SDimitry Andric            }
22610b57cec5SDimitry Andric        }
22620b57cec5SDimitry Andric        else
22630b57cec5SDimitry Andric        {   // erase from back
2264*bdd1243dSDimitry Andric            iterator __i = _VSTD::move(__p + __n, end(), __p);
2265*bdd1243dSDimitry Andric            for (iterator __e = end(); __i != __e; ++__i)
22660b57cec5SDimitry Andric                __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2267*bdd1243dSDimitry Andric            __size() -= __n;
2268e40139ffSDimitry Andric            while (__maybe_remove_back_spare()) {
22690b57cec5SDimitry Andric            }
22700b57cec5SDimitry Andric        }
22710b57cec5SDimitry Andric    }
2272*bdd1243dSDimitry Andric    return begin() + __pos;
22730b57cec5SDimitry Andric}
22740b57cec5SDimitry Andric
22750b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22760b57cec5SDimitry Andricvoid
22770b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
22780b57cec5SDimitry Andric{
2279*bdd1243dSDimitry Andric    iterator __e = end();
22800b57cec5SDimitry Andric    difference_type __n = __e - __f;
22810b57cec5SDimitry Andric    if (__n > 0)
22820b57cec5SDimitry Andric    {
2283*bdd1243dSDimitry Andric        allocator_type& __a = __alloc();
2284*bdd1243dSDimitry Andric        iterator __b = begin();
22850b57cec5SDimitry Andric        difference_type __pos = __f - __b;
22860b57cec5SDimitry Andric        for (iterator __p = __b + __pos; __p != __e; ++__p)
22870b57cec5SDimitry Andric            __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
2288*bdd1243dSDimitry Andric        __size() -= __n;
2289e40139ffSDimitry Andric        while (__maybe_remove_back_spare()) {
22900b57cec5SDimitry Andric        }
22910b57cec5SDimitry Andric    }
22920b57cec5SDimitry Andric}
22930b57cec5SDimitry Andric
22940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22950b57cec5SDimitry Andricinline
22960b57cec5SDimitry Andricvoid
22970b57cec5SDimitry Andricdeque<_Tp, _Allocator>::swap(deque& __c)
22980b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
22990b57cec5SDimitry Andric        _NOEXCEPT
23000b57cec5SDimitry Andric#else
23010b57cec5SDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
23020b57cec5SDimitry Andric                    __is_nothrow_swappable<allocator_type>::value)
23030b57cec5SDimitry Andric#endif
23040b57cec5SDimitry Andric{
2305*bdd1243dSDimitry Andric    __map_.swap(__c.__map_);
2306*bdd1243dSDimitry Andric    _VSTD::swap(__start_, __c.__start_);
2307*bdd1243dSDimitry Andric    _VSTD::swap(__size(), __c.__size());
2308*bdd1243dSDimitry Andric    _VSTD::__swap_allocator(__alloc(), __c.__alloc());
23090b57cec5SDimitry Andric}
23100b57cec5SDimitry Andric
23110b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
23120b57cec5SDimitry Andricinline
23130b57cec5SDimitry Andricvoid
23140b57cec5SDimitry Andricdeque<_Tp, _Allocator>::clear() _NOEXCEPT
23150b57cec5SDimitry Andric{
2316*bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2317*bdd1243dSDimitry Andric    for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
2318*bdd1243dSDimitry Andric        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2319*bdd1243dSDimitry Andric    __size() = 0;
2320*bdd1243dSDimitry Andric    while (__map_.size() > 2)
2321*bdd1243dSDimitry Andric    {
2322*bdd1243dSDimitry Andric        __alloc_traits::deallocate(__a, __map_.front(), __block_size);
2323*bdd1243dSDimitry Andric        __map_.pop_front();
2324*bdd1243dSDimitry Andric    }
2325*bdd1243dSDimitry Andric    switch (__map_.size())
2326*bdd1243dSDimitry Andric    {
2327*bdd1243dSDimitry Andric    case 1:
2328*bdd1243dSDimitry Andric        __start_ = __block_size / 2;
2329*bdd1243dSDimitry Andric        break;
2330*bdd1243dSDimitry Andric    case 2:
2331*bdd1243dSDimitry Andric        __start_ = __block_size;
2332*bdd1243dSDimitry Andric        break;
2333*bdd1243dSDimitry Andric    }
23340b57cec5SDimitry Andric}
23350b57cec5SDimitry Andric
23360b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2337*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
23380b57cec5SDimitry Andricbool
23390b57cec5SDimitry Andricoperator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
23400b57cec5SDimitry Andric{
23410b57cec5SDimitry Andric    const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
23420b57cec5SDimitry Andric    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
23430b57cec5SDimitry Andric}
23440b57cec5SDimitry Andric
23450b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2346*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
23470b57cec5SDimitry Andricbool
23480b57cec5SDimitry Andricoperator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
23490b57cec5SDimitry Andric{
23500b57cec5SDimitry Andric    return !(__x == __y);
23510b57cec5SDimitry Andric}
23520b57cec5SDimitry Andric
23530b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2354*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
23550b57cec5SDimitry Andricbool
23560b57cec5SDimitry Andricoperator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
23570b57cec5SDimitry Andric{
23580b57cec5SDimitry Andric    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
23590b57cec5SDimitry Andric}
23600b57cec5SDimitry Andric
23610b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2362*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
23630b57cec5SDimitry Andricbool
23640b57cec5SDimitry Andricoperator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
23650b57cec5SDimitry Andric{
23660b57cec5SDimitry Andric    return __y < __x;
23670b57cec5SDimitry Andric}
23680b57cec5SDimitry Andric
23690b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2370*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
23710b57cec5SDimitry Andricbool
23720b57cec5SDimitry Andricoperator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
23730b57cec5SDimitry Andric{
23740b57cec5SDimitry Andric    return !(__x < __y);
23750b57cec5SDimitry Andric}
23760b57cec5SDimitry Andric
23770b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2378*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
23790b57cec5SDimitry Andricbool
23800b57cec5SDimitry Andricoperator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
23810b57cec5SDimitry Andric{
23820b57cec5SDimitry Andric    return !(__y < __x);
23830b57cec5SDimitry Andric}
23840b57cec5SDimitry Andric
23850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2386*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
23870b57cec5SDimitry Andricvoid
23880b57cec5SDimitry Andricswap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
23890b57cec5SDimitry Andric    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
23900b57cec5SDimitry Andric{
23910b57cec5SDimitry Andric    __x.swap(__y);
23920b57cec5SDimitry Andric}
23930b57cec5SDimitry Andric
23940b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
23950b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up>
2396*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
23975ffd83dbSDimitry Andricerase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
23985ffd83dbSDimitry Andric  auto __old_size = __c.size();
23995ffd83dbSDimitry Andric  __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end());
24005ffd83dbSDimitry Andric  return __old_size - __c.size();
24015ffd83dbSDimitry Andric}
24020b57cec5SDimitry Andric
24030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate>
2404*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
24055ffd83dbSDimitry Andricerase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
24065ffd83dbSDimitry Andric  auto __old_size = __c.size();
24075ffd83dbSDimitry Andric  __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
24085ffd83dbSDimitry Andric  return __old_size - __c.size();
24095ffd83dbSDimitry Andric}
241081ad6265SDimitry Andric
241181ad6265SDimitry Andrictemplate <>
241281ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<char>> = true;
241381ad6265SDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
241481ad6265SDimitry Andrictemplate <>
241581ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;
24160b57cec5SDimitry Andric#endif
24170b57cec5SDimitry Andric
241881ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 17
24190b57cec5SDimitry Andric
24200b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
24210b57cec5SDimitry Andric
2422*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER > 14
2423*bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2424*bdd1243dSDimitry Andricnamespace pmr {
2425*bdd1243dSDimitry Andrictemplate <class _ValueT>
2426*bdd1243dSDimitry Andricusing deque = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;
2427*bdd1243dSDimitry Andric} // namespace pmr
2428*bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD
2429*bdd1243dSDimitry Andric#endif
2430*bdd1243dSDimitry Andric
24310b57cec5SDimitry Andric_LIBCPP_POP_MACROS
24320b57cec5SDimitry Andric
2433*bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
2434*bdd1243dSDimitry Andric#  include <algorithm>
2435*bdd1243dSDimitry Andric#  include <atomic>
2436*bdd1243dSDimitry Andric#  include <concepts>
2437*bdd1243dSDimitry Andric#  include <functional>
2438*bdd1243dSDimitry Andric#  include <iosfwd>
2439*bdd1243dSDimitry Andric#  include <iterator>
2440*bdd1243dSDimitry Andric#  include <typeinfo>
2441*bdd1243dSDimitry Andric#endif
2442*bdd1243dSDimitry Andric
24430b57cec5SDimitry Andric#endif // _LIBCPP_DEQUE
2444