xref: /freebsd/contrib/llvm-project/libcxx/include/deque (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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);
50*06c3fb27SDimitry Andric    template<container-compatible-range<T> R>
51*06c3fb27SDimitry Andric        deque(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
520b57cec5SDimitry Andric    deque(const deque& c);
530b57cec5SDimitry Andric    deque(deque&& c)
540b57cec5SDimitry Andric        noexcept(is_nothrow_move_constructible<allocator_type>::value);
550b57cec5SDimitry Andric    deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
560b57cec5SDimitry Andric    deque(const deque& c, const allocator_type& a);
570b57cec5SDimitry Andric    deque(deque&& c, const allocator_type& a);
580b57cec5SDimitry Andric    ~deque();
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric    deque& operator=(const deque& c);
610b57cec5SDimitry Andric    deque& operator=(deque&& c)
620b57cec5SDimitry Andric        noexcept(
630b57cec5SDimitry Andric             allocator_type::propagate_on_container_move_assignment::value &&
640b57cec5SDimitry Andric             is_nothrow_move_assignable<allocator_type>::value);
650b57cec5SDimitry Andric    deque& operator=(initializer_list<value_type> il);
660b57cec5SDimitry Andric
670b57cec5SDimitry Andric    template <class InputIterator>
680b57cec5SDimitry Andric        void assign(InputIterator f, InputIterator l);
69*06c3fb27SDimitry Andric    template<container-compatible-range<T> R>
70*06c3fb27SDimitry Andric      void assign_range(R&& rg); // C++23
710b57cec5SDimitry Andric    void assign(size_type n, const value_type& v);
720b57cec5SDimitry Andric    void assign(initializer_list<value_type> il);
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric    allocator_type get_allocator() const noexcept;
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric    // iterators:
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric    iterator       begin() noexcept;
790b57cec5SDimitry Andric    const_iterator begin() const noexcept;
800b57cec5SDimitry Andric    iterator       end() noexcept;
810b57cec5SDimitry Andric    const_iterator end() const noexcept;
820b57cec5SDimitry Andric
830b57cec5SDimitry Andric    reverse_iterator       rbegin() noexcept;
840b57cec5SDimitry Andric    const_reverse_iterator rbegin() const noexcept;
850b57cec5SDimitry Andric    reverse_iterator       rend() noexcept;
860b57cec5SDimitry Andric    const_reverse_iterator rend() const noexcept;
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric    const_iterator         cbegin() const noexcept;
890b57cec5SDimitry Andric    const_iterator         cend() const noexcept;
900b57cec5SDimitry Andric    const_reverse_iterator crbegin() const noexcept;
910b57cec5SDimitry Andric    const_reverse_iterator crend() const noexcept;
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric    // capacity:
940b57cec5SDimitry Andric    size_type size() const noexcept;
950b57cec5SDimitry Andric    size_type max_size() const noexcept;
960b57cec5SDimitry Andric    void resize(size_type n);
970b57cec5SDimitry Andric    void resize(size_type n, const value_type& v);
980b57cec5SDimitry Andric    void shrink_to_fit();
990b57cec5SDimitry Andric    bool empty() const noexcept;
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andric    // element access:
1020b57cec5SDimitry Andric    reference operator[](size_type i);
1030b57cec5SDimitry Andric    const_reference operator[](size_type i) const;
1040b57cec5SDimitry Andric    reference at(size_type i);
1050b57cec5SDimitry Andric    const_reference at(size_type i) const;
1060b57cec5SDimitry Andric    reference front();
1070b57cec5SDimitry Andric    const_reference front() const;
1080b57cec5SDimitry Andric    reference back();
1090b57cec5SDimitry Andric    const_reference back() const;
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric    // modifiers:
1120b57cec5SDimitry Andric    void push_front(const value_type& v);
1130b57cec5SDimitry Andric    void push_front(value_type&& v);
114*06c3fb27SDimitry Andric    template<container-compatible-range<T> R>
115*06c3fb27SDimitry Andric      void prepend_range(R&& rg); // C++23
1160b57cec5SDimitry Andric    void push_back(const value_type& v);
1170b57cec5SDimitry Andric    void push_back(value_type&& v);
118*06c3fb27SDimitry Andric    template<container-compatible-range<T> R>
119*06c3fb27SDimitry Andric      void append_range(R&& rg); // C++23
1200b57cec5SDimitry Andric    template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
1210b57cec5SDimitry Andric    template <class... Args> reference emplace_back(Args&&... args);   // reference in C++17
1220b57cec5SDimitry Andric    template <class... Args> iterator emplace(const_iterator p, Args&&... args);
1230b57cec5SDimitry Andric    iterator insert(const_iterator p, const value_type& v);
1240b57cec5SDimitry Andric    iterator insert(const_iterator p, value_type&& v);
1250b57cec5SDimitry Andric    iterator insert(const_iterator p, size_type n, const value_type& v);
1260b57cec5SDimitry Andric    template <class InputIterator>
1270b57cec5SDimitry Andric        iterator insert(const_iterator p, InputIterator f, InputIterator l);
128*06c3fb27SDimitry Andric    template<container-compatible-range<T> R>
129*06c3fb27SDimitry Andric      iterator insert_range(const_iterator position, R&& rg); // C++23
1300b57cec5SDimitry Andric    iterator insert(const_iterator p, initializer_list<value_type> il);
1310b57cec5SDimitry Andric    void pop_front();
1320b57cec5SDimitry Andric    void pop_back();
1330b57cec5SDimitry Andric    iterator erase(const_iterator p);
1340b57cec5SDimitry Andric    iterator erase(const_iterator f, const_iterator l);
1350b57cec5SDimitry Andric    void swap(deque& c)
1360b57cec5SDimitry Andric        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
1370b57cec5SDimitry Andric    void clear() noexcept;
1380b57cec5SDimitry Andric};
1390b57cec5SDimitry Andric
1400b57cec5SDimitry Andrictemplate <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
1410b57cec5SDimitry Andric   deque(InputIterator, InputIterator, Allocator = Allocator())
142349cc55cSDimitry Andric   -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
1430b57cec5SDimitry Andric
144*06c3fb27SDimitry Andrictemplate<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
145*06c3fb27SDimitry Andric  deque(from_range_t, R&&, Allocator = Allocator())
146*06c3fb27SDimitry Andric    -> deque<ranges::range_value_t<R>, Allocator>; // C++23
147*06c3fb27SDimitry Andric
1480b57cec5SDimitry Andrictemplate <class T, class Allocator>
1490b57cec5SDimitry Andric    bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1500b57cec5SDimitry Andrictemplate <class T, class Allocator>
151*06c3fb27SDimitry Andric    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
1520b57cec5SDimitry Andrictemplate <class T, class Allocator>
153*06c3fb27SDimitry Andric    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
1540b57cec5SDimitry Andrictemplate <class T, class Allocator>
155*06c3fb27SDimitry Andric    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
1560b57cec5SDimitry Andrictemplate <class T, class Allocator>
157*06c3fb27SDimitry Andric    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
1580b57cec5SDimitry Andrictemplate <class T, class Allocator>
159*06c3fb27SDimitry Andric    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
160*06c3fb27SDimitry Andrictemplate<class T, class Allocator>
161*06c3fb27SDimitry Andric    synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x,
162*06c3fb27SDimitry Andric                                          const deque<T, Allocator>& y);       // since C++20
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric// specialized algorithms:
1650b57cec5SDimitry Andrictemplate <class T, class Allocator>
1660b57cec5SDimitry Andric    void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
1670b57cec5SDimitry Andric         noexcept(noexcept(x.swap(y)));
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andrictemplate <class T, class Allocator, class U>
1705ffd83dbSDimitry Andric    typename deque<T, Allocator>::size_type
1715ffd83dbSDimitry Andric    erase(deque<T, Allocator>& c, const U& value);       // C++20
1720b57cec5SDimitry Andrictemplate <class T, class Allocator, class Predicate>
1735ffd83dbSDimitry Andric    typename deque<T, Allocator>::size_type
1745ffd83dbSDimitry Andric    erase_if(deque<T, Allocator>& c, Predicate pred);    // C++20
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andric}  // std
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric*/
1790b57cec5SDimitry Andric
18081ad6265SDimitry Andric#include <__algorithm/copy.h>
18181ad6265SDimitry Andric#include <__algorithm/copy_backward.h>
182*06c3fb27SDimitry Andric#include <__algorithm/copy_n.h>
18381ad6265SDimitry Andric#include <__algorithm/equal.h>
18481ad6265SDimitry Andric#include <__algorithm/fill_n.h>
18581ad6265SDimitry Andric#include <__algorithm/lexicographical_compare.h>
186*06c3fb27SDimitry Andric#include <__algorithm/lexicographical_compare_three_way.h>
18781ad6265SDimitry Andric#include <__algorithm/min.h>
18881ad6265SDimitry Andric#include <__algorithm/remove.h>
18981ad6265SDimitry Andric#include <__algorithm/remove_if.h>
19081ad6265SDimitry Andric#include <__algorithm/unwrap_iter.h>
19181ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
192*06c3fb27SDimitry Andric#include <__availability>
1930b57cec5SDimitry Andric#include <__config>
19481ad6265SDimitry Andric#include <__format/enable_insertable.h>
195*06c3fb27SDimitry Andric#include <__iterator/distance.h>
196349cc55cSDimitry Andric#include <__iterator/iterator_traits.h>
19781ad6265SDimitry Andric#include <__iterator/next.h>
19881ad6265SDimitry Andric#include <__iterator/prev.h>
19981ad6265SDimitry Andric#include <__iterator/reverse_iterator.h>
200bdd1243dSDimitry Andric#include <__iterator/segmented_iterator.h>
201*06c3fb27SDimitry Andric#include <__memory/addressof.h>
202bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h>
203bdd1243dSDimitry Andric#include <__memory/pointer_traits.h>
204bdd1243dSDimitry Andric#include <__memory/temp_value.h>
205bdd1243dSDimitry Andric#include <__memory/unique_ptr.h>
206bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h>
207*06c3fb27SDimitry Andric#include <__ranges/access.h>
208*06c3fb27SDimitry Andric#include <__ranges/concepts.h>
209*06c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h>
210*06c3fb27SDimitry Andric#include <__ranges/from_range.h>
211*06c3fb27SDimitry Andric#include <__ranges/size.h>
2120b57cec5SDimitry Andric#include <__split_buffer>
213bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h>
214*06c3fb27SDimitry Andric#include <__type_traits/is_convertible.h>
215*06c3fb27SDimitry Andric#include <__type_traits/is_same.h>
216*06c3fb27SDimitry Andric#include <__type_traits/type_identity.h>
217fe6060f1SDimitry Andric#include <__utility/forward.h>
21881ad6265SDimitry Andric#include <__utility/move.h>
219*06c3fb27SDimitry Andric#include <__utility/pair.h>
22081ad6265SDimitry Andric#include <__utility/swap.h>
221fe6060f1SDimitry Andric#include <limits>
2220b57cec5SDimitry Andric#include <stdexcept>
2230b57cec5SDimitry Andric#include <version>
2240b57cec5SDimitry Andric
22581ad6265SDimitry Andric// standard-mandated includes
22681ad6265SDimitry Andric
22781ad6265SDimitry Andric// [iterator.range]
22881ad6265SDimitry Andric#include <__iterator/access.h>
22981ad6265SDimitry Andric#include <__iterator/data.h>
23081ad6265SDimitry Andric#include <__iterator/empty.h>
23181ad6265SDimitry Andric#include <__iterator/reverse_access.h>
23281ad6265SDimitry Andric#include <__iterator/size.h>
23381ad6265SDimitry Andric
23481ad6265SDimitry Andric// [deque.syn]
23581ad6265SDimitry Andric#include <compare>
23681ad6265SDimitry Andric#include <initializer_list>
23781ad6265SDimitry Andric
2380b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2390b57cec5SDimitry Andric#  pragma GCC system_header
2400b57cec5SDimitry Andric#endif
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
2430b57cec5SDimitry Andric#include <__undef_macros>
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric
2460b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andrictemplate <class _ValueType, class _DiffType>
2510b57cec5SDimitry Andricstruct __deque_block_size {
2520b57cec5SDimitry Andric  static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
2530b57cec5SDimitry Andric};
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
2560b57cec5SDimitry Andric          class _DiffType, _DiffType _BS =
2570b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
2580b57cec5SDimitry Andric// Keep template parameter to avoid changing all template declarations thoughout
2590b57cec5SDimitry Andric// this file.
2600b57cec5SDimitry Andric                               0
2610b57cec5SDimitry Andric#else
2620b57cec5SDimitry Andric                               __deque_block_size<_ValueType, _DiffType>::value
2630b57cec5SDimitry Andric#endif
2640b57cec5SDimitry Andric          >
2650b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __deque_iterator
2660b57cec5SDimitry Andric{
2670b57cec5SDimitry Andric    typedef _MapPointer __map_iterator;
2680b57cec5SDimitry Andricpublic:
2690b57cec5SDimitry Andric    typedef _Pointer  pointer;
2700b57cec5SDimitry Andric    typedef _DiffType difference_type;
2710b57cec5SDimitry Andricprivate:
2720b57cec5SDimitry Andric    __map_iterator __m_iter_;
2730b57cec5SDimitry Andric    pointer        __ptr_;
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric    static const difference_type __block_size;
2760b57cec5SDimitry Andricpublic:
2770b57cec5SDimitry Andric    typedef _ValueType                  value_type;
2780b57cec5SDimitry Andric    typedef random_access_iterator_tag  iterator_category;
2790b57cec5SDimitry Andric    typedef _Reference                  reference;
2800b57cec5SDimitry Andric
281bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT
282*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
2830b57cec5SDimitry Andric     : __m_iter_(nullptr), __ptr_(nullptr)
2840b57cec5SDimitry Andric#endif
2850b57cec5SDimitry Andric     {}
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andric    template <class _Pp, class _Rp, class _MP>
288bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2890b57cec5SDimitry Andric    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
2900b57cec5SDimitry Andric                typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
2910b57cec5SDimitry Andric        : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
2920b57cec5SDimitry Andric
293bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI reference operator*() const {return *__ptr_;}
294bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI pointer operator->() const {return __ptr_;}
2950b57cec5SDimitry Andric
296bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++()
2970b57cec5SDimitry Andric    {
2980b57cec5SDimitry Andric        if (++__ptr_ - *__m_iter_ == __block_size)
2990b57cec5SDimitry Andric        {
3000b57cec5SDimitry Andric            ++__m_iter_;
3010b57cec5SDimitry Andric            __ptr_ = *__m_iter_;
3020b57cec5SDimitry Andric        }
3030b57cec5SDimitry Andric        return *this;
3040b57cec5SDimitry Andric    }
3050b57cec5SDimitry Andric
306bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int)
3070b57cec5SDimitry Andric    {
3080b57cec5SDimitry Andric        __deque_iterator __tmp = *this;
3090b57cec5SDimitry Andric        ++(*this);
3100b57cec5SDimitry Andric        return __tmp;
3110b57cec5SDimitry Andric    }
3120b57cec5SDimitry Andric
313bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--()
3140b57cec5SDimitry Andric    {
3150b57cec5SDimitry Andric        if (__ptr_ == *__m_iter_)
3160b57cec5SDimitry Andric        {
3170b57cec5SDimitry Andric            --__m_iter_;
3180b57cec5SDimitry Andric            __ptr_ = *__m_iter_ + __block_size;
3190b57cec5SDimitry Andric        }
3200b57cec5SDimitry Andric        --__ptr_;
3210b57cec5SDimitry Andric        return *this;
3220b57cec5SDimitry Andric    }
3230b57cec5SDimitry Andric
324bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int)
3250b57cec5SDimitry Andric    {
3260b57cec5SDimitry Andric        __deque_iterator __tmp = *this;
3270b57cec5SDimitry Andric        --(*this);
3280b57cec5SDimitry Andric        return __tmp;
3290b57cec5SDimitry Andric    }
3300b57cec5SDimitry Andric
331bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n)
3320b57cec5SDimitry Andric    {
3330b57cec5SDimitry Andric        if (__n != 0)
3340b57cec5SDimitry Andric        {
3350b57cec5SDimitry Andric            __n += __ptr_ - *__m_iter_;
3360b57cec5SDimitry Andric            if (__n > 0)
3370b57cec5SDimitry Andric            {
3380b57cec5SDimitry Andric                __m_iter_ += __n / __block_size;
3390b57cec5SDimitry Andric                __ptr_ = *__m_iter_ + __n % __block_size;
3400b57cec5SDimitry Andric            }
3410b57cec5SDimitry Andric            else // (__n < 0)
3420b57cec5SDimitry Andric            {
3430b57cec5SDimitry Andric                difference_type __z = __block_size - 1 - __n;
3440b57cec5SDimitry Andric                __m_iter_ -= __z / __block_size;
3450b57cec5SDimitry Andric                __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
3460b57cec5SDimitry Andric            }
3470b57cec5SDimitry Andric        }
3480b57cec5SDimitry Andric        return *this;
3490b57cec5SDimitry Andric    }
3500b57cec5SDimitry Andric
351bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n)
3520b57cec5SDimitry Andric    {
3530b57cec5SDimitry Andric        return *this += -__n;
3540b57cec5SDimitry Andric    }
3550b57cec5SDimitry Andric
356bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const
3570b57cec5SDimitry Andric    {
3580b57cec5SDimitry Andric        __deque_iterator __t(*this);
3590b57cec5SDimitry Andric        __t += __n;
3600b57cec5SDimitry Andric        return __t;
3610b57cec5SDimitry Andric    }
3620b57cec5SDimitry Andric
363bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const
3640b57cec5SDimitry Andric    {
3650b57cec5SDimitry Andric        __deque_iterator __t(*this);
3660b57cec5SDimitry Andric        __t -= __n;
3670b57cec5SDimitry Andric        return __t;
3680b57cec5SDimitry Andric    }
3690b57cec5SDimitry Andric
370bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3710b57cec5SDimitry Andric    friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
3720b57cec5SDimitry Andric        {return __it + __n;}
3730b57cec5SDimitry Andric
374bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3750b57cec5SDimitry Andric    friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
3760b57cec5SDimitry Andric    {
3770b57cec5SDimitry Andric        if (__x != __y)
3780b57cec5SDimitry Andric            return (__x.__m_iter_ - __y.__m_iter_) * __block_size
3790b57cec5SDimitry Andric                 + (__x.__ptr_ - *__x.__m_iter_)
3800b57cec5SDimitry Andric                 - (__y.__ptr_ - *__y.__m_iter_);
3810b57cec5SDimitry Andric        return 0;
3820b57cec5SDimitry Andric    }
3830b57cec5SDimitry Andric
384bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const
3850b57cec5SDimitry Andric        {return *(*this + __n);}
3860b57cec5SDimitry Andric
387bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3880b57cec5SDimitry Andric        bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
3890b57cec5SDimitry Andric        {return __x.__ptr_ == __y.__ptr_;}
3900b57cec5SDimitry Andric
391bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3920b57cec5SDimitry Andric        bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
3930b57cec5SDimitry Andric        {return !(__x == __y);}
3940b57cec5SDimitry Andric
395bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3960b57cec5SDimitry Andric        bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
3970b57cec5SDimitry Andric        {return __x.__m_iter_ < __y.__m_iter_ ||
3980b57cec5SDimitry Andric               (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
3990b57cec5SDimitry Andric
400bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
4010b57cec5SDimitry Andric        bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
4020b57cec5SDimitry Andric        {return __y < __x;}
4030b57cec5SDimitry Andric
404bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
4050b57cec5SDimitry Andric        bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
4060b57cec5SDimitry Andric        {return !(__y < __x);}
4070b57cec5SDimitry Andric
408bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
4090b57cec5SDimitry Andric        bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
4100b57cec5SDimitry Andric        {return !(__x < __y);}
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andricprivate:
413bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
4140b57cec5SDimitry Andric        : __m_iter_(__m), __ptr_(__p) {}
4150b57cec5SDimitry Andric
4160b57cec5SDimitry Andric    template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque;
4170b57cec5SDimitry Andric    template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
4180b57cec5SDimitry Andric        friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
4190b57cec5SDimitry Andric
420bdd1243dSDimitry Andric    template <class>
421bdd1243dSDimitry Andric    friend struct __segmented_iterator_traits;
422bdd1243dSDimitry Andric};
4230b57cec5SDimitry Andric
424bdd1243dSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize>
425bdd1243dSDimitry Andricstruct __segmented_iterator_traits<
426bdd1243dSDimitry Andric    __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > {
427bdd1243dSDimitry Andricprivate:
428bdd1243dSDimitry Andric  using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>;
4290b57cec5SDimitry Andric
430bdd1243dSDimitry Andricpublic:
431bdd1243dSDimitry Andric  using __is_segmented_iterator = true_type;
432bdd1243dSDimitry Andric  using __segment_iterator = _MapPointer;
433bdd1243dSDimitry Andric  using __local_iterator = _Pointer;
4340b57cec5SDimitry Andric
435bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; }
436bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; }
437bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; }
4380b57cec5SDimitry Andric
439bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
440bdd1243dSDimitry Andric        return *__iter + _Iterator::__block_size;
441bdd1243dSDimitry Andric  }
4420b57cec5SDimitry Andric
443bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) {
444bdd1243dSDimitry Andric        if (__local == __end(__segment)) {
445bdd1243dSDimitry Andric            ++__segment;
446bdd1243dSDimitry Andric            return _Iterator(__segment, *__segment);
447bdd1243dSDimitry Andric        }
448bdd1243dSDimitry Andric        return _Iterator(__segment, __local);
449bdd1243dSDimitry Andric  }
4500b57cec5SDimitry Andric};
4510b57cec5SDimitry Andric
4520b57cec5SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
4530b57cec5SDimitry Andric          class _DiffType, _DiffType _BlockSize>
4540b57cec5SDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
4550b57cec5SDimitry Andric                                 _DiffType, _BlockSize>::__block_size =
4560b57cec5SDimitry Andric    __deque_block_size<_ValueType, _DiffType>::value;
4570b57cec5SDimitry Andric
458bdd1243dSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/>
459bdd1243dSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque
4600b57cec5SDimitry Andric{
4610b57cec5SDimitry Andricpublic:
462bdd1243dSDimitry Andric    // types:
463e40139ffSDimitry Andric
464bdd1243dSDimitry Andric  using value_type = _Tp;
4650b57cec5SDimitry Andric
466bdd1243dSDimitry Andric  static_assert((is_same<typename _Allocator::value_type, value_type>::value),
467bdd1243dSDimitry Andric                "Allocator::value_type must be same type as value_type");
4680b57cec5SDimitry Andric
469bdd1243dSDimitry Andric  using allocator_type = _Allocator;
470bdd1243dSDimitry Andric  using __alloc_traits = allocator_traits<allocator_type>;
4710b57cec5SDimitry Andric
472bdd1243dSDimitry Andric  using size_type       = typename __alloc_traits::size_type;
473bdd1243dSDimitry Andric  using difference_type = typename __alloc_traits::difference_type;
4740b57cec5SDimitry Andric
475bdd1243dSDimitry Andric  using pointer       = typename __alloc_traits::pointer;
476bdd1243dSDimitry Andric  using const_pointer = typename __alloc_traits::const_pointer;
477bdd1243dSDimitry Andric
478bdd1243dSDimitry Andric  using __pointer_allocator       = __rebind_alloc<__alloc_traits, pointer>;
479bdd1243dSDimitry Andric  using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>;
480bdd1243dSDimitry Andric  using __map                     = __split_buffer<pointer, __pointer_allocator>;
481bdd1243dSDimitry Andric  using __map_alloc_traits        = allocator_traits<__pointer_allocator>;
482bdd1243dSDimitry Andric  using __map_pointer             = typename __map_alloc_traits::pointer;
483bdd1243dSDimitry Andric  using __map_const_pointer       = typename allocator_traits<__const_pointer_allocator>::const_pointer;
484*06c3fb27SDimitry Andric  using __map_const_iterator      = typename __map::const_iterator;
485bdd1243dSDimitry Andric
486bdd1243dSDimitry Andric  using reference       = value_type&;
487bdd1243dSDimitry Andric  using const_reference = const value_type&;
488bdd1243dSDimitry Andric
489bdd1243dSDimitry Andric  using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>;
490bdd1243dSDimitry Andric  using const_iterator =
491bdd1243dSDimitry Andric      __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>;
492bdd1243dSDimitry Andric  using reverse_iterator       = std::reverse_iterator<iterator>;
493bdd1243dSDimitry Andric  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
494bdd1243dSDimitry Andric
495bdd1243dSDimitry Andric  static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
496bdd1243dSDimitry Andric                "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
497bdd1243dSDimitry Andric                "original allocator");
498bdd1243dSDimitry Andric  static_assert(is_nothrow_default_constructible<allocator_type>::value ==
499bdd1243dSDimitry Andric                    is_nothrow_default_constructible<__pointer_allocator>::value,
500bdd1243dSDimitry Andric                "rebinding an allocator should not change excpetion guarantees");
501bdd1243dSDimitry Andric  static_assert(is_nothrow_move_constructible<allocator_type>::value ==
502bdd1243dSDimitry Andric                    is_nothrow_move_constructible<typename __map::allocator_type>::value,
503bdd1243dSDimitry Andric                "rebinding an allocator should not change excpetion guarantees");
504bdd1243dSDimitry Andric
505bdd1243dSDimitry Andricprivate:
506e40139ffSDimitry Andric  struct __deque_block_range {
507bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI
508bdd1243dSDimitry Andric    __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {}
509e40139ffSDimitry Andric    const pointer __begin_;
510e40139ffSDimitry Andric    const pointer __end_;
511e40139ffSDimitry Andric  };
512e40139ffSDimitry Andric
513e40139ffSDimitry Andric  struct __deque_range {
514e40139ffSDimitry Andric    iterator __pos_;
515e40139ffSDimitry Andric    const iterator __end_;
516e40139ffSDimitry Andric
517bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT
518e40139ffSDimitry Andric      : __pos_(__pos), __end_(__e) {}
519e40139ffSDimitry Andric
520bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT {
521e40139ffSDimitry Andric      return __pos_ != __end_;
522e40139ffSDimitry Andric    }
523e40139ffSDimitry Andric
524bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range begin() const {
525e40139ffSDimitry Andric      return *this;
526e40139ffSDimitry Andric    }
527e40139ffSDimitry Andric
528bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range end() const {
529e40139ffSDimitry Andric      return __deque_range(__end_, __end_);
530e40139ffSDimitry Andric    }
531bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT {
532e40139ffSDimitry Andric        if (__pos_.__m_iter_ == __end_.__m_iter_) {
533e40139ffSDimitry Andric        return __deque_block_range(__pos_.__ptr_, __end_.__ptr_);
534e40139ffSDimitry Andric      }
535e40139ffSDimitry Andric      return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size);
536e40139ffSDimitry Andric    }
537e40139ffSDimitry Andric
538bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT {
539e40139ffSDimitry Andric      if (__pos_.__m_iter_ == __end_.__m_iter_) {
540e40139ffSDimitry Andric        __pos_ = __end_;
541e40139ffSDimitry Andric      } else {
542e40139ffSDimitry Andric        ++__pos_.__m_iter_;
543e40139ffSDimitry Andric        __pos_.__ptr_ = *__pos_.__m_iter_;
544e40139ffSDimitry Andric      }
545e40139ffSDimitry Andric      return *this;
546e40139ffSDimitry Andric    }
547e40139ffSDimitry Andric
548e40139ffSDimitry Andric
549bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) {
550e40139ffSDimitry Andric      return __lhs.__pos_ == __rhs.__pos_;
551e40139ffSDimitry Andric    }
552bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) {
553e40139ffSDimitry Andric      return !(__lhs == __rhs);
554e40139ffSDimitry Andric    }
555e40139ffSDimitry Andric  };
556e40139ffSDimitry Andric
557e40139ffSDimitry Andric  struct _ConstructTransaction {
558bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r)
559e40139ffSDimitry Andric      : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {}
560e40139ffSDimitry Andric
561e40139ffSDimitry Andric
562bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
563bdd1243dSDimitry Andric      __base_->__size() += (__pos_ - __begin_);
564e40139ffSDimitry Andric    }
565e40139ffSDimitry Andric
566e40139ffSDimitry Andric    pointer __pos_;
567e40139ffSDimitry Andric    const pointer __end_;
568e40139ffSDimitry Andric  private:
569e40139ffSDimitry Andric    const pointer __begin_;
570bdd1243dSDimitry Andric    deque* const __base_;
571e40139ffSDimitry Andric  };
572e40139ffSDimitry Andric
573bdd1243dSDimitry Andric  static const difference_type __block_size;
574bdd1243dSDimitry Andric
5750b57cec5SDimitry Andric  __map __map_;
5760b57cec5SDimitry Andric  size_type __start_;
5770b57cec5SDimitry Andric  __compressed_pair<size_type, allocator_type> __size_;
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andricpublic:
580bdd1243dSDimitry Andric
581bdd1243dSDimitry Andric    // construct/copy/destroy:
582bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
583bdd1243dSDimitry Andric    deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
584*06c3fb27SDimitry Andric        : __start_(0), __size_(0, __default_init_tag()) {
585*06c3fb27SDimitry Andric      __annotate_new(0);
586*06c3fb27SDimitry Andric    }
587bdd1243dSDimitry Andric
588bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~deque() {
589bdd1243dSDimitry Andric      clear();
590*06c3fb27SDimitry Andric      __annotate_delete();
591bdd1243dSDimitry Andric      typename __map::iterator __i = __map_.begin();
592bdd1243dSDimitry Andric      typename __map::iterator __e = __map_.end();
593bdd1243dSDimitry Andric      for (; __i != __e; ++__i)
594bdd1243dSDimitry Andric          __alloc_traits::deallocate(__alloc(), *__i, __block_size);
595bdd1243dSDimitry Andric    }
596bdd1243dSDimitry Andric
597bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a)
598*06c3fb27SDimitry Andric        : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {
599*06c3fb27SDimitry Andric      __annotate_new(0);
600*06c3fb27SDimitry Andric    }
601bdd1243dSDimitry Andric
602bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n);
603*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
604bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a);
605bdd1243dSDimitry Andric#endif
606bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v);
607bdd1243dSDimitry Andric
608bdd1243dSDimitry Andric    template <class = __enable_if_t<__is_allocator<_Allocator>::value> >
609bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a)
610bdd1243dSDimitry Andric        : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
611bdd1243dSDimitry Andric    {
612*06c3fb27SDimitry Andric        __annotate_new(0);
613bdd1243dSDimitry Andric        if (__n > 0)
614bdd1243dSDimitry Andric            __append(__n, __v);
615bdd1243dSDimitry Andric    }
616bdd1243dSDimitry Andric
617bdd1243dSDimitry Andric    template <class _InputIter>
618bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l,
619*06c3fb27SDimitry Andric              typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0);
620bdd1243dSDimitry Andric    template <class _InputIter>
621bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
622*06c3fb27SDimitry Andric              typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0);
623*06c3fb27SDimitry Andric
624*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
625*06c3fb27SDimitry Andric  template <_ContainerCompatibleRange<_Tp> _Range>
626*06c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range,
627*06c3fb27SDimitry Andric      const allocator_type& __a = allocator_type())
628*06c3fb27SDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {
629*06c3fb27SDimitry Andric    if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
630*06c3fb27SDimitry Andric      __append_with_size(ranges::begin(__range), ranges::distance(__range));
631*06c3fb27SDimitry Andric
632*06c3fb27SDimitry Andric    } else {
633*06c3fb27SDimitry Andric      for (auto&& __e : __range) {
634*06c3fb27SDimitry Andric        emplace_back(std::forward<decltype(__e)>(__e));
635*06c3fb27SDimitry Andric      }
636*06c3fb27SDimitry Andric    }
637*06c3fb27SDimitry Andric  }
638*06c3fb27SDimitry Andric#endif
639*06c3fb27SDimitry Andric
640bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(const deque& __c);
641bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a);
642bdd1243dSDimitry Andric
643bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c);
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
646bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il);
647bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a);
648bdd1243dSDimitry Andric
649bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
650bdd1243dSDimitry Andric    deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
651bdd1243dSDimitry Andric
652bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
653bdd1243dSDimitry Andric    deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
654bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
655bdd1243dSDimitry Andric    deque(deque&& __c, const __type_identity_t<allocator_type>& __a);
656bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
657bdd1243dSDimitry Andric    deque& operator=(deque&& __c)
658bdd1243dSDimitry Andric        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
659bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value);
660bdd1243dSDimitry Andric
661bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
662bdd1243dSDimitry Andric    void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
6630b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
6640b57cec5SDimitry Andric
665bdd1243dSDimitry Andric    template <class _InputIter>
666bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l,
667*06c3fb27SDimitry Andric                    typename enable_if<__has_input_iterator_category<_InputIter>::value &&
668*06c3fb27SDimitry Andric                                      !__has_random_access_iterator_category<_InputIter>::value>::type* = 0);
669bdd1243dSDimitry Andric    template <class _RAIter>
670bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l,
671*06c3fb27SDimitry Andric                    typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type* = 0);
672*06c3fb27SDimitry Andric
673*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
674*06c3fb27SDimitry Andric    template <_ContainerCompatibleRange<_Tp> _Range>
675*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
676*06c3fb27SDimitry Andric    void assign_range(_Range&& __range) {
677*06c3fb27SDimitry Andric      if constexpr (ranges::random_access_range<_Range>) {
678*06c3fb27SDimitry Andric        auto __n = static_cast<size_type>(ranges::distance(__range));
679*06c3fb27SDimitry Andric        __assign_with_size_random_access(ranges::begin(__range), __n);
680*06c3fb27SDimitry Andric
681*06c3fb27SDimitry Andric      } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
682*06c3fb27SDimitry Andric        auto __n = static_cast<size_type>(ranges::distance(__range));
683*06c3fb27SDimitry Andric        __assign_with_size(ranges::begin(__range), __n);
684*06c3fb27SDimitry Andric
685*06c3fb27SDimitry Andric      } else {
686*06c3fb27SDimitry Andric        __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
687*06c3fb27SDimitry Andric      }
688*06c3fb27SDimitry Andric    }
689*06c3fb27SDimitry Andric#endif
690*06c3fb27SDimitry Andric
691bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
692bdd1243dSDimitry Andric
693bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
694bdd1243dSDimitry Andric    allocator_type get_allocator() const _NOEXCEPT;
695bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); }
696bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); }
697bdd1243dSDimitry Andric
698bdd1243dSDimitry Andric  // iterators:
699bdd1243dSDimitry Andric
700bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
701bdd1243dSDimitry Andric      __map_pointer __mp = __map_.begin() + __start_ / __block_size;
702bdd1243dSDimitry Andric      return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
703bdd1243dSDimitry Andric  }
704bdd1243dSDimitry Andric
705bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
706bdd1243dSDimitry Andric      __map_const_pointer __mp =
707bdd1243dSDimitry Andric          static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
708bdd1243dSDimitry Andric      return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
709bdd1243dSDimitry Andric  }
710bdd1243dSDimitry Andric
711bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
712bdd1243dSDimitry Andric      size_type __p      = size() + __start_;
713bdd1243dSDimitry Andric      __map_pointer __mp = __map_.begin() + __p / __block_size;
714bdd1243dSDimitry Andric      return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
715bdd1243dSDimitry Andric  }
716bdd1243dSDimitry Andric
717bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
718bdd1243dSDimitry Andric      size_type __p            = size() + __start_;
719bdd1243dSDimitry Andric      __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
720bdd1243dSDimitry Andric      return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
721bdd1243dSDimitry Andric  }
722bdd1243dSDimitry Andric
723bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
724bdd1243dSDimitry Andric    reverse_iterator       rbegin() _NOEXCEPT
725bdd1243dSDimitry Andric        {return       reverse_iterator(end());}
726bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
727bdd1243dSDimitry Andric    const_reverse_iterator rbegin() const _NOEXCEPT
728bdd1243dSDimitry Andric        {return const_reverse_iterator(end());}
729bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
730bdd1243dSDimitry Andric    reverse_iterator       rend() _NOEXCEPT
731bdd1243dSDimitry Andric        {return       reverse_iterator(begin());}
732bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
733bdd1243dSDimitry Andric    const_reverse_iterator rend()   const _NOEXCEPT
734bdd1243dSDimitry Andric        {return const_reverse_iterator(begin());}
735bdd1243dSDimitry Andric
736bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
737bdd1243dSDimitry Andric    const_iterator         cbegin()  const _NOEXCEPT
738bdd1243dSDimitry Andric        {return begin();}
739bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
740bdd1243dSDimitry Andric    const_iterator         cend()    const _NOEXCEPT
741bdd1243dSDimitry Andric        {return end();}
742bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
743bdd1243dSDimitry Andric    const_reverse_iterator crbegin() const _NOEXCEPT
744bdd1243dSDimitry Andric        {return const_reverse_iterator(end());}
745bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
746bdd1243dSDimitry Andric    const_reverse_iterator crend()   const _NOEXCEPT
747bdd1243dSDimitry Andric        {return const_reverse_iterator(begin());}
748bdd1243dSDimitry Andric
749bdd1243dSDimitry Andric    // capacity:
750bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
751bdd1243dSDimitry Andric    size_type size() const _NOEXCEPT {return __size();}
752bdd1243dSDimitry Andric
753bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); }
754bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); }
755bdd1243dSDimitry Andric
756bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
757bdd1243dSDimitry Andric    size_type max_size() const _NOEXCEPT
758bdd1243dSDimitry Andric        {return _VSTD::min<size_type>(
759bdd1243dSDimitry Andric            __alloc_traits::max_size(__alloc()),
760bdd1243dSDimitry Andric            numeric_limits<difference_type>::max());}
761bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
762bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
763bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
764bdd1243dSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
765bdd1243dSDimitry Andric    bool empty() const _NOEXCEPT {return size() == 0;}
766bdd1243dSDimitry Andric
767bdd1243dSDimitry Andric    // element access:
768bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
769bdd1243dSDimitry Andric    reference operator[](size_type __i) _NOEXCEPT;
770bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
771bdd1243dSDimitry Andric    const_reference operator[](size_type __i) const _NOEXCEPT;
772bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
773bdd1243dSDimitry Andric    reference at(size_type __i);
774bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
775bdd1243dSDimitry Andric    const_reference at(size_type __i) const;
776bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
777bdd1243dSDimitry Andric    reference front() _NOEXCEPT;
778bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
779bdd1243dSDimitry Andric    const_reference front() const _NOEXCEPT;
780bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
781bdd1243dSDimitry Andric    reference back() _NOEXCEPT;
782bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
783bdd1243dSDimitry Andric    const_reference back() const _NOEXCEPT;
784bdd1243dSDimitry Andric
785bdd1243dSDimitry Andric    // 23.2.2.3 modifiers:
786bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
787bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v);
788bdd1243dSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
789*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
790bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
791bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args);
792bdd1243dSDimitry Andric#else
793bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI void      emplace_front(_Args&&... __args);
794bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI void      emplace_back (_Args&&... __args);
795bdd1243dSDimitry Andric#endif
796bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args);
797bdd1243dSDimitry Andric
798bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
799bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v);
800*06c3fb27SDimitry Andric
801*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
802*06c3fb27SDimitry Andric    template <_ContainerCompatibleRange<_Tp> _Range>
803*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
804*06c3fb27SDimitry Andric    void prepend_range(_Range&& __range) {
805*06c3fb27SDimitry Andric      insert_range(begin(), std::forward<_Range>(__range));
806*06c3fb27SDimitry Andric    }
807*06c3fb27SDimitry Andric
808*06c3fb27SDimitry Andric    template <_ContainerCompatibleRange<_Tp> _Range>
809*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
810*06c3fb27SDimitry Andric    void append_range(_Range&& __range) {
811*06c3fb27SDimitry Andric      insert_range(end(), std::forward<_Range>(__range));
812*06c3fb27SDimitry Andric    }
813*06c3fb27SDimitry Andric#endif
814*06c3fb27SDimitry Andric
815bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v);
816bdd1243dSDimitry Andric
817bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
818bdd1243dSDimitry Andric    iterator insert(const_iterator __p, initializer_list<value_type> __il)
819bdd1243dSDimitry Andric        {return insert(__p, __il.begin(), __il.end());}
820bdd1243dSDimitry Andric#endif // _LIBCPP_CXX03_LANG
821bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v);
822bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v);
823bdd1243dSDimitry Andric    template <class _InputIter>
824bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
825*06c3fb27SDimitry Andric                         typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type* = 0);
826bdd1243dSDimitry Andric    template <class _ForwardIterator>
827bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
828*06c3fb27SDimitry Andric                        typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type* = 0);
829bdd1243dSDimitry Andric    template <class _BiIter>
830bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
831*06c3fb27SDimitry Andric                         typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type* = 0);
832*06c3fb27SDimitry Andric
833*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
834*06c3fb27SDimitry Andric    template <_ContainerCompatibleRange<_Tp> _Range>
835*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
836*06c3fb27SDimitry Andric    iterator insert_range(const_iterator __position, _Range&& __range) {
837*06c3fb27SDimitry Andric      if constexpr (ranges::bidirectional_range<_Range>) {
838*06c3fb27SDimitry Andric        auto __n = static_cast<size_type>(ranges::distance(__range));
839*06c3fb27SDimitry Andric        return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n);
840*06c3fb27SDimitry Andric
841*06c3fb27SDimitry Andric      } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
842*06c3fb27SDimitry Andric        auto __n = static_cast<size_type>(ranges::distance(__range));
843*06c3fb27SDimitry Andric        return __insert_with_size(__position, ranges::begin(__range), __n);
844*06c3fb27SDimitry Andric
845*06c3fb27SDimitry Andric      } else {
846*06c3fb27SDimitry Andric        return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
847*06c3fb27SDimitry Andric      }
848*06c3fb27SDimitry Andric    }
849*06c3fb27SDimitry Andric#endif
850bdd1243dSDimitry Andric
851bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void pop_front();
852bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void pop_back();
853bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
854bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
855bdd1243dSDimitry Andric
856bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
857bdd1243dSDimitry Andric    void swap(deque& __c)
8580b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
8590b57cec5SDimitry Andric        _NOEXCEPT;
8600b57cec5SDimitry Andric#else
8610b57cec5SDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
8620b57cec5SDimitry Andric                   __is_nothrow_swappable<allocator_type>::value);
8630b57cec5SDimitry Andric#endif
864bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8650b57cec5SDimitry Andric    void clear() _NOEXCEPT;
8660b57cec5SDimitry Andric
867bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
868bdd1243dSDimitry Andric    bool __invariants() const {
8690b57cec5SDimitry Andric        if (!__map_.__invariants())
8700b57cec5SDimitry Andric            return false;
8710b57cec5SDimitry Andric        if (__map_.size() >= size_type(-1) / __block_size)
8720b57cec5SDimitry Andric            return false;
873*06c3fb27SDimitry Andric        for (__map_const_iterator __i = __map_.begin(), __e = __map_.end();
8740b57cec5SDimitry Andric            __i != __e; ++__i)
8750b57cec5SDimitry Andric            if (*__i == nullptr)
8760b57cec5SDimitry Andric                return false;
8770b57cec5SDimitry Andric        if (__map_.size() != 0)
8780b57cec5SDimitry Andric        {
8790b57cec5SDimitry Andric            if (size() >= __map_.size() * __block_size)
8800b57cec5SDimitry Andric                return false;
8810b57cec5SDimitry Andric            if (__start_ >= __map_.size() * __block_size - size())
8820b57cec5SDimitry Andric                return false;
8830b57cec5SDimitry Andric        }
8840b57cec5SDimitry Andric        else
8850b57cec5SDimitry Andric        {
8860b57cec5SDimitry Andric            if (size() != 0)
8870b57cec5SDimitry Andric                return false;
8880b57cec5SDimitry Andric            if (__start_ != 0)
8890b57cec5SDimitry Andric                return false;
8900b57cec5SDimitry Andric        }
8910b57cec5SDimitry Andric        return true;
8920b57cec5SDimitry Andric    }
8930b57cec5SDimitry Andric
894bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
895bdd1243dSDimitry Andric    void __move_assign_alloc(deque& __c)
896bdd1243dSDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
897bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value)
898bdd1243dSDimitry Andric        {__move_assign_alloc(__c, integral_constant<bool,
899bdd1243dSDimitry Andric                      __alloc_traits::propagate_on_container_move_assignment::value>());}
900bdd1243dSDimitry Andric
901bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
902bdd1243dSDimitry Andric    void __move_assign_alloc(deque& __c, true_type)
903bdd1243dSDimitry Andric        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
9040b57cec5SDimitry Andric        {
905bdd1243dSDimitry Andric            __alloc() = _VSTD::move(__c.__alloc());
9060b57cec5SDimitry Andric        }
9070b57cec5SDimitry Andric
908bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
909bdd1243dSDimitry Andric    void __move_assign_alloc(deque&, false_type) _NOEXCEPT
9100b57cec5SDimitry Andric        {}
9114824e7fdSDimitry Andric
912bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
913bdd1243dSDimitry Andric    void __move_assign(deque& __c)
914bdd1243dSDimitry Andric        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
915bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value)
9164824e7fdSDimitry Andric    {
917bdd1243dSDimitry Andric        __map_ = _VSTD::move(__c.__map_);
918bdd1243dSDimitry Andric        __start_ = __c.__start_;
919bdd1243dSDimitry Andric        __size() = __c.size();
920bdd1243dSDimitry Andric        __move_assign_alloc(__c);
921bdd1243dSDimitry Andric        __c.__start_ = __c.__size() = 0;
9224824e7fdSDimitry Andric    }
9234824e7fdSDimitry Andric
924bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9250b57cec5SDimitry Andric    static size_type __recommend_blocks(size_type __n)
9260b57cec5SDimitry Andric    {
927bdd1243dSDimitry Andric        return __n / __block_size + (__n % __block_size != 0);
9280b57cec5SDimitry Andric    }
929bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9300b57cec5SDimitry Andric    size_type __capacity() const
9310b57cec5SDimitry Andric    {
932bdd1243dSDimitry Andric        return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1;
9330b57cec5SDimitry Andric    }
934bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
935e40139ffSDimitry Andric    size_type __block_count() const
936e40139ffSDimitry Andric    {
937bdd1243dSDimitry Andric        return __map_.size();
938e40139ffSDimitry Andric    }
939e40139ffSDimitry Andric
940bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9410b57cec5SDimitry Andric    size_type __front_spare() const
9420b57cec5SDimitry Andric    {
943bdd1243dSDimitry Andric        return __start_;
9440b57cec5SDimitry Andric    }
945bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
946e40139ffSDimitry Andric    size_type __front_spare_blocks() const {
947bdd1243dSDimitry Andric      return __front_spare() / __block_size;
948e40139ffSDimitry Andric    }
949bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9500b57cec5SDimitry Andric    size_type __back_spare() const
9510b57cec5SDimitry Andric    {
952bdd1243dSDimitry Andric        return __capacity() - (__start_ + size());
9530b57cec5SDimitry Andric    }
954bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
955e40139ffSDimitry Andric    size_type __back_spare_blocks() const {
956bdd1243dSDimitry Andric      return __back_spare() / __block_size;
957e40139ffSDimitry Andric    }
958e40139ffSDimitry Andric
959e40139ffSDimitry Andric private:
960*06c3fb27SDimitry Andric   enum __asan_annotation_type {
961*06c3fb27SDimitry Andric     __asan_unposion,
962*06c3fb27SDimitry Andric     __asan_poison
963*06c3fb27SDimitry Andric   };
964*06c3fb27SDimitry Andric
965*06c3fb27SDimitry Andric   enum __asan_annotation_place {
966*06c3fb27SDimitry Andric     __asan_front_moved,
967*06c3fb27SDimitry Andric     __asan_back_moved,
968*06c3fb27SDimitry Andric   };
969*06c3fb27SDimitry Andric
970*06c3fb27SDimitry Andric// The following functions are no-ops outside of AddressSanitizer mode.
971*06c3fb27SDimitry Andric// We call annotations for every allocator, unless explicitly disabled.
972*06c3fb27SDimitry Andric//
973*06c3fb27SDimitry Andric// To disable annotations for a particular allocator, change value of
974*06c3fb27SDimitry Andric// __asan_annotate_container_with_allocator to false.
975*06c3fb27SDimitry Andric// For more details, see the "Using libc++" documentation page or
976*06c3fb27SDimitry Andric// the documentation for __sanitizer_annotate_contiguous_container.
977*06c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600
978*06c3fb27SDimitry Andric    // TODO LLVM18: Remove the special-casing
979*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container(
980*06c3fb27SDimitry Andric        const void* __beg,
981*06c3fb27SDimitry Andric        const void* __end,
982*06c3fb27SDimitry Andric        const void* __old_con_beg,
983*06c3fb27SDimitry Andric        const void* __old_con_end,
984*06c3fb27SDimitry Andric        const void* __new_con_beg,
985*06c3fb27SDimitry Andric        const void* __new_con_end) const {
986*06c3fb27SDimitry Andric        if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value)
987*06c3fb27SDimitry Andric            __sanitizer_annotate_double_ended_contiguous_container(
988*06c3fb27SDimitry Andric                __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end);
989*06c3fb27SDimitry Andric    }
990*06c3fb27SDimitry Andric#else
991*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container(
992*06c3fb27SDimitry Andric        const void*, const void*, const void*, const void*, const void*, const void*) const _NOEXCEPT {}
993*06c3fb27SDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600
994*06c3fb27SDimitry Andric
995*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
996*06c3fb27SDimitry Andric    void __annotate_from_to(size_type __beg, size_type __end, __asan_annotation_type __annotation_type, __asan_annotation_place __place) const _NOEXCEPT {
997*06c3fb27SDimitry Andric        // __beg - index of the first item to annotate
998*06c3fb27SDimitry Andric        // __end - index behind the last item to annotate (so last item + 1)
999*06c3fb27SDimitry Andric        // __annotation_type - __asan_unposion or __asan_poison
1000*06c3fb27SDimitry Andric        // __place - __asan_front_moved or __asan_back_moved
1001*06c3fb27SDimitry Andric        // Note: All indexes in __map_
1002*06c3fb27SDimitry Andric        if (__beg == __end)
1003*06c3fb27SDimitry Andric            return;
1004*06c3fb27SDimitry Andric        // __annotations_beg_map - first chunk which annotations we want to modify
1005*06c3fb27SDimitry Andric        // __annotations_end_map - last chunk which annotations we want to modify
1006*06c3fb27SDimitry Andric        // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist
1007*06c3fb27SDimitry Andric        __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size;
1008*06c3fb27SDimitry Andric        __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size;
1009*06c3fb27SDimitry Andric
1010*06c3fb27SDimitry Andric        bool const __poisoning = __annotation_type == __asan_poison;
1011*06c3fb27SDimitry Andric        // __old_c_beg_index - index of the first element in old container
1012*06c3fb27SDimitry Andric        // __old_c_end_index - index of the end of old container (last + 1)
1013*06c3fb27SDimitry Andric        // Note: may be outside the area we are annotating
1014*06c3fb27SDimitry Andric        size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_;
1015*06c3fb27SDimitry Andric        size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved)  ? __end : __start_ + size();
1016*06c3fb27SDimitry Andric        bool const __front = __place == __asan_front_moved;
1017*06c3fb27SDimitry Andric
1018*06c3fb27SDimitry Andric        if (__poisoning && empty()) {
1019*06c3fb27SDimitry Andric            // Special case: we shouldn't trust __start_
1020*06c3fb27SDimitry Andric            __old_c_beg_index = __beg;
1021*06c3fb27SDimitry Andric            __old_c_end_index = __end;
1022*06c3fb27SDimitry Andric        }
1023*06c3fb27SDimitry Andric        // __old_c_beg_map - memory block (chunk) with first element
1024*06c3fb27SDimitry Andric        // __old_c_end_map - memory block (chunk) with end of old container
1025*06c3fb27SDimitry Andric        // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block,
1026*06c3fb27SDimitry Andric        // which may not exist
1027*06c3fb27SDimitry Andric        __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size;
1028*06c3fb27SDimitry Andric        __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size;
1029*06c3fb27SDimitry Andric
1030*06c3fb27SDimitry Andric        // One edge (front/end) of the container was moved and one was not modified.
1031*06c3fb27SDimitry Andric        // __new_edge_index - index of new edge
1032*06c3fb27SDimitry Andric        // __new_edge_map    - memory block (chunk) with new edge, it always equals to
1033*06c3fb27SDimitry Andric        //                    __annotations_beg_map or __annotations_end_map
1034*06c3fb27SDimitry Andric        // __old_edge_map    - memory block (chunk) with old edge, it always equals to
1035*06c3fb27SDimitry Andric        //                    __old_c_beg_map or __old_c_end_map
1036*06c3fb27SDimitry Andric        size_t __new_edge_index                      = (__poisoning ^ __front) ? __beg : __end;
1037*06c3fb27SDimitry Andric        __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size;
1038*06c3fb27SDimitry Andric        __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map;
1039*06c3fb27SDimitry Andric
1040*06c3fb27SDimitry Andric        // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last.
1041*06c3fb27SDimitry Andric        // First and last chunk may be partially poisoned.
1042*06c3fb27SDimitry Andric        // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it.
1043*06c3fb27SDimitry Andric        for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) {
1044*06c3fb27SDimitry Andric            if (__map_it == __annotations_end_map && __end % __block_size == 0)
1045*06c3fb27SDimitry Andric                // Chunk may not exist, but nothing to do here anyway
1046*06c3fb27SDimitry Andric                break;
1047*06c3fb27SDimitry Andric
1048*06c3fb27SDimitry Andric            // The beginning and the end of the current memory block
1049*06c3fb27SDimitry Andric            const void* __mem_beg = std::__to_address(*__map_it);
1050*06c3fb27SDimitry Andric            const void* __mem_end = std::__to_address(*__map_it + __block_size);
1051*06c3fb27SDimitry Andric
1052*06c3fb27SDimitry Andric            // The beginning of memory-in-use in the memory block before container modification
1053*06c3fb27SDimitry Andric            const void* __old_beg =
1054*06c3fb27SDimitry Andric                (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg;
1055*06c3fb27SDimitry Andric
1056*06c3fb27SDimitry Andric            // The end of memory-in-use in the memory block before container modification
1057*06c3fb27SDimitry Andric            const void* __old_end;
1058*06c3fb27SDimitry Andric            if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty()))
1059*06c3fb27SDimitry Andric                __old_end = __old_beg;
1060*06c3fb27SDimitry Andric            else
1061*06c3fb27SDimitry Andric                __old_end = (__map_it == __old_c_end_map) ? std::__to_address(*__map_it + (__old_c_end_index % __block_size))
1062*06c3fb27SDimitry Andric                                                   : __mem_end;
1063*06c3fb27SDimitry Andric
1064*06c3fb27SDimitry Andric            // New edge of the container in current memory block
1065*06c3fb27SDimitry Andric            // If the edge is in a different chunk it points on corresponding end of the memory block
1066*06c3fb27SDimitry Andric            const void* __new_edge;
1067*06c3fb27SDimitry Andric            if (__map_it == __new_edge_map)
1068*06c3fb27SDimitry Andric                __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size));
1069*06c3fb27SDimitry Andric            else
1070*06c3fb27SDimitry Andric                __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end;
1071*06c3fb27SDimitry Andric
1072*06c3fb27SDimitry Andric            // Not modified edge of the container
1073*06c3fb27SDimitry Andric            // If the edge is in a different chunk it points on corresponding end of the memory block
1074*06c3fb27SDimitry Andric            const void* __old_edge;
1075*06c3fb27SDimitry Andric            if (__map_it == __old_edge_map)
1076*06c3fb27SDimitry Andric                __old_edge = __front ? __old_end : __old_beg;
1077*06c3fb27SDimitry Andric            else
1078*06c3fb27SDimitry Andric                __old_edge = __front ? __mem_end : __mem_beg;
1079*06c3fb27SDimitry Andric
1080*06c3fb27SDimitry Andric            // __new_beg - the beginning of memory-in-use in the memory block after container modification
1081*06c3fb27SDimitry Andric            // __new_end - the end of memory-in-use in the memory block after container modification
1082*06c3fb27SDimitry Andric            const void* __new_beg = __front ? __new_edge : __old_edge;
1083*06c3fb27SDimitry Andric            const void* __new_end = __front ? __old_edge : __new_edge;
1084*06c3fb27SDimitry Andric
1085*06c3fb27SDimitry Andric            __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end);
1086*06c3fb27SDimitry Andric        }
1087*06c3fb27SDimitry Andric    }
1088*06c3fb27SDimitry Andric
1089*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1090*06c3fb27SDimitry Andric    void __annotate_new(size_type __current_size) const _NOEXCEPT {
1091*06c3fb27SDimitry Andric        if (__current_size == 0)
1092*06c3fb27SDimitry Andric            __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved);
1093*06c3fb27SDimitry Andric        else {
1094*06c3fb27SDimitry Andric            __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved);
1095*06c3fb27SDimitry Andric            __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved);
1096*06c3fb27SDimitry Andric        }
1097*06c3fb27SDimitry Andric    }
1098*06c3fb27SDimitry Andric
1099*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1100*06c3fb27SDimitry Andric    void __annotate_delete() const _NOEXCEPT {
1101*06c3fb27SDimitry Andric        if (empty()) {
1102*06c3fb27SDimitry Andric            for(size_t __i = 0; __i < __map_.size(); ++__i) {
1103*06c3fb27SDimitry Andric                __annotate_whole_block(__i, __asan_unposion);
1104*06c3fb27SDimitry Andric            }
1105*06c3fb27SDimitry Andric        }
1106*06c3fb27SDimitry Andric        else {
1107*06c3fb27SDimitry Andric            __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved);
1108*06c3fb27SDimitry Andric            __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved);
1109*06c3fb27SDimitry Andric        }
1110*06c3fb27SDimitry Andric    }
1111*06c3fb27SDimitry Andric
1112*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1113*06c3fb27SDimitry Andric    void __annotate_increase_front(size_type __n) const _NOEXCEPT {
1114*06c3fb27SDimitry Andric        __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved);
1115*06c3fb27SDimitry Andric    }
1116*06c3fb27SDimitry Andric
1117*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1118*06c3fb27SDimitry Andric    void __annotate_increase_back(size_type __n) const _NOEXCEPT {
1119*06c3fb27SDimitry Andric        __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved);
1120*06c3fb27SDimitry Andric    }
1121*06c3fb27SDimitry Andric
1122*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1123*06c3fb27SDimitry Andric    void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT {
1124*06c3fb27SDimitry Andric        __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved);
1125*06c3fb27SDimitry Andric    }
1126*06c3fb27SDimitry Andric
1127*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1128*06c3fb27SDimitry Andric    void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT {
1129*06c3fb27SDimitry Andric        __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved);
1130*06c3fb27SDimitry Andric    }
1131*06c3fb27SDimitry Andric
1132*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1133*06c3fb27SDimitry Andric    void __annotate_poison_block(const void *__beginning, const void *__end) const _NOEXCEPT {
1134*06c3fb27SDimitry Andric        __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end);
1135*06c3fb27SDimitry Andric    }
1136*06c3fb27SDimitry Andric
1137*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1138*06c3fb27SDimitry Andric    void __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT {
1139*06c3fb27SDimitry Andric        __map_const_iterator __block_it = __map_.begin() + __block_index;
1140*06c3fb27SDimitry Andric        const void* __block_start = std::__to_address(*__block_it);
1141*06c3fb27SDimitry Andric        const void* __block_end = std::__to_address(*__block_it + __block_size);
1142*06c3fb27SDimitry Andric
1143*06c3fb27SDimitry Andric        if(__annotation_type == __asan_poison)
1144*06c3fb27SDimitry Andric            __annotate_poison_block(__block_start, __block_end);
1145*06c3fb27SDimitry Andric        else {
1146*06c3fb27SDimitry Andric            __annotate_double_ended_contiguous_container(
1147*06c3fb27SDimitry Andric                __block_start, __block_end, __block_start, __block_start, __block_start, __block_end);
1148*06c3fb27SDimitry Andric        }
1149*06c3fb27SDimitry Andric    }
1150*06c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN)
1151*06c3fb27SDimitry Andric
1152*06c3fb27SDimitry Andric  public:
1153*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1154*06c3fb27SDimitry Andric    bool __verify_asan_annotations() const _NOEXCEPT {
1155*06c3fb27SDimitry Andric        // This function tests deque object annotations.
1156*06c3fb27SDimitry Andric        if (empty()) {
1157*06c3fb27SDimitry Andric            for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
1158*06c3fb27SDimitry Andric                if (!__sanitizer_verify_double_ended_contiguous_container(
1159*06c3fb27SDimitry Andric                        std::__to_address(*__it),
1160*06c3fb27SDimitry Andric                        std::__to_address(*__it),
1161*06c3fb27SDimitry Andric                        std::__to_address(*__it),
1162*06c3fb27SDimitry Andric                        std::__to_address(*__it + __block_size)))
1163*06c3fb27SDimitry Andric                  return false;
1164*06c3fb27SDimitry Andric            }
1165*06c3fb27SDimitry Andric
1166*06c3fb27SDimitry Andric            return true;
1167*06c3fb27SDimitry Andric        }
1168*06c3fb27SDimitry Andric
1169*06c3fb27SDimitry Andric        size_type __end                           = __start_ + size();
1170*06c3fb27SDimitry Andric        __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size;
1171*06c3fb27SDimitry Andric        __map_const_iterator __last_mp  = __map_.begin() + (__end - 1) / __block_size;
1172*06c3fb27SDimitry Andric
1173*06c3fb27SDimitry Andric        // Pointers to first and after last elements
1174*06c3fb27SDimitry Andric        // Those can be in different deque blocks
1175*06c3fb27SDimitry Andric        const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size));
1176*06c3fb27SDimitry Andric        const void* __p_end =
1177*06c3fb27SDimitry Andric            std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size));
1178*06c3fb27SDimitry Andric
1179*06c3fb27SDimitry Andric        for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
1180*06c3fb27SDimitry Andric            // Go over all blocks, find the place we are in and verify its annotations
1181*06c3fb27SDimitry Andric            // Note that __p_end points *behind* the last item.
1182*06c3fb27SDimitry Andric
1183*06c3fb27SDimitry Andric            // - blocks before the first block with container elements
1184*06c3fb27SDimitry Andric            // - first block with items
1185*06c3fb27SDimitry Andric            // - last block with items
1186*06c3fb27SDimitry Andric            // - blocks after last block with ciontainer elements
1187*06c3fb27SDimitry Andric
1188*06c3fb27SDimitry Andric            // Is the block before or after deque blocks that contain elements?
1189*06c3fb27SDimitry Andric            if (__it < __first_mp || __it > __last_mp) {
1190*06c3fb27SDimitry Andric                if (!__sanitizer_verify_double_ended_contiguous_container(
1191*06c3fb27SDimitry Andric                        std::__to_address(*__it),
1192*06c3fb27SDimitry Andric                        std::__to_address(*__it),
1193*06c3fb27SDimitry Andric                        std::__to_address(*__it),
1194*06c3fb27SDimitry Andric                        std::__to_address(*__it + __block_size)))
1195*06c3fb27SDimitry Andric                  return false;
1196*06c3fb27SDimitry Andric            } else {
1197*06c3fb27SDimitry Andric                const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it);
1198*06c3fb27SDimitry Andric                const void* __containers_buffer_end =
1199*06c3fb27SDimitry Andric                    (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size);
1200*06c3fb27SDimitry Andric                if (!__sanitizer_verify_double_ended_contiguous_container(
1201*06c3fb27SDimitry Andric                        std::__to_address(*__it),
1202*06c3fb27SDimitry Andric                        __containers_buffer_beg,
1203*06c3fb27SDimitry Andric                        __containers_buffer_end,
1204*06c3fb27SDimitry Andric                        std::__to_address(*__it + __block_size))) {
1205*06c3fb27SDimitry Andric                  return false;
1206*06c3fb27SDimitry Andric                }
1207*06c3fb27SDimitry Andric            }
1208*06c3fb27SDimitry Andric        }
1209*06c3fb27SDimitry Andric        return true;
1210*06c3fb27SDimitry Andric    }
1211*06c3fb27SDimitry Andric
1212*06c3fb27SDimitry Andric  private:
1213*06c3fb27SDimitry Andric#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS
1214bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1215e40139ffSDimitry Andric    bool __maybe_remove_front_spare(bool __keep_one = true) {
1216e40139ffSDimitry Andric      if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {
1217*06c3fb27SDimitry Andric        __annotate_whole_block(0, __asan_unposion);
1218bdd1243dSDimitry Andric        __alloc_traits::deallocate(__alloc(), __map_.front(),
1219bdd1243dSDimitry Andric                                   __block_size);
1220bdd1243dSDimitry Andric        __map_.pop_front();
1221bdd1243dSDimitry Andric        __start_ -= __block_size;
1222e40139ffSDimitry Andric        return true;
1223e40139ffSDimitry Andric      }
1224e40139ffSDimitry Andric      return false;
1225e40139ffSDimitry Andric    }
1226e40139ffSDimitry Andric
1227bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1228e40139ffSDimitry Andric    bool __maybe_remove_back_spare(bool __keep_one = true) {
1229e40139ffSDimitry Andric      if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {
1230*06c3fb27SDimitry Andric        __annotate_whole_block(__map_.size() - 1, __asan_unposion);
1231bdd1243dSDimitry Andric        __alloc_traits::deallocate(__alloc(), __map_.back(),
1232bdd1243dSDimitry Andric                                   __block_size);
1233bdd1243dSDimitry Andric        __map_.pop_back();
1234e40139ffSDimitry Andric        return true;
1235e40139ffSDimitry Andric      }
1236e40139ffSDimitry Andric      return false;
1237e40139ffSDimitry Andric    }
12380b57cec5SDimitry Andric
1239*06c3fb27SDimitry Andric    template <class _Iterator, class _Sentinel>
1240*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1241*06c3fb27SDimitry Andric    void __assign_with_sentinel(_Iterator __f, _Sentinel __l);
1242*06c3fb27SDimitry Andric
1243*06c3fb27SDimitry Andric    template <class _RandomAccessIterator>
1244*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1245*06c3fb27SDimitry Andric    void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n);
1246*06c3fb27SDimitry Andric    template <class _Iterator>
1247*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1248*06c3fb27SDimitry Andric    void __assign_with_size(_Iterator __f, difference_type __n);
1249*06c3fb27SDimitry Andric
1250*06c3fb27SDimitry Andric    template <class _Iterator, class _Sentinel>
1251*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1252*06c3fb27SDimitry Andric    iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l);
1253*06c3fb27SDimitry Andric
1254*06c3fb27SDimitry Andric    template <class _Iterator>
1255*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1256*06c3fb27SDimitry Andric    iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n);
1257*06c3fb27SDimitry Andric
1258*06c3fb27SDimitry Andric    template <class _BiIter, class _Sentinel>
1259*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1260*06c3fb27SDimitry Andric    iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n);
1261*06c3fb27SDimitry Andric    template <class _BiIter>
1262*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1263*06c3fb27SDimitry Andric    iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n);
1264*06c3fb27SDimitry Andric
12650b57cec5SDimitry Andric    template <class _InpIter>
1266bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l,
1267*06c3fb27SDimitry Andric                 typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type* = 0);
12680b57cec5SDimitry Andric    template <class _ForIter>
1269bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l,
1270*06c3fb27SDimitry Andric                      typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type* = 0);
1271*06c3fb27SDimitry Andric
1272*06c3fb27SDimitry Andric    template <class _InputIterator>
1273*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n);
1274*06c3fb27SDimitry Andric    template <class _InputIterator, class _Sentinel>
1275*06c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l);
1276*06c3fb27SDimitry Andric
1277bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
1278bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v);
1279bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f);
1280bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_front_capacity();
1281bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n);
1282bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_back_capacity();
1283bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n);
1284bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r,
12850b57cec5SDimitry Andric                              const_pointer& __vt);
1286bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
12870b57cec5SDimitry Andric                                       const_pointer& __vt);
1288bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l,
12890b57cec5SDimitry Andric                                    iterator __r, const_pointer& __vt);
1290bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_construct_backward_and_check(iterator __f, iterator __l,
12910b57cec5SDimitry Andric                                             iterator __r, const_pointer& __vt);
12920b57cec5SDimitry Andric
1293bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12940b57cec5SDimitry Andric    void __copy_assign_alloc(const deque& __c)
12950b57cec5SDimitry Andric        {__copy_assign_alloc(__c, integral_constant<bool,
12960b57cec5SDimitry Andric                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
12970b57cec5SDimitry Andric
1298bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12990b57cec5SDimitry Andric    void __copy_assign_alloc(const deque& __c, true_type)
13000b57cec5SDimitry Andric        {
1301bdd1243dSDimitry Andric            if (__alloc() != __c.__alloc())
13020b57cec5SDimitry Andric            {
13030b57cec5SDimitry Andric                clear();
13040b57cec5SDimitry Andric                shrink_to_fit();
13050b57cec5SDimitry Andric            }
1306bdd1243dSDimitry Andric            __alloc() = __c.__alloc();
1307bdd1243dSDimitry Andric            __map_.__alloc() = __c.__map_.__alloc();
13080b57cec5SDimitry Andric        }
13090b57cec5SDimitry Andric
1310bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
13110b57cec5SDimitry Andric    void __copy_assign_alloc(const deque&, false_type)
13120b57cec5SDimitry Andric        {}
13130b57cec5SDimitry Andric
1314bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type)
13150b57cec5SDimitry Andric        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
1316bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type);
13170b57cec5SDimitry Andric};
13180b57cec5SDimitry Andric
1319bdd1243dSDimitry Andrictemplate <class _Tp, class _Alloc>
1320bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size =
1321bdd1243dSDimitry Andric    __deque_block_size<value_type, difference_type>::value;
1322bdd1243dSDimitry Andric
1323349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17
13240b57cec5SDimitry Andrictemplate<class _InputIterator,
1325fe6060f1SDimitry Andric         class _Alloc = allocator<__iter_value_type<_InputIterator>>,
1326*06c3fb27SDimitry Andric         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1327349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Alloc>::value>
13280b57cec5SDimitry Andric         >
13290b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator)
1330fe6060f1SDimitry Andric  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
13310b57cec5SDimitry Andric
13320b57cec5SDimitry Andrictemplate<class _InputIterator,
13330b57cec5SDimitry Andric         class _Alloc,
1334*06c3fb27SDimitry Andric         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1335349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Alloc>::value>
13360b57cec5SDimitry Andric         >
13370b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc)
1338fe6060f1SDimitry Andric  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
13390b57cec5SDimitry Andric#endif
13400b57cec5SDimitry Andric
1341*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
1342*06c3fb27SDimitry Andrictemplate <ranges::input_range _Range,
1343*06c3fb27SDimitry Andric          class _Alloc = allocator<ranges::range_value_t<_Range>>,
1344*06c3fb27SDimitry Andric          class = enable_if_t<__is_allocator<_Alloc>::value>
1345*06c3fb27SDimitry Andric          >
1346*06c3fb27SDimitry Andricdeque(from_range_t, _Range&&, _Alloc = _Alloc())
1347*06c3fb27SDimitry Andric  -> deque<ranges::range_value_t<_Range>, _Alloc>;
1348*06c3fb27SDimitry Andric#endif
1349*06c3fb27SDimitry Andric
13500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13510b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n)
1352bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
13530b57cec5SDimitry Andric{
1354*06c3fb27SDimitry Andric    __annotate_new(0);
13550b57cec5SDimitry Andric    if (__n > 0)
13560b57cec5SDimitry Andric        __append(__n);
13570b57cec5SDimitry Andric}
13580b57cec5SDimitry Andric
1359*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
13600b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13610b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
1362bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
13630b57cec5SDimitry Andric{
1364*06c3fb27SDimitry Andric    __annotate_new(0);
13650b57cec5SDimitry Andric    if (__n > 0)
13660b57cec5SDimitry Andric        __append(__n);
13670b57cec5SDimitry Andric}
13680b57cec5SDimitry Andric#endif
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13710b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
1372bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
13730b57cec5SDimitry Andric{
1374*06c3fb27SDimitry Andric    __annotate_new(0);
13750b57cec5SDimitry Andric    if (__n > 0)
13760b57cec5SDimitry Andric        __append(__n, __v);
13770b57cec5SDimitry Andric}
13780b57cec5SDimitry Andric
13790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13800b57cec5SDimitry Andrictemplate <class _InputIter>
13810b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
1382*06c3fb27SDimitry Andric              typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*)
1383bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
13840b57cec5SDimitry Andric{
1385*06c3fb27SDimitry Andric    __annotate_new(0);
13860b57cec5SDimitry Andric    __append(__f, __l);
13870b57cec5SDimitry Andric}
13880b57cec5SDimitry Andric
13890b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13900b57cec5SDimitry Andrictemplate <class _InputIter>
13910b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1392*06c3fb27SDimitry Andric              typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*)
1393bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
13940b57cec5SDimitry Andric{
1395*06c3fb27SDimitry Andric    __annotate_new(0);
13960b57cec5SDimitry Andric    __append(__f, __l);
13970b57cec5SDimitry Andric}
13980b57cec5SDimitry Andric
13990b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14000b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c)
1401bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))),
1402bdd1243dSDimitry Andric      __start_(0),
1403bdd1243dSDimitry Andric      __size_(0, __map_.__alloc())
14040b57cec5SDimitry Andric{
1405*06c3fb27SDimitry Andric    __annotate_new(0);
14060b57cec5SDimitry Andric    __append(__c.begin(), __c.end());
14070b57cec5SDimitry Andric}
14080b57cec5SDimitry Andric
14090b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
141081ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a)
1411bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
14120b57cec5SDimitry Andric{
1413*06c3fb27SDimitry Andric    __annotate_new(0);
14140b57cec5SDimitry Andric    __append(__c.begin(), __c.end());
14150b57cec5SDimitry Andric}
14160b57cec5SDimitry Andric
14170b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14180b57cec5SDimitry Andricdeque<_Tp, _Allocator>&
14190b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator=(const deque& __c)
14200b57cec5SDimitry Andric{
1421349cc55cSDimitry Andric    if (this != _VSTD::addressof(__c))
14220b57cec5SDimitry Andric    {
14230b57cec5SDimitry Andric        __copy_assign_alloc(__c);
14240b57cec5SDimitry Andric        assign(__c.begin(), __c.end());
14250b57cec5SDimitry Andric    }
14260b57cec5SDimitry Andric    return *this;
14270b57cec5SDimitry Andric}
14280b57cec5SDimitry Andric
14290b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
14300b57cec5SDimitry Andric
14310b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14320b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
1433bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
14340b57cec5SDimitry Andric{
1435*06c3fb27SDimitry Andric    __annotate_new(0);
14360b57cec5SDimitry Andric    __append(__il.begin(), __il.end());
14370b57cec5SDimitry Andric}
14380b57cec5SDimitry Andric
14390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14400b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
1441bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
14420b57cec5SDimitry Andric{
1443*06c3fb27SDimitry Andric    __annotate_new(0);
14440b57cec5SDimitry Andric    __append(__il.begin(), __il.end());
14450b57cec5SDimitry Andric}
14460b57cec5SDimitry Andric
14470b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14480b57cec5SDimitry Andricinline
14490b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(deque&& __c)
1450bdd1243dSDimitry Andric    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
1451bdd1243dSDimitry Andric    : __map_(std::move(__c.__map_)), __start_(std::move(__c.__start_)), __size_(std::move(__c.__size_))
14520b57cec5SDimitry Andric{
1453bdd1243dSDimitry Andric  __c.__start_ = 0;
1454bdd1243dSDimitry Andric  __c.__size() = 0;
14550b57cec5SDimitry Andric}
14560b57cec5SDimitry Andric
14570b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14580b57cec5SDimitry Andricinline
145981ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a)
1460bdd1243dSDimitry Andric    : __map_(std::move(__c.__map_), __pointer_allocator(__a)),
1461bdd1243dSDimitry Andric      __start_(std::move(__c.__start_)),
1462bdd1243dSDimitry Andric      __size_(std::move(__c.__size()), __a)
14630b57cec5SDimitry Andric{
1464bdd1243dSDimitry Andric    if (__a == __c.__alloc())
14650b57cec5SDimitry Andric    {
1466bdd1243dSDimitry Andric        __c.__start_ = 0;
1467bdd1243dSDimitry Andric        __c.__size() = 0;
1468bdd1243dSDimitry Andric    }
1469bdd1243dSDimitry Andric    else
1470bdd1243dSDimitry Andric    {
1471bdd1243dSDimitry Andric        __map_.clear();
1472bdd1243dSDimitry Andric        __start_ = 0;
1473bdd1243dSDimitry Andric        __size() = 0;
14740b57cec5SDimitry Andric        typedef move_iterator<iterator> _Ip;
14750b57cec5SDimitry Andric        assign(_Ip(__c.begin()), _Ip(__c.end()));
14760b57cec5SDimitry Andric    }
14770b57cec5SDimitry Andric}
14780b57cec5SDimitry Andric
14790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14800b57cec5SDimitry Andricinline
14810b57cec5SDimitry Andricdeque<_Tp, _Allocator>&
14820b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator=(deque&& __c)
14830b57cec5SDimitry Andric        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
14840b57cec5SDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value)
14850b57cec5SDimitry Andric{
14860b57cec5SDimitry Andric    __move_assign(__c, integral_constant<bool,
14870b57cec5SDimitry Andric          __alloc_traits::propagate_on_container_move_assignment::value>());
14880b57cec5SDimitry Andric    return *this;
14890b57cec5SDimitry Andric}
14900b57cec5SDimitry Andric
14910b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
14920b57cec5SDimitry Andricvoid
14930b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
14940b57cec5SDimitry Andric{
1495bdd1243dSDimitry Andric    if (__alloc() != __c.__alloc())
14960b57cec5SDimitry Andric    {
14970b57cec5SDimitry Andric        typedef move_iterator<iterator> _Ip;
14980b57cec5SDimitry Andric        assign(_Ip(__c.begin()), _Ip(__c.end()));
14990b57cec5SDimitry Andric    }
15000b57cec5SDimitry Andric    else
15010b57cec5SDimitry Andric        __move_assign(__c, true_type());
15020b57cec5SDimitry Andric}
15030b57cec5SDimitry Andric
15040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
15050b57cec5SDimitry Andricvoid
15060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
15070b57cec5SDimitry Andric    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
15080b57cec5SDimitry Andric{
15090b57cec5SDimitry Andric    clear();
15100b57cec5SDimitry Andric    shrink_to_fit();
1511bdd1243dSDimitry Andric    __move_assign(__c);
15120b57cec5SDimitry Andric}
15130b57cec5SDimitry Andric
15140b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
15150b57cec5SDimitry Andric
15160b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
15170b57cec5SDimitry Andrictemplate <class _InputIter>
15180b57cec5SDimitry Andricvoid
15190b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
1520*06c3fb27SDimitry Andric                               typename enable_if<__has_input_iterator_category<_InputIter>::value &&
1521*06c3fb27SDimitry Andric                                                 !__has_random_access_iterator_category<_InputIter>::value>::type*)
15220b57cec5SDimitry Andric{
1523*06c3fb27SDimitry Andric  __assign_with_sentinel(__f, __l);
1524*06c3fb27SDimitry Andric}
1525*06c3fb27SDimitry Andric
1526*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
1527*06c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel>
1528*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
1529*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) {
1530bdd1243dSDimitry Andric    iterator __i = begin();
1531bdd1243dSDimitry Andric    iterator __e = end();
15320b57cec5SDimitry Andric    for (; __f != __l && __i != __e; ++__f, (void) ++__i)
15330b57cec5SDimitry Andric        *__i = *__f;
15340b57cec5SDimitry Andric    if (__f != __l)
1535*06c3fb27SDimitry Andric        __append_with_sentinel(std::move(__f), std::move(__l));
15360b57cec5SDimitry Andric    else
15370b57cec5SDimitry Andric        __erase_to_end(__i);
15380b57cec5SDimitry Andric}
15390b57cec5SDimitry Andric
15400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
15410b57cec5SDimitry Andrictemplate <class _RAIter>
15420b57cec5SDimitry Andricvoid
15430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
1544*06c3fb27SDimitry Andric                               typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type*)
15450b57cec5SDimitry Andric{
1546*06c3fb27SDimitry Andric  __assign_with_size_random_access(__f, __l - __f);
1547*06c3fb27SDimitry Andric}
1548*06c3fb27SDimitry Andric
1549*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
1550*06c3fb27SDimitry Andrictemplate <class _RandomAccessIterator>
1551*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
1552*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) {
1553*06c3fb27SDimitry Andric    if (static_cast<size_type>(__n) > size())
15540b57cec5SDimitry Andric    {
1555*06c3fb27SDimitry Andric        auto __l = __f + size();
1556*06c3fb27SDimitry Andric        std::copy(__f, __l, begin());
1557*06c3fb27SDimitry Andric        __append_with_size(__l, __n - size());
15580b57cec5SDimitry Andric    }
15590b57cec5SDimitry Andric    else
1560*06c3fb27SDimitry Andric        __erase_to_end(std::copy_n(__f, __n, begin()));
1561*06c3fb27SDimitry Andric}
1562*06c3fb27SDimitry Andric
1563*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
1564*06c3fb27SDimitry Andrictemplate <class _Iterator>
1565*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
1566*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) {
1567*06c3fb27SDimitry Andric  if (static_cast<size_type>(__n) > size()) {
1568*06c3fb27SDimitry Andric    auto __added_size = __n - size();
1569*06c3fb27SDimitry Andric
1570*06c3fb27SDimitry Andric    auto __i = begin();
1571*06c3fb27SDimitry Andric    for (auto __count = size(); __count != 0; --__count) {
1572*06c3fb27SDimitry Andric      *__i++ = *__f++;
1573*06c3fb27SDimitry Andric    }
1574*06c3fb27SDimitry Andric
1575*06c3fb27SDimitry Andric    __append_with_size(__f, __added_size);
1576*06c3fb27SDimitry Andric
1577*06c3fb27SDimitry Andric  } else {
1578*06c3fb27SDimitry Andric    __erase_to_end(std::copy_n(__f, __n, begin()));
1579*06c3fb27SDimitry Andric  }
15800b57cec5SDimitry Andric}
15810b57cec5SDimitry Andric
15820b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
15830b57cec5SDimitry Andricvoid
15840b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
15850b57cec5SDimitry Andric{
1586bdd1243dSDimitry Andric    if (__n > size())
15870b57cec5SDimitry Andric    {
1588bdd1243dSDimitry Andric        _VSTD::fill_n(begin(), size(), __v);
1589bdd1243dSDimitry Andric        __n -= size();
15900b57cec5SDimitry Andric        __append(__n, __v);
15910b57cec5SDimitry Andric    }
15920b57cec5SDimitry Andric    else
1593bdd1243dSDimitry Andric        __erase_to_end(_VSTD::fill_n(begin(), __n, __v));
15940b57cec5SDimitry Andric}
15950b57cec5SDimitry Andric
15960b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
15970b57cec5SDimitry Andricinline
15980b57cec5SDimitry Andric_Allocator
15990b57cec5SDimitry Andricdeque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
16000b57cec5SDimitry Andric{
1601bdd1243dSDimitry Andric    return __alloc();
16020b57cec5SDimitry Andric}
16030b57cec5SDimitry Andric
16040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16050b57cec5SDimitry Andricvoid
16060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n)
16070b57cec5SDimitry Andric{
1608bdd1243dSDimitry Andric    if (__n > size())
1609bdd1243dSDimitry Andric        __append(__n - size());
1610bdd1243dSDimitry Andric    else if (__n < size())
1611bdd1243dSDimitry Andric        __erase_to_end(begin() + __n);
16120b57cec5SDimitry Andric}
16130b57cec5SDimitry Andric
16140b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16150b57cec5SDimitry Andricvoid
16160b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
16170b57cec5SDimitry Andric{
1618bdd1243dSDimitry Andric    if (__n > size())
1619bdd1243dSDimitry Andric        __append(__n - size(), __v);
1620bdd1243dSDimitry Andric    else if (__n < size())
1621bdd1243dSDimitry Andric        __erase_to_end(begin() + __n);
16220b57cec5SDimitry Andric}
16230b57cec5SDimitry Andric
16240b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16250b57cec5SDimitry Andricvoid
16260b57cec5SDimitry Andricdeque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
16270b57cec5SDimitry Andric{
1628bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
16290b57cec5SDimitry Andric    if (empty())
16300b57cec5SDimitry Andric    {
1631*06c3fb27SDimitry Andric        __annotate_delete();
1632bdd1243dSDimitry Andric        while (__map_.size() > 0)
16330b57cec5SDimitry Andric        {
1634bdd1243dSDimitry Andric            __alloc_traits::deallocate(__a, __map_.back(), __block_size);
1635bdd1243dSDimitry Andric            __map_.pop_back();
16360b57cec5SDimitry Andric        }
1637bdd1243dSDimitry Andric        __start_ = 0;
16380b57cec5SDimitry Andric    }
16390b57cec5SDimitry Andric    else
16400b57cec5SDimitry Andric    {
1641e40139ffSDimitry Andric      __maybe_remove_front_spare(/*__keep_one=*/false);
1642e40139ffSDimitry Andric      __maybe_remove_back_spare(/*__keep_one=*/false);
16430b57cec5SDimitry Andric    }
1644bdd1243dSDimitry Andric    __map_.shrink_to_fit();
16450b57cec5SDimitry Andric}
16460b57cec5SDimitry Andric
16470b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16480b57cec5SDimitry Andricinline
16490b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
16500b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT
16510b57cec5SDimitry Andric{
1652bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1653bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
16540b57cec5SDimitry Andric}
16550b57cec5SDimitry Andric
16560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16570b57cec5SDimitry Andricinline
16580b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
16590b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT
16600b57cec5SDimitry Andric{
1661bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1662bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
16630b57cec5SDimitry Andric}
16640b57cec5SDimitry Andric
16650b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16660b57cec5SDimitry Andricinline
16670b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
16680b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i)
16690b57cec5SDimitry Andric{
1670bdd1243dSDimitry Andric    if (__i >= size())
1671349cc55cSDimitry Andric        _VSTD::__throw_out_of_range("deque");
1672bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1673bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
16740b57cec5SDimitry Andric}
16750b57cec5SDimitry Andric
16760b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16770b57cec5SDimitry Andricinline
16780b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
16790b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i) const
16800b57cec5SDimitry Andric{
1681bdd1243dSDimitry Andric    if (__i >= size())
1682349cc55cSDimitry Andric        _VSTD::__throw_out_of_range("deque");
1683bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1684bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
16850b57cec5SDimitry Andric}
16860b57cec5SDimitry Andric
16870b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16880b57cec5SDimitry Andricinline
16890b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
16900b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() _NOEXCEPT
16910b57cec5SDimitry Andric{
1692bdd1243dSDimitry Andric    return *(*(__map_.begin() + __start_ / __block_size)
1693bdd1243dSDimitry Andric                                    + __start_ % __block_size);
16940b57cec5SDimitry Andric}
16950b57cec5SDimitry Andric
16960b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16970b57cec5SDimitry Andricinline
16980b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
16990b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() const _NOEXCEPT
17000b57cec5SDimitry Andric{
1701bdd1243dSDimitry Andric    return *(*(__map_.begin() + __start_ / __block_size)
1702bdd1243dSDimitry Andric                                      + __start_ % __block_size);
17030b57cec5SDimitry Andric}
17040b57cec5SDimitry Andric
17050b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17060b57cec5SDimitry Andricinline
17070b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
17080b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() _NOEXCEPT
17090b57cec5SDimitry Andric{
1710bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
1711bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
17120b57cec5SDimitry Andric}
17130b57cec5SDimitry Andric
17140b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17150b57cec5SDimitry Andricinline
17160b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
17170b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() const _NOEXCEPT
17180b57cec5SDimitry Andric{
1719bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
1720bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
17210b57cec5SDimitry Andric}
17220b57cec5SDimitry Andric
17230b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17240b57cec5SDimitry Andricvoid
17250b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(const value_type& __v)
17260b57cec5SDimitry Andric{
1727bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17280b57cec5SDimitry Andric    if (__back_spare() == 0)
17290b57cec5SDimitry Andric        __add_back_capacity();
17300b57cec5SDimitry Andric    // __back_spare() >= 1
1731*06c3fb27SDimitry Andric    __annotate_increase_back(1);
1732bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v);
1733bdd1243dSDimitry Andric    ++__size();
17340b57cec5SDimitry Andric}
17350b57cec5SDimitry Andric
17360b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17370b57cec5SDimitry Andricvoid
17380b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(const value_type& __v)
17390b57cec5SDimitry Andric{
1740bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17410b57cec5SDimitry Andric    if (__front_spare() == 0)
17420b57cec5SDimitry Andric        __add_front_capacity();
17430b57cec5SDimitry Andric    // __front_spare() >= 1
1744*06c3fb27SDimitry Andric    __annotate_increase_front(1);
1745bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v);
1746bdd1243dSDimitry Andric    --__start_;
1747bdd1243dSDimitry Andric    ++__size();
17480b57cec5SDimitry Andric}
17490b57cec5SDimitry Andric
17500b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
17510b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17520b57cec5SDimitry Andricvoid
17530b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(value_type&& __v)
17540b57cec5SDimitry Andric{
1755bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17560b57cec5SDimitry Andric    if (__back_spare() == 0)
17570b57cec5SDimitry Andric        __add_back_capacity();
17580b57cec5SDimitry Andric    // __back_spare() >= 1
1759*06c3fb27SDimitry Andric    __annotate_increase_back(1);
1760bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v));
1761bdd1243dSDimitry Andric    ++__size();
17620b57cec5SDimitry Andric}
17630b57cec5SDimitry Andric
17640b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17650b57cec5SDimitry Andrictemplate <class... _Args>
1766*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
17670b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
17680b57cec5SDimitry Andric#else
17690b57cec5SDimitry Andricvoid
17700b57cec5SDimitry Andric#endif
17710b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
17720b57cec5SDimitry Andric{
1773bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17740b57cec5SDimitry Andric    if (__back_spare() == 0)
17750b57cec5SDimitry Andric        __add_back_capacity();
17760b57cec5SDimitry Andric    // __back_spare() >= 1
1777*06c3fb27SDimitry Andric    __annotate_increase_back(1);
1778bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*end()),
17790b57cec5SDimitry Andric                              _VSTD::forward<_Args>(__args)...);
1780bdd1243dSDimitry Andric    ++__size();
1781*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1782bdd1243dSDimitry Andric    return *--end();
17830b57cec5SDimitry Andric#endif
17840b57cec5SDimitry Andric}
17850b57cec5SDimitry Andric
17860b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17870b57cec5SDimitry Andricvoid
17880b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(value_type&& __v)
17890b57cec5SDimitry Andric{
1790bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17910b57cec5SDimitry Andric    if (__front_spare() == 0)
17920b57cec5SDimitry Andric        __add_front_capacity();
17930b57cec5SDimitry Andric    // __front_spare() >= 1
1794*06c3fb27SDimitry Andric    __annotate_increase_front(1);
1795bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v));
1796bdd1243dSDimitry Andric    --__start_;
1797bdd1243dSDimitry Andric    ++__size();
17980b57cec5SDimitry Andric}
17990b57cec5SDimitry Andric
18000b57cec5SDimitry Andric
18010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
18020b57cec5SDimitry Andrictemplate <class... _Args>
1803*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
18040b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
18050b57cec5SDimitry Andric#else
18060b57cec5SDimitry Andricvoid
18070b57cec5SDimitry Andric#endif
18080b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
18090b57cec5SDimitry Andric{
1810bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
18110b57cec5SDimitry Andric    if (__front_spare() == 0)
18120b57cec5SDimitry Andric        __add_front_capacity();
18130b57cec5SDimitry Andric    // __front_spare() >= 1
1814*06c3fb27SDimitry Andric    __annotate_increase_front(1);
1815bdd1243dSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...);
1816bdd1243dSDimitry Andric    --__start_;
1817bdd1243dSDimitry Andric    ++__size();
1818*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1819bdd1243dSDimitry Andric    return *begin();
18200b57cec5SDimitry Andric#endif
18210b57cec5SDimitry Andric}
18220b57cec5SDimitry Andric
18230b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
18240b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
18250b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
18260b57cec5SDimitry Andric{
1827bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1828bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1829bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
18300b57cec5SDimitry Andric    if (__pos < __to_end)
18310b57cec5SDimitry Andric    {   // insert by shifting things backward
18320b57cec5SDimitry Andric        if (__front_spare() == 0)
18330b57cec5SDimitry Andric            __add_front_capacity();
18340b57cec5SDimitry Andric        // __front_spare() >= 1
1835*06c3fb27SDimitry Andric        __annotate_increase_front(1);
18360b57cec5SDimitry Andric        if (__pos == 0)
18370b57cec5SDimitry Andric        {
1838bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v));
1839bdd1243dSDimitry Andric            --__start_;
1840bdd1243dSDimitry Andric            ++__size();
18410b57cec5SDimitry Andric        }
18420b57cec5SDimitry Andric        else
18430b57cec5SDimitry Andric        {
1844bdd1243dSDimitry Andric            iterator __b = begin();
18450b57cec5SDimitry Andric            iterator __bm1 = _VSTD::prev(__b);
18460b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1847bdd1243dSDimitry Andric            --__start_;
1848bdd1243dSDimitry Andric            ++__size();
18490b57cec5SDimitry Andric            if (__pos > 1)
18500b57cec5SDimitry Andric                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
18510b57cec5SDimitry Andric            *__b = _VSTD::move(__v);
18520b57cec5SDimitry Andric        }
18530b57cec5SDimitry Andric    }
18540b57cec5SDimitry Andric    else
18550b57cec5SDimitry Andric    {   // insert by shifting things forward
18560b57cec5SDimitry Andric        if (__back_spare() == 0)
18570b57cec5SDimitry Andric            __add_back_capacity();
18580b57cec5SDimitry Andric        // __back_capacity >= 1
1859*06c3fb27SDimitry Andric        __annotate_increase_back(1);
1860bdd1243dSDimitry Andric        size_type __de = size() - __pos;
18610b57cec5SDimitry Andric        if (__de == 0)
18620b57cec5SDimitry Andric        {
1863bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v));
1864bdd1243dSDimitry Andric            ++__size();
18650b57cec5SDimitry Andric        }
18660b57cec5SDimitry Andric        else
18670b57cec5SDimitry Andric        {
1868bdd1243dSDimitry Andric            iterator __e = end();
18690b57cec5SDimitry Andric            iterator __em1 = _VSTD::prev(__e);
18700b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
1871bdd1243dSDimitry Andric            ++__size();
18720b57cec5SDimitry Andric            if (__de > 1)
18730b57cec5SDimitry Andric                __e = _VSTD::move_backward(__e - __de, __em1, __e);
18740b57cec5SDimitry Andric            *--__e = _VSTD::move(__v);
18750b57cec5SDimitry Andric        }
18760b57cec5SDimitry Andric    }
1877bdd1243dSDimitry Andric    return begin() + __pos;
18780b57cec5SDimitry Andric}
18790b57cec5SDimitry Andric
18800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
18810b57cec5SDimitry Andrictemplate <class... _Args>
18820b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
18830b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
18840b57cec5SDimitry Andric{
1885bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1886bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1887bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
18880b57cec5SDimitry Andric    if (__pos < __to_end)
18890b57cec5SDimitry Andric    {   // insert by shifting things backward
18900b57cec5SDimitry Andric        if (__front_spare() == 0)
18910b57cec5SDimitry Andric            __add_front_capacity();
18920b57cec5SDimitry Andric        // __front_spare() >= 1
1893*06c3fb27SDimitry Andric        __annotate_increase_front(1);
18940b57cec5SDimitry Andric        if (__pos == 0)
18950b57cec5SDimitry Andric        {
1896bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...);
1897bdd1243dSDimitry Andric            --__start_;
1898bdd1243dSDimitry Andric            ++__size();
18990b57cec5SDimitry Andric        }
19000b57cec5SDimitry Andric        else
19010b57cec5SDimitry Andric        {
1902bdd1243dSDimitry Andric            __temp_value<value_type, _Allocator> __tmp(__alloc(), _VSTD::forward<_Args>(__args)...);
1903bdd1243dSDimitry Andric            iterator __b = begin();
19040b57cec5SDimitry Andric            iterator __bm1 = _VSTD::prev(__b);
19050b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1906bdd1243dSDimitry Andric            --__start_;
1907bdd1243dSDimitry Andric            ++__size();
19080b57cec5SDimitry Andric            if (__pos > 1)
19090b57cec5SDimitry Andric                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
19100b57cec5SDimitry Andric            *__b = _VSTD::move(__tmp.get());
19110b57cec5SDimitry Andric        }
19120b57cec5SDimitry Andric    }
19130b57cec5SDimitry Andric    else
19140b57cec5SDimitry Andric    {   // insert by shifting things forward
19150b57cec5SDimitry Andric        if (__back_spare() == 0)
19160b57cec5SDimitry Andric            __add_back_capacity();
19170b57cec5SDimitry Andric        // __back_capacity >= 1
1918*06c3fb27SDimitry Andric        __annotate_increase_back(1);
1919bdd1243dSDimitry Andric        size_type __de = size() - __pos;
19200b57cec5SDimitry Andric        if (__de == 0)
19210b57cec5SDimitry Andric        {
1922bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::forward<_Args>(__args)...);
1923bdd1243dSDimitry Andric            ++__size();
19240b57cec5SDimitry Andric        }
19250b57cec5SDimitry Andric        else
19260b57cec5SDimitry Andric        {
1927bdd1243dSDimitry Andric            __temp_value<value_type, _Allocator> __tmp(__alloc(), _VSTD::forward<_Args>(__args)...);
1928bdd1243dSDimitry Andric            iterator __e = end();
19290b57cec5SDimitry Andric            iterator __em1 = _VSTD::prev(__e);
19300b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
1931bdd1243dSDimitry Andric            ++__size();
19320b57cec5SDimitry Andric            if (__de > 1)
19330b57cec5SDimitry Andric                __e = _VSTD::move_backward(__e - __de, __em1, __e);
19340b57cec5SDimitry Andric            *--__e = _VSTD::move(__tmp.get());
19350b57cec5SDimitry Andric        }
19360b57cec5SDimitry Andric    }
1937bdd1243dSDimitry Andric    return begin() + __pos;
19380b57cec5SDimitry Andric}
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
19410b57cec5SDimitry Andric
19420b57cec5SDimitry Andric
19430b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
19440b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
19450b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
19460b57cec5SDimitry Andric{
1947bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1948bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1949bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
19500b57cec5SDimitry Andric    if (__pos < __to_end)
19510b57cec5SDimitry Andric    {   // insert by shifting things backward
19520b57cec5SDimitry Andric        if (__front_spare() == 0)
19530b57cec5SDimitry Andric            __add_front_capacity();
19540b57cec5SDimitry Andric        // __front_spare() >= 1
1955*06c3fb27SDimitry Andric        __annotate_increase_front(1);
19560b57cec5SDimitry Andric        if (__pos == 0)
19570b57cec5SDimitry Andric        {
1958bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v);
1959bdd1243dSDimitry Andric            --__start_;
1960bdd1243dSDimitry Andric            ++__size();
19610b57cec5SDimitry Andric        }
19620b57cec5SDimitry Andric        else
19630b57cec5SDimitry Andric        {
19640b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1965bdd1243dSDimitry Andric            iterator __b = begin();
19660b57cec5SDimitry Andric            iterator __bm1 = _VSTD::prev(__b);
19670b57cec5SDimitry Andric            if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
19680b57cec5SDimitry Andric                __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
19690b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1970bdd1243dSDimitry Andric            --__start_;
1971bdd1243dSDimitry Andric            ++__size();
19720b57cec5SDimitry Andric            if (__pos > 1)
19730b57cec5SDimitry Andric                __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);
19740b57cec5SDimitry Andric            *__b = *__vt;
19750b57cec5SDimitry Andric        }
19760b57cec5SDimitry Andric    }
19770b57cec5SDimitry Andric    else
19780b57cec5SDimitry Andric    {   // insert by shifting things forward
19790b57cec5SDimitry Andric        if (__back_spare() == 0)
19800b57cec5SDimitry Andric            __add_back_capacity();
19810b57cec5SDimitry Andric        // __back_capacity >= 1
1982*06c3fb27SDimitry Andric        __annotate_increase_back(1);
1983bdd1243dSDimitry Andric        size_type __de = size() - __pos;
19840b57cec5SDimitry Andric        if (__de == 0)
19850b57cec5SDimitry Andric        {
1986bdd1243dSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v);
1987bdd1243dSDimitry Andric            ++__size();
19880b57cec5SDimitry Andric        }
19890b57cec5SDimitry Andric        else
19900b57cec5SDimitry Andric        {
19910b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1992bdd1243dSDimitry Andric            iterator __e = end();
19930b57cec5SDimitry Andric            iterator __em1 = _VSTD::prev(__e);
19940b57cec5SDimitry Andric            if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
19950b57cec5SDimitry Andric                __vt = pointer_traits<const_pointer>::pointer_to(*__e);
19960b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
1997bdd1243dSDimitry Andric            ++__size();
19980b57cec5SDimitry Andric            if (__de > 1)
19990b57cec5SDimitry Andric                __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
20000b57cec5SDimitry Andric            *--__e = *__vt;
20010b57cec5SDimitry Andric        }
20020b57cec5SDimitry Andric    }
2003bdd1243dSDimitry Andric    return begin() + __pos;
20040b57cec5SDimitry Andric}
20050b57cec5SDimitry Andric
20060b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
20070b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
20080b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
20090b57cec5SDimitry Andric{
2010bdd1243dSDimitry Andric    size_type __pos = __p - begin();
2011bdd1243dSDimitry Andric    size_type __to_end = __size() - __pos;
2012bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
20130b57cec5SDimitry Andric    if (__pos < __to_end)
20140b57cec5SDimitry Andric    {   // insert by shifting things backward
20150b57cec5SDimitry Andric        if (__n > __front_spare())
20160b57cec5SDimitry Andric            __add_front_capacity(__n - __front_spare());
20170b57cec5SDimitry Andric        // __n <= __front_spare()
2018*06c3fb27SDimitry Andric        __annotate_increase_front(__n);
2019bdd1243dSDimitry Andric        iterator __old_begin = begin();
20200b57cec5SDimitry Andric        iterator __i = __old_begin;
20210b57cec5SDimitry Andric        if (__n > __pos)
20220b57cec5SDimitry Andric        {
2023bdd1243dSDimitry Andric            for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size())
20240b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);
20250b57cec5SDimitry Andric            __n = __pos;
20260b57cec5SDimitry Andric        }
20270b57cec5SDimitry Andric        if (__n > 0)
20280b57cec5SDimitry Andric        {
20290b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
20300b57cec5SDimitry Andric            iterator __obn = __old_begin + __n;
20310b57cec5SDimitry Andric            __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
20320b57cec5SDimitry Andric            if (__n < __pos)
20330b57cec5SDimitry Andric                __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
20340b57cec5SDimitry Andric            _VSTD::fill_n(__old_begin, __n, *__vt);
20350b57cec5SDimitry Andric        }
20360b57cec5SDimitry Andric    }
20370b57cec5SDimitry Andric    else
20380b57cec5SDimitry Andric    {   // insert by shifting things forward
20390b57cec5SDimitry Andric        size_type __back_capacity = __back_spare();
20400b57cec5SDimitry Andric        if (__n > __back_capacity)
20410b57cec5SDimitry Andric            __add_back_capacity(__n - __back_capacity);
20420b57cec5SDimitry Andric        // __n <= __back_capacity
2043*06c3fb27SDimitry Andric        __annotate_increase_back(__n);
2044bdd1243dSDimitry Andric        iterator __old_end = end();
20450b57cec5SDimitry Andric        iterator __i = __old_end;
2046bdd1243dSDimitry Andric        size_type __de = size() - __pos;
20470b57cec5SDimitry Andric        if (__n > __de)
20480b57cec5SDimitry Andric        {
2049bdd1243dSDimitry Andric            for (size_type __m = __n - __de; __m; --__m, (void) ++__i, ++__size())
20500b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
20510b57cec5SDimitry Andric            __n = __de;
20520b57cec5SDimitry Andric        }
20530b57cec5SDimitry Andric        if (__n > 0)
20540b57cec5SDimitry Andric        {
20550b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
20560b57cec5SDimitry Andric            iterator __oen = __old_end - __n;
20570b57cec5SDimitry Andric            __move_construct_and_check(__oen, __old_end, __i, __vt);
20580b57cec5SDimitry Andric            if (__n < __de)
20590b57cec5SDimitry Andric                __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
20600b57cec5SDimitry Andric            _VSTD::fill_n(__old_end - __n, __n, *__vt);
20610b57cec5SDimitry Andric        }
20620b57cec5SDimitry Andric    }
2063bdd1243dSDimitry Andric    return begin() + __pos;
20640b57cec5SDimitry Andric}
20650b57cec5SDimitry Andric
20660b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
20670b57cec5SDimitry Andrictemplate <class _InputIter>
20680b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
20690b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
2070*06c3fb27SDimitry Andric                               typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type*)
20710b57cec5SDimitry Andric{
2072*06c3fb27SDimitry Andric  return __insert_with_sentinel(__p, __f, __l);
2073*06c3fb27SDimitry Andric}
2074*06c3fb27SDimitry Andric
2075*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
2076*06c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel>
2077*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
2078*06c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
2079*06c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) {
2080bdd1243dSDimitry Andric    __split_buffer<value_type, allocator_type&> __buf(__alloc());
2081*06c3fb27SDimitry Andric    __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l));
20820b57cec5SDimitry Andric    typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
20830b57cec5SDimitry Andric    return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
20840b57cec5SDimitry Andric}
20850b57cec5SDimitry Andric
20860b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
20870b57cec5SDimitry Andrictemplate <class _ForwardIterator>
20880b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
20890b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
2090*06c3fb27SDimitry Andric                               typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type*)
20910b57cec5SDimitry Andric{
2092*06c3fb27SDimitry Andric  return __insert_with_size(__p, __f, std::distance(__f, __l));
2093*06c3fb27SDimitry Andric}
2094*06c3fb27SDimitry Andric
2095*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
2096*06c3fb27SDimitry Andrictemplate <class _Iterator>
2097*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
2098*06c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
2099*06c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) {
2100bdd1243dSDimitry Andric    __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc());
2101*06c3fb27SDimitry Andric    __buf.__construct_at_end_with_size(__f, __n);
21020b57cec5SDimitry Andric    typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
21030b57cec5SDimitry Andric    return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
21040b57cec5SDimitry Andric}
21050b57cec5SDimitry Andric
21060b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
21070b57cec5SDimitry Andrictemplate <class _BiIter>
21080b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
21090b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
2110*06c3fb27SDimitry Andric                               typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type*)
21110b57cec5SDimitry Andric{
2112*06c3fb27SDimitry Andric  return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l));
2113*06c3fb27SDimitry Andric}
2114*06c3fb27SDimitry Andric
2115*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
2116*06c3fb27SDimitry Andrictemplate <class _BiIter, class _Sentinel>
2117*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
2118*06c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
2119*06c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) {
2120*06c3fb27SDimitry Andric  return __insert_bidirectional(__p, __f, std::next(__f, __n), __n);
2121*06c3fb27SDimitry Andric}
2122*06c3fb27SDimitry Andric
2123*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
2124*06c3fb27SDimitry Andrictemplate <class _BiIter>
2125*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
2126*06c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
2127*06c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) {
2128bdd1243dSDimitry Andric    size_type __pos = __p - begin();
2129bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
2130bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
21310b57cec5SDimitry Andric    if (__pos < __to_end)
21320b57cec5SDimitry Andric    {   // insert by shifting things backward
21330b57cec5SDimitry Andric        if (__n > __front_spare())
21340b57cec5SDimitry Andric            __add_front_capacity(__n - __front_spare());
21350b57cec5SDimitry Andric        // __n <= __front_spare()
2136*06c3fb27SDimitry Andric        __annotate_increase_front(__n);
2137bdd1243dSDimitry Andric        iterator __old_begin = begin();
21380b57cec5SDimitry Andric        iterator __i = __old_begin;
21390b57cec5SDimitry Andric        _BiIter __m = __f;
21400b57cec5SDimitry Andric        if (__n > __pos)
21410b57cec5SDimitry Andric        {
21420b57cec5SDimitry Andric            __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);
2143bdd1243dSDimitry Andric            for (_BiIter __j = __m; __j != __f; --__start_, ++__size())
21440b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);
21450b57cec5SDimitry Andric            __n = __pos;
21460b57cec5SDimitry Andric        }
21470b57cec5SDimitry Andric        if (__n > 0)
21480b57cec5SDimitry Andric        {
21490b57cec5SDimitry Andric            iterator __obn = __old_begin + __n;
21500b57cec5SDimitry Andric            for (iterator __j = __obn; __j != __old_begin;)
21510b57cec5SDimitry Andric            {
21520b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));
2153bdd1243dSDimitry Andric                --__start_;
2154bdd1243dSDimitry Andric                ++__size();
21550b57cec5SDimitry Andric            }
21560b57cec5SDimitry Andric            if (__n < __pos)
21570b57cec5SDimitry Andric                __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);
21580b57cec5SDimitry Andric            _VSTD::copy(__m, __l, __old_begin);
21590b57cec5SDimitry Andric        }
21600b57cec5SDimitry Andric    }
21610b57cec5SDimitry Andric    else
21620b57cec5SDimitry Andric    {   // insert by shifting things forward
21630b57cec5SDimitry Andric        size_type __back_capacity = __back_spare();
21640b57cec5SDimitry Andric        if (__n > __back_capacity)
21650b57cec5SDimitry Andric            __add_back_capacity(__n - __back_capacity);
21660b57cec5SDimitry Andric        // __n <= __back_capacity
2167*06c3fb27SDimitry Andric        __annotate_increase_back(__n);
2168bdd1243dSDimitry Andric        iterator __old_end = end();
21690b57cec5SDimitry Andric        iterator __i = __old_end;
21700b57cec5SDimitry Andric        _BiIter __m = __l;
2171bdd1243dSDimitry Andric        size_type __de = size() - __pos;
21720b57cec5SDimitry Andric        if (__n > __de)
21730b57cec5SDimitry Andric        {
21740b57cec5SDimitry Andric            __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
2175bdd1243dSDimitry Andric            for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__size())
21760b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
21770b57cec5SDimitry Andric            __n = __de;
21780b57cec5SDimitry Andric        }
21790b57cec5SDimitry Andric        if (__n > 0)
21800b57cec5SDimitry Andric        {
21810b57cec5SDimitry Andric            iterator __oen = __old_end - __n;
2182bdd1243dSDimitry Andric            for (iterator __j = __oen; __j != __old_end; ++__i, (void) ++__j, ++__size())
21830b57cec5SDimitry Andric                __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));
21840b57cec5SDimitry Andric            if (__n < __de)
21850b57cec5SDimitry Andric                __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);
21860b57cec5SDimitry Andric            _VSTD::copy_backward(__f, __m, __old_end);
21870b57cec5SDimitry Andric        }
21880b57cec5SDimitry Andric    }
2189bdd1243dSDimitry Andric    return begin() + __pos;
21900b57cec5SDimitry Andric}
21910b57cec5SDimitry Andric
21920b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
21930b57cec5SDimitry Andrictemplate <class _InpIter>
21940b57cec5SDimitry Andricvoid
21950b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
2196*06c3fb27SDimitry Andric                                 typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type*)
21970b57cec5SDimitry Andric{
2198*06c3fb27SDimitry Andric  __append_with_sentinel(__f, __l);
2199*06c3fb27SDimitry Andric}
2200*06c3fb27SDimitry Andric
2201*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
2202*06c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel>
2203*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
2204*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) {
22050b57cec5SDimitry Andric    for (; __f != __l; ++__f)
22060b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
22070b57cec5SDimitry Andric        push_back(*__f);
22080b57cec5SDimitry Andric#else
22090b57cec5SDimitry Andric        emplace_back(*__f);
22100b57cec5SDimitry Andric#endif
22110b57cec5SDimitry Andric}
22120b57cec5SDimitry Andric
22130b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22140b57cec5SDimitry Andrictemplate <class _ForIter>
22150b57cec5SDimitry Andricvoid
22160b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
2217*06c3fb27SDimitry Andric                                 typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type*)
22180b57cec5SDimitry Andric{
2219*06c3fb27SDimitry Andric    __append_with_size(__f, std::distance(__f, __l));
2220*06c3fb27SDimitry Andric}
2221*06c3fb27SDimitry Andric
2222*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
2223*06c3fb27SDimitry Andrictemplate <class _InputIterator>
2224*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
2225*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) {
2226bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
22270b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
22280b57cec5SDimitry Andric    if (__n > __back_capacity)
22290b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
2230*06c3fb27SDimitry Andric
22310b57cec5SDimitry Andric    // __n <= __back_capacity
2232*06c3fb27SDimitry Andric    __annotate_increase_back(__n);
2233bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
2234e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
2235e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {
2236e8d8bef9SDimitry Andric        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f);
2237e40139ffSDimitry Andric      }
2238e40139ffSDimitry Andric    }
22390b57cec5SDimitry Andric}
22400b57cec5SDimitry Andric
22410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22420b57cec5SDimitry Andricvoid
22430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n)
22440b57cec5SDimitry Andric{
2245bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
22460b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
22470b57cec5SDimitry Andric    if (__n > __back_capacity)
22480b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
22490b57cec5SDimitry Andric    // __n <= __back_capacity
2250*06c3fb27SDimitry Andric    __annotate_increase_back(__n);
2251bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
2252e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
2253e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
2254e8d8bef9SDimitry Andric        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_));
2255e40139ffSDimitry Andric      }
2256e40139ffSDimitry Andric    }
22570b57cec5SDimitry Andric}
22580b57cec5SDimitry Andric
22590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22600b57cec5SDimitry Andricvoid
22610b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
22620b57cec5SDimitry Andric{
2263bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
22640b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
22650b57cec5SDimitry Andric    if (__n > __back_capacity)
22660b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
22670b57cec5SDimitry Andric    // __n <= __back_capacity
2268*06c3fb27SDimitry Andric    __annotate_increase_back(__n);
2269bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
2270e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
2271e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
2272e8d8bef9SDimitry Andric        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v);
2273e40139ffSDimitry Andric      }
2274e40139ffSDimitry Andric    }
2275e40139ffSDimitry Andric
22760b57cec5SDimitry Andric}
22770b57cec5SDimitry Andric
22780b57cec5SDimitry Andric// Create front capacity for one block of elements.
22790b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
22800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22810b57cec5SDimitry Andricvoid
22820b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity()
22830b57cec5SDimitry Andric{
2284bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2285bdd1243dSDimitry Andric    if (__back_spare() >= __block_size)
22860b57cec5SDimitry Andric    {
2287bdd1243dSDimitry Andric        __start_ += __block_size;
2288bdd1243dSDimitry Andric        pointer __pt = __map_.back();
2289bdd1243dSDimitry Andric        __map_.pop_back();
2290bdd1243dSDimitry Andric        __map_.push_front(__pt);
22910b57cec5SDimitry Andric    }
2292bdd1243dSDimitry Andric    // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer
2293bdd1243dSDimitry Andric    else if (__map_.size() < __map_.capacity())
22940b57cec5SDimitry Andric    {   // we can put the new buffer into the map, but don't shift things around
22950b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
22960b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
2297bdd1243dSDimitry Andric        if (__map_.__front_spare() > 0)
2298bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
22990b57cec5SDimitry Andric        else
23000b57cec5SDimitry Andric        {
2301bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
23020b57cec5SDimitry Andric            // Done allocating, reorder capacity
2303bdd1243dSDimitry Andric            pointer __pt = __map_.back();
2304bdd1243dSDimitry Andric            __map_.pop_back();
2305bdd1243dSDimitry Andric            __map_.push_front(__pt);
23060b57cec5SDimitry Andric        }
2307bdd1243dSDimitry Andric        __start_ = __map_.size() == 1 ?
2308bdd1243dSDimitry Andric                               __block_size / 2 :
2309bdd1243dSDimitry Andric                               __start_ + __block_size;
23100b57cec5SDimitry Andric    }
23110b57cec5SDimitry Andric    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
23120b57cec5SDimitry Andric    else
23130b57cec5SDimitry Andric    {
2314bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2315bdd1243dSDimitry Andric            __buf(std::max<size_type>(2 * __map_.capacity(), 1),
2316bdd1243dSDimitry Andric                  0, __map_.__alloc());
23170b57cec5SDimitry Andric
23180b57cec5SDimitry Andric        typedef __allocator_destructor<_Allocator> _Dp;
23190b57cec5SDimitry Andric        unique_ptr<pointer, _Dp> __hold(
2320bdd1243dSDimitry Andric            __alloc_traits::allocate(__a, __block_size),
2321bdd1243dSDimitry Andric                _Dp(__a, __block_size));
23220b57cec5SDimitry Andric        __buf.push_back(__hold.get());
23230b57cec5SDimitry Andric        __hold.release();
23240b57cec5SDimitry Andric
2325bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.begin();
2326bdd1243dSDimitry Andric                __i != __map_.end(); ++__i)
23270b57cec5SDimitry Andric            __buf.push_back(*__i);
2328bdd1243dSDimitry Andric        _VSTD::swap(__map_.__first_, __buf.__first_);
2329bdd1243dSDimitry Andric        _VSTD::swap(__map_.__begin_, __buf.__begin_);
2330bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_, __buf.__end_);
2331bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
2332bdd1243dSDimitry Andric        __start_ = __map_.size() == 1 ?
2333bdd1243dSDimitry Andric                               __block_size / 2 :
2334bdd1243dSDimitry Andric                               __start_ + __block_size;
23350b57cec5SDimitry Andric    }
2336*06c3fb27SDimitry Andric    __annotate_whole_block(0, __asan_poison);
23370b57cec5SDimitry Andric}
23380b57cec5SDimitry Andric
23390b57cec5SDimitry Andric// Create front capacity for __n elements.
23400b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
23410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
23420b57cec5SDimitry Andricvoid
23430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
23440b57cec5SDimitry Andric{
2345bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2346bdd1243dSDimitry Andric    size_type __nb = __recommend_blocks(__n + __map_.empty());
23470b57cec5SDimitry Andric    // Number of unused blocks at back:
2348bdd1243dSDimitry Andric    size_type __back_capacity = __back_spare() / __block_size;
23490b57cec5SDimitry Andric    __back_capacity = _VSTD::min(__back_capacity, __nb);  // don't take more than you need
23500b57cec5SDimitry Andric    __nb -= __back_capacity;  // number of blocks need to allocate
23510b57cec5SDimitry Andric    // If __nb == 0, then we have sufficient capacity.
23520b57cec5SDimitry Andric    if (__nb == 0)
23530b57cec5SDimitry Andric    {
2354bdd1243dSDimitry Andric        __start_ += __block_size * __back_capacity;
23550b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
23560b57cec5SDimitry Andric        {
2357bdd1243dSDimitry Andric            pointer __pt = __map_.back();
2358bdd1243dSDimitry Andric            __map_.pop_back();
2359bdd1243dSDimitry Andric            __map_.push_front(__pt);
23600b57cec5SDimitry Andric        }
23610b57cec5SDimitry Andric    }
23620b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2363bdd1243dSDimitry Andric    else if (__nb <= __map_.capacity() - __map_.size())
23640b57cec5SDimitry Andric    {   // we can put the new buffers into the map, but don't shift things around
23650b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
23660b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
2367bdd1243dSDimitry Andric        for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1))
23680b57cec5SDimitry Andric        {
2369bdd1243dSDimitry Andric            if (__map_.__front_spare() == 0)
23700b57cec5SDimitry Andric                break;
2371bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
2372*06c3fb27SDimitry Andric            __annotate_whole_block(0, __asan_poison);
23730b57cec5SDimitry Andric        }
23740b57cec5SDimitry Andric        for (; __nb > 0; --__nb, ++__back_capacity)
2375bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
23760b57cec5SDimitry Andric        // Done allocating, reorder capacity
2377bdd1243dSDimitry Andric        __start_ += __back_capacity * __block_size;
23780b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
23790b57cec5SDimitry Andric        {
2380bdd1243dSDimitry Andric            pointer __pt = __map_.back();
2381bdd1243dSDimitry Andric            __map_.pop_back();
2382bdd1243dSDimitry Andric            __map_.push_front(__pt);
2383*06c3fb27SDimitry Andric            __annotate_whole_block(0, __asan_poison);
23840b57cec5SDimitry Andric        }
23850b57cec5SDimitry Andric    }
23860b57cec5SDimitry Andric    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
23870b57cec5SDimitry Andric    else
23880b57cec5SDimitry Andric    {
2389bdd1243dSDimitry Andric        size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty();
2390bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2391bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(),
2392bdd1243dSDimitry Andric                                      __nb + __map_.size()),
2393bdd1243dSDimitry Andric                  0, __map_.__alloc());
2394*06c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
23950b57cec5SDimitry Andric        try
23960b57cec5SDimitry Andric        {
2397*06c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2398*06c3fb27SDimitry Andric            for (; __nb > 0; --__nb) {
2399bdd1243dSDimitry Andric                __buf.push_back(__alloc_traits::allocate(__a, __block_size));
2400*06c3fb27SDimitry Andric                // ASan: this is empty container, we have to poison whole block
2401*06c3fb27SDimitry Andric                __annotate_poison_block(
2402*06c3fb27SDimitry Andric                    std::__to_address(__buf.back()),
2403*06c3fb27SDimitry Andric                    std::__to_address(__buf.back() + __block_size));
2404*06c3fb27SDimitry Andric            }
2405*06c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
24060b57cec5SDimitry Andric        }
24070b57cec5SDimitry Andric        catch (...)
24080b57cec5SDimitry Andric        {
2409*06c3fb27SDimitry Andric            __annotate_delete();
2410bdd1243dSDimitry Andric            for (__map_pointer __i = __buf.begin();
24110b57cec5SDimitry Andric                    __i != __buf.end(); ++__i)
2412bdd1243dSDimitry Andric                __alloc_traits::deallocate(__a, *__i, __block_size);
24130b57cec5SDimitry Andric            throw;
24140b57cec5SDimitry Andric        }
2415*06c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
24160b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
24170b57cec5SDimitry Andric        {
2418bdd1243dSDimitry Andric            __buf.push_back(__map_.back());
2419bdd1243dSDimitry Andric            __map_.pop_back();
24200b57cec5SDimitry Andric        }
2421bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.begin();
2422bdd1243dSDimitry Andric                __i != __map_.end(); ++__i)
24230b57cec5SDimitry Andric            __buf.push_back(*__i);
2424bdd1243dSDimitry Andric        _VSTD::swap(__map_.__first_, __buf.__first_);
2425bdd1243dSDimitry Andric        _VSTD::swap(__map_.__begin_, __buf.__begin_);
2426bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_, __buf.__end_);
2427bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
2428bdd1243dSDimitry Andric        __start_ += __ds;
24290b57cec5SDimitry Andric    }
24300b57cec5SDimitry Andric}
24310b57cec5SDimitry Andric
24320b57cec5SDimitry Andric// Create back capacity for one block of elements.
24330b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
24340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
24350b57cec5SDimitry Andricvoid
24360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity()
24370b57cec5SDimitry Andric{
2438bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2439bdd1243dSDimitry Andric    if (__front_spare() >= __block_size)
24400b57cec5SDimitry Andric    {
2441bdd1243dSDimitry Andric        __start_ -= __block_size;
2442bdd1243dSDimitry Andric        pointer __pt = __map_.front();
2443bdd1243dSDimitry Andric        __map_.pop_front();
2444bdd1243dSDimitry Andric        __map_.push_back(__pt);
24450b57cec5SDimitry Andric    }
24460b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2447bdd1243dSDimitry Andric    else if (__map_.size() < __map_.capacity())
24480b57cec5SDimitry Andric    {   // we can put the new buffer into the map, but don't shift things around
24490b57cec5SDimitry Andric        // until it is allocated.  If we throw, we don't need to fix
24500b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
2451bdd1243dSDimitry Andric        if (__map_.__back_spare() != 0)
2452bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
24530b57cec5SDimitry Andric        else
24540b57cec5SDimitry Andric        {
2455bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
24560b57cec5SDimitry Andric            // Done allocating, reorder capacity
2457bdd1243dSDimitry Andric            pointer __pt = __map_.front();
2458bdd1243dSDimitry Andric            __map_.pop_front();
2459bdd1243dSDimitry Andric            __map_.push_back(__pt);
24600b57cec5SDimitry Andric        }
2461*06c3fb27SDimitry Andric        __annotate_whole_block(__map_.size() - 1, __asan_poison);
24620b57cec5SDimitry Andric    }
24630b57cec5SDimitry Andric    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
24640b57cec5SDimitry Andric    else
24650b57cec5SDimitry Andric    {
2466bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2467bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(), 1),
2468bdd1243dSDimitry Andric                  __map_.size(),
2469bdd1243dSDimitry Andric                  __map_.__alloc());
24700b57cec5SDimitry Andric
24710b57cec5SDimitry Andric        typedef __allocator_destructor<_Allocator> _Dp;
24720b57cec5SDimitry Andric        unique_ptr<pointer, _Dp> __hold(
2473bdd1243dSDimitry Andric            __alloc_traits::allocate(__a, __block_size),
2474bdd1243dSDimitry Andric                _Dp(__a, __block_size));
24750b57cec5SDimitry Andric        __buf.push_back(__hold.get());
24760b57cec5SDimitry Andric        __hold.release();
24770b57cec5SDimitry Andric
2478bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.end();
2479bdd1243dSDimitry Andric                __i != __map_.begin();)
24800b57cec5SDimitry Andric            __buf.push_front(*--__i);
2481bdd1243dSDimitry Andric        _VSTD::swap(__map_.__first_, __buf.__first_);
2482bdd1243dSDimitry Andric        _VSTD::swap(__map_.__begin_, __buf.__begin_);
2483bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_, __buf.__end_);
2484bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
2485*06c3fb27SDimitry Andric        __annotate_whole_block(__map_.size() - 1, __asan_poison);
24860b57cec5SDimitry Andric    }
24870b57cec5SDimitry Andric}
24880b57cec5SDimitry Andric
24890b57cec5SDimitry Andric// Create back capacity for __n elements.
24900b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
24910b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
24920b57cec5SDimitry Andricvoid
24930b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
24940b57cec5SDimitry Andric{
2495bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2496bdd1243dSDimitry Andric    size_type __nb = __recommend_blocks(__n + __map_.empty());
24970b57cec5SDimitry Andric    // Number of unused blocks at front:
2498bdd1243dSDimitry Andric    size_type __front_capacity = __front_spare() / __block_size;
24990b57cec5SDimitry Andric    __front_capacity = _VSTD::min(__front_capacity, __nb);  // don't take more than you need
25000b57cec5SDimitry Andric    __nb -= __front_capacity;  // number of blocks need to allocate
25010b57cec5SDimitry Andric    // If __nb == 0, then we have sufficient capacity.
25020b57cec5SDimitry Andric    if (__nb == 0)
25030b57cec5SDimitry Andric    {
2504bdd1243dSDimitry Andric        __start_ -= __block_size * __front_capacity;
25050b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
25060b57cec5SDimitry Andric        {
2507bdd1243dSDimitry Andric            pointer __pt = __map_.front();
2508bdd1243dSDimitry Andric            __map_.pop_front();
2509bdd1243dSDimitry Andric            __map_.push_back(__pt);
25100b57cec5SDimitry Andric        }
25110b57cec5SDimitry Andric    }
25120b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2513bdd1243dSDimitry Andric    else if (__nb <= __map_.capacity() - __map_.size())
25140b57cec5SDimitry Andric    {   // we can put the new buffers into the map, but don't shift things around
25150b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
25160b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
25170b57cec5SDimitry Andric        for (; __nb > 0; --__nb)
25180b57cec5SDimitry Andric        {
2519bdd1243dSDimitry Andric            if (__map_.__back_spare() == 0)
25200b57cec5SDimitry Andric                break;
2521bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
2522*06c3fb27SDimitry Andric            __annotate_whole_block(__map_.size() - 1, __asan_poison);
25230b57cec5SDimitry Andric        }
2524bdd1243dSDimitry Andric        for (; __nb > 0; --__nb, ++__front_capacity, __start_ +=
2525*06c3fb27SDimitry Andric                                 __block_size - (__map_.size() == 1)) {
2526bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
2527*06c3fb27SDimitry Andric            __annotate_whole_block(0, __asan_poison);
2528*06c3fb27SDimitry Andric        }
25290b57cec5SDimitry Andric        // Done allocating, reorder capacity
2530bdd1243dSDimitry Andric        __start_ -= __block_size * __front_capacity;
25310b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
25320b57cec5SDimitry Andric        {
2533bdd1243dSDimitry Andric            pointer __pt = __map_.front();
2534bdd1243dSDimitry Andric            __map_.pop_front();
2535bdd1243dSDimitry Andric            __map_.push_back(__pt);
25360b57cec5SDimitry Andric        }
25370b57cec5SDimitry Andric    }
25380b57cec5SDimitry Andric    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
25390b57cec5SDimitry Andric    else
25400b57cec5SDimitry Andric    {
2541bdd1243dSDimitry Andric        size_type __ds = __front_capacity * __block_size;
2542bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2543bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(),
2544bdd1243dSDimitry Andric                                      __nb + __map_.size()),
2545bdd1243dSDimitry Andric                  __map_.size() - __front_capacity,
2546bdd1243dSDimitry Andric                  __map_.__alloc());
2547*06c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
25480b57cec5SDimitry Andric        try
25490b57cec5SDimitry Andric        {
2550*06c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2551*06c3fb27SDimitry Andric            for (; __nb > 0; --__nb) {
2552bdd1243dSDimitry Andric                __buf.push_back(__alloc_traits::allocate(__a, __block_size));
2553*06c3fb27SDimitry Andric                // ASan: this is an empty container, we have to poison the whole block
2554*06c3fb27SDimitry Andric                __annotate_poison_block(
2555*06c3fb27SDimitry Andric                    std::__to_address(__buf.back()),
2556*06c3fb27SDimitry Andric                    std::__to_address(__buf.back() + __block_size));
2557*06c3fb27SDimitry Andric            }
2558*06c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
25590b57cec5SDimitry Andric        }
25600b57cec5SDimitry Andric        catch (...)
25610b57cec5SDimitry Andric        {
2562*06c3fb27SDimitry Andric            __annotate_delete();
2563bdd1243dSDimitry Andric            for (__map_pointer __i = __buf.begin();
25640b57cec5SDimitry Andric                    __i != __buf.end(); ++__i)
2565bdd1243dSDimitry Andric                __alloc_traits::deallocate(__a, *__i, __block_size);
25660b57cec5SDimitry Andric            throw;
25670b57cec5SDimitry Andric        }
2568*06c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
25690b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
25700b57cec5SDimitry Andric        {
2571bdd1243dSDimitry Andric            __buf.push_back(__map_.front());
2572bdd1243dSDimitry Andric            __map_.pop_front();
25730b57cec5SDimitry Andric        }
2574bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.end();
2575bdd1243dSDimitry Andric                __i != __map_.begin();)
25760b57cec5SDimitry Andric            __buf.push_front(*--__i);
2577bdd1243dSDimitry Andric        _VSTD::swap(__map_.__first_, __buf.__first_);
2578bdd1243dSDimitry Andric        _VSTD::swap(__map_.__begin_, __buf.__begin_);
2579bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_, __buf.__end_);
2580bdd1243dSDimitry Andric        _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
2581bdd1243dSDimitry Andric        __start_ -= __ds;
25820b57cec5SDimitry Andric    }
25830b57cec5SDimitry Andric}
25840b57cec5SDimitry Andric
25850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
25860b57cec5SDimitry Andricvoid
25870b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_front()
25880b57cec5SDimitry Andric{
2589*06c3fb27SDimitry Andric    size_type __old_sz    = size();
2590*06c3fb27SDimitry Andric    size_type __old_start = __start_;
2591bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2592bdd1243dSDimitry Andric    __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() +
2593bdd1243dSDimitry Andric                                                    __start_ / __block_size) +
2594bdd1243dSDimitry Andric                                                    __start_ % __block_size));
2595bdd1243dSDimitry Andric    --__size();
2596bdd1243dSDimitry Andric    ++__start_;
2597*06c3fb27SDimitry Andric    __annotate_shrink_front(__old_sz, __old_start);
2598e40139ffSDimitry Andric    __maybe_remove_front_spare();
25990b57cec5SDimitry Andric}
26000b57cec5SDimitry Andric
26010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
26020b57cec5SDimitry Andricvoid
26030b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_back()
26040b57cec5SDimitry Andric{
2605*06c3fb27SDimitry Andric    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque");
2606*06c3fb27SDimitry Andric    size_type __old_sz    = size();
2607*06c3fb27SDimitry Andric    size_type __old_start = __start_;
2608bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2609bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
2610bdd1243dSDimitry Andric    __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() +
2611bdd1243dSDimitry Andric                                                    __p / __block_size) +
2612bdd1243dSDimitry Andric                                                    __p % __block_size));
2613bdd1243dSDimitry Andric    --__size();
2614*06c3fb27SDimitry Andric    __annotate_shrink_back(__old_sz, __old_start);
2615e40139ffSDimitry Andric    __maybe_remove_back_spare();
26160b57cec5SDimitry Andric}
26170b57cec5SDimitry Andric
26180b57cec5SDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)).
26190b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
26200b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
26210b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
26220b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
26230b57cec5SDimitry Andric                                         const_pointer& __vt)
26240b57cec5SDimitry Andric{
26250b57cec5SDimitry Andric    // as if
26260b57cec5SDimitry Andric    //   for (; __f != __l; ++__f, ++__r)
26270b57cec5SDimitry Andric    //       *__r = _VSTD::move(*__f);
26280b57cec5SDimitry Andric    difference_type __n = __l - __f;
26290b57cec5SDimitry Andric    while (__n > 0)
26300b57cec5SDimitry Andric    {
26310b57cec5SDimitry Andric        pointer __fb = __f.__ptr_;
2632bdd1243dSDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
26330b57cec5SDimitry Andric        difference_type __bs = __fe - __fb;
26340b57cec5SDimitry Andric        if (__bs > __n)
26350b57cec5SDimitry Andric        {
26360b57cec5SDimitry Andric            __bs = __n;
26370b57cec5SDimitry Andric            __fe = __fb + __bs;
26380b57cec5SDimitry Andric        }
26390b57cec5SDimitry Andric        if (__fb <= __vt && __vt < __fe)
26400b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
26410b57cec5SDimitry Andric        __r = _VSTD::move(__fb, __fe, __r);
26420b57cec5SDimitry Andric        __n -= __bs;
26430b57cec5SDimitry Andric        __f += __bs;
26440b57cec5SDimitry Andric    }
26450b57cec5SDimitry Andric    return __r;
26460b57cec5SDimitry Andric}
26470b57cec5SDimitry Andric
26480b57cec5SDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
26490b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt.
26500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
26510b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
26520b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
26530b57cec5SDimitry Andric                                                  const_pointer& __vt)
26540b57cec5SDimitry Andric{
26550b57cec5SDimitry Andric    // as if
26560b57cec5SDimitry Andric    //   while (__f != __l)
26570b57cec5SDimitry Andric    //       *--__r = _VSTD::move(*--__l);
26580b57cec5SDimitry Andric    difference_type __n = __l - __f;
26590b57cec5SDimitry Andric    while (__n > 0)
26600b57cec5SDimitry Andric    {
26610b57cec5SDimitry Andric        --__l;
26620b57cec5SDimitry Andric        pointer __lb = *__l.__m_iter_;
26630b57cec5SDimitry Andric        pointer __le = __l.__ptr_ + 1;
26640b57cec5SDimitry Andric        difference_type __bs = __le - __lb;
26650b57cec5SDimitry Andric        if (__bs > __n)
26660b57cec5SDimitry Andric        {
26670b57cec5SDimitry Andric            __bs = __n;
26680b57cec5SDimitry Andric            __lb = __le - __bs;
26690b57cec5SDimitry Andric        }
26700b57cec5SDimitry Andric        if (__lb <= __vt && __vt < __le)
26710b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
26720b57cec5SDimitry Andric        __r = _VSTD::move_backward(__lb, __le, __r);
26730b57cec5SDimitry Andric        __n -= __bs;
26740b57cec5SDimitry Andric        __l -= __bs - 1;
26750b57cec5SDimitry Andric    }
26760b57cec5SDimitry Andric    return __r;
26770b57cec5SDimitry Andric}
26780b57cec5SDimitry Andric
26790b57cec5SDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)).
26800b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt.
26810b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
26820b57cec5SDimitry Andricvoid
26830b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
26840b57cec5SDimitry Andric                                                   iterator __r, const_pointer& __vt)
26850b57cec5SDimitry Andric{
2686bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
26870b57cec5SDimitry Andric    // as if
2688bdd1243dSDimitry Andric    //   for (; __f != __l; ++__r, ++__f, ++__size())
26890b57cec5SDimitry Andric    //       __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));
26900b57cec5SDimitry Andric    difference_type __n = __l - __f;
26910b57cec5SDimitry Andric    while (__n > 0)
26920b57cec5SDimitry Andric    {
26930b57cec5SDimitry Andric        pointer __fb = __f.__ptr_;
2694bdd1243dSDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
26950b57cec5SDimitry Andric        difference_type __bs = __fe - __fb;
26960b57cec5SDimitry Andric        if (__bs > __n)
26970b57cec5SDimitry Andric        {
26980b57cec5SDimitry Andric            __bs = __n;
26990b57cec5SDimitry Andric            __fe = __fb + __bs;
27000b57cec5SDimitry Andric        }
27010b57cec5SDimitry Andric        if (__fb <= __vt && __vt < __fe)
27020b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
2703bdd1243dSDimitry Andric        for (; __fb != __fe; ++__fb, ++__r, ++__size())
27040b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
27050b57cec5SDimitry Andric        __n -= __bs;
27060b57cec5SDimitry Andric        __f += __bs;
27070b57cec5SDimitry Andric    }
27080b57cec5SDimitry Andric}
27090b57cec5SDimitry Andric
27100b57cec5SDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
27110b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
27120b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
27130b57cec5SDimitry Andricvoid
27140b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
27150b57cec5SDimitry Andric                                                            iterator __r, const_pointer& __vt)
27160b57cec5SDimitry Andric{
2717bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
27180b57cec5SDimitry Andric    // as if
27190b57cec5SDimitry Andric    //   for (iterator __j = __l; __j != __f;)
27200b57cec5SDimitry Andric    //   {
27210b57cec5SDimitry Andric    //       __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));
2722bdd1243dSDimitry Andric    //       --__start_;
2723bdd1243dSDimitry Andric    //       ++__size();
27240b57cec5SDimitry Andric    //   }
27250b57cec5SDimitry Andric    difference_type __n = __l - __f;
27260b57cec5SDimitry Andric    while (__n > 0)
27270b57cec5SDimitry Andric    {
27280b57cec5SDimitry Andric        --__l;
27290b57cec5SDimitry Andric        pointer __lb = *__l.__m_iter_;
27300b57cec5SDimitry Andric        pointer __le = __l.__ptr_ + 1;
27310b57cec5SDimitry Andric        difference_type __bs = __le - __lb;
27320b57cec5SDimitry Andric        if (__bs > __n)
27330b57cec5SDimitry Andric        {
27340b57cec5SDimitry Andric            __bs = __n;
27350b57cec5SDimitry Andric            __lb = __le - __bs;
27360b57cec5SDimitry Andric        }
27370b57cec5SDimitry Andric        if (__lb <= __vt && __vt < __le)
27380b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
27390b57cec5SDimitry Andric        while (__le != __lb)
27400b57cec5SDimitry Andric        {
27410b57cec5SDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
2742bdd1243dSDimitry Andric            --__start_;
2743bdd1243dSDimitry Andric            ++__size();
27440b57cec5SDimitry Andric        }
27450b57cec5SDimitry Andric        __n -= __bs;
27460b57cec5SDimitry Andric        __l -= __bs - 1;
27470b57cec5SDimitry Andric    }
27480b57cec5SDimitry Andric}
27490b57cec5SDimitry Andric
27500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
27510b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
27520b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f)
27530b57cec5SDimitry Andric{
2754*06c3fb27SDimitry Andric    size_type __old_sz    = size();
2755*06c3fb27SDimitry Andric    size_type __old_start = __start_;
2756bdd1243dSDimitry Andric    iterator __b = begin();
27570b57cec5SDimitry Andric    difference_type __pos = __f - __b;
27580b57cec5SDimitry Andric    iterator __p = __b + __pos;
2759bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2760bdd1243dSDimitry Andric    if (static_cast<size_t>(__pos) <= (size() - 1) / 2)
27610b57cec5SDimitry Andric    {   // erase from front
27620b57cec5SDimitry Andric        _VSTD::move_backward(__b, __p, _VSTD::next(__p));
27630b57cec5SDimitry Andric        __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
2764bdd1243dSDimitry Andric        --__size();
2765bdd1243dSDimitry Andric        ++__start_;
2766*06c3fb27SDimitry Andric        __annotate_shrink_front(__old_sz, __old_start);
2767e40139ffSDimitry Andric        __maybe_remove_front_spare();
27680b57cec5SDimitry Andric    }
27690b57cec5SDimitry Andric    else
27700b57cec5SDimitry Andric    {   // erase from back
2771bdd1243dSDimitry Andric        iterator __i = _VSTD::move(_VSTD::next(__p), end(), __p);
27720b57cec5SDimitry Andric        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2773bdd1243dSDimitry Andric        --__size();
2774*06c3fb27SDimitry Andric        __annotate_shrink_back(__old_sz, __old_start);
2775e40139ffSDimitry Andric        __maybe_remove_back_spare();
27760b57cec5SDimitry Andric    }
2777bdd1243dSDimitry Andric    return begin() + __pos;
27780b57cec5SDimitry Andric}
27790b57cec5SDimitry Andric
27800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
27810b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
27820b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
27830b57cec5SDimitry Andric{
2784*06c3fb27SDimitry Andric    size_type __old_sz    = size();
2785*06c3fb27SDimitry Andric    size_type __old_start = __start_;
27860b57cec5SDimitry Andric    difference_type __n = __l - __f;
2787bdd1243dSDimitry Andric    iterator __b = begin();
27880b57cec5SDimitry Andric    difference_type __pos = __f - __b;
27890b57cec5SDimitry Andric    iterator __p = __b + __pos;
27900b57cec5SDimitry Andric    if (__n > 0)
27910b57cec5SDimitry Andric    {
2792bdd1243dSDimitry Andric        allocator_type& __a = __alloc();
2793bdd1243dSDimitry Andric        if (static_cast<size_t>(__pos) <= (size() - __n) / 2)
27940b57cec5SDimitry Andric        {   // erase from front
27950b57cec5SDimitry Andric            iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
27960b57cec5SDimitry Andric            for (; __b != __i; ++__b)
27970b57cec5SDimitry Andric                __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
2798bdd1243dSDimitry Andric            __size() -= __n;
2799bdd1243dSDimitry Andric            __start_ += __n;
2800*06c3fb27SDimitry Andric            __annotate_shrink_front(__old_sz, __old_start);
2801e40139ffSDimitry Andric            while (__maybe_remove_front_spare()) {
28020b57cec5SDimitry Andric            }
28030b57cec5SDimitry Andric        }
28040b57cec5SDimitry Andric        else
28050b57cec5SDimitry Andric        {   // erase from back
2806bdd1243dSDimitry Andric            iterator __i = _VSTD::move(__p + __n, end(), __p);
2807bdd1243dSDimitry Andric            for (iterator __e = end(); __i != __e; ++__i)
28080b57cec5SDimitry Andric                __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2809bdd1243dSDimitry Andric            __size() -= __n;
2810*06c3fb27SDimitry Andric            __annotate_shrink_back(__old_sz, __old_start);
2811e40139ffSDimitry Andric            while (__maybe_remove_back_spare()) {
28120b57cec5SDimitry Andric            }
28130b57cec5SDimitry Andric        }
28140b57cec5SDimitry Andric    }
2815bdd1243dSDimitry Andric    return begin() + __pos;
28160b57cec5SDimitry Andric}
28170b57cec5SDimitry Andric
28180b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
28190b57cec5SDimitry Andricvoid
28200b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
28210b57cec5SDimitry Andric{
2822*06c3fb27SDimitry Andric    size_type __old_sz    = size();
2823*06c3fb27SDimitry Andric    size_type __old_start = __start_;
2824bdd1243dSDimitry Andric    iterator __e = end();
28250b57cec5SDimitry Andric    difference_type __n = __e - __f;
28260b57cec5SDimitry Andric    if (__n > 0)
28270b57cec5SDimitry Andric    {
2828bdd1243dSDimitry Andric        allocator_type& __a = __alloc();
2829bdd1243dSDimitry Andric        iterator __b = begin();
28300b57cec5SDimitry Andric        difference_type __pos = __f - __b;
28310b57cec5SDimitry Andric        for (iterator __p = __b + __pos; __p != __e; ++__p)
28320b57cec5SDimitry Andric            __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
2833bdd1243dSDimitry Andric        __size() -= __n;
2834*06c3fb27SDimitry Andric        __annotate_shrink_back(__old_sz, __old_start);
2835e40139ffSDimitry Andric        while (__maybe_remove_back_spare()) {
28360b57cec5SDimitry Andric        }
28370b57cec5SDimitry Andric    }
28380b57cec5SDimitry Andric}
28390b57cec5SDimitry Andric
28400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
28410b57cec5SDimitry Andricinline
28420b57cec5SDimitry Andricvoid
28430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::swap(deque& __c)
28440b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
28450b57cec5SDimitry Andric        _NOEXCEPT
28460b57cec5SDimitry Andric#else
28470b57cec5SDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
28480b57cec5SDimitry Andric                    __is_nothrow_swappable<allocator_type>::value)
28490b57cec5SDimitry Andric#endif
28500b57cec5SDimitry Andric{
2851bdd1243dSDimitry Andric    __map_.swap(__c.__map_);
2852bdd1243dSDimitry Andric    _VSTD::swap(__start_, __c.__start_);
2853bdd1243dSDimitry Andric    _VSTD::swap(__size(), __c.__size());
2854bdd1243dSDimitry Andric    _VSTD::__swap_allocator(__alloc(), __c.__alloc());
28550b57cec5SDimitry Andric}
28560b57cec5SDimitry Andric
28570b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
28580b57cec5SDimitry Andricinline
28590b57cec5SDimitry Andricvoid
28600b57cec5SDimitry Andricdeque<_Tp, _Allocator>::clear() _NOEXCEPT
28610b57cec5SDimitry Andric{
2862*06c3fb27SDimitry Andric    __annotate_delete();
2863bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2864bdd1243dSDimitry Andric    for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
2865bdd1243dSDimitry Andric        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2866bdd1243dSDimitry Andric    __size() = 0;
2867bdd1243dSDimitry Andric    while (__map_.size() > 2)
2868bdd1243dSDimitry Andric    {
2869bdd1243dSDimitry Andric        __alloc_traits::deallocate(__a, __map_.front(), __block_size);
2870bdd1243dSDimitry Andric        __map_.pop_front();
2871bdd1243dSDimitry Andric    }
2872bdd1243dSDimitry Andric    switch (__map_.size())
2873bdd1243dSDimitry Andric    {
2874bdd1243dSDimitry Andric    case 1:
2875bdd1243dSDimitry Andric        __start_ = __block_size / 2;
2876bdd1243dSDimitry Andric        break;
2877bdd1243dSDimitry Andric    case 2:
2878bdd1243dSDimitry Andric        __start_ = __block_size;
2879bdd1243dSDimitry Andric        break;
2880bdd1243dSDimitry Andric    }
2881*06c3fb27SDimitry Andric    __annotate_new(0);
28820b57cec5SDimitry Andric}
28830b57cec5SDimitry Andric
28840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2885bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
28860b57cec5SDimitry Andricbool
28870b57cec5SDimitry Andricoperator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
28880b57cec5SDimitry Andric{
28890b57cec5SDimitry Andric    const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
28900b57cec5SDimitry Andric    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
28910b57cec5SDimitry Andric}
28920b57cec5SDimitry Andric
2893*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17
2894*06c3fb27SDimitry Andric
28950b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2896bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
28970b57cec5SDimitry Andricbool
28980b57cec5SDimitry Andricoperator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
28990b57cec5SDimitry Andric{
29000b57cec5SDimitry Andric    return !(__x == __y);
29010b57cec5SDimitry Andric}
29020b57cec5SDimitry Andric
29030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2904bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29050b57cec5SDimitry Andricbool
29060b57cec5SDimitry Andricoperator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29070b57cec5SDimitry Andric{
29080b57cec5SDimitry Andric    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
29090b57cec5SDimitry Andric}
29100b57cec5SDimitry Andric
29110b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2912bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29130b57cec5SDimitry Andricbool
29140b57cec5SDimitry Andricoperator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29150b57cec5SDimitry Andric{
29160b57cec5SDimitry Andric    return __y < __x;
29170b57cec5SDimitry Andric}
29180b57cec5SDimitry Andric
29190b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2920bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29210b57cec5SDimitry Andricbool
29220b57cec5SDimitry Andricoperator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29230b57cec5SDimitry Andric{
29240b57cec5SDimitry Andric    return !(__x < __y);
29250b57cec5SDimitry Andric}
29260b57cec5SDimitry Andric
29270b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2928bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29290b57cec5SDimitry Andricbool
29300b57cec5SDimitry Andricoperator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29310b57cec5SDimitry Andric{
29320b57cec5SDimitry Andric    return !(__y < __x);
29330b57cec5SDimitry Andric}
29340b57cec5SDimitry Andric
2935*06c3fb27SDimitry Andric#else // _LIBCPP_STD_VER <= 17
2936*06c3fb27SDimitry Andric
2937*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
2938*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
2939*06c3fb27SDimitry Andricoperator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
2940*06c3fb27SDimitry Andric    return std::lexicographical_compare_three_way(
2941*06c3fb27SDimitry Andric        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
2942*06c3fb27SDimitry Andric}
2943*06c3fb27SDimitry Andric
2944*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER <= 17
2945*06c3fb27SDimitry Andric
29460b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2947bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29480b57cec5SDimitry Andricvoid
29490b57cec5SDimitry Andricswap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
29500b57cec5SDimitry Andric    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
29510b57cec5SDimitry Andric{
29520b57cec5SDimitry Andric    __x.swap(__y);
29530b57cec5SDimitry Andric}
29540b57cec5SDimitry Andric
2955*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
29560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up>
2957bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
29585ffd83dbSDimitry Andricerase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
29595ffd83dbSDimitry Andric  auto __old_size = __c.size();
29605ffd83dbSDimitry Andric  __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end());
29615ffd83dbSDimitry Andric  return __old_size - __c.size();
29625ffd83dbSDimitry Andric}
29630b57cec5SDimitry Andric
29640b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate>
2965bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
29665ffd83dbSDimitry Andricerase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
29675ffd83dbSDimitry Andric  auto __old_size = __c.size();
29685ffd83dbSDimitry Andric  __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
29695ffd83dbSDimitry Andric  return __old_size - __c.size();
29705ffd83dbSDimitry Andric}
297181ad6265SDimitry Andric
297281ad6265SDimitry Andrictemplate <>
297381ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<char>> = true;
297481ad6265SDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
297581ad6265SDimitry Andrictemplate <>
297681ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;
29770b57cec5SDimitry Andric#endif
29780b57cec5SDimitry Andric
2979*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20
29800b57cec5SDimitry Andric
29810b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
29820b57cec5SDimitry Andric
2983*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
2984bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2985bdd1243dSDimitry Andricnamespace pmr {
2986bdd1243dSDimitry Andrictemplate <class _ValueT>
2987*06c3fb27SDimitry Andricusing deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;
2988bdd1243dSDimitry Andric} // namespace pmr
2989bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD
2990bdd1243dSDimitry Andric#endif
2991bdd1243dSDimitry Andric
29920b57cec5SDimitry Andric_LIBCPP_POP_MACROS
29930b57cec5SDimitry Andric
2994bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
2995bdd1243dSDimitry Andric#  include <algorithm>
2996bdd1243dSDimitry Andric#  include <atomic>
2997bdd1243dSDimitry Andric#  include <concepts>
2998*06c3fb27SDimitry Andric#  include <cstdlib>
2999bdd1243dSDimitry Andric#  include <functional>
3000bdd1243dSDimitry Andric#  include <iosfwd>
3001bdd1243dSDimitry Andric#  include <iterator>
3002*06c3fb27SDimitry Andric#  include <type_traits>
3003bdd1243dSDimitry Andric#  include <typeinfo>
3004bdd1243dSDimitry Andric#endif
3005bdd1243dSDimitry Andric
30060b57cec5SDimitry Andric#endif // _LIBCPP_DEQUE
3007