xref: /freebsd/contrib/llvm-project/libcxx/include/deque (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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);
5006c3fb27SDimitry Andric    template<container-compatible-range<T> R>
5106c3fb27SDimitry 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);
6906c3fb27SDimitry Andric    template<container-compatible-range<T> R>
7006c3fb27SDimitry 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);
11406c3fb27SDimitry Andric    template<container-compatible-range<T> R>
11506c3fb27SDimitry 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);
11806c3fb27SDimitry Andric    template<container-compatible-range<T> R>
11906c3fb27SDimitry 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);
12806c3fb27SDimitry Andric    template<container-compatible-range<T> R>
12906c3fb27SDimitry 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
14406c3fb27SDimitry Andrictemplate<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
14506c3fb27SDimitry Andric  deque(from_range_t, R&&, Allocator = Allocator())
14606c3fb27SDimitry Andric    -> deque<ranges::range_value_t<R>, Allocator>; // C++23
14706c3fb27SDimitry 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>
15106c3fb27SDimitry Andric    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
1520b57cec5SDimitry Andrictemplate <class T, class Allocator>
15306c3fb27SDimitry Andric    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
1540b57cec5SDimitry Andrictemplate <class T, class Allocator>
15506c3fb27SDimitry Andric    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
1560b57cec5SDimitry Andrictemplate <class T, class Allocator>
15706c3fb27SDimitry Andric    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
1580b57cec5SDimitry Andrictemplate <class T, class Allocator>
15906c3fb27SDimitry Andric    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
16006c3fb27SDimitry Andrictemplate<class T, class Allocator>
16106c3fb27SDimitry Andric    synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x,
16206c3fb27SDimitry 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>
18206c3fb27SDimitry 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>
18606c3fb27SDimitry 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
19206c3fb27SDimitry Andric#include <__availability>
1930b57cec5SDimitry Andric#include <__config>
19481ad6265SDimitry Andric#include <__format/enable_insertable.h>
19506c3fb27SDimitry 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>
20106c3fb27SDimitry 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>
20706c3fb27SDimitry Andric#include <__ranges/access.h>
20806c3fb27SDimitry Andric#include <__ranges/concepts.h>
20906c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h>
21006c3fb27SDimitry Andric#include <__ranges/from_range.h>
21106c3fb27SDimitry Andric#include <__ranges/size.h>
2120b57cec5SDimitry Andric#include <__split_buffer>
213bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h>
21406c3fb27SDimitry Andric#include <__type_traits/is_convertible.h>
21506c3fb27SDimitry Andric#include <__type_traits/is_same.h>
21606c3fb27SDimitry Andric#include <__type_traits/type_identity.h>
217fe6060f1SDimitry Andric#include <__utility/forward.h>
21881ad6265SDimitry Andric#include <__utility/move.h>
21906c3fb27SDimitry 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
28206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
2830b57cec5SDimitry Andric     : __m_iter_(nullptr), __ptr_(nullptr)
2840b57cec5SDimitry Andric#endif
2850b57cec5SDimitry Andric     {}
2860b57cec5SDimitry Andric
287*5f757f3fSDimitry Andric    template <class _Pp, class _Rp, class _MP, __enable_if_t<is_convertible<_Pp, pointer>::value, int> = 0>
288bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
289*5f757f3fSDimitry Andric    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it) _NOEXCEPT
2900b57cec5SDimitry Andric        : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
2910b57cec5SDimitry Andric
292bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI reference operator*() const {return *__ptr_;}
293bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI pointer operator->() const {return __ptr_;}
2940b57cec5SDimitry Andric
295bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++()
2960b57cec5SDimitry Andric    {
2970b57cec5SDimitry Andric        if (++__ptr_ - *__m_iter_ == __block_size)
2980b57cec5SDimitry Andric        {
2990b57cec5SDimitry Andric            ++__m_iter_;
3000b57cec5SDimitry Andric            __ptr_ = *__m_iter_;
3010b57cec5SDimitry Andric        }
3020b57cec5SDimitry Andric        return *this;
3030b57cec5SDimitry Andric    }
3040b57cec5SDimitry Andric
305bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int)
3060b57cec5SDimitry Andric    {
3070b57cec5SDimitry Andric        __deque_iterator __tmp = *this;
3080b57cec5SDimitry Andric        ++(*this);
3090b57cec5SDimitry Andric        return __tmp;
3100b57cec5SDimitry Andric    }
3110b57cec5SDimitry Andric
312bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--()
3130b57cec5SDimitry Andric    {
3140b57cec5SDimitry Andric        if (__ptr_ == *__m_iter_)
3150b57cec5SDimitry Andric        {
3160b57cec5SDimitry Andric            --__m_iter_;
3170b57cec5SDimitry Andric            __ptr_ = *__m_iter_ + __block_size;
3180b57cec5SDimitry Andric        }
3190b57cec5SDimitry Andric        --__ptr_;
3200b57cec5SDimitry Andric        return *this;
3210b57cec5SDimitry Andric    }
3220b57cec5SDimitry Andric
323bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int)
3240b57cec5SDimitry Andric    {
3250b57cec5SDimitry Andric        __deque_iterator __tmp = *this;
3260b57cec5SDimitry Andric        --(*this);
3270b57cec5SDimitry Andric        return __tmp;
3280b57cec5SDimitry Andric    }
3290b57cec5SDimitry Andric
330bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n)
3310b57cec5SDimitry Andric    {
3320b57cec5SDimitry Andric        if (__n != 0)
3330b57cec5SDimitry Andric        {
3340b57cec5SDimitry Andric            __n += __ptr_ - *__m_iter_;
3350b57cec5SDimitry Andric            if (__n > 0)
3360b57cec5SDimitry Andric            {
3370b57cec5SDimitry Andric                __m_iter_ += __n / __block_size;
3380b57cec5SDimitry Andric                __ptr_ = *__m_iter_ + __n % __block_size;
3390b57cec5SDimitry Andric            }
3400b57cec5SDimitry Andric            else // (__n < 0)
3410b57cec5SDimitry Andric            {
3420b57cec5SDimitry Andric                difference_type __z = __block_size - 1 - __n;
3430b57cec5SDimitry Andric                __m_iter_ -= __z / __block_size;
3440b57cec5SDimitry Andric                __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
3450b57cec5SDimitry Andric            }
3460b57cec5SDimitry Andric        }
3470b57cec5SDimitry Andric        return *this;
3480b57cec5SDimitry Andric    }
3490b57cec5SDimitry Andric
350bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n)
3510b57cec5SDimitry Andric    {
3520b57cec5SDimitry Andric        return *this += -__n;
3530b57cec5SDimitry Andric    }
3540b57cec5SDimitry Andric
355bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const
3560b57cec5SDimitry Andric    {
3570b57cec5SDimitry Andric        __deque_iterator __t(*this);
3580b57cec5SDimitry Andric        __t += __n;
3590b57cec5SDimitry Andric        return __t;
3600b57cec5SDimitry Andric    }
3610b57cec5SDimitry Andric
362bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const
3630b57cec5SDimitry Andric    {
3640b57cec5SDimitry Andric        __deque_iterator __t(*this);
3650b57cec5SDimitry Andric        __t -= __n;
3660b57cec5SDimitry Andric        return __t;
3670b57cec5SDimitry Andric    }
3680b57cec5SDimitry Andric
369bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3700b57cec5SDimitry Andric    friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
3710b57cec5SDimitry Andric        {return __it + __n;}
3720b57cec5SDimitry Andric
373bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3740b57cec5SDimitry Andric    friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
3750b57cec5SDimitry Andric    {
3760b57cec5SDimitry Andric        if (__x != __y)
3770b57cec5SDimitry Andric            return (__x.__m_iter_ - __y.__m_iter_) * __block_size
3780b57cec5SDimitry Andric                 + (__x.__ptr_ - *__x.__m_iter_)
3790b57cec5SDimitry Andric                 - (__y.__ptr_ - *__y.__m_iter_);
3800b57cec5SDimitry Andric        return 0;
3810b57cec5SDimitry Andric    }
3820b57cec5SDimitry Andric
383bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const
3840b57cec5SDimitry Andric        {return *(*this + __n);}
3850b57cec5SDimitry Andric
386bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3870b57cec5SDimitry Andric        bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
3880b57cec5SDimitry Andric        {return __x.__ptr_ == __y.__ptr_;}
3890b57cec5SDimitry Andric
390bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3910b57cec5SDimitry Andric        bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
3920b57cec5SDimitry Andric        {return !(__x == __y);}
3930b57cec5SDimitry Andric
394bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
3950b57cec5SDimitry Andric        bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
3960b57cec5SDimitry Andric        {return __x.__m_iter_ < __y.__m_iter_ ||
3970b57cec5SDimitry Andric               (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
3980b57cec5SDimitry Andric
399bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
4000b57cec5SDimitry Andric        bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
4010b57cec5SDimitry Andric        {return __y < __x;}
4020b57cec5SDimitry Andric
403bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
4040b57cec5SDimitry Andric        bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
4050b57cec5SDimitry Andric        {return !(__y < __x);}
4060b57cec5SDimitry Andric
407bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend
4080b57cec5SDimitry Andric        bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
4090b57cec5SDimitry Andric        {return !(__x < __y);}
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andricprivate:
412bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
4130b57cec5SDimitry Andric        : __m_iter_(__m), __ptr_(__p) {}
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andric    template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque;
4160b57cec5SDimitry Andric    template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
4170b57cec5SDimitry Andric        friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
4180b57cec5SDimitry Andric
419bdd1243dSDimitry Andric    template <class>
420bdd1243dSDimitry Andric    friend struct __segmented_iterator_traits;
421bdd1243dSDimitry Andric};
4220b57cec5SDimitry Andric
423bdd1243dSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize>
424bdd1243dSDimitry Andricstruct __segmented_iterator_traits<
425bdd1243dSDimitry Andric    __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > {
426bdd1243dSDimitry Andricprivate:
427bdd1243dSDimitry Andric  using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>;
4280b57cec5SDimitry Andric
429bdd1243dSDimitry Andricpublic:
430bdd1243dSDimitry Andric  using __is_segmented_iterator = true_type;
431bdd1243dSDimitry Andric  using __segment_iterator = _MapPointer;
432bdd1243dSDimitry Andric  using __local_iterator = _Pointer;
4330b57cec5SDimitry Andric
434bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; }
435bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; }
436bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; }
4370b57cec5SDimitry Andric
438bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
439bdd1243dSDimitry Andric        return *__iter + _Iterator::__block_size;
440bdd1243dSDimitry Andric  }
4410b57cec5SDimitry Andric
442bdd1243dSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) {
443*5f757f3fSDimitry Andric        if (__segment && __local == __end(__segment)) {
444bdd1243dSDimitry Andric            ++__segment;
445bdd1243dSDimitry Andric            return _Iterator(__segment, *__segment);
446bdd1243dSDimitry Andric        }
447bdd1243dSDimitry Andric        return _Iterator(__segment, __local);
448bdd1243dSDimitry Andric  }
4490b57cec5SDimitry Andric};
4500b57cec5SDimitry Andric
4510b57cec5SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
4520b57cec5SDimitry Andric          class _DiffType, _DiffType _BlockSize>
4530b57cec5SDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
4540b57cec5SDimitry Andric                                 _DiffType, _BlockSize>::__block_size =
4550b57cec5SDimitry Andric    __deque_block_size<_ValueType, _DiffType>::value;
4560b57cec5SDimitry Andric
457bdd1243dSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/>
458bdd1243dSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque
4590b57cec5SDimitry Andric{
4600b57cec5SDimitry Andricpublic:
461bdd1243dSDimitry Andric    // types:
462e40139ffSDimitry Andric
463bdd1243dSDimitry Andric  using value_type = _Tp;
4640b57cec5SDimitry Andric
465bdd1243dSDimitry Andric  static_assert((is_same<typename _Allocator::value_type, value_type>::value),
466bdd1243dSDimitry Andric                "Allocator::value_type must be same type as value_type");
4670b57cec5SDimitry Andric
468bdd1243dSDimitry Andric  using allocator_type = _Allocator;
469bdd1243dSDimitry Andric  using __alloc_traits = allocator_traits<allocator_type>;
4700b57cec5SDimitry Andric
471bdd1243dSDimitry Andric  using size_type       = typename __alloc_traits::size_type;
472bdd1243dSDimitry Andric  using difference_type = typename __alloc_traits::difference_type;
4730b57cec5SDimitry Andric
474bdd1243dSDimitry Andric  using pointer       = typename __alloc_traits::pointer;
475bdd1243dSDimitry Andric  using const_pointer = typename __alloc_traits::const_pointer;
476bdd1243dSDimitry Andric
477bdd1243dSDimitry Andric  using __pointer_allocator       = __rebind_alloc<__alloc_traits, pointer>;
478bdd1243dSDimitry Andric  using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>;
479bdd1243dSDimitry Andric  using __map                     = __split_buffer<pointer, __pointer_allocator>;
480bdd1243dSDimitry Andric  using __map_alloc_traits        = allocator_traits<__pointer_allocator>;
481bdd1243dSDimitry Andric  using __map_pointer             = typename __map_alloc_traits::pointer;
482bdd1243dSDimitry Andric  using __map_const_pointer       = typename allocator_traits<__const_pointer_allocator>::const_pointer;
48306c3fb27SDimitry Andric  using __map_const_iterator      = typename __map::const_iterator;
484bdd1243dSDimitry Andric
485bdd1243dSDimitry Andric  using reference       = value_type&;
486bdd1243dSDimitry Andric  using const_reference = const value_type&;
487bdd1243dSDimitry Andric
488bdd1243dSDimitry Andric  using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>;
489bdd1243dSDimitry Andric  using const_iterator =
490bdd1243dSDimitry Andric      __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>;
491bdd1243dSDimitry Andric  using reverse_iterator       = std::reverse_iterator<iterator>;
492bdd1243dSDimitry Andric  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
493bdd1243dSDimitry Andric
494bdd1243dSDimitry Andric  static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
495bdd1243dSDimitry Andric                "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
496bdd1243dSDimitry Andric                "original allocator");
497bdd1243dSDimitry Andric  static_assert(is_nothrow_default_constructible<allocator_type>::value ==
498bdd1243dSDimitry Andric                    is_nothrow_default_constructible<__pointer_allocator>::value,
499bdd1243dSDimitry Andric                "rebinding an allocator should not change excpetion guarantees");
500bdd1243dSDimitry Andric  static_assert(is_nothrow_move_constructible<allocator_type>::value ==
501bdd1243dSDimitry Andric                    is_nothrow_move_constructible<typename __map::allocator_type>::value,
502bdd1243dSDimitry Andric                "rebinding an allocator should not change excpetion guarantees");
503bdd1243dSDimitry Andric
504bdd1243dSDimitry Andricprivate:
505e40139ffSDimitry Andric  struct __deque_block_range {
506bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI
507bdd1243dSDimitry Andric    __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {}
508e40139ffSDimitry Andric    const pointer __begin_;
509e40139ffSDimitry Andric    const pointer __end_;
510e40139ffSDimitry Andric  };
511e40139ffSDimitry Andric
512e40139ffSDimitry Andric  struct __deque_range {
513e40139ffSDimitry Andric    iterator __pos_;
514e40139ffSDimitry Andric    const iterator __end_;
515e40139ffSDimitry Andric
516bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT
517e40139ffSDimitry Andric      : __pos_(__pos), __end_(__e) {}
518e40139ffSDimitry Andric
519bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT {
520e40139ffSDimitry Andric      return __pos_ != __end_;
521e40139ffSDimitry Andric    }
522e40139ffSDimitry Andric
523bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range begin() const {
524e40139ffSDimitry Andric      return *this;
525e40139ffSDimitry Andric    }
526e40139ffSDimitry Andric
527bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range end() const {
528e40139ffSDimitry Andric      return __deque_range(__end_, __end_);
529e40139ffSDimitry Andric    }
530bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT {
531e40139ffSDimitry Andric        if (__pos_.__m_iter_ == __end_.__m_iter_) {
532e40139ffSDimitry Andric        return __deque_block_range(__pos_.__ptr_, __end_.__ptr_);
533e40139ffSDimitry Andric      }
534e40139ffSDimitry Andric      return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size);
535e40139ffSDimitry Andric    }
536e40139ffSDimitry Andric
537bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT {
538e40139ffSDimitry Andric      if (__pos_.__m_iter_ == __end_.__m_iter_) {
539e40139ffSDimitry Andric        __pos_ = __end_;
540e40139ffSDimitry Andric      } else {
541e40139ffSDimitry Andric        ++__pos_.__m_iter_;
542e40139ffSDimitry Andric        __pos_.__ptr_ = *__pos_.__m_iter_;
543e40139ffSDimitry Andric      }
544e40139ffSDimitry Andric      return *this;
545e40139ffSDimitry Andric    }
546e40139ffSDimitry Andric
547e40139ffSDimitry Andric
548bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) {
549e40139ffSDimitry Andric      return __lhs.__pos_ == __rhs.__pos_;
550e40139ffSDimitry Andric    }
551bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) {
552e40139ffSDimitry Andric      return !(__lhs == __rhs);
553e40139ffSDimitry Andric    }
554e40139ffSDimitry Andric  };
555e40139ffSDimitry Andric
556e40139ffSDimitry Andric  struct _ConstructTransaction {
557bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r)
558e40139ffSDimitry Andric      : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {}
559e40139ffSDimitry Andric
560e40139ffSDimitry Andric
561bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
562bdd1243dSDimitry Andric      __base_->__size() += (__pos_ - __begin_);
563e40139ffSDimitry Andric    }
564e40139ffSDimitry Andric
565e40139ffSDimitry Andric    pointer __pos_;
566e40139ffSDimitry Andric    const pointer __end_;
567e40139ffSDimitry Andric  private:
568e40139ffSDimitry Andric    const pointer __begin_;
569bdd1243dSDimitry Andric    deque* const __base_;
570e40139ffSDimitry Andric  };
571e40139ffSDimitry Andric
572bdd1243dSDimitry Andric  static const difference_type __block_size;
573bdd1243dSDimitry Andric
5740b57cec5SDimitry Andric  __map __map_;
5750b57cec5SDimitry Andric  size_type __start_;
5760b57cec5SDimitry Andric  __compressed_pair<size_type, allocator_type> __size_;
5770b57cec5SDimitry Andric
5780b57cec5SDimitry Andricpublic:
579bdd1243dSDimitry Andric
580bdd1243dSDimitry Andric    // construct/copy/destroy:
581bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
582bdd1243dSDimitry Andric    deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
58306c3fb27SDimitry Andric        : __start_(0), __size_(0, __default_init_tag()) {
58406c3fb27SDimitry Andric      __annotate_new(0);
58506c3fb27SDimitry Andric    }
586bdd1243dSDimitry Andric
587bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~deque() {
588bdd1243dSDimitry Andric      clear();
58906c3fb27SDimitry Andric      __annotate_delete();
590bdd1243dSDimitry Andric      typename __map::iterator __i = __map_.begin();
591bdd1243dSDimitry Andric      typename __map::iterator __e = __map_.end();
592bdd1243dSDimitry Andric      for (; __i != __e; ++__i)
593bdd1243dSDimitry Andric          __alloc_traits::deallocate(__alloc(), *__i, __block_size);
594bdd1243dSDimitry Andric    }
595bdd1243dSDimitry Andric
596bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a)
59706c3fb27SDimitry Andric        : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {
59806c3fb27SDimitry Andric      __annotate_new(0);
59906c3fb27SDimitry Andric    }
600bdd1243dSDimitry Andric
601bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n);
60206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
603bdd1243dSDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a);
604bdd1243dSDimitry Andric#endif
605bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v);
606bdd1243dSDimitry Andric
607bdd1243dSDimitry Andric    template <class = __enable_if_t<__is_allocator<_Allocator>::value> >
608bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a)
609bdd1243dSDimitry Andric        : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
610bdd1243dSDimitry Andric    {
61106c3fb27SDimitry Andric        __annotate_new(0);
612bdd1243dSDimitry Andric        if (__n > 0)
613bdd1243dSDimitry Andric            __append(__n, __v);
614bdd1243dSDimitry Andric    }
615bdd1243dSDimitry Andric
616*5f757f3fSDimitry Andric    template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0>
617*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l);
618*5f757f3fSDimitry Andric    template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0>
619*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a);
62006c3fb27SDimitry Andric
62106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
62206c3fb27SDimitry Andric  template <_ContainerCompatibleRange<_Tp> _Range>
62306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range,
62406c3fb27SDimitry Andric      const allocator_type& __a = allocator_type())
62506c3fb27SDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {
62606c3fb27SDimitry Andric    if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
62706c3fb27SDimitry Andric      __append_with_size(ranges::begin(__range), ranges::distance(__range));
62806c3fb27SDimitry Andric
62906c3fb27SDimitry Andric    } else {
63006c3fb27SDimitry Andric      for (auto&& __e : __range) {
63106c3fb27SDimitry Andric        emplace_back(std::forward<decltype(__e)>(__e));
63206c3fb27SDimitry Andric      }
63306c3fb27SDimitry Andric    }
63406c3fb27SDimitry Andric  }
63506c3fb27SDimitry Andric#endif
63606c3fb27SDimitry Andric
637bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(const deque& __c);
638bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a);
639bdd1243dSDimitry Andric
640bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c);
6410b57cec5SDimitry Andric
6420b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
643bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il);
644bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a);
645bdd1243dSDimitry Andric
646bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
647bdd1243dSDimitry Andric    deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
648bdd1243dSDimitry Andric
649bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
650bdd1243dSDimitry Andric    deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
651bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
652bdd1243dSDimitry Andric    deque(deque&& __c, const __type_identity_t<allocator_type>& __a);
653bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
654bdd1243dSDimitry Andric    deque& operator=(deque&& __c)
655bdd1243dSDimitry Andric        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
656bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value);
657bdd1243dSDimitry Andric
658bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
659bdd1243dSDimitry Andric    void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
6600b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
6610b57cec5SDimitry Andric
662*5f757f3fSDimitry Andric    template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value &&
663*5f757f3fSDimitry Andric                                              !__has_random_access_iterator_category<_InputIter>::value, int> = 0>
664*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l);
665*5f757f3fSDimitry Andric    template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> = 0>
666*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l);
66706c3fb27SDimitry Andric
66806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
66906c3fb27SDimitry Andric    template <_ContainerCompatibleRange<_Tp> _Range>
67006c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
67106c3fb27SDimitry Andric    void assign_range(_Range&& __range) {
67206c3fb27SDimitry Andric      if constexpr (ranges::random_access_range<_Range>) {
67306c3fb27SDimitry Andric        auto __n = static_cast<size_type>(ranges::distance(__range));
67406c3fb27SDimitry Andric        __assign_with_size_random_access(ranges::begin(__range), __n);
67506c3fb27SDimitry Andric
67606c3fb27SDimitry Andric      } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
67706c3fb27SDimitry Andric        auto __n = static_cast<size_type>(ranges::distance(__range));
67806c3fb27SDimitry Andric        __assign_with_size(ranges::begin(__range), __n);
67906c3fb27SDimitry Andric
68006c3fb27SDimitry Andric      } else {
68106c3fb27SDimitry Andric        __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
68206c3fb27SDimitry Andric      }
68306c3fb27SDimitry Andric    }
68406c3fb27SDimitry Andric#endif
68506c3fb27SDimitry Andric
686bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
687bdd1243dSDimitry Andric
688bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
689bdd1243dSDimitry Andric    allocator_type get_allocator() const _NOEXCEPT;
690bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); }
691bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); }
692bdd1243dSDimitry Andric
693bdd1243dSDimitry Andric  // iterators:
694bdd1243dSDimitry Andric
695bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
696bdd1243dSDimitry Andric      __map_pointer __mp = __map_.begin() + __start_ / __block_size;
697bdd1243dSDimitry Andric      return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
698bdd1243dSDimitry Andric  }
699bdd1243dSDimitry Andric
700bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
701bdd1243dSDimitry Andric      __map_const_pointer __mp =
702bdd1243dSDimitry Andric          static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
703bdd1243dSDimitry Andric      return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
704bdd1243dSDimitry Andric  }
705bdd1243dSDimitry Andric
706bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
707bdd1243dSDimitry Andric      size_type __p      = size() + __start_;
708bdd1243dSDimitry Andric      __map_pointer __mp = __map_.begin() + __p / __block_size;
709bdd1243dSDimitry Andric      return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
710bdd1243dSDimitry Andric  }
711bdd1243dSDimitry Andric
712bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
713bdd1243dSDimitry Andric      size_type __p            = size() + __start_;
714bdd1243dSDimitry Andric      __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
715bdd1243dSDimitry Andric      return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
716bdd1243dSDimitry Andric  }
717bdd1243dSDimitry Andric
718bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
719bdd1243dSDimitry Andric    reverse_iterator       rbegin() _NOEXCEPT
720bdd1243dSDimitry Andric        {return       reverse_iterator(end());}
721bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
722bdd1243dSDimitry Andric    const_reverse_iterator rbegin() const _NOEXCEPT
723bdd1243dSDimitry Andric        {return const_reverse_iterator(end());}
724bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
725bdd1243dSDimitry Andric    reverse_iterator       rend() _NOEXCEPT
726bdd1243dSDimitry Andric        {return       reverse_iterator(begin());}
727bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
728bdd1243dSDimitry Andric    const_reverse_iterator rend()   const _NOEXCEPT
729bdd1243dSDimitry Andric        {return const_reverse_iterator(begin());}
730bdd1243dSDimitry Andric
731bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
732bdd1243dSDimitry Andric    const_iterator         cbegin()  const _NOEXCEPT
733bdd1243dSDimitry Andric        {return begin();}
734bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
735bdd1243dSDimitry Andric    const_iterator         cend()    const _NOEXCEPT
736bdd1243dSDimitry Andric        {return end();}
737bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
738bdd1243dSDimitry Andric    const_reverse_iterator crbegin() const _NOEXCEPT
739bdd1243dSDimitry Andric        {return const_reverse_iterator(end());}
740bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
741bdd1243dSDimitry Andric    const_reverse_iterator crend()   const _NOEXCEPT
742bdd1243dSDimitry Andric        {return const_reverse_iterator(begin());}
743bdd1243dSDimitry Andric
744bdd1243dSDimitry Andric    // capacity:
745bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
746bdd1243dSDimitry Andric    size_type size() const _NOEXCEPT {return __size();}
747bdd1243dSDimitry Andric
748bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); }
749bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); }
750bdd1243dSDimitry Andric
751bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
752bdd1243dSDimitry Andric    size_type max_size() const _NOEXCEPT
753*5f757f3fSDimitry Andric        {return std::min<size_type>(
754bdd1243dSDimitry Andric            __alloc_traits::max_size(__alloc()),
755bdd1243dSDimitry Andric            numeric_limits<difference_type>::max());}
756bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
757bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
758bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
759bdd1243dSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
760bdd1243dSDimitry Andric    bool empty() const _NOEXCEPT {return size() == 0;}
761bdd1243dSDimitry Andric
762bdd1243dSDimitry Andric    // element access:
763bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
764bdd1243dSDimitry Andric    reference operator[](size_type __i) _NOEXCEPT;
765bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
766bdd1243dSDimitry Andric    const_reference operator[](size_type __i) const _NOEXCEPT;
767bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
768bdd1243dSDimitry Andric    reference at(size_type __i);
769bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
770bdd1243dSDimitry Andric    const_reference at(size_type __i) const;
771bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
772bdd1243dSDimitry Andric    reference front() _NOEXCEPT;
773bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
774bdd1243dSDimitry Andric    const_reference front() const _NOEXCEPT;
775bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
776bdd1243dSDimitry Andric    reference back() _NOEXCEPT;
777bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
778bdd1243dSDimitry Andric    const_reference back() const _NOEXCEPT;
779bdd1243dSDimitry Andric
780bdd1243dSDimitry Andric    // 23.2.2.3 modifiers:
781bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
782bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v);
783bdd1243dSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
78406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
785bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
786bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args);
787bdd1243dSDimitry Andric#else
788bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI void      emplace_front(_Args&&... __args);
789bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI void      emplace_back (_Args&&... __args);
790bdd1243dSDimitry Andric#endif
791bdd1243dSDimitry Andric    template <class... _Args> _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args);
792bdd1243dSDimitry Andric
793bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
794bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v);
79506c3fb27SDimitry Andric
79606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
79706c3fb27SDimitry Andric    template <_ContainerCompatibleRange<_Tp> _Range>
79806c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
79906c3fb27SDimitry Andric    void prepend_range(_Range&& __range) {
80006c3fb27SDimitry Andric      insert_range(begin(), std::forward<_Range>(__range));
80106c3fb27SDimitry Andric    }
80206c3fb27SDimitry Andric
80306c3fb27SDimitry Andric    template <_ContainerCompatibleRange<_Tp> _Range>
80406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
80506c3fb27SDimitry Andric    void append_range(_Range&& __range) {
80606c3fb27SDimitry Andric      insert_range(end(), std::forward<_Range>(__range));
80706c3fb27SDimitry Andric    }
80806c3fb27SDimitry Andric#endif
80906c3fb27SDimitry Andric
810bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v);
811bdd1243dSDimitry Andric
812bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
813bdd1243dSDimitry Andric    iterator insert(const_iterator __p, initializer_list<value_type> __il)
814bdd1243dSDimitry Andric        {return insert(__p, __il.begin(), __il.end());}
815bdd1243dSDimitry Andric#endif // _LIBCPP_CXX03_LANG
816bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v);
817bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v);
818*5f757f3fSDimitry Andric    template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0>
819*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l);
820*5f757f3fSDimitry Andric    template <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> = 0>
821*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l);
822*5f757f3fSDimitry Andric    template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> = 0>
823*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l);
82406c3fb27SDimitry Andric
82506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
82606c3fb27SDimitry Andric    template <_ContainerCompatibleRange<_Tp> _Range>
82706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
82806c3fb27SDimitry Andric    iterator insert_range(const_iterator __position, _Range&& __range) {
82906c3fb27SDimitry Andric      if constexpr (ranges::bidirectional_range<_Range>) {
83006c3fb27SDimitry Andric        auto __n = static_cast<size_type>(ranges::distance(__range));
83106c3fb27SDimitry Andric        return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n);
83206c3fb27SDimitry Andric
83306c3fb27SDimitry Andric      } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
83406c3fb27SDimitry Andric        auto __n = static_cast<size_type>(ranges::distance(__range));
83506c3fb27SDimitry Andric        return __insert_with_size(__position, ranges::begin(__range), __n);
83606c3fb27SDimitry Andric
83706c3fb27SDimitry Andric      } else {
83806c3fb27SDimitry Andric        return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
83906c3fb27SDimitry Andric      }
84006c3fb27SDimitry Andric    }
84106c3fb27SDimitry Andric#endif
842bdd1243dSDimitry Andric
843bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void pop_front();
844bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void pop_back();
845bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
846bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
847bdd1243dSDimitry Andric
848bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
849bdd1243dSDimitry Andric    void swap(deque& __c)
8500b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
8510b57cec5SDimitry Andric        _NOEXCEPT;
8520b57cec5SDimitry Andric#else
8530b57cec5SDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
8540b57cec5SDimitry Andric                   __is_nothrow_swappable<allocator_type>::value);
8550b57cec5SDimitry Andric#endif
856bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8570b57cec5SDimitry Andric    void clear() _NOEXCEPT;
8580b57cec5SDimitry Andric
859bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
860bdd1243dSDimitry Andric    bool __invariants() const {
8610b57cec5SDimitry Andric        if (!__map_.__invariants())
8620b57cec5SDimitry Andric            return false;
8630b57cec5SDimitry Andric        if (__map_.size() >= size_type(-1) / __block_size)
8640b57cec5SDimitry Andric            return false;
86506c3fb27SDimitry Andric        for (__map_const_iterator __i = __map_.begin(), __e = __map_.end();
8660b57cec5SDimitry Andric            __i != __e; ++__i)
8670b57cec5SDimitry Andric            if (*__i == nullptr)
8680b57cec5SDimitry Andric                return false;
8690b57cec5SDimitry Andric        if (__map_.size() != 0)
8700b57cec5SDimitry Andric        {
8710b57cec5SDimitry Andric            if (size() >= __map_.size() * __block_size)
8720b57cec5SDimitry Andric                return false;
8730b57cec5SDimitry Andric            if (__start_ >= __map_.size() * __block_size - size())
8740b57cec5SDimitry Andric                return false;
8750b57cec5SDimitry Andric        }
8760b57cec5SDimitry Andric        else
8770b57cec5SDimitry Andric        {
8780b57cec5SDimitry Andric            if (size() != 0)
8790b57cec5SDimitry Andric                return false;
8800b57cec5SDimitry Andric            if (__start_ != 0)
8810b57cec5SDimitry Andric                return false;
8820b57cec5SDimitry Andric        }
8830b57cec5SDimitry Andric        return true;
8840b57cec5SDimitry Andric    }
8850b57cec5SDimitry Andric
886bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
887bdd1243dSDimitry Andric    void __move_assign_alloc(deque& __c)
888bdd1243dSDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
889bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value)
890bdd1243dSDimitry Andric        {__move_assign_alloc(__c, integral_constant<bool,
891bdd1243dSDimitry Andric                      __alloc_traits::propagate_on_container_move_assignment::value>());}
892bdd1243dSDimitry Andric
893bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
894bdd1243dSDimitry Andric    void __move_assign_alloc(deque& __c, true_type)
895bdd1243dSDimitry Andric        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
8960b57cec5SDimitry Andric        {
897*5f757f3fSDimitry Andric            __alloc() = std::move(__c.__alloc());
8980b57cec5SDimitry Andric        }
8990b57cec5SDimitry Andric
900bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
901bdd1243dSDimitry Andric    void __move_assign_alloc(deque&, false_type) _NOEXCEPT
9020b57cec5SDimitry Andric        {}
9034824e7fdSDimitry Andric
904bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
905bdd1243dSDimitry Andric    void __move_assign(deque& __c)
906bdd1243dSDimitry Andric        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
907bdd1243dSDimitry Andric                   is_nothrow_move_assignable<allocator_type>::value)
9084824e7fdSDimitry Andric    {
909*5f757f3fSDimitry Andric        __map_ = std::move(__c.__map_);
910bdd1243dSDimitry Andric        __start_ = __c.__start_;
911bdd1243dSDimitry Andric        __size() = __c.size();
912bdd1243dSDimitry Andric        __move_assign_alloc(__c);
913bdd1243dSDimitry Andric        __c.__start_ = __c.__size() = 0;
9144824e7fdSDimitry Andric    }
9154824e7fdSDimitry Andric
916bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9170b57cec5SDimitry Andric    static size_type __recommend_blocks(size_type __n)
9180b57cec5SDimitry Andric    {
919bdd1243dSDimitry Andric        return __n / __block_size + (__n % __block_size != 0);
9200b57cec5SDimitry Andric    }
921bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9220b57cec5SDimitry Andric    size_type __capacity() const
9230b57cec5SDimitry Andric    {
924bdd1243dSDimitry Andric        return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1;
9250b57cec5SDimitry Andric    }
926bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
927e40139ffSDimitry Andric    size_type __block_count() const
928e40139ffSDimitry Andric    {
929bdd1243dSDimitry Andric        return __map_.size();
930e40139ffSDimitry Andric    }
931e40139ffSDimitry Andric
932bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9330b57cec5SDimitry Andric    size_type __front_spare() const
9340b57cec5SDimitry Andric    {
935bdd1243dSDimitry Andric        return __start_;
9360b57cec5SDimitry Andric    }
937bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
938e40139ffSDimitry Andric    size_type __front_spare_blocks() const {
939bdd1243dSDimitry Andric      return __front_spare() / __block_size;
940e40139ffSDimitry Andric    }
941bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9420b57cec5SDimitry Andric    size_type __back_spare() const
9430b57cec5SDimitry Andric    {
944bdd1243dSDimitry Andric        return __capacity() - (__start_ + size());
9450b57cec5SDimitry Andric    }
946bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
947e40139ffSDimitry Andric    size_type __back_spare_blocks() const {
948bdd1243dSDimitry Andric      return __back_spare() / __block_size;
949e40139ffSDimitry Andric    }
950e40139ffSDimitry Andric
951e40139ffSDimitry Andric private:
95206c3fb27SDimitry Andric   enum __asan_annotation_type {
95306c3fb27SDimitry Andric     __asan_unposion,
95406c3fb27SDimitry Andric     __asan_poison
95506c3fb27SDimitry Andric   };
95606c3fb27SDimitry Andric
95706c3fb27SDimitry Andric   enum __asan_annotation_place {
95806c3fb27SDimitry Andric     __asan_front_moved,
95906c3fb27SDimitry Andric     __asan_back_moved,
96006c3fb27SDimitry Andric   };
96106c3fb27SDimitry Andric
96206c3fb27SDimitry Andric// The following functions are no-ops outside of AddressSanitizer mode.
96306c3fb27SDimitry Andric// We call annotations for every allocator, unless explicitly disabled.
96406c3fb27SDimitry Andric//
96506c3fb27SDimitry Andric// To disable annotations for a particular allocator, change value of
96606c3fb27SDimitry Andric// __asan_annotate_container_with_allocator to false.
96706c3fb27SDimitry Andric// For more details, see the "Using libc++" documentation page or
96806c3fb27SDimitry Andric// the documentation for __sanitizer_annotate_contiguous_container.
96906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container(
97006c3fb27SDimitry Andric        const void* __beg,
97106c3fb27SDimitry Andric        const void* __end,
97206c3fb27SDimitry Andric        const void* __old_con_beg,
97306c3fb27SDimitry Andric        const void* __old_con_end,
97406c3fb27SDimitry Andric        const void* __new_con_beg,
97506c3fb27SDimitry Andric        const void* __new_con_end) const {
976*5f757f3fSDimitry Andric        (void)__beg;
977*5f757f3fSDimitry Andric        (void)__end;
978*5f757f3fSDimitry Andric        (void)__old_con_beg;
979*5f757f3fSDimitry Andric        (void)__old_con_end;
980*5f757f3fSDimitry Andric        (void)__new_con_beg;
981*5f757f3fSDimitry Andric        (void)__new_con_end;
982*5f757f3fSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN
98306c3fb27SDimitry Andric        if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value)
98406c3fb27SDimitry Andric            __sanitizer_annotate_double_ended_contiguous_container(
98506c3fb27SDimitry Andric                __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end);
986*5f757f3fSDimitry Andric#endif
98706c3fb27SDimitry Andric    }
98806c3fb27SDimitry Andric
98906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
990*5f757f3fSDimitry Andric    void __annotate_from_to(
991*5f757f3fSDimitry Andric            size_type __beg,
992*5f757f3fSDimitry Andric            size_type __end,
993*5f757f3fSDimitry Andric            __asan_annotation_type __annotation_type,
994*5f757f3fSDimitry Andric            __asan_annotation_place __place) const _NOEXCEPT {
995*5f757f3fSDimitry Andric        (void)__beg;
996*5f757f3fSDimitry Andric        (void)__end;
997*5f757f3fSDimitry Andric        (void)__annotation_type;
998*5f757f3fSDimitry Andric        (void)__place;
999*5f757f3fSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN
100006c3fb27SDimitry Andric        // __beg - index of the first item to annotate
100106c3fb27SDimitry Andric        // __end - index behind the last item to annotate (so last item + 1)
100206c3fb27SDimitry Andric        // __annotation_type - __asan_unposion or __asan_poison
100306c3fb27SDimitry Andric        // __place - __asan_front_moved or __asan_back_moved
100406c3fb27SDimitry Andric        // Note: All indexes in __map_
100506c3fb27SDimitry Andric        if (__beg == __end)
100606c3fb27SDimitry Andric            return;
100706c3fb27SDimitry Andric        // __annotations_beg_map - first chunk which annotations we want to modify
100806c3fb27SDimitry Andric        // __annotations_end_map - last chunk which annotations we want to modify
100906c3fb27SDimitry Andric        // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist
101006c3fb27SDimitry Andric        __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size;
101106c3fb27SDimitry Andric        __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size;
101206c3fb27SDimitry Andric
101306c3fb27SDimitry Andric        bool const __poisoning = __annotation_type == __asan_poison;
101406c3fb27SDimitry Andric        // __old_c_beg_index - index of the first element in old container
101506c3fb27SDimitry Andric        // __old_c_end_index - index of the end of old container (last + 1)
101606c3fb27SDimitry Andric        // Note: may be outside the area we are annotating
101706c3fb27SDimitry Andric        size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_;
101806c3fb27SDimitry Andric        size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved)  ? __end : __start_ + size();
101906c3fb27SDimitry Andric        bool const __front = __place == __asan_front_moved;
102006c3fb27SDimitry Andric
102106c3fb27SDimitry Andric        if (__poisoning && empty()) {
102206c3fb27SDimitry Andric            // Special case: we shouldn't trust __start_
102306c3fb27SDimitry Andric            __old_c_beg_index = __beg;
102406c3fb27SDimitry Andric            __old_c_end_index = __end;
102506c3fb27SDimitry Andric        }
102606c3fb27SDimitry Andric        // __old_c_beg_map - memory block (chunk) with first element
102706c3fb27SDimitry Andric        // __old_c_end_map - memory block (chunk) with end of old container
102806c3fb27SDimitry Andric        // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block,
102906c3fb27SDimitry Andric        // which may not exist
103006c3fb27SDimitry Andric        __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size;
103106c3fb27SDimitry Andric        __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size;
103206c3fb27SDimitry Andric
103306c3fb27SDimitry Andric        // One edge (front/end) of the container was moved and one was not modified.
103406c3fb27SDimitry Andric        // __new_edge_index - index of new edge
103506c3fb27SDimitry Andric        // __new_edge_map    - memory block (chunk) with new edge, it always equals to
103606c3fb27SDimitry Andric        //                    __annotations_beg_map or __annotations_end_map
103706c3fb27SDimitry Andric        // __old_edge_map    - memory block (chunk) with old edge, it always equals to
103806c3fb27SDimitry Andric        //                    __old_c_beg_map or __old_c_end_map
103906c3fb27SDimitry Andric        size_t __new_edge_index                      = (__poisoning ^ __front) ? __beg : __end;
104006c3fb27SDimitry Andric        __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size;
104106c3fb27SDimitry Andric        __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map;
104206c3fb27SDimitry Andric
104306c3fb27SDimitry Andric        // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last.
104406c3fb27SDimitry Andric        // First and last chunk may be partially poisoned.
104506c3fb27SDimitry Andric        // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it.
104606c3fb27SDimitry Andric        for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) {
104706c3fb27SDimitry Andric            if (__map_it == __annotations_end_map && __end % __block_size == 0)
104806c3fb27SDimitry Andric                // Chunk may not exist, but nothing to do here anyway
104906c3fb27SDimitry Andric                break;
105006c3fb27SDimitry Andric
105106c3fb27SDimitry Andric            // The beginning and the end of the current memory block
105206c3fb27SDimitry Andric            const void* __mem_beg = std::__to_address(*__map_it);
105306c3fb27SDimitry Andric            const void* __mem_end = std::__to_address(*__map_it + __block_size);
105406c3fb27SDimitry Andric
105506c3fb27SDimitry Andric            // The beginning of memory-in-use in the memory block before container modification
105606c3fb27SDimitry Andric            const void* __old_beg =
105706c3fb27SDimitry Andric                (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg;
105806c3fb27SDimitry Andric
105906c3fb27SDimitry Andric            // The end of memory-in-use in the memory block before container modification
106006c3fb27SDimitry Andric            const void* __old_end;
106106c3fb27SDimitry Andric            if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty()))
106206c3fb27SDimitry Andric                __old_end = __old_beg;
106306c3fb27SDimitry Andric            else
106406c3fb27SDimitry Andric                __old_end = (__map_it == __old_c_end_map) ? std::__to_address(*__map_it + (__old_c_end_index % __block_size))
106506c3fb27SDimitry Andric                                                   : __mem_end;
106606c3fb27SDimitry Andric
106706c3fb27SDimitry Andric            // New edge of the container in current memory block
106806c3fb27SDimitry Andric            // If the edge is in a different chunk it points on corresponding end of the memory block
106906c3fb27SDimitry Andric            const void* __new_edge;
107006c3fb27SDimitry Andric            if (__map_it == __new_edge_map)
107106c3fb27SDimitry Andric                __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size));
107206c3fb27SDimitry Andric            else
107306c3fb27SDimitry Andric                __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end;
107406c3fb27SDimitry Andric
107506c3fb27SDimitry Andric            // Not modified edge of the container
107606c3fb27SDimitry Andric            // If the edge is in a different chunk it points on corresponding end of the memory block
107706c3fb27SDimitry Andric            const void* __old_edge;
107806c3fb27SDimitry Andric            if (__map_it == __old_edge_map)
107906c3fb27SDimitry Andric                __old_edge = __front ? __old_end : __old_beg;
108006c3fb27SDimitry Andric            else
108106c3fb27SDimitry Andric                __old_edge = __front ? __mem_end : __mem_beg;
108206c3fb27SDimitry Andric
108306c3fb27SDimitry Andric            // __new_beg - the beginning of memory-in-use in the memory block after container modification
108406c3fb27SDimitry Andric            // __new_end - the end of memory-in-use in the memory block after container modification
108506c3fb27SDimitry Andric            const void* __new_beg = __front ? __new_edge : __old_edge;
108606c3fb27SDimitry Andric            const void* __new_end = __front ? __old_edge : __new_edge;
108706c3fb27SDimitry Andric
108806c3fb27SDimitry Andric            __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end);
108906c3fb27SDimitry Andric        }
1090*5f757f3fSDimitry Andric#endif // !_LIBCPP_HAS_NO_ASAN
109106c3fb27SDimitry Andric    }
109206c3fb27SDimitry Andric
109306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
109406c3fb27SDimitry Andric    void __annotate_new(size_type __current_size) const _NOEXCEPT {
109506c3fb27SDimitry Andric        if (__current_size == 0)
109606c3fb27SDimitry Andric            __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved);
109706c3fb27SDimitry Andric        else {
109806c3fb27SDimitry Andric            __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved);
109906c3fb27SDimitry Andric            __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved);
110006c3fb27SDimitry Andric        }
110106c3fb27SDimitry Andric    }
110206c3fb27SDimitry Andric
110306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
110406c3fb27SDimitry Andric    void __annotate_delete() const _NOEXCEPT {
110506c3fb27SDimitry Andric        if (empty()) {
110606c3fb27SDimitry Andric            for(size_t __i = 0; __i < __map_.size(); ++__i) {
110706c3fb27SDimitry Andric                __annotate_whole_block(__i, __asan_unposion);
110806c3fb27SDimitry Andric            }
110906c3fb27SDimitry Andric        }
111006c3fb27SDimitry Andric        else {
111106c3fb27SDimitry Andric            __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved);
111206c3fb27SDimitry Andric            __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved);
111306c3fb27SDimitry Andric        }
111406c3fb27SDimitry Andric    }
111506c3fb27SDimitry Andric
111606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
111706c3fb27SDimitry Andric    void __annotate_increase_front(size_type __n) const _NOEXCEPT {
111806c3fb27SDimitry Andric        __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved);
111906c3fb27SDimitry Andric    }
112006c3fb27SDimitry Andric
112106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
112206c3fb27SDimitry Andric    void __annotate_increase_back(size_type __n) const _NOEXCEPT {
112306c3fb27SDimitry Andric        __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved);
112406c3fb27SDimitry Andric    }
112506c3fb27SDimitry Andric
112606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
112706c3fb27SDimitry Andric    void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT {
112806c3fb27SDimitry Andric        __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved);
112906c3fb27SDimitry Andric    }
113006c3fb27SDimitry Andric
113106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
113206c3fb27SDimitry Andric    void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT {
113306c3fb27SDimitry Andric        __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved);
113406c3fb27SDimitry Andric    }
113506c3fb27SDimitry Andric
113606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
113706c3fb27SDimitry Andric    void __annotate_poison_block(const void *__beginning, const void *__end) const _NOEXCEPT {
113806c3fb27SDimitry Andric        __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end);
113906c3fb27SDimitry Andric    }
114006c3fb27SDimitry Andric
114106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
114206c3fb27SDimitry Andric    void __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT {
114306c3fb27SDimitry Andric        __map_const_iterator __block_it = __map_.begin() + __block_index;
114406c3fb27SDimitry Andric        const void* __block_start = std::__to_address(*__block_it);
114506c3fb27SDimitry Andric        const void* __block_end = std::__to_address(*__block_it + __block_size);
114606c3fb27SDimitry Andric
114706c3fb27SDimitry Andric        if(__annotation_type == __asan_poison)
114806c3fb27SDimitry Andric            __annotate_poison_block(__block_start, __block_end);
114906c3fb27SDimitry Andric        else {
115006c3fb27SDimitry Andric            __annotate_double_ended_contiguous_container(
115106c3fb27SDimitry Andric                __block_start, __block_end, __block_start, __block_start, __block_start, __block_end);
115206c3fb27SDimitry Andric        }
115306c3fb27SDimitry Andric    }
115406c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN)
115506c3fb27SDimitry Andric
115606c3fb27SDimitry Andric  public:
115706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
115806c3fb27SDimitry Andric    bool __verify_asan_annotations() const _NOEXCEPT {
115906c3fb27SDimitry Andric        // This function tests deque object annotations.
116006c3fb27SDimitry Andric        if (empty()) {
116106c3fb27SDimitry Andric            for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
116206c3fb27SDimitry Andric                if (!__sanitizer_verify_double_ended_contiguous_container(
116306c3fb27SDimitry Andric                        std::__to_address(*__it),
116406c3fb27SDimitry Andric                        std::__to_address(*__it),
116506c3fb27SDimitry Andric                        std::__to_address(*__it),
116606c3fb27SDimitry Andric                        std::__to_address(*__it + __block_size)))
116706c3fb27SDimitry Andric                  return false;
116806c3fb27SDimitry Andric            }
116906c3fb27SDimitry Andric
117006c3fb27SDimitry Andric            return true;
117106c3fb27SDimitry Andric        }
117206c3fb27SDimitry Andric
117306c3fb27SDimitry Andric        size_type __end                           = __start_ + size();
117406c3fb27SDimitry Andric        __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size;
117506c3fb27SDimitry Andric        __map_const_iterator __last_mp  = __map_.begin() + (__end - 1) / __block_size;
117606c3fb27SDimitry Andric
117706c3fb27SDimitry Andric        // Pointers to first and after last elements
117806c3fb27SDimitry Andric        // Those can be in different deque blocks
117906c3fb27SDimitry Andric        const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size));
118006c3fb27SDimitry Andric        const void* __p_end =
118106c3fb27SDimitry Andric            std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size));
118206c3fb27SDimitry Andric
118306c3fb27SDimitry Andric        for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
118406c3fb27SDimitry Andric            // Go over all blocks, find the place we are in and verify its annotations
118506c3fb27SDimitry Andric            // Note that __p_end points *behind* the last item.
118606c3fb27SDimitry Andric
118706c3fb27SDimitry Andric            // - blocks before the first block with container elements
118806c3fb27SDimitry Andric            // - first block with items
118906c3fb27SDimitry Andric            // - last block with items
119006c3fb27SDimitry Andric            // - blocks after last block with ciontainer elements
119106c3fb27SDimitry Andric
119206c3fb27SDimitry Andric            // Is the block before or after deque blocks that contain elements?
119306c3fb27SDimitry Andric            if (__it < __first_mp || __it > __last_mp) {
119406c3fb27SDimitry Andric                if (!__sanitizer_verify_double_ended_contiguous_container(
119506c3fb27SDimitry Andric                        std::__to_address(*__it),
119606c3fb27SDimitry Andric                        std::__to_address(*__it),
119706c3fb27SDimitry Andric                        std::__to_address(*__it),
119806c3fb27SDimitry Andric                        std::__to_address(*__it + __block_size)))
119906c3fb27SDimitry Andric                  return false;
120006c3fb27SDimitry Andric            } else {
120106c3fb27SDimitry Andric                const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it);
120206c3fb27SDimitry Andric                const void* __containers_buffer_end =
120306c3fb27SDimitry Andric                    (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size);
120406c3fb27SDimitry Andric                if (!__sanitizer_verify_double_ended_contiguous_container(
120506c3fb27SDimitry Andric                        std::__to_address(*__it),
120606c3fb27SDimitry Andric                        __containers_buffer_beg,
120706c3fb27SDimitry Andric                        __containers_buffer_end,
120806c3fb27SDimitry Andric                        std::__to_address(*__it + __block_size))) {
120906c3fb27SDimitry Andric                  return false;
121006c3fb27SDimitry Andric                }
121106c3fb27SDimitry Andric            }
121206c3fb27SDimitry Andric        }
121306c3fb27SDimitry Andric        return true;
121406c3fb27SDimitry Andric    }
121506c3fb27SDimitry Andric
121606c3fb27SDimitry Andric  private:
121706c3fb27SDimitry Andric#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS
1218bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1219e40139ffSDimitry Andric    bool __maybe_remove_front_spare(bool __keep_one = true) {
1220e40139ffSDimitry Andric      if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {
122106c3fb27SDimitry Andric        __annotate_whole_block(0, __asan_unposion);
1222bdd1243dSDimitry Andric        __alloc_traits::deallocate(__alloc(), __map_.front(),
1223bdd1243dSDimitry Andric                                   __block_size);
1224bdd1243dSDimitry Andric        __map_.pop_front();
1225bdd1243dSDimitry Andric        __start_ -= __block_size;
1226e40139ffSDimitry Andric        return true;
1227e40139ffSDimitry Andric      }
1228e40139ffSDimitry Andric      return false;
1229e40139ffSDimitry Andric    }
1230e40139ffSDimitry Andric
1231bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1232e40139ffSDimitry Andric    bool __maybe_remove_back_spare(bool __keep_one = true) {
1233e40139ffSDimitry Andric      if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {
123406c3fb27SDimitry Andric        __annotate_whole_block(__map_.size() - 1, __asan_unposion);
1235bdd1243dSDimitry Andric        __alloc_traits::deallocate(__alloc(), __map_.back(),
1236bdd1243dSDimitry Andric                                   __block_size);
1237bdd1243dSDimitry Andric        __map_.pop_back();
1238e40139ffSDimitry Andric        return true;
1239e40139ffSDimitry Andric      }
1240e40139ffSDimitry Andric      return false;
1241e40139ffSDimitry Andric    }
12420b57cec5SDimitry Andric
124306c3fb27SDimitry Andric    template <class _Iterator, class _Sentinel>
124406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
124506c3fb27SDimitry Andric    void __assign_with_sentinel(_Iterator __f, _Sentinel __l);
124606c3fb27SDimitry Andric
124706c3fb27SDimitry Andric    template <class _RandomAccessIterator>
124806c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
124906c3fb27SDimitry Andric    void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n);
125006c3fb27SDimitry Andric    template <class _Iterator>
125106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
125206c3fb27SDimitry Andric    void __assign_with_size(_Iterator __f, difference_type __n);
125306c3fb27SDimitry Andric
125406c3fb27SDimitry Andric    template <class _Iterator, class _Sentinel>
125506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
125606c3fb27SDimitry Andric    iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l);
125706c3fb27SDimitry Andric
125806c3fb27SDimitry Andric    template <class _Iterator>
125906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
126006c3fb27SDimitry Andric    iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n);
126106c3fb27SDimitry Andric
126206c3fb27SDimitry Andric    template <class _BiIter, class _Sentinel>
126306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
126406c3fb27SDimitry Andric    iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n);
126506c3fb27SDimitry Andric    template <class _BiIter>
126606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
126706c3fb27SDimitry Andric    iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n);
126806c3fb27SDimitry Andric
1269*5f757f3fSDimitry Andric    template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> = 0>
1270*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l);
1271*5f757f3fSDimitry Andric    template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> = 0>
1272*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l);
127306c3fb27SDimitry Andric
127406c3fb27SDimitry Andric    template <class _InputIterator>
127506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n);
127606c3fb27SDimitry Andric    template <class _InputIterator, class _Sentinel>
127706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l);
127806c3fb27SDimitry Andric
1279bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
1280bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v);
1281bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f);
1282bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_front_capacity();
1283bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n);
1284bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_back_capacity();
1285bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n);
1286bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r,
12870b57cec5SDimitry Andric                              const_pointer& __vt);
1288bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
12890b57cec5SDimitry Andric                                       const_pointer& __vt);
1290bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l,
12910b57cec5SDimitry Andric                                    iterator __r, const_pointer& __vt);
1292bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_construct_backward_and_check(iterator __f, iterator __l,
12930b57cec5SDimitry Andric                                             iterator __r, const_pointer& __vt);
12940b57cec5SDimitry Andric
1295bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12960b57cec5SDimitry Andric    void __copy_assign_alloc(const deque& __c)
12970b57cec5SDimitry Andric        {__copy_assign_alloc(__c, integral_constant<bool,
12980b57cec5SDimitry Andric                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
12990b57cec5SDimitry Andric
1300bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
13010b57cec5SDimitry Andric    void __copy_assign_alloc(const deque& __c, true_type)
13020b57cec5SDimitry Andric        {
1303bdd1243dSDimitry Andric            if (__alloc() != __c.__alloc())
13040b57cec5SDimitry Andric            {
13050b57cec5SDimitry Andric                clear();
13060b57cec5SDimitry Andric                shrink_to_fit();
13070b57cec5SDimitry Andric            }
1308bdd1243dSDimitry Andric            __alloc() = __c.__alloc();
1309bdd1243dSDimitry Andric            __map_.__alloc() = __c.__map_.__alloc();
13100b57cec5SDimitry Andric        }
13110b57cec5SDimitry Andric
1312bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
13130b57cec5SDimitry Andric    void __copy_assign_alloc(const deque&, false_type)
13140b57cec5SDimitry Andric        {}
13150b57cec5SDimitry Andric
1316bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type)
13170b57cec5SDimitry Andric        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
1318bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type);
13190b57cec5SDimitry Andric};
13200b57cec5SDimitry Andric
1321bdd1243dSDimitry Andrictemplate <class _Tp, class _Alloc>
1322bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size =
1323bdd1243dSDimitry Andric    __deque_block_size<value_type, difference_type>::value;
1324bdd1243dSDimitry Andric
1325349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17
13260b57cec5SDimitry Andrictemplate<class _InputIterator,
1327fe6060f1SDimitry Andric         class _Alloc = allocator<__iter_value_type<_InputIterator>>,
132806c3fb27SDimitry Andric         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1329349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Alloc>::value>
13300b57cec5SDimitry Andric         >
13310b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator)
1332fe6060f1SDimitry Andric  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
13330b57cec5SDimitry Andric
13340b57cec5SDimitry Andrictemplate<class _InputIterator,
13350b57cec5SDimitry Andric         class _Alloc,
133606c3fb27SDimitry Andric         class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1337349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Alloc>::value>
13380b57cec5SDimitry Andric         >
13390b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc)
1340fe6060f1SDimitry Andric  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
13410b57cec5SDimitry Andric#endif
13420b57cec5SDimitry Andric
134306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
134406c3fb27SDimitry Andrictemplate <ranges::input_range _Range,
134506c3fb27SDimitry Andric          class _Alloc = allocator<ranges::range_value_t<_Range>>,
134606c3fb27SDimitry Andric          class = enable_if_t<__is_allocator<_Alloc>::value>
134706c3fb27SDimitry Andric          >
134806c3fb27SDimitry Andricdeque(from_range_t, _Range&&, _Alloc = _Alloc())
134906c3fb27SDimitry Andric  -> deque<ranges::range_value_t<_Range>, _Alloc>;
135006c3fb27SDimitry Andric#endif
135106c3fb27SDimitry Andric
13520b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13530b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n)
1354bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
13550b57cec5SDimitry Andric{
135606c3fb27SDimitry Andric    __annotate_new(0);
13570b57cec5SDimitry Andric    if (__n > 0)
13580b57cec5SDimitry Andric        __append(__n);
13590b57cec5SDimitry Andric}
13600b57cec5SDimitry Andric
136106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
13620b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13630b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
1364bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
13650b57cec5SDimitry Andric{
136606c3fb27SDimitry Andric    __annotate_new(0);
13670b57cec5SDimitry Andric    if (__n > 0)
13680b57cec5SDimitry Andric        __append(__n);
13690b57cec5SDimitry Andric}
13700b57cec5SDimitry Andric#endif
13710b57cec5SDimitry Andric
13720b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
13730b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
1374bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
13750b57cec5SDimitry Andric{
137606c3fb27SDimitry Andric    __annotate_new(0);
13770b57cec5SDimitry Andric    if (__n > 0)
13780b57cec5SDimitry Andric        __append(__n, __v);
13790b57cec5SDimitry Andric}
13800b57cec5SDimitry Andric
13810b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
1382*5f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> >
1383*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l)
1384bdd1243dSDimitry Andric    : __start_(0), __size_(0, __default_init_tag())
13850b57cec5SDimitry Andric{
138606c3fb27SDimitry Andric    __annotate_new(0);
13870b57cec5SDimitry Andric    __append(__f, __l);
13880b57cec5SDimitry Andric}
13890b57cec5SDimitry Andric
13900b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
1391*5f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> >
1392*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a)
1393bdd1243dSDimitry Andric    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
13940b57cec5SDimitry Andric{
139506c3fb27SDimitry 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{
140506c3fb27SDimitry 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{
141306c3fb27SDimitry 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{
1421*5f757f3fSDimitry Andric    if (this != std::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{
143506c3fb27SDimitry 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{
144306c3fb27SDimitry 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>
1517*5f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value &&
1518*5f757f3fSDimitry Andric                                          !__has_random_access_iterator_category<_InputIter>::value, int> >
15190b57cec5SDimitry Andricvoid
1520*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l)
15210b57cec5SDimitry Andric{
152206c3fb27SDimitry Andric  __assign_with_sentinel(__f, __l);
152306c3fb27SDimitry Andric}
152406c3fb27SDimitry Andric
152506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
152606c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel>
152706c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
152806c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) {
1529bdd1243dSDimitry Andric    iterator __i = begin();
1530bdd1243dSDimitry Andric    iterator __e = end();
15310b57cec5SDimitry Andric    for (; __f != __l && __i != __e; ++__f, (void) ++__i)
15320b57cec5SDimitry Andric        *__i = *__f;
15330b57cec5SDimitry Andric    if (__f != __l)
153406c3fb27SDimitry Andric        __append_with_sentinel(std::move(__f), std::move(__l));
15350b57cec5SDimitry Andric    else
15360b57cec5SDimitry Andric        __erase_to_end(__i);
15370b57cec5SDimitry Andric}
15380b57cec5SDimitry Andric
15390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
1540*5f757f3fSDimitry Andrictemplate <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> >
15410b57cec5SDimitry Andricvoid
1542*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l)
15430b57cec5SDimitry Andric{
154406c3fb27SDimitry Andric  __assign_with_size_random_access(__f, __l - __f);
154506c3fb27SDimitry Andric}
154606c3fb27SDimitry Andric
154706c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
154806c3fb27SDimitry Andrictemplate <class _RandomAccessIterator>
154906c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
155006c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) {
155106c3fb27SDimitry Andric    if (static_cast<size_type>(__n) > size())
15520b57cec5SDimitry Andric    {
155306c3fb27SDimitry Andric        auto __l = __f + size();
155406c3fb27SDimitry Andric        std::copy(__f, __l, begin());
155506c3fb27SDimitry Andric        __append_with_size(__l, __n - size());
15560b57cec5SDimitry Andric    }
15570b57cec5SDimitry Andric    else
155806c3fb27SDimitry Andric        __erase_to_end(std::copy_n(__f, __n, begin()));
155906c3fb27SDimitry Andric}
156006c3fb27SDimitry Andric
156106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
156206c3fb27SDimitry Andrictemplate <class _Iterator>
156306c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
156406c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) {
156506c3fb27SDimitry Andric  if (static_cast<size_type>(__n) > size()) {
156606c3fb27SDimitry Andric    auto __added_size = __n - size();
156706c3fb27SDimitry Andric
156806c3fb27SDimitry Andric    auto __i = begin();
156906c3fb27SDimitry Andric    for (auto __count = size(); __count != 0; --__count) {
157006c3fb27SDimitry Andric      *__i++ = *__f++;
157106c3fb27SDimitry Andric    }
157206c3fb27SDimitry Andric
157306c3fb27SDimitry Andric    __append_with_size(__f, __added_size);
157406c3fb27SDimitry Andric
157506c3fb27SDimitry Andric  } else {
157606c3fb27SDimitry Andric    __erase_to_end(std::copy_n(__f, __n, begin()));
157706c3fb27SDimitry Andric  }
15780b57cec5SDimitry Andric}
15790b57cec5SDimitry Andric
15800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
15810b57cec5SDimitry Andricvoid
15820b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
15830b57cec5SDimitry Andric{
1584bdd1243dSDimitry Andric    if (__n > size())
15850b57cec5SDimitry Andric    {
1586*5f757f3fSDimitry Andric        std::fill_n(begin(), size(), __v);
1587bdd1243dSDimitry Andric        __n -= size();
15880b57cec5SDimitry Andric        __append(__n, __v);
15890b57cec5SDimitry Andric    }
15900b57cec5SDimitry Andric    else
1591*5f757f3fSDimitry Andric        __erase_to_end(std::fill_n(begin(), __n, __v));
15920b57cec5SDimitry Andric}
15930b57cec5SDimitry Andric
15940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
15950b57cec5SDimitry Andricinline
15960b57cec5SDimitry Andric_Allocator
15970b57cec5SDimitry Andricdeque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
15980b57cec5SDimitry Andric{
1599bdd1243dSDimitry Andric    return __alloc();
16000b57cec5SDimitry Andric}
16010b57cec5SDimitry Andric
16020b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16030b57cec5SDimitry Andricvoid
16040b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n)
16050b57cec5SDimitry Andric{
1606bdd1243dSDimitry Andric    if (__n > size())
1607bdd1243dSDimitry Andric        __append(__n - size());
1608bdd1243dSDimitry Andric    else if (__n < size())
1609bdd1243dSDimitry Andric        __erase_to_end(begin() + __n);
16100b57cec5SDimitry Andric}
16110b57cec5SDimitry Andric
16120b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16130b57cec5SDimitry Andricvoid
16140b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
16150b57cec5SDimitry Andric{
1616bdd1243dSDimitry Andric    if (__n > size())
1617bdd1243dSDimitry Andric        __append(__n - size(), __v);
1618bdd1243dSDimitry Andric    else if (__n < size())
1619bdd1243dSDimitry Andric        __erase_to_end(begin() + __n);
16200b57cec5SDimitry Andric}
16210b57cec5SDimitry Andric
16220b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16230b57cec5SDimitry Andricvoid
16240b57cec5SDimitry Andricdeque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
16250b57cec5SDimitry Andric{
1626bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
16270b57cec5SDimitry Andric    if (empty())
16280b57cec5SDimitry Andric    {
162906c3fb27SDimitry Andric        __annotate_delete();
1630bdd1243dSDimitry Andric        while (__map_.size() > 0)
16310b57cec5SDimitry Andric        {
1632bdd1243dSDimitry Andric            __alloc_traits::deallocate(__a, __map_.back(), __block_size);
1633bdd1243dSDimitry Andric            __map_.pop_back();
16340b57cec5SDimitry Andric        }
1635bdd1243dSDimitry Andric        __start_ = 0;
16360b57cec5SDimitry Andric    }
16370b57cec5SDimitry Andric    else
16380b57cec5SDimitry Andric    {
1639e40139ffSDimitry Andric      __maybe_remove_front_spare(/*__keep_one=*/false);
1640e40139ffSDimitry Andric      __maybe_remove_back_spare(/*__keep_one=*/false);
16410b57cec5SDimitry Andric    }
1642bdd1243dSDimitry Andric    __map_.shrink_to_fit();
16430b57cec5SDimitry Andric}
16440b57cec5SDimitry Andric
16450b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16460b57cec5SDimitry Andricinline
16470b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
16480b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT
16490b57cec5SDimitry Andric{
1650bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1651bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
16520b57cec5SDimitry Andric}
16530b57cec5SDimitry Andric
16540b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16550b57cec5SDimitry Andricinline
16560b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
16570b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT
16580b57cec5SDimitry Andric{
1659bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1660bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
16610b57cec5SDimitry Andric}
16620b57cec5SDimitry Andric
16630b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16640b57cec5SDimitry Andricinline
16650b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
16660b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i)
16670b57cec5SDimitry Andric{
1668bdd1243dSDimitry Andric    if (__i >= size())
1669*5f757f3fSDimitry Andric        std::__throw_out_of_range("deque");
1670bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1671bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
16720b57cec5SDimitry Andric}
16730b57cec5SDimitry Andric
16740b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16750b57cec5SDimitry Andricinline
16760b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
16770b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i) const
16780b57cec5SDimitry Andric{
1679bdd1243dSDimitry Andric    if (__i >= size())
1680*5f757f3fSDimitry Andric        std::__throw_out_of_range("deque");
1681bdd1243dSDimitry Andric    size_type __p = __start_ + __i;
1682bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
16830b57cec5SDimitry Andric}
16840b57cec5SDimitry Andric
16850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16860b57cec5SDimitry Andricinline
16870b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
16880b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() _NOEXCEPT
16890b57cec5SDimitry Andric{
1690bdd1243dSDimitry Andric    return *(*(__map_.begin() + __start_ / __block_size)
1691bdd1243dSDimitry Andric                                    + __start_ % __block_size);
16920b57cec5SDimitry Andric}
16930b57cec5SDimitry Andric
16940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
16950b57cec5SDimitry Andricinline
16960b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
16970b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() const _NOEXCEPT
16980b57cec5SDimitry Andric{
1699bdd1243dSDimitry Andric    return *(*(__map_.begin() + __start_ / __block_size)
1700bdd1243dSDimitry Andric                                      + __start_ % __block_size);
17010b57cec5SDimitry Andric}
17020b57cec5SDimitry Andric
17030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17040b57cec5SDimitry Andricinline
17050b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
17060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() _NOEXCEPT
17070b57cec5SDimitry Andric{
1708bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
1709bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
17100b57cec5SDimitry Andric}
17110b57cec5SDimitry Andric
17120b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17130b57cec5SDimitry Andricinline
17140b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference
17150b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() const _NOEXCEPT
17160b57cec5SDimitry Andric{
1717bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
1718bdd1243dSDimitry Andric    return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);
17190b57cec5SDimitry Andric}
17200b57cec5SDimitry Andric
17210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17220b57cec5SDimitry Andricvoid
17230b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(const value_type& __v)
17240b57cec5SDimitry Andric{
1725bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17260b57cec5SDimitry Andric    if (__back_spare() == 0)
17270b57cec5SDimitry Andric        __add_back_capacity();
17280b57cec5SDimitry Andric    // __back_spare() >= 1
172906c3fb27SDimitry Andric    __annotate_increase_back(1);
1730*5f757f3fSDimitry Andric    __alloc_traits::construct(__a, std::addressof(*end()), __v);
1731bdd1243dSDimitry Andric    ++__size();
17320b57cec5SDimitry Andric}
17330b57cec5SDimitry Andric
17340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17350b57cec5SDimitry Andricvoid
17360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(const value_type& __v)
17370b57cec5SDimitry Andric{
1738bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17390b57cec5SDimitry Andric    if (__front_spare() == 0)
17400b57cec5SDimitry Andric        __add_front_capacity();
17410b57cec5SDimitry Andric    // __front_spare() >= 1
174206c3fb27SDimitry Andric    __annotate_increase_front(1);
1743*5f757f3fSDimitry Andric    __alloc_traits::construct(__a, std::addressof(*--begin()), __v);
1744bdd1243dSDimitry Andric    --__start_;
1745bdd1243dSDimitry Andric    ++__size();
17460b57cec5SDimitry Andric}
17470b57cec5SDimitry Andric
17480b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
17490b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17500b57cec5SDimitry Andricvoid
17510b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(value_type&& __v)
17520b57cec5SDimitry Andric{
1753bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17540b57cec5SDimitry Andric    if (__back_spare() == 0)
17550b57cec5SDimitry Andric        __add_back_capacity();
17560b57cec5SDimitry Andric    // __back_spare() >= 1
175706c3fb27SDimitry Andric    __annotate_increase_back(1);
1758*5f757f3fSDimitry Andric    __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v));
1759bdd1243dSDimitry Andric    ++__size();
17600b57cec5SDimitry Andric}
17610b57cec5SDimitry Andric
17620b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17630b57cec5SDimitry Andrictemplate <class... _Args>
176406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
17650b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
17660b57cec5SDimitry Andric#else
17670b57cec5SDimitry Andricvoid
17680b57cec5SDimitry Andric#endif
17690b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
17700b57cec5SDimitry Andric{
1771bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17720b57cec5SDimitry Andric    if (__back_spare() == 0)
17730b57cec5SDimitry Andric        __add_back_capacity();
17740b57cec5SDimitry Andric    // __back_spare() >= 1
177506c3fb27SDimitry Andric    __annotate_increase_back(1);
1776*5f757f3fSDimitry Andric    __alloc_traits::construct(__a, std::addressof(*end()),
1777*5f757f3fSDimitry Andric                              std::forward<_Args>(__args)...);
1778bdd1243dSDimitry Andric    ++__size();
177906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1780bdd1243dSDimitry Andric    return *--end();
17810b57cec5SDimitry Andric#endif
17820b57cec5SDimitry Andric}
17830b57cec5SDimitry Andric
17840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
17850b57cec5SDimitry Andricvoid
17860b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(value_type&& __v)
17870b57cec5SDimitry Andric{
1788bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
17890b57cec5SDimitry Andric    if (__front_spare() == 0)
17900b57cec5SDimitry Andric        __add_front_capacity();
17910b57cec5SDimitry Andric    // __front_spare() >= 1
179206c3fb27SDimitry Andric    __annotate_increase_front(1);
1793*5f757f3fSDimitry Andric    __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v));
1794bdd1243dSDimitry Andric    --__start_;
1795bdd1243dSDimitry Andric    ++__size();
17960b57cec5SDimitry Andric}
17970b57cec5SDimitry Andric
17980b57cec5SDimitry Andric
17990b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
18000b57cec5SDimitry Andrictemplate <class... _Args>
180106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
18020b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference
18030b57cec5SDimitry Andric#else
18040b57cec5SDimitry Andricvoid
18050b57cec5SDimitry Andric#endif
18060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
18070b57cec5SDimitry Andric{
1808bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
18090b57cec5SDimitry Andric    if (__front_spare() == 0)
18100b57cec5SDimitry Andric        __add_front_capacity();
18110b57cec5SDimitry Andric    // __front_spare() >= 1
181206c3fb27SDimitry Andric    __annotate_increase_front(1);
1813*5f757f3fSDimitry Andric    __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...);
1814bdd1243dSDimitry Andric    --__start_;
1815bdd1243dSDimitry Andric    ++__size();
181606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1817bdd1243dSDimitry Andric    return *begin();
18180b57cec5SDimitry Andric#endif
18190b57cec5SDimitry Andric}
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
18220b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
18230b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
18240b57cec5SDimitry Andric{
1825bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1826bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1827bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
18280b57cec5SDimitry Andric    if (__pos < __to_end)
18290b57cec5SDimitry Andric    {   // insert by shifting things backward
18300b57cec5SDimitry Andric        if (__front_spare() == 0)
18310b57cec5SDimitry Andric            __add_front_capacity();
18320b57cec5SDimitry Andric        // __front_spare() >= 1
183306c3fb27SDimitry Andric        __annotate_increase_front(1);
18340b57cec5SDimitry Andric        if (__pos == 0)
18350b57cec5SDimitry Andric        {
1836*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v));
1837bdd1243dSDimitry Andric            --__start_;
1838bdd1243dSDimitry Andric            ++__size();
18390b57cec5SDimitry Andric        }
18400b57cec5SDimitry Andric        else
18410b57cec5SDimitry Andric        {
1842bdd1243dSDimitry Andric            iterator __b = begin();
1843*5f757f3fSDimitry Andric            iterator __bm1 = std::prev(__b);
1844*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b));
1845bdd1243dSDimitry Andric            --__start_;
1846bdd1243dSDimitry Andric            ++__size();
18470b57cec5SDimitry Andric            if (__pos > 1)
1848*5f757f3fSDimitry Andric                __b = std::move(std::next(__b), __b + __pos, __b);
1849*5f757f3fSDimitry Andric            *__b = std::move(__v);
18500b57cec5SDimitry Andric        }
18510b57cec5SDimitry Andric    }
18520b57cec5SDimitry Andric    else
18530b57cec5SDimitry Andric    {   // insert by shifting things forward
18540b57cec5SDimitry Andric        if (__back_spare() == 0)
18550b57cec5SDimitry Andric            __add_back_capacity();
18560b57cec5SDimitry Andric        // __back_capacity >= 1
185706c3fb27SDimitry Andric        __annotate_increase_back(1);
1858bdd1243dSDimitry Andric        size_type __de = size() - __pos;
18590b57cec5SDimitry Andric        if (__de == 0)
18600b57cec5SDimitry Andric        {
1861*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v));
1862bdd1243dSDimitry Andric            ++__size();
18630b57cec5SDimitry Andric        }
18640b57cec5SDimitry Andric        else
18650b57cec5SDimitry Andric        {
1866bdd1243dSDimitry Andric            iterator __e = end();
1867*5f757f3fSDimitry Andric            iterator __em1 = std::prev(__e);
1868*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1));
1869bdd1243dSDimitry Andric            ++__size();
18700b57cec5SDimitry Andric            if (__de > 1)
1871*5f757f3fSDimitry Andric                __e = std::move_backward(__e - __de, __em1, __e);
1872*5f757f3fSDimitry Andric            *--__e = std::move(__v);
18730b57cec5SDimitry Andric        }
18740b57cec5SDimitry Andric    }
1875bdd1243dSDimitry Andric    return begin() + __pos;
18760b57cec5SDimitry Andric}
18770b57cec5SDimitry Andric
18780b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
18790b57cec5SDimitry Andrictemplate <class... _Args>
18800b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
18810b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
18820b57cec5SDimitry Andric{
1883bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1884bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1885bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
18860b57cec5SDimitry Andric    if (__pos < __to_end)
18870b57cec5SDimitry Andric    {   // insert by shifting things backward
18880b57cec5SDimitry Andric        if (__front_spare() == 0)
18890b57cec5SDimitry Andric            __add_front_capacity();
18900b57cec5SDimitry Andric        // __front_spare() >= 1
189106c3fb27SDimitry Andric        __annotate_increase_front(1);
18920b57cec5SDimitry Andric        if (__pos == 0)
18930b57cec5SDimitry Andric        {
1894*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...);
1895bdd1243dSDimitry Andric            --__start_;
1896bdd1243dSDimitry Andric            ++__size();
18970b57cec5SDimitry Andric        }
18980b57cec5SDimitry Andric        else
18990b57cec5SDimitry Andric        {
1900*5f757f3fSDimitry Andric            __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...);
1901bdd1243dSDimitry Andric            iterator __b = begin();
1902*5f757f3fSDimitry Andric            iterator __bm1 = std::prev(__b);
1903*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b));
1904bdd1243dSDimitry Andric            --__start_;
1905bdd1243dSDimitry Andric            ++__size();
19060b57cec5SDimitry Andric            if (__pos > 1)
1907*5f757f3fSDimitry Andric                __b = std::move(std::next(__b), __b + __pos, __b);
1908*5f757f3fSDimitry Andric            *__b = std::move(__tmp.get());
19090b57cec5SDimitry Andric        }
19100b57cec5SDimitry Andric    }
19110b57cec5SDimitry Andric    else
19120b57cec5SDimitry Andric    {   // insert by shifting things forward
19130b57cec5SDimitry Andric        if (__back_spare() == 0)
19140b57cec5SDimitry Andric            __add_back_capacity();
19150b57cec5SDimitry Andric        // __back_capacity >= 1
191606c3fb27SDimitry Andric        __annotate_increase_back(1);
1917bdd1243dSDimitry Andric        size_type __de = size() - __pos;
19180b57cec5SDimitry Andric        if (__de == 0)
19190b57cec5SDimitry Andric        {
1920*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...);
1921bdd1243dSDimitry Andric            ++__size();
19220b57cec5SDimitry Andric        }
19230b57cec5SDimitry Andric        else
19240b57cec5SDimitry Andric        {
1925*5f757f3fSDimitry Andric            __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...);
1926bdd1243dSDimitry Andric            iterator __e = end();
1927*5f757f3fSDimitry Andric            iterator __em1 = std::prev(__e);
1928*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1));
1929bdd1243dSDimitry Andric            ++__size();
19300b57cec5SDimitry Andric            if (__de > 1)
1931*5f757f3fSDimitry Andric                __e = std::move_backward(__e - __de, __em1, __e);
1932*5f757f3fSDimitry Andric            *--__e = std::move(__tmp.get());
19330b57cec5SDimitry Andric        }
19340b57cec5SDimitry Andric    }
1935bdd1243dSDimitry Andric    return begin() + __pos;
19360b57cec5SDimitry Andric}
19370b57cec5SDimitry Andric
19380b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andric
19410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
19420b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
19430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
19440b57cec5SDimitry Andric{
1945bdd1243dSDimitry Andric    size_type __pos = __p - begin();
1946bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
1947bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
19480b57cec5SDimitry Andric    if (__pos < __to_end)
19490b57cec5SDimitry Andric    {   // insert by shifting things backward
19500b57cec5SDimitry Andric        if (__front_spare() == 0)
19510b57cec5SDimitry Andric            __add_front_capacity();
19520b57cec5SDimitry Andric        // __front_spare() >= 1
195306c3fb27SDimitry Andric        __annotate_increase_front(1);
19540b57cec5SDimitry Andric        if (__pos == 0)
19550b57cec5SDimitry Andric        {
1956*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*--begin()), __v);
1957bdd1243dSDimitry Andric            --__start_;
1958bdd1243dSDimitry Andric            ++__size();
19590b57cec5SDimitry Andric        }
19600b57cec5SDimitry Andric        else
19610b57cec5SDimitry Andric        {
19620b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1963bdd1243dSDimitry Andric            iterator __b = begin();
1964*5f757f3fSDimitry Andric            iterator __bm1 = std::prev(__b);
19650b57cec5SDimitry Andric            if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
19660b57cec5SDimitry Andric                __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
1967*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b));
1968bdd1243dSDimitry Andric            --__start_;
1969bdd1243dSDimitry Andric            ++__size();
19700b57cec5SDimitry Andric            if (__pos > 1)
1971*5f757f3fSDimitry Andric                __b = __move_and_check(std::next(__b), __b + __pos, __b, __vt);
19720b57cec5SDimitry Andric            *__b = *__vt;
19730b57cec5SDimitry Andric        }
19740b57cec5SDimitry Andric    }
19750b57cec5SDimitry Andric    else
19760b57cec5SDimitry Andric    {   // insert by shifting things forward
19770b57cec5SDimitry Andric        if (__back_spare() == 0)
19780b57cec5SDimitry Andric            __add_back_capacity();
19790b57cec5SDimitry Andric        // __back_capacity >= 1
198006c3fb27SDimitry Andric        __annotate_increase_back(1);
1981bdd1243dSDimitry Andric        size_type __de = size() - __pos;
19820b57cec5SDimitry Andric        if (__de == 0)
19830b57cec5SDimitry Andric        {
1984*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*end()), __v);
1985bdd1243dSDimitry Andric            ++__size();
19860b57cec5SDimitry Andric        }
19870b57cec5SDimitry Andric        else
19880b57cec5SDimitry Andric        {
19890b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1990bdd1243dSDimitry Andric            iterator __e = end();
1991*5f757f3fSDimitry Andric            iterator __em1 = std::prev(__e);
19920b57cec5SDimitry Andric            if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
19930b57cec5SDimitry Andric                __vt = pointer_traits<const_pointer>::pointer_to(*__e);
1994*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1));
1995bdd1243dSDimitry Andric            ++__size();
19960b57cec5SDimitry Andric            if (__de > 1)
19970b57cec5SDimitry Andric                __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
19980b57cec5SDimitry Andric            *--__e = *__vt;
19990b57cec5SDimitry Andric        }
20000b57cec5SDimitry Andric    }
2001bdd1243dSDimitry Andric    return begin() + __pos;
20020b57cec5SDimitry Andric}
20030b57cec5SDimitry Andric
20040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
20050b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
20060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
20070b57cec5SDimitry Andric{
2008bdd1243dSDimitry Andric    size_type __pos = __p - begin();
2009bdd1243dSDimitry Andric    size_type __to_end = __size() - __pos;
2010bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
20110b57cec5SDimitry Andric    if (__pos < __to_end)
20120b57cec5SDimitry Andric    {   // insert by shifting things backward
20130b57cec5SDimitry Andric        if (__n > __front_spare())
20140b57cec5SDimitry Andric            __add_front_capacity(__n - __front_spare());
20150b57cec5SDimitry Andric        // __n <= __front_spare()
201606c3fb27SDimitry Andric        __annotate_increase_front(__n);
2017bdd1243dSDimitry Andric        iterator __old_begin = begin();
20180b57cec5SDimitry Andric        iterator __i = __old_begin;
20190b57cec5SDimitry Andric        if (__n > __pos)
20200b57cec5SDimitry Andric        {
2021bdd1243dSDimitry Andric            for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size())
2022*5f757f3fSDimitry Andric                __alloc_traits::construct(__a, std::addressof(*--__i), __v);
20230b57cec5SDimitry Andric            __n = __pos;
20240b57cec5SDimitry Andric        }
20250b57cec5SDimitry Andric        if (__n > 0)
20260b57cec5SDimitry Andric        {
20270b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
20280b57cec5SDimitry Andric            iterator __obn = __old_begin + __n;
20290b57cec5SDimitry Andric            __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
20300b57cec5SDimitry Andric            if (__n < __pos)
20310b57cec5SDimitry Andric                __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
2032*5f757f3fSDimitry Andric            std::fill_n(__old_begin, __n, *__vt);
20330b57cec5SDimitry Andric        }
20340b57cec5SDimitry Andric    }
20350b57cec5SDimitry Andric    else
20360b57cec5SDimitry Andric    {   // insert by shifting things forward
20370b57cec5SDimitry Andric        size_type __back_capacity = __back_spare();
20380b57cec5SDimitry Andric        if (__n > __back_capacity)
20390b57cec5SDimitry Andric            __add_back_capacity(__n - __back_capacity);
20400b57cec5SDimitry Andric        // __n <= __back_capacity
204106c3fb27SDimitry Andric        __annotate_increase_back(__n);
2042bdd1243dSDimitry Andric        iterator __old_end = end();
20430b57cec5SDimitry Andric        iterator __i = __old_end;
2044bdd1243dSDimitry Andric        size_type __de = size() - __pos;
20450b57cec5SDimitry Andric        if (__n > __de)
20460b57cec5SDimitry Andric        {
2047bdd1243dSDimitry Andric            for (size_type __m = __n - __de; __m; --__m, (void) ++__i, ++__size())
2048*5f757f3fSDimitry Andric                __alloc_traits::construct(__a, std::addressof(*__i), __v);
20490b57cec5SDimitry Andric            __n = __de;
20500b57cec5SDimitry Andric        }
20510b57cec5SDimitry Andric        if (__n > 0)
20520b57cec5SDimitry Andric        {
20530b57cec5SDimitry Andric            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
20540b57cec5SDimitry Andric            iterator __oen = __old_end - __n;
20550b57cec5SDimitry Andric            __move_construct_and_check(__oen, __old_end, __i, __vt);
20560b57cec5SDimitry Andric            if (__n < __de)
20570b57cec5SDimitry Andric                __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
2058*5f757f3fSDimitry Andric            std::fill_n(__old_end - __n, __n, *__vt);
20590b57cec5SDimitry Andric        }
20600b57cec5SDimitry Andric    }
2061bdd1243dSDimitry Andric    return begin() + __pos;
20620b57cec5SDimitry Andric}
20630b57cec5SDimitry Andric
20640b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2065*5f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> >
20660b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
2067*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l)
20680b57cec5SDimitry Andric{
206906c3fb27SDimitry Andric  return __insert_with_sentinel(__p, __f, __l);
207006c3fb27SDimitry Andric}
207106c3fb27SDimitry Andric
207206c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
207306c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel>
207406c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
207506c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
207606c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) {
2077bdd1243dSDimitry Andric    __split_buffer<value_type, allocator_type&> __buf(__alloc());
207806c3fb27SDimitry Andric    __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l));
20790b57cec5SDimitry Andric    typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
20800b57cec5SDimitry Andric    return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
20810b57cec5SDimitry Andric}
20820b57cec5SDimitry Andric
20830b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2084*5f757f3fSDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> >
20850b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
2086*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l)
20870b57cec5SDimitry Andric{
208806c3fb27SDimitry Andric  return __insert_with_size(__p, __f, std::distance(__f, __l));
208906c3fb27SDimitry Andric}
209006c3fb27SDimitry Andric
209106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
209206c3fb27SDimitry Andrictemplate <class _Iterator>
209306c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
209406c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
209506c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) {
2096bdd1243dSDimitry Andric    __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc());
209706c3fb27SDimitry Andric    __buf.__construct_at_end_with_size(__f, __n);
20980b57cec5SDimitry Andric    typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
20990b57cec5SDimitry Andric    return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
21000b57cec5SDimitry Andric}
21010b57cec5SDimitry Andric
21020b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2103*5f757f3fSDimitry Andrictemplate <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> >
21040b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
2105*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l)
21060b57cec5SDimitry Andric{
210706c3fb27SDimitry Andric  return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l));
210806c3fb27SDimitry Andric}
210906c3fb27SDimitry Andric
211006c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
211106c3fb27SDimitry Andrictemplate <class _BiIter, class _Sentinel>
211206c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
211306c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
211406c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) {
211506c3fb27SDimitry Andric  return __insert_bidirectional(__p, __f, std::next(__f, __n), __n);
211606c3fb27SDimitry Andric}
211706c3fb27SDimitry Andric
211806c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
211906c3fb27SDimitry Andrictemplate <class _BiIter>
212006c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
212106c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
212206c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) {
2123bdd1243dSDimitry Andric    size_type __pos = __p - begin();
2124bdd1243dSDimitry Andric    size_type __to_end = size() - __pos;
2125bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
21260b57cec5SDimitry Andric    if (__pos < __to_end)
21270b57cec5SDimitry Andric    {   // insert by shifting things backward
21280b57cec5SDimitry Andric        if (__n > __front_spare())
21290b57cec5SDimitry Andric            __add_front_capacity(__n - __front_spare());
21300b57cec5SDimitry Andric        // __n <= __front_spare()
213106c3fb27SDimitry Andric        __annotate_increase_front(__n);
2132bdd1243dSDimitry Andric        iterator __old_begin = begin();
21330b57cec5SDimitry Andric        iterator __i = __old_begin;
21340b57cec5SDimitry Andric        _BiIter __m = __f;
21350b57cec5SDimitry Andric        if (__n > __pos)
21360b57cec5SDimitry Andric        {
2137*5f757f3fSDimitry Andric            __m = __pos < __n / 2 ? std::prev(__l, __pos) : std::next(__f, __n - __pos);
2138bdd1243dSDimitry Andric            for (_BiIter __j = __m; __j != __f; --__start_, ++__size())
2139*5f757f3fSDimitry Andric                __alloc_traits::construct(__a, std::addressof(*--__i), *--__j);
21400b57cec5SDimitry Andric            __n = __pos;
21410b57cec5SDimitry Andric        }
21420b57cec5SDimitry Andric        if (__n > 0)
21430b57cec5SDimitry Andric        {
21440b57cec5SDimitry Andric            iterator __obn = __old_begin + __n;
21450b57cec5SDimitry Andric            for (iterator __j = __obn; __j != __old_begin;)
21460b57cec5SDimitry Andric            {
2147*5f757f3fSDimitry Andric                __alloc_traits::construct(__a, std::addressof(*--__i), std::move(*--__j));
2148bdd1243dSDimitry Andric                --__start_;
2149bdd1243dSDimitry Andric                ++__size();
21500b57cec5SDimitry Andric            }
21510b57cec5SDimitry Andric            if (__n < __pos)
2152*5f757f3fSDimitry Andric                __old_begin = std::move(__obn, __old_begin + __pos, __old_begin);
2153*5f757f3fSDimitry Andric            std::copy(__m, __l, __old_begin);
21540b57cec5SDimitry Andric        }
21550b57cec5SDimitry Andric    }
21560b57cec5SDimitry Andric    else
21570b57cec5SDimitry Andric    {   // insert by shifting things forward
21580b57cec5SDimitry Andric        size_type __back_capacity = __back_spare();
21590b57cec5SDimitry Andric        if (__n > __back_capacity)
21600b57cec5SDimitry Andric            __add_back_capacity(__n - __back_capacity);
21610b57cec5SDimitry Andric        // __n <= __back_capacity
216206c3fb27SDimitry Andric        __annotate_increase_back(__n);
2163bdd1243dSDimitry Andric        iterator __old_end = end();
21640b57cec5SDimitry Andric        iterator __i = __old_end;
21650b57cec5SDimitry Andric        _BiIter __m = __l;
2166bdd1243dSDimitry Andric        size_type __de = size() - __pos;
21670b57cec5SDimitry Andric        if (__n > __de)
21680b57cec5SDimitry Andric        {
2169*5f757f3fSDimitry Andric            __m = __de < __n / 2 ? std::next(__f, __de) : std::prev(__l, __n - __de);
2170bdd1243dSDimitry Andric            for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__size())
2171*5f757f3fSDimitry Andric                __alloc_traits::construct(__a, std::addressof(*__i), *__j);
21720b57cec5SDimitry Andric            __n = __de;
21730b57cec5SDimitry Andric        }
21740b57cec5SDimitry Andric        if (__n > 0)
21750b57cec5SDimitry Andric        {
21760b57cec5SDimitry Andric            iterator __oen = __old_end - __n;
2177bdd1243dSDimitry Andric            for (iterator __j = __oen; __j != __old_end; ++__i, (void) ++__j, ++__size())
2178*5f757f3fSDimitry Andric                __alloc_traits::construct(__a, std::addressof(*__i), std::move(*__j));
21790b57cec5SDimitry Andric            if (__n < __de)
2180*5f757f3fSDimitry Andric                __old_end = std::move_backward(__old_end - __de, __oen, __old_end);
2181*5f757f3fSDimitry Andric            std::copy_backward(__f, __m, __old_end);
21820b57cec5SDimitry Andric        }
21830b57cec5SDimitry Andric    }
2184bdd1243dSDimitry Andric    return begin() + __pos;
21850b57cec5SDimitry Andric}
21860b57cec5SDimitry Andric
21870b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2188*5f757f3fSDimitry Andrictemplate <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> >
21890b57cec5SDimitry Andricvoid
2190*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l)
21910b57cec5SDimitry Andric{
219206c3fb27SDimitry Andric  __append_with_sentinel(__f, __l);
219306c3fb27SDimitry Andric}
219406c3fb27SDimitry Andric
219506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
219606c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel>
219706c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
219806c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) {
21990b57cec5SDimitry Andric    for (; __f != __l; ++__f)
22000b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
22010b57cec5SDimitry Andric        push_back(*__f);
22020b57cec5SDimitry Andric#else
22030b57cec5SDimitry Andric        emplace_back(*__f);
22040b57cec5SDimitry Andric#endif
22050b57cec5SDimitry Andric}
22060b57cec5SDimitry Andric
22070b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2208*5f757f3fSDimitry Andrictemplate <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> >
22090b57cec5SDimitry Andricvoid
2210*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l)
22110b57cec5SDimitry Andric{
221206c3fb27SDimitry Andric    __append_with_size(__f, std::distance(__f, __l));
221306c3fb27SDimitry Andric}
221406c3fb27SDimitry Andric
221506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
221606c3fb27SDimitry Andrictemplate <class _InputIterator>
221706c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI
221806c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) {
2219bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
22200b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
22210b57cec5SDimitry Andric    if (__n > __back_capacity)
22220b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
222306c3fb27SDimitry Andric
22240b57cec5SDimitry Andric    // __n <= __back_capacity
222506c3fb27SDimitry Andric    __annotate_increase_back(__n);
2226bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
2227e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
2228e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {
2229*5f757f3fSDimitry Andric        __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f);
2230e40139ffSDimitry Andric      }
2231e40139ffSDimitry Andric    }
22320b57cec5SDimitry Andric}
22330b57cec5SDimitry Andric
22340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22350b57cec5SDimitry Andricvoid
22360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n)
22370b57cec5SDimitry Andric{
2238bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
22390b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
22400b57cec5SDimitry Andric    if (__n > __back_capacity)
22410b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
22420b57cec5SDimitry Andric    // __n <= __back_capacity
224306c3fb27SDimitry Andric    __annotate_increase_back(__n);
2244bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
2245e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
2246e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
2247*5f757f3fSDimitry Andric        __alloc_traits::construct(__a, std::__to_address(__tx.__pos_));
2248e40139ffSDimitry Andric      }
2249e40139ffSDimitry Andric    }
22500b57cec5SDimitry Andric}
22510b57cec5SDimitry Andric
22520b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22530b57cec5SDimitry Andricvoid
22540b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
22550b57cec5SDimitry Andric{
2256bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
22570b57cec5SDimitry Andric    size_type __back_capacity = __back_spare();
22580b57cec5SDimitry Andric    if (__n > __back_capacity)
22590b57cec5SDimitry Andric        __add_back_capacity(__n - __back_capacity);
22600b57cec5SDimitry Andric    // __n <= __back_capacity
226106c3fb27SDimitry Andric    __annotate_increase_back(__n);
2262bdd1243dSDimitry Andric    for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
2263e40139ffSDimitry Andric      _ConstructTransaction __tx(this, __br);
2264e40139ffSDimitry Andric      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
2265*5f757f3fSDimitry Andric        __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v);
2266e40139ffSDimitry Andric      }
2267e40139ffSDimitry Andric    }
2268e40139ffSDimitry Andric
22690b57cec5SDimitry Andric}
22700b57cec5SDimitry Andric
22710b57cec5SDimitry Andric// Create front capacity for one block of elements.
22720b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
22730b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
22740b57cec5SDimitry Andricvoid
22750b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity()
22760b57cec5SDimitry Andric{
2277bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2278bdd1243dSDimitry Andric    if (__back_spare() >= __block_size)
22790b57cec5SDimitry Andric    {
2280bdd1243dSDimitry Andric        __start_ += __block_size;
2281bdd1243dSDimitry Andric        pointer __pt = __map_.back();
2282bdd1243dSDimitry Andric        __map_.pop_back();
2283bdd1243dSDimitry Andric        __map_.push_front(__pt);
22840b57cec5SDimitry Andric    }
2285bdd1243dSDimitry Andric    // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer
2286bdd1243dSDimitry Andric    else if (__map_.size() < __map_.capacity())
22870b57cec5SDimitry Andric    {   // we can put the new buffer into the map, but don't shift things around
22880b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
22890b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
2290bdd1243dSDimitry Andric        if (__map_.__front_spare() > 0)
2291bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
22920b57cec5SDimitry Andric        else
22930b57cec5SDimitry Andric        {
2294bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
22950b57cec5SDimitry Andric            // Done allocating, reorder capacity
2296bdd1243dSDimitry Andric            pointer __pt = __map_.back();
2297bdd1243dSDimitry Andric            __map_.pop_back();
2298bdd1243dSDimitry Andric            __map_.push_front(__pt);
22990b57cec5SDimitry Andric        }
2300bdd1243dSDimitry Andric        __start_ = __map_.size() == 1 ?
2301bdd1243dSDimitry Andric                               __block_size / 2 :
2302bdd1243dSDimitry Andric                               __start_ + __block_size;
23030b57cec5SDimitry Andric    }
23040b57cec5SDimitry Andric    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
23050b57cec5SDimitry Andric    else
23060b57cec5SDimitry Andric    {
2307bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2308bdd1243dSDimitry Andric            __buf(std::max<size_type>(2 * __map_.capacity(), 1),
2309bdd1243dSDimitry Andric                  0, __map_.__alloc());
23100b57cec5SDimitry Andric
23110b57cec5SDimitry Andric        typedef __allocator_destructor<_Allocator> _Dp;
23120b57cec5SDimitry Andric        unique_ptr<pointer, _Dp> __hold(
2313bdd1243dSDimitry Andric            __alloc_traits::allocate(__a, __block_size),
2314bdd1243dSDimitry Andric                _Dp(__a, __block_size));
23150b57cec5SDimitry Andric        __buf.push_back(__hold.get());
23160b57cec5SDimitry Andric        __hold.release();
23170b57cec5SDimitry Andric
2318bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.begin();
2319bdd1243dSDimitry Andric                __i != __map_.end(); ++__i)
23200b57cec5SDimitry Andric            __buf.push_back(*__i);
2321*5f757f3fSDimitry Andric        std::swap(__map_.__first_, __buf.__first_);
2322*5f757f3fSDimitry Andric        std::swap(__map_.__begin_, __buf.__begin_);
2323*5f757f3fSDimitry Andric        std::swap(__map_.__end_, __buf.__end_);
2324*5f757f3fSDimitry Andric        std::swap(__map_.__end_cap(), __buf.__end_cap());
2325bdd1243dSDimitry Andric        __start_ = __map_.size() == 1 ?
2326bdd1243dSDimitry Andric                               __block_size / 2 :
2327bdd1243dSDimitry Andric                               __start_ + __block_size;
23280b57cec5SDimitry Andric    }
232906c3fb27SDimitry Andric    __annotate_whole_block(0, __asan_poison);
23300b57cec5SDimitry Andric}
23310b57cec5SDimitry Andric
23320b57cec5SDimitry Andric// Create front capacity for __n elements.
23330b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
23340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
23350b57cec5SDimitry Andricvoid
23360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
23370b57cec5SDimitry Andric{
2338bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2339bdd1243dSDimitry Andric    size_type __nb = __recommend_blocks(__n + __map_.empty());
23400b57cec5SDimitry Andric    // Number of unused blocks at back:
2341bdd1243dSDimitry Andric    size_type __back_capacity = __back_spare() / __block_size;
2342*5f757f3fSDimitry Andric    __back_capacity = std::min(__back_capacity, __nb);  // don't take more than you need
23430b57cec5SDimitry Andric    __nb -= __back_capacity;  // number of blocks need to allocate
23440b57cec5SDimitry Andric    // If __nb == 0, then we have sufficient capacity.
23450b57cec5SDimitry Andric    if (__nb == 0)
23460b57cec5SDimitry Andric    {
2347bdd1243dSDimitry Andric        __start_ += __block_size * __back_capacity;
23480b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
23490b57cec5SDimitry Andric        {
2350bdd1243dSDimitry Andric            pointer __pt = __map_.back();
2351bdd1243dSDimitry Andric            __map_.pop_back();
2352bdd1243dSDimitry Andric            __map_.push_front(__pt);
23530b57cec5SDimitry Andric        }
23540b57cec5SDimitry Andric    }
23550b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2356bdd1243dSDimitry Andric    else if (__nb <= __map_.capacity() - __map_.size())
23570b57cec5SDimitry Andric    {   // we can put the new buffers into the map, but don't shift things around
23580b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
23590b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
2360bdd1243dSDimitry Andric        for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1))
23610b57cec5SDimitry Andric        {
2362bdd1243dSDimitry Andric            if (__map_.__front_spare() == 0)
23630b57cec5SDimitry Andric                break;
2364bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
236506c3fb27SDimitry Andric            __annotate_whole_block(0, __asan_poison);
23660b57cec5SDimitry Andric        }
23670b57cec5SDimitry Andric        for (; __nb > 0; --__nb, ++__back_capacity)
2368bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
23690b57cec5SDimitry Andric        // Done allocating, reorder capacity
2370bdd1243dSDimitry Andric        __start_ += __back_capacity * __block_size;
23710b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
23720b57cec5SDimitry Andric        {
2373bdd1243dSDimitry Andric            pointer __pt = __map_.back();
2374bdd1243dSDimitry Andric            __map_.pop_back();
2375bdd1243dSDimitry Andric            __map_.push_front(__pt);
237606c3fb27SDimitry Andric            __annotate_whole_block(0, __asan_poison);
23770b57cec5SDimitry Andric        }
23780b57cec5SDimitry Andric    }
23790b57cec5SDimitry Andric    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
23800b57cec5SDimitry Andric    else
23810b57cec5SDimitry Andric    {
2382bdd1243dSDimitry Andric        size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty();
2383bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2384bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(),
2385bdd1243dSDimitry Andric                                      __nb + __map_.size()),
2386bdd1243dSDimitry Andric                  0, __map_.__alloc());
238706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
23880b57cec5SDimitry Andric        try
23890b57cec5SDimitry Andric        {
239006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
239106c3fb27SDimitry Andric            for (; __nb > 0; --__nb) {
2392bdd1243dSDimitry Andric                __buf.push_back(__alloc_traits::allocate(__a, __block_size));
239306c3fb27SDimitry Andric                // ASan: this is empty container, we have to poison whole block
239406c3fb27SDimitry Andric                __annotate_poison_block(
239506c3fb27SDimitry Andric                    std::__to_address(__buf.back()),
239606c3fb27SDimitry Andric                    std::__to_address(__buf.back() + __block_size));
239706c3fb27SDimitry Andric            }
239806c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
23990b57cec5SDimitry Andric        }
24000b57cec5SDimitry Andric        catch (...)
24010b57cec5SDimitry Andric        {
240206c3fb27SDimitry Andric            __annotate_delete();
2403bdd1243dSDimitry Andric            for (__map_pointer __i = __buf.begin();
24040b57cec5SDimitry Andric                    __i != __buf.end(); ++__i)
2405bdd1243dSDimitry Andric                __alloc_traits::deallocate(__a, *__i, __block_size);
24060b57cec5SDimitry Andric            throw;
24070b57cec5SDimitry Andric        }
240806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
24090b57cec5SDimitry Andric        for (; __back_capacity > 0; --__back_capacity)
24100b57cec5SDimitry Andric        {
2411bdd1243dSDimitry Andric            __buf.push_back(__map_.back());
2412bdd1243dSDimitry Andric            __map_.pop_back();
24130b57cec5SDimitry Andric        }
2414bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.begin();
2415bdd1243dSDimitry Andric                __i != __map_.end(); ++__i)
24160b57cec5SDimitry Andric            __buf.push_back(*__i);
2417*5f757f3fSDimitry Andric        std::swap(__map_.__first_, __buf.__first_);
2418*5f757f3fSDimitry Andric        std::swap(__map_.__begin_, __buf.__begin_);
2419*5f757f3fSDimitry Andric        std::swap(__map_.__end_, __buf.__end_);
2420*5f757f3fSDimitry Andric        std::swap(__map_.__end_cap(), __buf.__end_cap());
2421bdd1243dSDimitry Andric        __start_ += __ds;
24220b57cec5SDimitry Andric    }
24230b57cec5SDimitry Andric}
24240b57cec5SDimitry Andric
24250b57cec5SDimitry Andric// Create back capacity for one block of elements.
24260b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
24270b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
24280b57cec5SDimitry Andricvoid
24290b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity()
24300b57cec5SDimitry Andric{
2431bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2432bdd1243dSDimitry Andric    if (__front_spare() >= __block_size)
24330b57cec5SDimitry Andric    {
2434bdd1243dSDimitry Andric        __start_ -= __block_size;
2435bdd1243dSDimitry Andric        pointer __pt = __map_.front();
2436bdd1243dSDimitry Andric        __map_.pop_front();
2437bdd1243dSDimitry Andric        __map_.push_back(__pt);
24380b57cec5SDimitry Andric    }
24390b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2440bdd1243dSDimitry Andric    else if (__map_.size() < __map_.capacity())
24410b57cec5SDimitry Andric    {   // we can put the new buffer into the map, but don't shift things around
24420b57cec5SDimitry Andric        // until it is allocated.  If we throw, we don't need to fix
24430b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
2444bdd1243dSDimitry Andric        if (__map_.__back_spare() != 0)
2445bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
24460b57cec5SDimitry Andric        else
24470b57cec5SDimitry Andric        {
2448bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
24490b57cec5SDimitry Andric            // Done allocating, reorder capacity
2450bdd1243dSDimitry Andric            pointer __pt = __map_.front();
2451bdd1243dSDimitry Andric            __map_.pop_front();
2452bdd1243dSDimitry Andric            __map_.push_back(__pt);
24530b57cec5SDimitry Andric        }
245406c3fb27SDimitry Andric        __annotate_whole_block(__map_.size() - 1, __asan_poison);
24550b57cec5SDimitry Andric    }
24560b57cec5SDimitry Andric    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
24570b57cec5SDimitry Andric    else
24580b57cec5SDimitry Andric    {
2459bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2460bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(), 1),
2461bdd1243dSDimitry Andric                  __map_.size(),
2462bdd1243dSDimitry Andric                  __map_.__alloc());
24630b57cec5SDimitry Andric
24640b57cec5SDimitry Andric        typedef __allocator_destructor<_Allocator> _Dp;
24650b57cec5SDimitry Andric        unique_ptr<pointer, _Dp> __hold(
2466bdd1243dSDimitry Andric            __alloc_traits::allocate(__a, __block_size),
2467bdd1243dSDimitry Andric                _Dp(__a, __block_size));
24680b57cec5SDimitry Andric        __buf.push_back(__hold.get());
24690b57cec5SDimitry Andric        __hold.release();
24700b57cec5SDimitry Andric
2471bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.end();
2472bdd1243dSDimitry Andric                __i != __map_.begin();)
24730b57cec5SDimitry Andric            __buf.push_front(*--__i);
2474*5f757f3fSDimitry Andric        std::swap(__map_.__first_, __buf.__first_);
2475*5f757f3fSDimitry Andric        std::swap(__map_.__begin_, __buf.__begin_);
2476*5f757f3fSDimitry Andric        std::swap(__map_.__end_, __buf.__end_);
2477*5f757f3fSDimitry Andric        std::swap(__map_.__end_cap(), __buf.__end_cap());
247806c3fb27SDimitry Andric        __annotate_whole_block(__map_.size() - 1, __asan_poison);
24790b57cec5SDimitry Andric    }
24800b57cec5SDimitry Andric}
24810b57cec5SDimitry Andric
24820b57cec5SDimitry Andric// Create back capacity for __n elements.
24830b57cec5SDimitry Andric// Strong guarantee.  Either do it or don't touch anything.
24840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
24850b57cec5SDimitry Andricvoid
24860b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
24870b57cec5SDimitry Andric{
2488bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2489bdd1243dSDimitry Andric    size_type __nb = __recommend_blocks(__n + __map_.empty());
24900b57cec5SDimitry Andric    // Number of unused blocks at front:
2491bdd1243dSDimitry Andric    size_type __front_capacity = __front_spare() / __block_size;
2492*5f757f3fSDimitry Andric    __front_capacity = std::min(__front_capacity, __nb);  // don't take more than you need
24930b57cec5SDimitry Andric    __nb -= __front_capacity;  // number of blocks need to allocate
24940b57cec5SDimitry Andric    // If __nb == 0, then we have sufficient capacity.
24950b57cec5SDimitry Andric    if (__nb == 0)
24960b57cec5SDimitry Andric    {
2497bdd1243dSDimitry Andric        __start_ -= __block_size * __front_capacity;
24980b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
24990b57cec5SDimitry Andric        {
2500bdd1243dSDimitry Andric            pointer __pt = __map_.front();
2501bdd1243dSDimitry Andric            __map_.pop_front();
2502bdd1243dSDimitry Andric            __map_.push_back(__pt);
25030b57cec5SDimitry Andric        }
25040b57cec5SDimitry Andric    }
25050b57cec5SDimitry Andric    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2506bdd1243dSDimitry Andric    else if (__nb <= __map_.capacity() - __map_.size())
25070b57cec5SDimitry Andric    {   // we can put the new buffers into the map, but don't shift things around
25080b57cec5SDimitry Andric        // until all buffers are allocated.  If we throw, we don't need to fix
25090b57cec5SDimitry Andric        // anything up (any added buffers are undetectible)
25100b57cec5SDimitry Andric        for (; __nb > 0; --__nb)
25110b57cec5SDimitry Andric        {
2512bdd1243dSDimitry Andric            if (__map_.__back_spare() == 0)
25130b57cec5SDimitry Andric                break;
2514bdd1243dSDimitry Andric            __map_.push_back(__alloc_traits::allocate(__a, __block_size));
251506c3fb27SDimitry Andric            __annotate_whole_block(__map_.size() - 1, __asan_poison);
25160b57cec5SDimitry Andric        }
2517bdd1243dSDimitry Andric        for (; __nb > 0; --__nb, ++__front_capacity, __start_ +=
251806c3fb27SDimitry Andric                                 __block_size - (__map_.size() == 1)) {
2519bdd1243dSDimitry Andric            __map_.push_front(__alloc_traits::allocate(__a, __block_size));
252006c3fb27SDimitry Andric            __annotate_whole_block(0, __asan_poison);
252106c3fb27SDimitry Andric        }
25220b57cec5SDimitry Andric        // Done allocating, reorder capacity
2523bdd1243dSDimitry Andric        __start_ -= __block_size * __front_capacity;
25240b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
25250b57cec5SDimitry Andric        {
2526bdd1243dSDimitry Andric            pointer __pt = __map_.front();
2527bdd1243dSDimitry Andric            __map_.pop_front();
2528bdd1243dSDimitry Andric            __map_.push_back(__pt);
25290b57cec5SDimitry Andric        }
25300b57cec5SDimitry Andric    }
25310b57cec5SDimitry Andric    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
25320b57cec5SDimitry Andric    else
25330b57cec5SDimitry Andric    {
2534bdd1243dSDimitry Andric        size_type __ds = __front_capacity * __block_size;
2535bdd1243dSDimitry Andric        __split_buffer<pointer, __pointer_allocator&>
2536bdd1243dSDimitry Andric            __buf(std::max<size_type>(2* __map_.capacity(),
2537bdd1243dSDimitry Andric                                      __nb + __map_.size()),
2538bdd1243dSDimitry Andric                  __map_.size() - __front_capacity,
2539bdd1243dSDimitry Andric                  __map_.__alloc());
254006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
25410b57cec5SDimitry Andric        try
25420b57cec5SDimitry Andric        {
254306c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
254406c3fb27SDimitry Andric            for (; __nb > 0; --__nb) {
2545bdd1243dSDimitry Andric                __buf.push_back(__alloc_traits::allocate(__a, __block_size));
254606c3fb27SDimitry Andric                // ASan: this is an empty container, we have to poison the whole block
254706c3fb27SDimitry Andric                __annotate_poison_block(
254806c3fb27SDimitry Andric                    std::__to_address(__buf.back()),
254906c3fb27SDimitry Andric                    std::__to_address(__buf.back() + __block_size));
255006c3fb27SDimitry Andric            }
255106c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
25520b57cec5SDimitry Andric        }
25530b57cec5SDimitry Andric        catch (...)
25540b57cec5SDimitry Andric        {
255506c3fb27SDimitry Andric            __annotate_delete();
2556bdd1243dSDimitry Andric            for (__map_pointer __i = __buf.begin();
25570b57cec5SDimitry Andric                    __i != __buf.end(); ++__i)
2558bdd1243dSDimitry Andric                __alloc_traits::deallocate(__a, *__i, __block_size);
25590b57cec5SDimitry Andric            throw;
25600b57cec5SDimitry Andric        }
256106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
25620b57cec5SDimitry Andric        for (; __front_capacity > 0; --__front_capacity)
25630b57cec5SDimitry Andric        {
2564bdd1243dSDimitry Andric            __buf.push_back(__map_.front());
2565bdd1243dSDimitry Andric            __map_.pop_front();
25660b57cec5SDimitry Andric        }
2567bdd1243dSDimitry Andric        for (__map_pointer __i = __map_.end();
2568bdd1243dSDimitry Andric                __i != __map_.begin();)
25690b57cec5SDimitry Andric            __buf.push_front(*--__i);
2570*5f757f3fSDimitry Andric        std::swap(__map_.__first_, __buf.__first_);
2571*5f757f3fSDimitry Andric        std::swap(__map_.__begin_, __buf.__begin_);
2572*5f757f3fSDimitry Andric        std::swap(__map_.__end_, __buf.__end_);
2573*5f757f3fSDimitry Andric        std::swap(__map_.__end_cap(), __buf.__end_cap());
2574bdd1243dSDimitry Andric        __start_ -= __ds;
25750b57cec5SDimitry Andric    }
25760b57cec5SDimitry Andric}
25770b57cec5SDimitry Andric
25780b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
25790b57cec5SDimitry Andricvoid
25800b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_front()
25810b57cec5SDimitry Andric{
258206c3fb27SDimitry Andric    size_type __old_sz    = size();
258306c3fb27SDimitry Andric    size_type __old_start = __start_;
2584bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2585*5f757f3fSDimitry Andric    __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() +
2586bdd1243dSDimitry Andric                                                    __start_ / __block_size) +
2587bdd1243dSDimitry Andric                                                    __start_ % __block_size));
2588bdd1243dSDimitry Andric    --__size();
2589bdd1243dSDimitry Andric    ++__start_;
259006c3fb27SDimitry Andric    __annotate_shrink_front(__old_sz, __old_start);
2591e40139ffSDimitry Andric    __maybe_remove_front_spare();
25920b57cec5SDimitry Andric}
25930b57cec5SDimitry Andric
25940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
25950b57cec5SDimitry Andricvoid
25960b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_back()
25970b57cec5SDimitry Andric{
259806c3fb27SDimitry Andric    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque");
259906c3fb27SDimitry Andric    size_type __old_sz    = size();
260006c3fb27SDimitry Andric    size_type __old_start = __start_;
2601bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2602bdd1243dSDimitry Andric    size_type __p = size() + __start_ - 1;
2603*5f757f3fSDimitry Andric    __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() +
2604bdd1243dSDimitry Andric                                                    __p / __block_size) +
2605bdd1243dSDimitry Andric                                                    __p % __block_size));
2606bdd1243dSDimitry Andric    --__size();
260706c3fb27SDimitry Andric    __annotate_shrink_back(__old_sz, __old_start);
2608e40139ffSDimitry Andric    __maybe_remove_back_spare();
26090b57cec5SDimitry Andric}
26100b57cec5SDimitry Andric
26110b57cec5SDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)).
26120b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
26130b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
26140b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
26150b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
26160b57cec5SDimitry Andric                                         const_pointer& __vt)
26170b57cec5SDimitry Andric{
26180b57cec5SDimitry Andric    // as if
26190b57cec5SDimitry Andric    //   for (; __f != __l; ++__f, ++__r)
2620*5f757f3fSDimitry Andric    //       *__r = std::move(*__f);
26210b57cec5SDimitry Andric    difference_type __n = __l - __f;
26220b57cec5SDimitry Andric    while (__n > 0)
26230b57cec5SDimitry Andric    {
26240b57cec5SDimitry Andric        pointer __fb = __f.__ptr_;
2625bdd1243dSDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
26260b57cec5SDimitry Andric        difference_type __bs = __fe - __fb;
26270b57cec5SDimitry Andric        if (__bs > __n)
26280b57cec5SDimitry Andric        {
26290b57cec5SDimitry Andric            __bs = __n;
26300b57cec5SDimitry Andric            __fe = __fb + __bs;
26310b57cec5SDimitry Andric        }
26320b57cec5SDimitry Andric        if (__fb <= __vt && __vt < __fe)
26330b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
2634*5f757f3fSDimitry Andric        __r = std::move(__fb, __fe, __r);
26350b57cec5SDimitry Andric        __n -= __bs;
26360b57cec5SDimitry Andric        __f += __bs;
26370b57cec5SDimitry Andric    }
26380b57cec5SDimitry Andric    return __r;
26390b57cec5SDimitry Andric}
26400b57cec5SDimitry Andric
26410b57cec5SDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
26420b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt.
26430b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
26440b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
26450b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
26460b57cec5SDimitry Andric                                                  const_pointer& __vt)
26470b57cec5SDimitry Andric{
26480b57cec5SDimitry Andric    // as if
26490b57cec5SDimitry Andric    //   while (__f != __l)
2650*5f757f3fSDimitry Andric    //       *--__r = std::move(*--__l);
26510b57cec5SDimitry Andric    difference_type __n = __l - __f;
26520b57cec5SDimitry Andric    while (__n > 0)
26530b57cec5SDimitry Andric    {
26540b57cec5SDimitry Andric        --__l;
26550b57cec5SDimitry Andric        pointer __lb = *__l.__m_iter_;
26560b57cec5SDimitry Andric        pointer __le = __l.__ptr_ + 1;
26570b57cec5SDimitry Andric        difference_type __bs = __le - __lb;
26580b57cec5SDimitry Andric        if (__bs > __n)
26590b57cec5SDimitry Andric        {
26600b57cec5SDimitry Andric            __bs = __n;
26610b57cec5SDimitry Andric            __lb = __le - __bs;
26620b57cec5SDimitry Andric        }
26630b57cec5SDimitry Andric        if (__lb <= __vt && __vt < __le)
26640b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
2665*5f757f3fSDimitry Andric        __r = std::move_backward(__lb, __le, __r);
26660b57cec5SDimitry Andric        __n -= __bs;
26670b57cec5SDimitry Andric        __l -= __bs - 1;
26680b57cec5SDimitry Andric    }
26690b57cec5SDimitry Andric    return __r;
26700b57cec5SDimitry Andric}
26710b57cec5SDimitry Andric
26720b57cec5SDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)).
26730b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt.
26740b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
26750b57cec5SDimitry Andricvoid
26760b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
26770b57cec5SDimitry Andric                                                   iterator __r, const_pointer& __vt)
26780b57cec5SDimitry Andric{
2679bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
26800b57cec5SDimitry Andric    // as if
2681bdd1243dSDimitry Andric    //   for (; __f != __l; ++__r, ++__f, ++__size())
2682*5f757f3fSDimitry Andric    //       __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__f));
26830b57cec5SDimitry Andric    difference_type __n = __l - __f;
26840b57cec5SDimitry Andric    while (__n > 0)
26850b57cec5SDimitry Andric    {
26860b57cec5SDimitry Andric        pointer __fb = __f.__ptr_;
2687bdd1243dSDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
26880b57cec5SDimitry Andric        difference_type __bs = __fe - __fb;
26890b57cec5SDimitry Andric        if (__bs > __n)
26900b57cec5SDimitry Andric        {
26910b57cec5SDimitry Andric            __bs = __n;
26920b57cec5SDimitry Andric            __fe = __fb + __bs;
26930b57cec5SDimitry Andric        }
26940b57cec5SDimitry Andric        if (__fb <= __vt && __vt < __fe)
26950b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
2696bdd1243dSDimitry Andric        for (; __fb != __fe; ++__fb, ++__r, ++__size())
2697*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__fb));
26980b57cec5SDimitry Andric        __n -= __bs;
26990b57cec5SDimitry Andric        __f += __bs;
27000b57cec5SDimitry Andric    }
27010b57cec5SDimitry Andric}
27020b57cec5SDimitry Andric
27030b57cec5SDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
27040b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
27050b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
27060b57cec5SDimitry Andricvoid
27070b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
27080b57cec5SDimitry Andric                                                            iterator __r, const_pointer& __vt)
27090b57cec5SDimitry Andric{
2710bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
27110b57cec5SDimitry Andric    // as if
27120b57cec5SDimitry Andric    //   for (iterator __j = __l; __j != __f;)
27130b57cec5SDimitry Andric    //   {
2714*5f757f3fSDimitry Andric    //       __alloc_traitsconstruct(__a, std::addressof(*--__r), std::move(*--__j));
2715bdd1243dSDimitry Andric    //       --__start_;
2716bdd1243dSDimitry Andric    //       ++__size();
27170b57cec5SDimitry Andric    //   }
27180b57cec5SDimitry Andric    difference_type __n = __l - __f;
27190b57cec5SDimitry Andric    while (__n > 0)
27200b57cec5SDimitry Andric    {
27210b57cec5SDimitry Andric        --__l;
27220b57cec5SDimitry Andric        pointer __lb = *__l.__m_iter_;
27230b57cec5SDimitry Andric        pointer __le = __l.__ptr_ + 1;
27240b57cec5SDimitry Andric        difference_type __bs = __le - __lb;
27250b57cec5SDimitry Andric        if (__bs > __n)
27260b57cec5SDimitry Andric        {
27270b57cec5SDimitry Andric            __bs = __n;
27280b57cec5SDimitry Andric            __lb = __le - __bs;
27290b57cec5SDimitry Andric        }
27300b57cec5SDimitry Andric        if (__lb <= __vt && __vt < __le)
27310b57cec5SDimitry Andric            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
27320b57cec5SDimitry Andric        while (__le != __lb)
27330b57cec5SDimitry Andric        {
2734*5f757f3fSDimitry Andric            __alloc_traits::construct(__a, std::addressof(*--__r), std::move(*--__le));
2735bdd1243dSDimitry Andric            --__start_;
2736bdd1243dSDimitry Andric            ++__size();
27370b57cec5SDimitry Andric        }
27380b57cec5SDimitry Andric        __n -= __bs;
27390b57cec5SDimitry Andric        __l -= __bs - 1;
27400b57cec5SDimitry Andric    }
27410b57cec5SDimitry Andric}
27420b57cec5SDimitry Andric
27430b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
27440b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
27450b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f)
27460b57cec5SDimitry Andric{
274706c3fb27SDimitry Andric    size_type __old_sz    = size();
274806c3fb27SDimitry Andric    size_type __old_start = __start_;
2749bdd1243dSDimitry Andric    iterator __b = begin();
27500b57cec5SDimitry Andric    difference_type __pos = __f - __b;
27510b57cec5SDimitry Andric    iterator __p = __b + __pos;
2752bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2753bdd1243dSDimitry Andric    if (static_cast<size_t>(__pos) <= (size() - 1) / 2)
27540b57cec5SDimitry Andric    {   // erase from front
2755*5f757f3fSDimitry Andric        std::move_backward(__b, __p, std::next(__p));
2756*5f757f3fSDimitry Andric        __alloc_traits::destroy(__a, std::addressof(*__b));
2757bdd1243dSDimitry Andric        --__size();
2758bdd1243dSDimitry Andric        ++__start_;
275906c3fb27SDimitry Andric        __annotate_shrink_front(__old_sz, __old_start);
2760e40139ffSDimitry Andric        __maybe_remove_front_spare();
27610b57cec5SDimitry Andric    }
27620b57cec5SDimitry Andric    else
27630b57cec5SDimitry Andric    {   // erase from back
2764*5f757f3fSDimitry Andric        iterator __i = std::move(std::next(__p), end(), __p);
2765*5f757f3fSDimitry Andric        __alloc_traits::destroy(__a, std::addressof(*__i));
2766bdd1243dSDimitry Andric        --__size();
276706c3fb27SDimitry Andric        __annotate_shrink_back(__old_sz, __old_start);
2768e40139ffSDimitry Andric        __maybe_remove_back_spare();
27690b57cec5SDimitry Andric    }
2770bdd1243dSDimitry Andric    return begin() + __pos;
27710b57cec5SDimitry Andric}
27720b57cec5SDimitry Andric
27730b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
27740b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator
27750b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
27760b57cec5SDimitry Andric{
277706c3fb27SDimitry Andric    size_type __old_sz    = size();
277806c3fb27SDimitry Andric    size_type __old_start = __start_;
27790b57cec5SDimitry Andric    difference_type __n = __l - __f;
2780bdd1243dSDimitry Andric    iterator __b = begin();
27810b57cec5SDimitry Andric    difference_type __pos = __f - __b;
27820b57cec5SDimitry Andric    iterator __p = __b + __pos;
27830b57cec5SDimitry Andric    if (__n > 0)
27840b57cec5SDimitry Andric    {
2785bdd1243dSDimitry Andric        allocator_type& __a = __alloc();
2786bdd1243dSDimitry Andric        if (static_cast<size_t>(__pos) <= (size() - __n) / 2)
27870b57cec5SDimitry Andric        {   // erase from front
2788*5f757f3fSDimitry Andric            iterator __i = std::move_backward(__b, __p, __p + __n);
27890b57cec5SDimitry Andric            for (; __b != __i; ++__b)
2790*5f757f3fSDimitry Andric                __alloc_traits::destroy(__a, std::addressof(*__b));
2791bdd1243dSDimitry Andric            __size() -= __n;
2792bdd1243dSDimitry Andric            __start_ += __n;
279306c3fb27SDimitry Andric            __annotate_shrink_front(__old_sz, __old_start);
2794e40139ffSDimitry Andric            while (__maybe_remove_front_spare()) {
27950b57cec5SDimitry Andric            }
27960b57cec5SDimitry Andric        }
27970b57cec5SDimitry Andric        else
27980b57cec5SDimitry Andric        {   // erase from back
2799*5f757f3fSDimitry Andric            iterator __i = std::move(__p + __n, end(), __p);
2800bdd1243dSDimitry Andric            for (iterator __e = end(); __i != __e; ++__i)
2801*5f757f3fSDimitry Andric                __alloc_traits::destroy(__a, std::addressof(*__i));
2802bdd1243dSDimitry Andric            __size() -= __n;
280306c3fb27SDimitry Andric            __annotate_shrink_back(__old_sz, __old_start);
2804e40139ffSDimitry Andric            while (__maybe_remove_back_spare()) {
28050b57cec5SDimitry Andric            }
28060b57cec5SDimitry Andric        }
28070b57cec5SDimitry Andric    }
2808bdd1243dSDimitry Andric    return begin() + __pos;
28090b57cec5SDimitry Andric}
28100b57cec5SDimitry Andric
28110b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
28120b57cec5SDimitry Andricvoid
28130b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
28140b57cec5SDimitry Andric{
281506c3fb27SDimitry Andric    size_type __old_sz    = size();
281606c3fb27SDimitry Andric    size_type __old_start = __start_;
2817bdd1243dSDimitry Andric    iterator __e = end();
28180b57cec5SDimitry Andric    difference_type __n = __e - __f;
28190b57cec5SDimitry Andric    if (__n > 0)
28200b57cec5SDimitry Andric    {
2821bdd1243dSDimitry Andric        allocator_type& __a = __alloc();
2822bdd1243dSDimitry Andric        iterator __b = begin();
28230b57cec5SDimitry Andric        difference_type __pos = __f - __b;
28240b57cec5SDimitry Andric        for (iterator __p = __b + __pos; __p != __e; ++__p)
2825*5f757f3fSDimitry Andric            __alloc_traits::destroy(__a, std::addressof(*__p));
2826bdd1243dSDimitry Andric        __size() -= __n;
282706c3fb27SDimitry Andric        __annotate_shrink_back(__old_sz, __old_start);
2828e40139ffSDimitry Andric        while (__maybe_remove_back_spare()) {
28290b57cec5SDimitry Andric        }
28300b57cec5SDimitry Andric    }
28310b57cec5SDimitry Andric}
28320b57cec5SDimitry Andric
28330b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
28340b57cec5SDimitry Andricinline
28350b57cec5SDimitry Andricvoid
28360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::swap(deque& __c)
28370b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
28380b57cec5SDimitry Andric        _NOEXCEPT
28390b57cec5SDimitry Andric#else
28400b57cec5SDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
28410b57cec5SDimitry Andric                    __is_nothrow_swappable<allocator_type>::value)
28420b57cec5SDimitry Andric#endif
28430b57cec5SDimitry Andric{
2844bdd1243dSDimitry Andric    __map_.swap(__c.__map_);
2845*5f757f3fSDimitry Andric    std::swap(__start_, __c.__start_);
2846*5f757f3fSDimitry Andric    std::swap(__size(), __c.__size());
2847*5f757f3fSDimitry Andric    std::__swap_allocator(__alloc(), __c.__alloc());
28480b57cec5SDimitry Andric}
28490b57cec5SDimitry Andric
28500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
28510b57cec5SDimitry Andricinline
28520b57cec5SDimitry Andricvoid
28530b57cec5SDimitry Andricdeque<_Tp, _Allocator>::clear() _NOEXCEPT
28540b57cec5SDimitry Andric{
285506c3fb27SDimitry Andric    __annotate_delete();
2856bdd1243dSDimitry Andric    allocator_type& __a = __alloc();
2857bdd1243dSDimitry Andric    for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
2858*5f757f3fSDimitry Andric        __alloc_traits::destroy(__a, std::addressof(*__i));
2859bdd1243dSDimitry Andric    __size() = 0;
2860bdd1243dSDimitry Andric    while (__map_.size() > 2)
2861bdd1243dSDimitry Andric    {
2862bdd1243dSDimitry Andric        __alloc_traits::deallocate(__a, __map_.front(), __block_size);
2863bdd1243dSDimitry Andric        __map_.pop_front();
2864bdd1243dSDimitry Andric    }
2865bdd1243dSDimitry Andric    switch (__map_.size())
2866bdd1243dSDimitry Andric    {
2867bdd1243dSDimitry Andric    case 1:
2868bdd1243dSDimitry Andric        __start_ = __block_size / 2;
2869bdd1243dSDimitry Andric        break;
2870bdd1243dSDimitry Andric    case 2:
2871bdd1243dSDimitry Andric        __start_ = __block_size;
2872bdd1243dSDimitry Andric        break;
2873bdd1243dSDimitry Andric    }
287406c3fb27SDimitry Andric    __annotate_new(0);
28750b57cec5SDimitry Andric}
28760b57cec5SDimitry Andric
28770b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2878bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
28790b57cec5SDimitry Andricbool
28800b57cec5SDimitry Andricoperator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
28810b57cec5SDimitry Andric{
28820b57cec5SDimitry Andric    const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
2883*5f757f3fSDimitry Andric    return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
28840b57cec5SDimitry Andric}
28850b57cec5SDimitry Andric
288606c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17
288706c3fb27SDimitry Andric
28880b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2889bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
28900b57cec5SDimitry Andricbool
28910b57cec5SDimitry Andricoperator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
28920b57cec5SDimitry Andric{
28930b57cec5SDimitry Andric    return !(__x == __y);
28940b57cec5SDimitry Andric}
28950b57cec5SDimitry Andric
28960b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2897bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
28980b57cec5SDimitry Andricbool
28990b57cec5SDimitry Andricoperator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29000b57cec5SDimitry Andric{
2901*5f757f3fSDimitry Andric    return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
29020b57cec5SDimitry Andric}
29030b57cec5SDimitry Andric
29040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2905bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29060b57cec5SDimitry Andricbool
29070b57cec5SDimitry Andricoperator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29080b57cec5SDimitry Andric{
29090b57cec5SDimitry Andric    return __y < __x;
29100b57cec5SDimitry Andric}
29110b57cec5SDimitry Andric
29120b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2913bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29140b57cec5SDimitry Andricbool
29150b57cec5SDimitry Andricoperator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29160b57cec5SDimitry Andric{
29170b57cec5SDimitry Andric    return !(__x < __y);
29180b57cec5SDimitry Andric}
29190b57cec5SDimitry Andric
29200b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2921bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29220b57cec5SDimitry Andricbool
29230b57cec5SDimitry Andricoperator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29240b57cec5SDimitry Andric{
29250b57cec5SDimitry Andric    return !(__y < __x);
29260b57cec5SDimitry Andric}
29270b57cec5SDimitry Andric
292806c3fb27SDimitry Andric#else // _LIBCPP_STD_VER <= 17
292906c3fb27SDimitry Andric
293006c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
293106c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
293206c3fb27SDimitry Andricoperator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
293306c3fb27SDimitry Andric    return std::lexicographical_compare_three_way(
293406c3fb27SDimitry Andric        __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
293506c3fb27SDimitry Andric}
293606c3fb27SDimitry Andric
293706c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER <= 17
293806c3fb27SDimitry Andric
29390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
2940bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
29410b57cec5SDimitry Andricvoid
29420b57cec5SDimitry Andricswap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
29430b57cec5SDimitry Andric    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
29440b57cec5SDimitry Andric{
29450b57cec5SDimitry Andric    __x.swap(__y);
29460b57cec5SDimitry Andric}
29470b57cec5SDimitry Andric
294806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
29490b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up>
2950bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
29515ffd83dbSDimitry Andricerase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
29525ffd83dbSDimitry Andric  auto __old_size = __c.size();
2953*5f757f3fSDimitry Andric  __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end());
29545ffd83dbSDimitry Andric  return __old_size - __c.size();
29555ffd83dbSDimitry Andric}
29560b57cec5SDimitry Andric
29570b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate>
2958bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
29595ffd83dbSDimitry Andricerase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
29605ffd83dbSDimitry Andric  auto __old_size = __c.size();
2961*5f757f3fSDimitry Andric  __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end());
29625ffd83dbSDimitry Andric  return __old_size - __c.size();
29635ffd83dbSDimitry Andric}
296481ad6265SDimitry Andric
296581ad6265SDimitry Andrictemplate <>
296681ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<char>> = true;
296781ad6265SDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
296881ad6265SDimitry Andrictemplate <>
296981ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;
29700b57cec5SDimitry Andric#endif
29710b57cec5SDimitry Andric
297206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20
29730b57cec5SDimitry Andric
29740b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
29750b57cec5SDimitry Andric
297606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
2977bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2978bdd1243dSDimitry Andricnamespace pmr {
2979bdd1243dSDimitry Andrictemplate <class _ValueT>
298006c3fb27SDimitry Andricusing deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;
2981bdd1243dSDimitry Andric} // namespace pmr
2982bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD
2983bdd1243dSDimitry Andric#endif
2984bdd1243dSDimitry Andric
29850b57cec5SDimitry Andric_LIBCPP_POP_MACROS
29860b57cec5SDimitry Andric
2987bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
2988bdd1243dSDimitry Andric#  include <algorithm>
2989bdd1243dSDimitry Andric#  include <atomic>
2990bdd1243dSDimitry Andric#  include <concepts>
299106c3fb27SDimitry Andric#  include <cstdlib>
2992bdd1243dSDimitry Andric#  include <functional>
2993bdd1243dSDimitry Andric#  include <iosfwd>
2994bdd1243dSDimitry Andric#  include <iterator>
299506c3fb27SDimitry Andric#  include <type_traits>
2996bdd1243dSDimitry Andric#  include <typeinfo>
2997bdd1243dSDimitry Andric#endif
2998bdd1243dSDimitry Andric
29990b57cec5SDimitry Andric#endif // _LIBCPP_DEQUE
3000