xref: /llvm-project-15.0.7/libcxx/include/deque (revision 6adbc83e)
1// -*- C++ -*-
2//===---------------------------- deque -----------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_DEQUE
11#define _LIBCPP_DEQUE
12
13/*
14    deque synopsis
15
16namespace std
17{
18
19template <class T, class Allocator = allocator<T> >
20class deque
21{
22public:
23    // types:
24    typedef T value_type;
25    typedef Allocator allocator_type;
26
27    typedef typename allocator_type::reference       reference;
28    typedef typename allocator_type::const_reference const_reference;
29    typedef implementation-defined                   iterator;
30    typedef implementation-defined                   const_iterator;
31    typedef typename allocator_type::size_type       size_type;
32    typedef typename allocator_type::difference_type difference_type;
33
34    typedef typename allocator_type::pointer         pointer;
35    typedef typename allocator_type::const_pointer   const_pointer;
36    typedef std::reverse_iterator<iterator>          reverse_iterator;
37    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
38
39    // construct/copy/destroy:
40    deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);
41    explicit deque(const allocator_type& a);
42    explicit deque(size_type n);
43    explicit deque(size_type n, const allocator_type& a); // C++14
44    deque(size_type n, const value_type& v);
45    deque(size_type n, const value_type& v, const allocator_type& a);
46    template <class InputIterator>
47        deque(InputIterator f, InputIterator l);
48    template <class InputIterator>
49        deque(InputIterator f, InputIterator l, const allocator_type& a);
50    deque(const deque& c);
51    deque(deque&& c)
52        noexcept(is_nothrow_move_constructible<allocator_type>::value);
53    deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
54    deque(const deque& c, const allocator_type& a);
55    deque(deque&& c, const allocator_type& a);
56    ~deque();
57
58    deque& operator=(const deque& c);
59    deque& operator=(deque&& c)
60        noexcept(
61             allocator_type::propagate_on_container_move_assignment::value &&
62             is_nothrow_move_assignable<allocator_type>::value);
63    deque& operator=(initializer_list<value_type> il);
64
65    template <class InputIterator>
66        void assign(InputIterator f, InputIterator l);
67    void assign(size_type n, const value_type& v);
68    void assign(initializer_list<value_type> il);
69
70    allocator_type get_allocator() const noexcept;
71
72    // iterators:
73
74    iterator       begin() noexcept;
75    const_iterator begin() const noexcept;
76    iterator       end() noexcept;
77    const_iterator end() const noexcept;
78
79    reverse_iterator       rbegin() noexcept;
80    const_reverse_iterator rbegin() const noexcept;
81    reverse_iterator       rend() noexcept;
82    const_reverse_iterator rend() const noexcept;
83
84    const_iterator         cbegin() const noexcept;
85    const_iterator         cend() const noexcept;
86    const_reverse_iterator crbegin() const noexcept;
87    const_reverse_iterator crend() const noexcept;
88
89    // capacity:
90    size_type size() const noexcept;
91    size_type max_size() const noexcept;
92    void resize(size_type n);
93    void resize(size_type n, const value_type& v);
94    void shrink_to_fit();
95    bool empty() const noexcept;
96
97    // element access:
98    reference operator[](size_type i);
99    const_reference operator[](size_type i) const;
100    reference at(size_type i);
101    const_reference at(size_type i) const;
102    reference front();
103    const_reference front() const;
104    reference back();
105    const_reference back() const;
106
107    // modifiers:
108    void push_front(const value_type& v);
109    void push_front(value_type&& v);
110    void push_back(const value_type& v);
111    void push_back(value_type&& v);
112    template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
113    template <class... Args> reference emplace_back(Args&&... args);   // reference in C++17
114    template <class... Args> iterator emplace(const_iterator p, Args&&... args);
115    iterator insert(const_iterator p, const value_type& v);
116    iterator insert(const_iterator p, value_type&& v);
117    iterator insert(const_iterator p, size_type n, const value_type& v);
118    template <class InputIterator>
119        iterator insert(const_iterator p, InputIterator f, InputIterator l);
120    iterator insert(const_iterator p, initializer_list<value_type> il);
121    void pop_front();
122    void pop_back();
123    iterator erase(const_iterator p);
124    iterator erase(const_iterator f, const_iterator l);
125    void swap(deque& c)
126        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
127    void clear() noexcept;
128};
129
130template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
131   deque(InputIterator, InputIterator, Allocator = Allocator())
132   -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
133
134template <class T, class Allocator>
135    bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
136template <class T, class Allocator>
137    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
138template <class T, class Allocator>
139    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
140template <class T, class Allocator>
141    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
142template <class T, class Allocator>
143    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
144template <class T, class Allocator>
145    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
146
147// specialized algorithms:
148template <class T, class Allocator>
149    void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
150         noexcept(noexcept(x.swap(y)));
151
152template <class T, class Allocator, class U>
153    typename deque<T, Allocator>::size_type
154    erase(deque<T, Allocator>& c, const U& value);       // C++20
155template <class T, class Allocator, class Predicate>
156    typename deque<T, Allocator>::size_type
157    erase_if(deque<T, Allocator>& c, Predicate pred);    // C++20
158
159}  // std
160
161*/
162
163#include <__config>
164#include <__debug>
165#include <__split_buffer>
166#include <__utility/forward.h>
167#include <algorithm>
168#include <compare>
169#include <initializer_list>
170#include <iterator>
171#include <stdexcept>
172#include <type_traits>
173#include <version>
174
175#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
176#pragma GCC system_header
177#endif
178
179_LIBCPP_PUSH_MACROS
180#include <__undef_macros>
181
182
183_LIBCPP_BEGIN_NAMESPACE_STD
184
185template <class _Tp, class _Allocator> class __deque_base;
186template <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;
187
188template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
189          class _DiffType, _DiffType _BlockSize>
190class _LIBCPP_TEMPLATE_VIS __deque_iterator;
191
192template <class _RAIter,
193          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
194__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
195copy(_RAIter __f,
196     _RAIter __l,
197     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
198     typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
199
200template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
201          class _OutputIterator>
202_OutputIterator
203copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
204     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
205     _OutputIterator __r);
206
207template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
208          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
209__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
210copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
211     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
212     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
213
214template <class _RAIter,
215          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
216__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
217copy_backward(_RAIter __f,
218              _RAIter __l,
219              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
220              typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
221
222template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
223          class _OutputIterator>
224_OutputIterator
225copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
226              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
227              _OutputIterator __r);
228
229template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
230          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
231__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
232copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
233              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
234              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
235
236template <class _RAIter,
237          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
238__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
239move(_RAIter __f,
240     _RAIter __l,
241     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
242     typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
243
244template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
245          class _OutputIterator>
246_OutputIterator
247move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
248     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
249     _OutputIterator __r);
250
251template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
252          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
253__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
254move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
255     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
256     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
257
258template <class _RAIter,
259          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
260__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
261move_backward(_RAIter __f,
262              _RAIter __l,
263              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
264              typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
265
266template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
267          class _OutputIterator>
268_OutputIterator
269move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
270              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
271              _OutputIterator __r);
272
273template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
274          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
275__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
276move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
277              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
278              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
279
280template <class _ValueType, class _DiffType>
281struct __deque_block_size {
282  static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
283};
284
285template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
286          class _DiffType, _DiffType _BS =
287#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
288// Keep template parameter to avoid changing all template declarations thoughout
289// this file.
290                               0
291#else
292                               __deque_block_size<_ValueType, _DiffType>::value
293#endif
294          >
295class _LIBCPP_TEMPLATE_VIS __deque_iterator
296{
297    typedef _MapPointer __map_iterator;
298public:
299    typedef _Pointer  pointer;
300    typedef _DiffType difference_type;
301private:
302    __map_iterator __m_iter_;
303    pointer        __ptr_;
304
305    static const difference_type __block_size;
306public:
307    typedef _ValueType                  value_type;
308    typedef random_access_iterator_tag  iterator_category;
309    typedef _Reference                  reference;
310
311    _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT
312#if _LIBCPP_STD_VER > 11
313     : __m_iter_(nullptr), __ptr_(nullptr)
314#endif
315     {}
316
317    template <class _Pp, class _Rp, class _MP>
318    _LIBCPP_INLINE_VISIBILITY
319    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
320                typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
321        : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
322
323    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;}
324    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;}
325
326    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++()
327    {
328        if (++__ptr_ - *__m_iter_ == __block_size)
329        {
330            ++__m_iter_;
331            __ptr_ = *__m_iter_;
332        }
333        return *this;
334    }
335
336    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int)
337    {
338        __deque_iterator __tmp = *this;
339        ++(*this);
340        return __tmp;
341    }
342
343    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--()
344    {
345        if (__ptr_ == *__m_iter_)
346        {
347            --__m_iter_;
348            __ptr_ = *__m_iter_ + __block_size;
349        }
350        --__ptr_;
351        return *this;
352    }
353
354    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int)
355    {
356        __deque_iterator __tmp = *this;
357        --(*this);
358        return __tmp;
359    }
360
361    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n)
362    {
363        if (__n != 0)
364        {
365            __n += __ptr_ - *__m_iter_;
366            if (__n > 0)
367            {
368                __m_iter_ += __n / __block_size;
369                __ptr_ = *__m_iter_ + __n % __block_size;
370            }
371            else // (__n < 0)
372            {
373                difference_type __z = __block_size - 1 - __n;
374                __m_iter_ -= __z / __block_size;
375                __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
376            }
377        }
378        return *this;
379    }
380
381    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n)
382    {
383        return *this += -__n;
384    }
385
386    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const
387    {
388        __deque_iterator __t(*this);
389        __t += __n;
390        return __t;
391    }
392
393    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const
394    {
395        __deque_iterator __t(*this);
396        __t -= __n;
397        return __t;
398    }
399
400    _LIBCPP_INLINE_VISIBILITY
401    friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
402        {return __it + __n;}
403
404    _LIBCPP_INLINE_VISIBILITY
405    friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
406    {
407        if (__x != __y)
408            return (__x.__m_iter_ - __y.__m_iter_) * __block_size
409                 + (__x.__ptr_ - *__x.__m_iter_)
410                 - (__y.__ptr_ - *__y.__m_iter_);
411        return 0;
412    }
413
414    _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
415        {return *(*this + __n);}
416
417    _LIBCPP_INLINE_VISIBILITY friend
418        bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
419        {return __x.__ptr_ == __y.__ptr_;}
420
421    _LIBCPP_INLINE_VISIBILITY friend
422        bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
423        {return !(__x == __y);}
424
425    _LIBCPP_INLINE_VISIBILITY friend
426        bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
427        {return __x.__m_iter_ < __y.__m_iter_ ||
428               (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
429
430    _LIBCPP_INLINE_VISIBILITY friend
431        bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
432        {return __y < __x;}
433
434    _LIBCPP_INLINE_VISIBILITY friend
435        bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
436        {return !(__y < __x);}
437
438    _LIBCPP_INLINE_VISIBILITY friend
439        bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
440        {return !(__x < __y);}
441
442private:
443    _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
444        : __m_iter_(__m), __ptr_(__p) {}
445
446    template <class _Tp, class _Ap> friend class __deque_base;
447    template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque;
448    template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
449        friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
450
451    template <class _RAIter,
452              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
453    friend
454    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
455    copy(_RAIter __f,
456         _RAIter __l,
457         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
458         typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
459
460    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
461              class _OutputIterator>
462    friend
463    _OutputIterator
464    copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
465         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
466         _OutputIterator __r);
467
468    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
469              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
470    friend
471    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
472    copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
473         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
474         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
475
476    template <class _RAIter,
477              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
478    friend
479    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
480    copy_backward(_RAIter __f,
481                  _RAIter __l,
482                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
483                  typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
484
485    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
486              class _OutputIterator>
487    friend
488    _OutputIterator
489    copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
490                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
491                  _OutputIterator __r);
492
493    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
494              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
495    friend
496    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
497    copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
498                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
499                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
500
501    template <class _RAIter,
502              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
503    friend
504    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
505    move(_RAIter __f,
506         _RAIter __l,
507         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
508         typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
509
510    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
511              class _OutputIterator>
512    friend
513    _OutputIterator
514    move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
515         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
516         _OutputIterator __r);
517
518    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
519              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
520    friend
521    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
522    move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
523         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
524         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
525
526    template <class _RAIter,
527              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
528    friend
529    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
530    move_backward(_RAIter __f,
531                  _RAIter __l,
532                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
533                  typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
534
535    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
536              class _OutputIterator>
537    friend
538    _OutputIterator
539    move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
540                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
541                  _OutputIterator __r);
542
543    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
544              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
545    friend
546    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
547    move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
548                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
549                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
550};
551
552template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
553          class _DiffType, _DiffType _BlockSize>
554const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
555                                 _DiffType, _BlockSize>::__block_size =
556    __deque_block_size<_ValueType, _DiffType>::value;
557
558// copy
559
560template <class _RAIter,
561          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
562__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
563copy(_RAIter __f,
564     _RAIter __l,
565     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
566     typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
567{
568    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
569    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
570    const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
571    while (__f != __l)
572    {
573        pointer __rb = __r.__ptr_;
574        pointer __re = *__r.__m_iter_ + __block_size;
575        difference_type __bs = __re - __rb;
576        difference_type __n = __l - __f;
577        _RAIter __m = __l;
578        if (__n > __bs)
579        {
580            __n = __bs;
581            __m = __f + __n;
582        }
583        _VSTD::copy(__f, __m, __rb);
584        __f = __m;
585        __r += __n;
586    }
587    return __r;
588}
589
590template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
591          class _OutputIterator>
592_OutputIterator
593copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
594     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
595     _OutputIterator __r)
596{
597    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
598    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
599    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
600    difference_type __n = __l - __f;
601    while (__n > 0)
602    {
603        pointer __fb = __f.__ptr_;
604        pointer __fe = *__f.__m_iter_ + __block_size;
605        difference_type __bs = __fe - __fb;
606        if (__bs > __n)
607        {
608            __bs = __n;
609            __fe = __fb + __bs;
610        }
611        __r = _VSTD::copy(__fb, __fe, __r);
612        __n -= __bs;
613        __f += __bs;
614    }
615    return __r;
616}
617
618template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
619          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
620__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
621copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
622     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
623     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
624{
625    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
626    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
627    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
628    difference_type __n = __l - __f;
629    while (__n > 0)
630    {
631        pointer __fb = __f.__ptr_;
632        pointer __fe = *__f.__m_iter_ + __block_size;
633        difference_type __bs = __fe - __fb;
634        if (__bs > __n)
635        {
636            __bs = __n;
637            __fe = __fb + __bs;
638        }
639        __r = _VSTD::copy(__fb, __fe, __r);
640        __n -= __bs;
641        __f += __bs;
642    }
643    return __r;
644}
645
646// copy_backward
647
648template <class _RAIter,
649          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
650__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
651copy_backward(_RAIter __f,
652              _RAIter __l,
653              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
654              typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
655{
656    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
657    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
658    while (__f != __l)
659    {
660        __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
661        pointer __rb = *__rp.__m_iter_;
662        pointer __re = __rp.__ptr_ + 1;
663        difference_type __bs = __re - __rb;
664        difference_type __n = __l - __f;
665        _RAIter __m = __f;
666        if (__n > __bs)
667        {
668            __n = __bs;
669            __m = __l - __n;
670        }
671        _VSTD::copy_backward(__m, __l, __re);
672        __l = __m;
673        __r -= __n;
674    }
675    return __r;
676}
677
678template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
679          class _OutputIterator>
680_OutputIterator
681copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
682              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
683              _OutputIterator __r)
684{
685    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
686    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
687    difference_type __n = __l - __f;
688    while (__n > 0)
689    {
690        --__l;
691        pointer __lb = *__l.__m_iter_;
692        pointer __le = __l.__ptr_ + 1;
693        difference_type __bs = __le - __lb;
694        if (__bs > __n)
695        {
696            __bs = __n;
697            __lb = __le - __bs;
698        }
699        __r = _VSTD::copy_backward(__lb, __le, __r);
700        __n -= __bs;
701        __l -= __bs - 1;
702    }
703    return __r;
704}
705
706template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
707          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
708__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
709copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
710              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
711              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
712{
713    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
714    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
715    difference_type __n = __l - __f;
716    while (__n > 0)
717    {
718        --__l;
719        pointer __lb = *__l.__m_iter_;
720        pointer __le = __l.__ptr_ + 1;
721        difference_type __bs = __le - __lb;
722        if (__bs > __n)
723        {
724            __bs = __n;
725            __lb = __le - __bs;
726        }
727        __r = _VSTD::copy_backward(__lb, __le, __r);
728        __n -= __bs;
729        __l -= __bs - 1;
730    }
731    return __r;
732}
733
734// move
735
736template <class _RAIter,
737          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
738__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
739move(_RAIter __f,
740     _RAIter __l,
741     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
742     typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
743{
744    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
745    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
746    const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
747    while (__f != __l)
748    {
749        pointer __rb = __r.__ptr_;
750        pointer __re = *__r.__m_iter_ + __block_size;
751        difference_type __bs = __re - __rb;
752        difference_type __n = __l - __f;
753        _RAIter __m = __l;
754        if (__n > __bs)
755        {
756            __n = __bs;
757            __m = __f + __n;
758        }
759        _VSTD::move(__f, __m, __rb);
760        __f = __m;
761        __r += __n;
762    }
763    return __r;
764}
765
766template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
767          class _OutputIterator>
768_OutputIterator
769move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
770     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
771     _OutputIterator __r)
772{
773    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
774    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
775    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
776    difference_type __n = __l - __f;
777    while (__n > 0)
778    {
779        pointer __fb = __f.__ptr_;
780        pointer __fe = *__f.__m_iter_ + __block_size;
781        difference_type __bs = __fe - __fb;
782        if (__bs > __n)
783        {
784            __bs = __n;
785            __fe = __fb + __bs;
786        }
787        __r = _VSTD::move(__fb, __fe, __r);
788        __n -= __bs;
789        __f += __bs;
790    }
791    return __r;
792}
793
794template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
795          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
796__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
797move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
798     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
799     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
800{
801    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
802    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
803    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
804    difference_type __n = __l - __f;
805    while (__n > 0)
806    {
807        pointer __fb = __f.__ptr_;
808        pointer __fe = *__f.__m_iter_ + __block_size;
809        difference_type __bs = __fe - __fb;
810        if (__bs > __n)
811        {
812            __bs = __n;
813            __fe = __fb + __bs;
814        }
815        __r = _VSTD::move(__fb, __fe, __r);
816        __n -= __bs;
817        __f += __bs;
818    }
819    return __r;
820}
821
822// move_backward
823
824template <class _RAIter,
825          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
826__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
827move_backward(_RAIter __f,
828              _RAIter __l,
829              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
830              typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
831{
832    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
833    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
834    while (__f != __l)
835    {
836        __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
837        pointer __rb = *__rp.__m_iter_;
838        pointer __re = __rp.__ptr_ + 1;
839        difference_type __bs = __re - __rb;
840        difference_type __n = __l - __f;
841        _RAIter __m = __f;
842        if (__n > __bs)
843        {
844            __n = __bs;
845            __m = __l - __n;
846        }
847        _VSTD::move_backward(__m, __l, __re);
848        __l = __m;
849        __r -= __n;
850    }
851    return __r;
852}
853
854template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
855          class _OutputIterator>
856_OutputIterator
857move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
858              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
859              _OutputIterator __r)
860{
861    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
862    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
863    difference_type __n = __l - __f;
864    while (__n > 0)
865    {
866        --__l;
867        pointer __lb = *__l.__m_iter_;
868        pointer __le = __l.__ptr_ + 1;
869        difference_type __bs = __le - __lb;
870        if (__bs > __n)
871        {
872            __bs = __n;
873            __lb = __le - __bs;
874        }
875        __r = _VSTD::move_backward(__lb, __le, __r);
876        __n -= __bs;
877        __l -= __bs - 1;
878    }
879    return __r;
880}
881
882template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
883          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
884__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
885move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
886              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
887              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
888{
889    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
890    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
891    difference_type __n = __l - __f;
892    while (__n > 0)
893    {
894        --__l;
895        pointer __lb = *__l.__m_iter_;
896        pointer __le = __l.__ptr_ + 1;
897        difference_type __bs = __le - __lb;
898        if (__bs > __n)
899        {
900            __bs = __n;
901            __lb = __le - __bs;
902        }
903        __r = _VSTD::move_backward(__lb, __le, __r);
904        __n -= __bs;
905        __l -= __bs - 1;
906    }
907    return __r;
908}
909
910template <bool>
911class __deque_base_common
912{
913protected:
914    _LIBCPP_NORETURN void __throw_length_error() const;
915    _LIBCPP_NORETURN void __throw_out_of_range() const;
916};
917
918template <bool __b>
919void
920__deque_base_common<__b>::__throw_length_error() const
921{
922    _VSTD::__throw_length_error("deque");
923}
924
925template <bool __b>
926void
927__deque_base_common<__b>::__throw_out_of_range() const
928{
929    _VSTD::__throw_out_of_range("deque");
930}
931
932template <class _Tp, class _Allocator>
933class __deque_base
934    : protected __deque_base_common<true>
935{
936    __deque_base(const __deque_base& __c);
937    __deque_base& operator=(const __deque_base& __c);
938public:
939    typedef _Allocator                               allocator_type;
940    typedef allocator_traits<allocator_type>         __alloc_traits;
941    typedef typename __alloc_traits::size_type       size_type;
942
943    typedef _Tp                                      value_type;
944    typedef value_type&                              reference;
945    typedef const value_type&                        const_reference;
946    typedef typename __alloc_traits::difference_type difference_type;
947    typedef typename __alloc_traits::pointer         pointer;
948    typedef typename __alloc_traits::const_pointer   const_pointer;
949
950    static const difference_type __block_size;
951
952    typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;
953    typedef allocator_traits<__pointer_allocator>        __map_traits;
954    typedef typename __map_traits::pointer               __map_pointer;
955    typedef typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type __const_pointer_allocator;
956    typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;
957    typedef __split_buffer<pointer, __pointer_allocator> __map;
958
959    typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
960                             difference_type>    iterator;
961    typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
962                             difference_type>    const_iterator;
963
964    struct __deque_block_range {
965      explicit __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {}
966      const pointer __begin_;
967      const pointer __end_;
968    };
969
970    struct __deque_range {
971      iterator __pos_;
972      const iterator __end_;
973
974      __deque_range(iterator __pos, iterator __e) _NOEXCEPT
975        : __pos_(__pos), __end_(__e) {}
976
977      explicit operator bool() const _NOEXCEPT {
978        return __pos_ != __end_;
979      }
980
981      __deque_range begin() const {
982        return *this;
983      }
984
985      __deque_range end() const {
986        return __deque_range(__end_, __end_);
987      }
988      __deque_block_range operator*() const _NOEXCEPT {
989         if (__pos_.__m_iter_ == __end_.__m_iter_) {
990          return __deque_block_range(__pos_.__ptr_, __end_.__ptr_);
991        }
992        return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size);
993      }
994
995      __deque_range& operator++() _NOEXCEPT {
996        if (__pos_.__m_iter_ == __end_.__m_iter_) {
997          __pos_ = __end_;
998        } else {
999          ++__pos_.__m_iter_;
1000          __pos_.__ptr_ = *__pos_.__m_iter_;
1001        }
1002        return *this;
1003      }
1004
1005
1006      friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) {
1007        return __lhs.__pos_ == __rhs.__pos_;
1008      }
1009      friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) {
1010        return !(__lhs == __rhs);
1011      }
1012    };
1013
1014
1015
1016    struct _ConstructTransaction {
1017      _ConstructTransaction(__deque_base* __db, __deque_block_range& __r)
1018        : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {}
1019
1020
1021      ~_ConstructTransaction() {
1022        __base_->size() += (__pos_ - __begin_);
1023      }
1024
1025      pointer __pos_;
1026      const pointer __end_;
1027    private:
1028      const pointer __begin_;
1029      __deque_base * const __base_;
1030    };
1031
1032protected:
1033    __map __map_;
1034    size_type __start_;
1035    __compressed_pair<size_type, allocator_type> __size_;
1036
1037    iterator       begin() _NOEXCEPT;
1038    const_iterator begin() const _NOEXCEPT;
1039    iterator       end() _NOEXCEPT;
1040    const_iterator end() const _NOEXCEPT;
1041
1042    _LIBCPP_INLINE_VISIBILITY size_type&            size()          {return __size_.first();}
1043    _LIBCPP_INLINE_VISIBILITY
1044    const size_type& size() const _NOEXCEPT {return __size_.first();}
1045    _LIBCPP_INLINE_VISIBILITY allocator_type&       __alloc()       {return __size_.second();}
1046    _LIBCPP_INLINE_VISIBILITY
1047    const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
1048
1049    _LIBCPP_INLINE_VISIBILITY
1050    __deque_base()
1051        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
1052    _LIBCPP_INLINE_VISIBILITY
1053    explicit __deque_base(const allocator_type& __a);
1054public:
1055    ~__deque_base();
1056
1057#ifndef _LIBCPP_CXX03_LANG
1058    __deque_base(__deque_base&& __c)
1059        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
1060    __deque_base(__deque_base&& __c, const allocator_type& __a);
1061#endif // _LIBCPP_CXX03_LANG
1062
1063    void swap(__deque_base& __c)
1064#if _LIBCPP_STD_VER >= 14
1065        _NOEXCEPT;
1066#else
1067        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1068                    __is_nothrow_swappable<allocator_type>::value);
1069#endif
1070protected:
1071    void clear() _NOEXCEPT;
1072
1073    bool __invariants() const;
1074
1075    _LIBCPP_INLINE_VISIBILITY
1076    void __move_assign(__deque_base& __c)
1077        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1078                   is_nothrow_move_assignable<allocator_type>::value)
1079    {
1080        __map_ = _VSTD::move(__c.__map_);
1081        __start_ = __c.__start_;
1082        size() = __c.size();
1083        __move_assign_alloc(__c);
1084        __c.__start_ = __c.size() = 0;
1085    }
1086
1087    _LIBCPP_INLINE_VISIBILITY
1088    void __move_assign_alloc(__deque_base& __c)
1089        _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
1090                   is_nothrow_move_assignable<allocator_type>::value)
1091        {__move_assign_alloc(__c, integral_constant<bool,
1092                      __alloc_traits::propagate_on_container_move_assignment::value>());}
1093
1094private:
1095    _LIBCPP_INLINE_VISIBILITY
1096    void __move_assign_alloc(__deque_base& __c, true_type)
1097        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1098        {
1099            __alloc() = _VSTD::move(__c.__alloc());
1100        }
1101
1102    _LIBCPP_INLINE_VISIBILITY
1103    void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT
1104        {}
1105};
1106
1107template <class _Tp, class _Allocator>
1108const typename __deque_base<_Tp, _Allocator>::difference_type
1109    __deque_base<_Tp, _Allocator>::__block_size =
1110        __deque_block_size<value_type, difference_type>::value;
1111
1112template <class _Tp, class _Allocator>
1113bool
1114__deque_base<_Tp, _Allocator>::__invariants() const
1115{
1116    if (!__map_.__invariants())
1117        return false;
1118    if (__map_.size() >= size_type(-1) / __block_size)
1119        return false;
1120    for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
1121         __i != __e; ++__i)
1122        if (*__i == nullptr)
1123            return false;
1124    if (__map_.size() != 0)
1125    {
1126        if (size() >= __map_.size() * __block_size)
1127            return false;
1128        if (__start_ >= __map_.size() * __block_size - size())
1129            return false;
1130    }
1131    else
1132    {
1133        if (size() != 0)
1134            return false;
1135        if (__start_ != 0)
1136            return false;
1137    }
1138    return true;
1139}
1140
1141template <class _Tp, class _Allocator>
1142typename __deque_base<_Tp, _Allocator>::iterator
1143__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT
1144{
1145    __map_pointer __mp = __map_.begin() + __start_ / __block_size;
1146    return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1147}
1148
1149template <class _Tp, class _Allocator>
1150typename __deque_base<_Tp, _Allocator>::const_iterator
1151__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
1152{
1153    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
1154    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1155}
1156
1157template <class _Tp, class _Allocator>
1158typename __deque_base<_Tp, _Allocator>::iterator
1159__deque_base<_Tp, _Allocator>::end() _NOEXCEPT
1160{
1161    size_type __p = size() + __start_;
1162    __map_pointer __mp = __map_.begin() + __p / __block_size;
1163    return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1164}
1165
1166template <class _Tp, class _Allocator>
1167typename __deque_base<_Tp, _Allocator>::const_iterator
1168__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
1169{
1170    size_type __p = size() + __start_;
1171    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
1172    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1173}
1174
1175template <class _Tp, class _Allocator>
1176inline
1177__deque_base<_Tp, _Allocator>::__deque_base()
1178    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
1179    : __start_(0), __size_(0, __default_init_tag()) {}
1180
1181template <class _Tp, class _Allocator>
1182inline
1183__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
1184    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
1185
1186template <class _Tp, class _Allocator>
1187__deque_base<_Tp, _Allocator>::~__deque_base()
1188{
1189    clear();
1190    typename __map::iterator __i = __map_.begin();
1191    typename __map::iterator __e = __map_.end();
1192    for (; __i != __e; ++__i)
1193        __alloc_traits::deallocate(__alloc(), *__i, __block_size);
1194}
1195
1196#ifndef _LIBCPP_CXX03_LANG
1197
1198template <class _Tp, class _Allocator>
1199__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)
1200    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
1201    : __map_(_VSTD::move(__c.__map_)),
1202      __start_(_VSTD::move(__c.__start_)),
1203      __size_(_VSTD::move(__c.__size_))
1204{
1205    __c.__start_ = 0;
1206    __c.size() = 0;
1207}
1208
1209template <class _Tp, class _Allocator>
1210__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)
1211    : __map_(_VSTD::move(__c.__map_), __pointer_allocator(__a)),
1212      __start_(_VSTD::move(__c.__start_)),
1213      __size_(_VSTD::move(__c.size()), __a)
1214{
1215    if (__a == __c.__alloc())
1216    {
1217        __c.__start_ = 0;
1218        __c.size() = 0;
1219    }
1220    else
1221    {
1222        __map_.clear();
1223        __start_ = 0;
1224        size() = 0;
1225    }
1226}
1227
1228#endif // _LIBCPP_CXX03_LANG
1229
1230template <class _Tp, class _Allocator>
1231void
1232__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
1233#if _LIBCPP_STD_VER >= 14
1234        _NOEXCEPT
1235#else
1236        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1237                    __is_nothrow_swappable<allocator_type>::value)
1238#endif
1239{
1240    __map_.swap(__c.__map_);
1241    _VSTD::swap(__start_, __c.__start_);
1242    _VSTD::swap(size(), __c.size());
1243    _VSTD::__swap_allocator(__alloc(), __c.__alloc());
1244}
1245
1246template <class _Tp, class _Allocator>
1247void
1248__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
1249{
1250    allocator_type& __a = __alloc();
1251    for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
1252        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
1253    size() = 0;
1254    while (__map_.size() > 2)
1255    {
1256        __alloc_traits::deallocate(__a, __map_.front(), __block_size);
1257        __map_.pop_front();
1258    }
1259    switch (__map_.size())
1260    {
1261    case 1:
1262        __start_ = __block_size / 2;
1263        break;
1264    case 2:
1265        __start_ = __block_size;
1266        break;
1267    }
1268}
1269
1270template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
1271class _LIBCPP_TEMPLATE_VIS deque
1272    : private __deque_base<_Tp, _Allocator>
1273{
1274public:
1275    // types:
1276
1277    typedef _Tp value_type;
1278    typedef _Allocator allocator_type;
1279
1280    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
1281                  "Allocator::value_type must be same type as value_type");
1282
1283    typedef __deque_base<value_type, allocator_type> __base;
1284
1285    typedef typename __base::__alloc_traits        __alloc_traits;
1286    typedef typename __base::reference             reference;
1287    typedef typename __base::const_reference       const_reference;
1288    typedef typename __base::iterator              iterator;
1289    typedef typename __base::const_iterator        const_iterator;
1290    typedef typename __base::size_type             size_type;
1291    typedef typename __base::difference_type       difference_type;
1292
1293    typedef typename __base::pointer               pointer;
1294    typedef typename __base::const_pointer         const_pointer;
1295    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
1296    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
1297
1298    using typename __base::__deque_range;
1299    using typename __base::__deque_block_range;
1300    using typename __base::_ConstructTransaction;
1301
1302    // construct/copy/destroy:
1303    _LIBCPP_INLINE_VISIBILITY
1304    deque()
1305        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
1306        {}
1307    _LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}
1308    explicit deque(size_type __n);
1309#if _LIBCPP_STD_VER > 11
1310    explicit deque(size_type __n, const _Allocator& __a);
1311#endif
1312    deque(size_type __n, const value_type& __v);
1313    deque(size_type __n, const value_type& __v, const allocator_type& __a);
1314    template <class _InputIter>
1315        deque(_InputIter __f, _InputIter __l,
1316              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
1317    template <class _InputIter>
1318        deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1319              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
1320    deque(const deque& __c);
1321    deque(const deque& __c, const __identity_t<allocator_type>& __a);
1322
1323    deque& operator=(const deque& __c);
1324
1325#ifndef _LIBCPP_CXX03_LANG
1326    deque(initializer_list<value_type> __il);
1327    deque(initializer_list<value_type> __il, const allocator_type& __a);
1328
1329    _LIBCPP_INLINE_VISIBILITY
1330    deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
1331
1332    _LIBCPP_INLINE_VISIBILITY
1333    deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
1334    _LIBCPP_INLINE_VISIBILITY
1335    deque(deque&& __c, const __identity_t<allocator_type>& __a);
1336    _LIBCPP_INLINE_VISIBILITY
1337    deque& operator=(deque&& __c)
1338        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1339                   is_nothrow_move_assignable<allocator_type>::value);
1340
1341    _LIBCPP_INLINE_VISIBILITY
1342    void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
1343#endif // _LIBCPP_CXX03_LANG
1344
1345    template <class _InputIter>
1346        void assign(_InputIter __f, _InputIter __l,
1347                    typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
1348                                      !__is_cpp17_random_access_iterator<_InputIter>::value>::type* = 0);
1349    template <class _RAIter>
1350        void assign(_RAIter __f, _RAIter __l,
1351                    typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
1352    void assign(size_type __n, const value_type& __v);
1353
1354    _LIBCPP_INLINE_VISIBILITY
1355    allocator_type get_allocator() const _NOEXCEPT;
1356
1357    // iterators:
1358
1359    _LIBCPP_INLINE_VISIBILITY
1360    iterator       begin() _NOEXCEPT       {return __base::begin();}
1361    _LIBCPP_INLINE_VISIBILITY
1362    const_iterator begin() const _NOEXCEPT {return __base::begin();}
1363    _LIBCPP_INLINE_VISIBILITY
1364    iterator       end() _NOEXCEPT         {return __base::end();}
1365    _LIBCPP_INLINE_VISIBILITY
1366    const_iterator end()   const _NOEXCEPT {return __base::end();}
1367
1368    _LIBCPP_INLINE_VISIBILITY
1369    reverse_iterator       rbegin() _NOEXCEPT
1370        {return       reverse_iterator(__base::end());}
1371    _LIBCPP_INLINE_VISIBILITY
1372    const_reverse_iterator rbegin() const _NOEXCEPT
1373        {return const_reverse_iterator(__base::end());}
1374    _LIBCPP_INLINE_VISIBILITY
1375    reverse_iterator       rend() _NOEXCEPT
1376        {return       reverse_iterator(__base::begin());}
1377    _LIBCPP_INLINE_VISIBILITY
1378    const_reverse_iterator rend()   const _NOEXCEPT
1379        {return const_reverse_iterator(__base::begin());}
1380
1381    _LIBCPP_INLINE_VISIBILITY
1382    const_iterator         cbegin()  const _NOEXCEPT
1383        {return __base::begin();}
1384    _LIBCPP_INLINE_VISIBILITY
1385    const_iterator         cend()    const _NOEXCEPT
1386        {return __base::end();}
1387    _LIBCPP_INLINE_VISIBILITY
1388    const_reverse_iterator crbegin() const _NOEXCEPT
1389        {return const_reverse_iterator(__base::end());}
1390    _LIBCPP_INLINE_VISIBILITY
1391    const_reverse_iterator crend()   const _NOEXCEPT
1392        {return const_reverse_iterator(__base::begin());}
1393
1394    // capacity:
1395    _LIBCPP_INLINE_VISIBILITY
1396    size_type size() const _NOEXCEPT {return __base::size();}
1397    _LIBCPP_INLINE_VISIBILITY
1398    size_type max_size() const _NOEXCEPT
1399        {return _VSTD::min<size_type>(
1400            __alloc_traits::max_size(__base::__alloc()),
1401            numeric_limits<difference_type>::max());}
1402    void resize(size_type __n);
1403    void resize(size_type __n, const value_type& __v);
1404    void shrink_to_fit() _NOEXCEPT;
1405    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1406    bool empty() const _NOEXCEPT {return __base::size() == 0;}
1407
1408    // element access:
1409    _LIBCPP_INLINE_VISIBILITY
1410    reference operator[](size_type __i) _NOEXCEPT;
1411    _LIBCPP_INLINE_VISIBILITY
1412    const_reference operator[](size_type __i) const _NOEXCEPT;
1413    _LIBCPP_INLINE_VISIBILITY
1414    reference at(size_type __i);
1415    _LIBCPP_INLINE_VISIBILITY
1416    const_reference at(size_type __i) const;
1417    _LIBCPP_INLINE_VISIBILITY
1418    reference front() _NOEXCEPT;
1419    _LIBCPP_INLINE_VISIBILITY
1420    const_reference front() const _NOEXCEPT;
1421    _LIBCPP_INLINE_VISIBILITY
1422    reference back() _NOEXCEPT;
1423    _LIBCPP_INLINE_VISIBILITY
1424    const_reference back() const _NOEXCEPT;
1425
1426    // 23.2.2.3 modifiers:
1427    void push_front(const value_type& __v);
1428    void push_back(const value_type& __v);
1429#ifndef _LIBCPP_CXX03_LANG
1430#if _LIBCPP_STD_VER > 14
1431    template <class... _Args> reference emplace_front(_Args&&... __args);
1432    template <class... _Args> reference emplace_back (_Args&&... __args);
1433#else
1434    template <class... _Args> void      emplace_front(_Args&&... __args);
1435    template <class... _Args> void      emplace_back (_Args&&... __args);
1436#endif
1437    template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);
1438
1439    void push_front(value_type&& __v);
1440    void push_back(value_type&& __v);
1441    iterator insert(const_iterator __p, value_type&& __v);
1442
1443    _LIBCPP_INLINE_VISIBILITY
1444    iterator insert(const_iterator __p, initializer_list<value_type> __il)
1445        {return insert(__p, __il.begin(), __il.end());}
1446#endif // _LIBCPP_CXX03_LANG
1447    iterator insert(const_iterator __p, const value_type& __v);
1448    iterator insert(const_iterator __p, size_type __n, const value_type& __v);
1449    template <class _InputIter>
1450        iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
1451                         typename enable_if<__is_cpp17_input_iterator<_InputIter>::value
1452                                         &&!__is_cpp17_forward_iterator<_InputIter>::value>::type* = 0);
1453    template <class _ForwardIterator>
1454        iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
1455                               typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value
1456                                         &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type* = 0);
1457    template <class _BiIter>
1458        iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
1459                         typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0);
1460
1461    void pop_front();
1462    void pop_back();
1463    iterator erase(const_iterator __p);
1464    iterator erase(const_iterator __f, const_iterator __l);
1465
1466    _LIBCPP_INLINE_VISIBILITY
1467    void swap(deque& __c)
1468#if _LIBCPP_STD_VER >= 14
1469        _NOEXCEPT;
1470#else
1471        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1472                   __is_nothrow_swappable<allocator_type>::value);
1473#endif
1474    _LIBCPP_INLINE_VISIBILITY
1475    void clear() _NOEXCEPT;
1476
1477    _LIBCPP_INLINE_VISIBILITY
1478    bool __invariants() const {return __base::__invariants();}
1479
1480    typedef typename __base::__map_const_pointer __map_const_pointer;
1481
1482    _LIBCPP_INLINE_VISIBILITY
1483    static size_type __recommend_blocks(size_type __n)
1484    {
1485        return __n / __base::__block_size + (__n % __base::__block_size != 0);
1486    }
1487    _LIBCPP_INLINE_VISIBILITY
1488    size_type __capacity() const
1489    {
1490        return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;
1491    }
1492    _LIBCPP_INLINE_VISIBILITY
1493    size_type __block_count() const
1494    {
1495        return __base::__map_.size();
1496    }
1497
1498    _LIBCPP_INLINE_VISIBILITY
1499    size_type __front_spare() const
1500    {
1501        return __base::__start_;
1502    }
1503    _LIBCPP_INLINE_VISIBILITY
1504    size_type __front_spare_blocks() const {
1505      return __front_spare() / __base::__block_size;
1506    }
1507    _LIBCPP_INLINE_VISIBILITY
1508    size_type __back_spare() const
1509    {
1510        return __capacity() - (__base::__start_ + __base::size());
1511    }
1512    _LIBCPP_INLINE_VISIBILITY
1513    size_type __back_spare_blocks() const {
1514      return __back_spare() / __base::__block_size;
1515    }
1516
1517 private:
1518    _LIBCPP_INLINE_VISIBILITY
1519    bool __maybe_remove_front_spare(bool __keep_one = true) {
1520      if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {
1521        __alloc_traits::deallocate(__base::__alloc(), __base::__map_.front(),
1522                                   __base::__block_size);
1523        __base::__map_.pop_front();
1524        __base::__start_ -= __base::__block_size;
1525        return true;
1526      }
1527      return false;
1528    }
1529
1530    _LIBCPP_INLINE_VISIBILITY
1531    bool __maybe_remove_back_spare(bool __keep_one = true) {
1532      if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {
1533        __alloc_traits::deallocate(__base::__alloc(), __base::__map_.back(),
1534                                   __base::__block_size);
1535        __base::__map_.pop_back();
1536        return true;
1537      }
1538      return false;
1539    }
1540
1541    template <class _InpIter>
1542        void __append(_InpIter __f, _InpIter __l,
1543                 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value &&
1544                                   !__is_cpp17_forward_iterator<_InpIter>::value>::type* = 0);
1545    template <class _ForIter>
1546        void __append(_ForIter __f, _ForIter __l,
1547                      typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0);
1548    void __append(size_type __n);
1549    void __append(size_type __n, const value_type& __v);
1550    void __erase_to_end(const_iterator __f);
1551    void __add_front_capacity();
1552    void __add_front_capacity(size_type __n);
1553    void __add_back_capacity();
1554    void __add_back_capacity(size_type __n);
1555    iterator __move_and_check(iterator __f, iterator __l, iterator __r,
1556                              const_pointer& __vt);
1557    iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
1558                                       const_pointer& __vt);
1559    void __move_construct_and_check(iterator __f, iterator __l,
1560                                    iterator __r, const_pointer& __vt);
1561    void __move_construct_backward_and_check(iterator __f, iterator __l,
1562                                             iterator __r, const_pointer& __vt);
1563
1564    _LIBCPP_INLINE_VISIBILITY
1565    void __copy_assign_alloc(const deque& __c)
1566        {__copy_assign_alloc(__c, integral_constant<bool,
1567                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
1568
1569    _LIBCPP_INLINE_VISIBILITY
1570    void __copy_assign_alloc(const deque& __c, true_type)
1571        {
1572            if (__base::__alloc() != __c.__alloc())
1573            {
1574                clear();
1575                shrink_to_fit();
1576            }
1577            __base::__alloc() = __c.__alloc();
1578            __base::__map_.__alloc() = __c.__map_.__alloc();
1579        }
1580
1581    _LIBCPP_INLINE_VISIBILITY
1582    void __copy_assign_alloc(const deque&, false_type)
1583        {}
1584
1585    void __move_assign(deque& __c, true_type)
1586        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
1587    void __move_assign(deque& __c, false_type);
1588};
1589
1590#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1591template<class _InputIterator,
1592         class _Alloc = allocator<__iter_value_type<_InputIterator>>,
1593         class = _EnableIf<__is_allocator<_Alloc>::value>
1594         >
1595deque(_InputIterator, _InputIterator)
1596  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
1597
1598template<class _InputIterator,
1599         class _Alloc,
1600         class = _EnableIf<__is_allocator<_Alloc>::value>
1601         >
1602deque(_InputIterator, _InputIterator, _Alloc)
1603  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
1604#endif
1605
1606
1607template <class _Tp, class _Allocator>
1608deque<_Tp, _Allocator>::deque(size_type __n)
1609{
1610    if (__n > 0)
1611        __append(__n);
1612}
1613
1614#if _LIBCPP_STD_VER > 11
1615template <class _Tp, class _Allocator>
1616deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
1617    : __base(__a)
1618{
1619    if (__n > 0)
1620        __append(__n);
1621}
1622#endif
1623
1624template <class _Tp, class _Allocator>
1625deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
1626{
1627    if (__n > 0)
1628        __append(__n, __v);
1629}
1630
1631template <class _Tp, class _Allocator>
1632deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
1633    : __base(__a)
1634{
1635    if (__n > 0)
1636        __append(__n, __v);
1637}
1638
1639template <class _Tp, class _Allocator>
1640template <class _InputIter>
1641deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
1642              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
1643{
1644    __append(__f, __l);
1645}
1646
1647template <class _Tp, class _Allocator>
1648template <class _InputIter>
1649deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1650              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
1651    : __base(__a)
1652{
1653    __append(__f, __l);
1654}
1655
1656template <class _Tp, class _Allocator>
1657deque<_Tp, _Allocator>::deque(const deque& __c)
1658    : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
1659{
1660    __append(__c.begin(), __c.end());
1661}
1662
1663template <class _Tp, class _Allocator>
1664deque<_Tp, _Allocator>::deque(const deque& __c, const __identity_t<allocator_type>& __a)
1665    : __base(__a)
1666{
1667    __append(__c.begin(), __c.end());
1668}
1669
1670template <class _Tp, class _Allocator>
1671deque<_Tp, _Allocator>&
1672deque<_Tp, _Allocator>::operator=(const deque& __c)
1673{
1674    if (this != &__c)
1675    {
1676        __copy_assign_alloc(__c);
1677        assign(__c.begin(), __c.end());
1678    }
1679    return *this;
1680}
1681
1682#ifndef _LIBCPP_CXX03_LANG
1683
1684template <class _Tp, class _Allocator>
1685deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
1686{
1687    __append(__il.begin(), __il.end());
1688}
1689
1690template <class _Tp, class _Allocator>
1691deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
1692    : __base(__a)
1693{
1694    __append(__il.begin(), __il.end());
1695}
1696
1697template <class _Tp, class _Allocator>
1698inline
1699deque<_Tp, _Allocator>::deque(deque&& __c)
1700    _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
1701    : __base(_VSTD::move(__c))
1702{
1703}
1704
1705template <class _Tp, class _Allocator>
1706inline
1707deque<_Tp, _Allocator>::deque(deque&& __c, const __identity_t<allocator_type>& __a)
1708    : __base(_VSTD::move(__c), __a)
1709{
1710    if (__a != __c.__alloc())
1711    {
1712        typedef move_iterator<iterator> _Ip;
1713        assign(_Ip(__c.begin()), _Ip(__c.end()));
1714    }
1715}
1716
1717template <class _Tp, class _Allocator>
1718inline
1719deque<_Tp, _Allocator>&
1720deque<_Tp, _Allocator>::operator=(deque&& __c)
1721        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1722                   is_nothrow_move_assignable<allocator_type>::value)
1723{
1724    __move_assign(__c, integral_constant<bool,
1725          __alloc_traits::propagate_on_container_move_assignment::value>());
1726    return *this;
1727}
1728
1729template <class _Tp, class _Allocator>
1730void
1731deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
1732{
1733    if (__base::__alloc() != __c.__alloc())
1734    {
1735        typedef move_iterator<iterator> _Ip;
1736        assign(_Ip(__c.begin()), _Ip(__c.end()));
1737    }
1738    else
1739        __move_assign(__c, true_type());
1740}
1741
1742template <class _Tp, class _Allocator>
1743void
1744deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
1745    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1746{
1747    clear();
1748    shrink_to_fit();
1749    __base::__move_assign(__c);
1750}
1751
1752#endif // _LIBCPP_CXX03_LANG
1753
1754template <class _Tp, class _Allocator>
1755template <class _InputIter>
1756void
1757deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
1758                               typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
1759                                                 !__is_cpp17_random_access_iterator<_InputIter>::value>::type*)
1760{
1761    iterator __i = __base::begin();
1762    iterator __e = __base::end();
1763    for (; __f != __l && __i != __e; ++__f, (void) ++__i)
1764        *__i = *__f;
1765    if (__f != __l)
1766        __append(__f, __l);
1767    else
1768        __erase_to_end(__i);
1769}
1770
1771template <class _Tp, class _Allocator>
1772template <class _RAIter>
1773void
1774deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
1775                               typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
1776{
1777    if (static_cast<size_type>(__l - __f) > __base::size())
1778    {
1779        _RAIter __m = __f + __base::size();
1780        _VSTD::copy(__f, __m, __base::begin());
1781        __append(__m, __l);
1782    }
1783    else
1784        __erase_to_end(_VSTD::copy(__f, __l, __base::begin()));
1785}
1786
1787template <class _Tp, class _Allocator>
1788void
1789deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
1790{
1791    if (__n > __base::size())
1792    {
1793        _VSTD::fill_n(__base::begin(), __base::size(), __v);
1794        __n -= __base::size();
1795        __append(__n, __v);
1796    }
1797    else
1798        __erase_to_end(_VSTD::fill_n(__base::begin(), __n, __v));
1799}
1800
1801template <class _Tp, class _Allocator>
1802inline
1803_Allocator
1804deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
1805{
1806    return __base::__alloc();
1807}
1808
1809template <class _Tp, class _Allocator>
1810void
1811deque<_Tp, _Allocator>::resize(size_type __n)
1812{
1813    if (__n > __base::size())
1814        __append(__n - __base::size());
1815    else if (__n < __base::size())
1816        __erase_to_end(__base::begin() + __n);
1817}
1818
1819template <class _Tp, class _Allocator>
1820void
1821deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
1822{
1823    if (__n > __base::size())
1824        __append(__n - __base::size(), __v);
1825    else if (__n < __base::size())
1826        __erase_to_end(__base::begin() + __n);
1827}
1828
1829template <class _Tp, class _Allocator>
1830void
1831deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
1832{
1833    allocator_type& __a = __base::__alloc();
1834    if (empty())
1835    {
1836        while (__base::__map_.size() > 0)
1837        {
1838            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
1839            __base::__map_.pop_back();
1840        }
1841        __base::__start_ = 0;
1842    }
1843    else
1844    {
1845      __maybe_remove_front_spare(/*__keep_one=*/false);
1846      __maybe_remove_back_spare(/*__keep_one=*/false);
1847    }
1848    __base::__map_.shrink_to_fit();
1849}
1850
1851template <class _Tp, class _Allocator>
1852inline
1853typename deque<_Tp, _Allocator>::reference
1854deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT
1855{
1856    size_type __p = __base::__start_ + __i;
1857    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1858}
1859
1860template <class _Tp, class _Allocator>
1861inline
1862typename deque<_Tp, _Allocator>::const_reference
1863deque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT
1864{
1865    size_type __p = __base::__start_ + __i;
1866    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1867}
1868
1869template <class _Tp, class _Allocator>
1870inline
1871typename deque<_Tp, _Allocator>::reference
1872deque<_Tp, _Allocator>::at(size_type __i)
1873{
1874    if (__i >= __base::size())
1875        __base::__throw_out_of_range();
1876    size_type __p = __base::__start_ + __i;
1877    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1878}
1879
1880template <class _Tp, class _Allocator>
1881inline
1882typename deque<_Tp, _Allocator>::const_reference
1883deque<_Tp, _Allocator>::at(size_type __i) const
1884{
1885    if (__i >= __base::size())
1886        __base::__throw_out_of_range();
1887    size_type __p = __base::__start_ + __i;
1888    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1889}
1890
1891template <class _Tp, class _Allocator>
1892inline
1893typename deque<_Tp, _Allocator>::reference
1894deque<_Tp, _Allocator>::front() _NOEXCEPT
1895{
1896    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1897                                      + __base::__start_ % __base::__block_size);
1898}
1899
1900template <class _Tp, class _Allocator>
1901inline
1902typename deque<_Tp, _Allocator>::const_reference
1903deque<_Tp, _Allocator>::front() const _NOEXCEPT
1904{
1905    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1906                                      + __base::__start_ % __base::__block_size);
1907}
1908
1909template <class _Tp, class _Allocator>
1910inline
1911typename deque<_Tp, _Allocator>::reference
1912deque<_Tp, _Allocator>::back() _NOEXCEPT
1913{
1914    size_type __p = __base::size() + __base::__start_ - 1;
1915    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1916}
1917
1918template <class _Tp, class _Allocator>
1919inline
1920typename deque<_Tp, _Allocator>::const_reference
1921deque<_Tp, _Allocator>::back() const _NOEXCEPT
1922{
1923    size_type __p = __base::size() + __base::__start_ - 1;
1924    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1925}
1926
1927template <class _Tp, class _Allocator>
1928void
1929deque<_Tp, _Allocator>::push_back(const value_type& __v)
1930{
1931    allocator_type& __a = __base::__alloc();
1932    if (__back_spare() == 0)
1933        __add_back_capacity();
1934    // __back_spare() >= 1
1935    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
1936    ++__base::size();
1937}
1938
1939template <class _Tp, class _Allocator>
1940void
1941deque<_Tp, _Allocator>::push_front(const value_type& __v)
1942{
1943    allocator_type& __a = __base::__alloc();
1944    if (__front_spare() == 0)
1945        __add_front_capacity();
1946    // __front_spare() >= 1
1947    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
1948    --__base::__start_;
1949    ++__base::size();
1950}
1951
1952#ifndef _LIBCPP_CXX03_LANG
1953template <class _Tp, class _Allocator>
1954void
1955deque<_Tp, _Allocator>::push_back(value_type&& __v)
1956{
1957    allocator_type& __a = __base::__alloc();
1958    if (__back_spare() == 0)
1959        __add_back_capacity();
1960    // __back_spare() >= 1
1961    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
1962    ++__base::size();
1963}
1964
1965template <class _Tp, class _Allocator>
1966template <class... _Args>
1967#if _LIBCPP_STD_VER > 14
1968typename deque<_Tp, _Allocator>::reference
1969#else
1970void
1971#endif
1972deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
1973{
1974    allocator_type& __a = __base::__alloc();
1975    if (__back_spare() == 0)
1976        __add_back_capacity();
1977    // __back_spare() >= 1
1978    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()),
1979                              _VSTD::forward<_Args>(__args)...);
1980    ++__base::size();
1981#if _LIBCPP_STD_VER > 14
1982    return *--__base::end();
1983#endif
1984}
1985
1986template <class _Tp, class _Allocator>
1987void
1988deque<_Tp, _Allocator>::push_front(value_type&& __v)
1989{
1990    allocator_type& __a = __base::__alloc();
1991    if (__front_spare() == 0)
1992        __add_front_capacity();
1993    // __front_spare() >= 1
1994    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
1995    --__base::__start_;
1996    ++__base::size();
1997}
1998
1999
2000template <class _Tp, class _Allocator>
2001template <class... _Args>
2002#if _LIBCPP_STD_VER > 14
2003typename deque<_Tp, _Allocator>::reference
2004#else
2005void
2006#endif
2007deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
2008{
2009    allocator_type& __a = __base::__alloc();
2010    if (__front_spare() == 0)
2011        __add_front_capacity();
2012    // __front_spare() >= 1
2013    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
2014    --__base::__start_;
2015    ++__base::size();
2016#if _LIBCPP_STD_VER > 14
2017    return *__base::begin();
2018#endif
2019}
2020
2021template <class _Tp, class _Allocator>
2022typename deque<_Tp, _Allocator>::iterator
2023deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
2024{
2025    size_type __pos = __p - __base::begin();
2026    size_type __to_end = __base::size() - __pos;
2027    allocator_type& __a = __base::__alloc();
2028    if (__pos < __to_end)
2029    {   // insert by shifting things backward
2030        if (__front_spare() == 0)
2031            __add_front_capacity();
2032        // __front_spare() >= 1
2033        if (__pos == 0)
2034        {
2035            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
2036            --__base::__start_;
2037            ++__base::size();
2038        }
2039        else
2040        {
2041            iterator __b = __base::begin();
2042            iterator __bm1 = _VSTD::prev(__b);
2043            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
2044            --__base::__start_;
2045            ++__base::size();
2046            if (__pos > 1)
2047                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
2048            *__b = _VSTD::move(__v);
2049        }
2050    }
2051    else
2052    {   // insert by shifting things forward
2053        if (__back_spare() == 0)
2054            __add_back_capacity();
2055        // __back_capacity >= 1
2056        size_type __de = __base::size() - __pos;
2057        if (__de == 0)
2058        {
2059            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
2060            ++__base::size();
2061        }
2062        else
2063        {
2064            iterator __e = __base::end();
2065            iterator __em1 = _VSTD::prev(__e);
2066            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
2067            ++__base::size();
2068            if (__de > 1)
2069                __e = _VSTD::move_backward(__e - __de, __em1, __e);
2070            *--__e = _VSTD::move(__v);
2071        }
2072    }
2073    return __base::begin() + __pos;
2074}
2075
2076template <class _Tp, class _Allocator>
2077template <class... _Args>
2078typename deque<_Tp, _Allocator>::iterator
2079deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
2080{
2081    size_type __pos = __p - __base::begin();
2082    size_type __to_end = __base::size() - __pos;
2083    allocator_type& __a = __base::__alloc();
2084    if (__pos < __to_end)
2085    {   // insert by shifting things backward
2086        if (__front_spare() == 0)
2087            __add_front_capacity();
2088        // __front_spare() >= 1
2089        if (__pos == 0)
2090        {
2091            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
2092            --__base::__start_;
2093            ++__base::size();
2094        }
2095        else
2096        {
2097            __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
2098            iterator __b = __base::begin();
2099            iterator __bm1 = _VSTD::prev(__b);
2100            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
2101            --__base::__start_;
2102            ++__base::size();
2103            if (__pos > 1)
2104                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
2105            *__b = _VSTD::move(__tmp.get());
2106        }
2107    }
2108    else
2109    {   // insert by shifting things forward
2110        if (__back_spare() == 0)
2111            __add_back_capacity();
2112        // __back_capacity >= 1
2113        size_type __de = __base::size() - __pos;
2114        if (__de == 0)
2115        {
2116            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);
2117            ++__base::size();
2118        }
2119        else
2120        {
2121            __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
2122            iterator __e = __base::end();
2123            iterator __em1 = _VSTD::prev(__e);
2124            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
2125            ++__base::size();
2126            if (__de > 1)
2127                __e = _VSTD::move_backward(__e - __de, __em1, __e);
2128            *--__e = _VSTD::move(__tmp.get());
2129        }
2130    }
2131    return __base::begin() + __pos;
2132}
2133
2134#endif // _LIBCPP_CXX03_LANG
2135
2136
2137template <class _Tp, class _Allocator>
2138typename deque<_Tp, _Allocator>::iterator
2139deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
2140{
2141    size_type __pos = __p - __base::begin();
2142    size_type __to_end = __base::size() - __pos;
2143    allocator_type& __a = __base::__alloc();
2144    if (__pos < __to_end)
2145    {   // insert by shifting things backward
2146        if (__front_spare() == 0)
2147            __add_front_capacity();
2148        // __front_spare() >= 1
2149        if (__pos == 0)
2150        {
2151            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
2152            --__base::__start_;
2153            ++__base::size();
2154        }
2155        else
2156        {
2157            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2158            iterator __b = __base::begin();
2159            iterator __bm1 = _VSTD::prev(__b);
2160            if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
2161                __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
2162            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
2163            --__base::__start_;
2164            ++__base::size();
2165            if (__pos > 1)
2166                __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);
2167            *__b = *__vt;
2168        }
2169    }
2170    else
2171    {   // insert by shifting things forward
2172        if (__back_spare() == 0)
2173            __add_back_capacity();
2174        // __back_capacity >= 1
2175        size_type __de = __base::size() - __pos;
2176        if (__de == 0)
2177        {
2178            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
2179            ++__base::size();
2180        }
2181        else
2182        {
2183            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2184            iterator __e = __base::end();
2185            iterator __em1 = _VSTD::prev(__e);
2186            if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
2187                __vt = pointer_traits<const_pointer>::pointer_to(*__e);
2188            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
2189            ++__base::size();
2190            if (__de > 1)
2191                __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
2192            *--__e = *__vt;
2193        }
2194    }
2195    return __base::begin() + __pos;
2196}
2197
2198template <class _Tp, class _Allocator>
2199typename deque<_Tp, _Allocator>::iterator
2200deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
2201{
2202    size_type __pos = __p - __base::begin();
2203    size_type __to_end = __base::size() - __pos;
2204    allocator_type& __a = __base::__alloc();
2205    if (__pos < __to_end)
2206    {   // insert by shifting things backward
2207        if (__n > __front_spare())
2208            __add_front_capacity(__n - __front_spare());
2209        // __n <= __front_spare()
2210        iterator __old_begin = __base::begin();
2211        iterator __i = __old_begin;
2212        if (__n > __pos)
2213        {
2214            for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())
2215                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);
2216            __n = __pos;
2217        }
2218        if (__n > 0)
2219        {
2220            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2221            iterator __obn = __old_begin + __n;
2222            __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
2223            if (__n < __pos)
2224                __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
2225            _VSTD::fill_n(__old_begin, __n, *__vt);
2226        }
2227    }
2228    else
2229    {   // insert by shifting things forward
2230        size_type __back_capacity = __back_spare();
2231        if (__n > __back_capacity)
2232            __add_back_capacity(__n - __back_capacity);
2233        // __n <= __back_capacity
2234        iterator __old_end = __base::end();
2235        iterator __i = __old_end;
2236        size_type __de = __base::size() - __pos;
2237        if (__n > __de)
2238        {
2239            for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size())
2240                __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
2241            __n = __de;
2242        }
2243        if (__n > 0)
2244        {
2245            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2246            iterator __oen = __old_end - __n;
2247            __move_construct_and_check(__oen, __old_end, __i, __vt);
2248            if (__n < __de)
2249                __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
2250            _VSTD::fill_n(__old_end - __n, __n, *__vt);
2251        }
2252    }
2253    return __base::begin() + __pos;
2254}
2255
2256template <class _Tp, class _Allocator>
2257template <class _InputIter>
2258typename deque<_Tp, _Allocator>::iterator
2259deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
2260                               typename enable_if<__is_cpp17_input_iterator<_InputIter>::value
2261                                               &&!__is_cpp17_forward_iterator<_InputIter>::value>::type*)
2262{
2263    __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
2264    __buf.__construct_at_end(__f, __l);
2265    typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
2266    return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
2267}
2268
2269template <class _Tp, class _Allocator>
2270template <class _ForwardIterator>
2271typename deque<_Tp, _Allocator>::iterator
2272deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
2273                               typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value
2274                                               &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type*)
2275{
2276    size_type __n = _VSTD::distance(__f, __l);
2277    __split_buffer<value_type, allocator_type&> __buf(__n, 0, __base::__alloc());
2278    __buf.__construct_at_end(__f, __l);
2279    typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
2280    return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
2281}
2282
2283template <class _Tp, class _Allocator>
2284template <class _BiIter>
2285typename deque<_Tp, _Allocator>::iterator
2286deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
2287                               typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type*)
2288{
2289    size_type __n = _VSTD::distance(__f, __l);
2290    size_type __pos = __p - __base::begin();
2291    size_type __to_end = __base::size() - __pos;
2292    allocator_type& __a = __base::__alloc();
2293    if (__pos < __to_end)
2294    {   // insert by shifting things backward
2295        if (__n > __front_spare())
2296            __add_front_capacity(__n - __front_spare());
2297        // __n <= __front_spare()
2298        iterator __old_begin = __base::begin();
2299        iterator __i = __old_begin;
2300        _BiIter __m = __f;
2301        if (__n > __pos)
2302        {
2303            __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);
2304            for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())
2305                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);
2306            __n = __pos;
2307        }
2308        if (__n > 0)
2309        {
2310            iterator __obn = __old_begin + __n;
2311            for (iterator __j = __obn; __j != __old_begin;)
2312            {
2313                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));
2314                --__base::__start_;
2315                ++__base::size();
2316            }
2317            if (__n < __pos)
2318                __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);
2319            _VSTD::copy(__m, __l, __old_begin);
2320        }
2321    }
2322    else
2323    {   // insert by shifting things forward
2324        size_type __back_capacity = __back_spare();
2325        if (__n > __back_capacity)
2326            __add_back_capacity(__n - __back_capacity);
2327        // __n <= __back_capacity
2328        iterator __old_end = __base::end();
2329        iterator __i = __old_end;
2330        _BiIter __m = __l;
2331        size_type __de = __base::size() - __pos;
2332        if (__n > __de)
2333        {
2334            __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
2335            for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__base::size())
2336                __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
2337            __n = __de;
2338        }
2339        if (__n > 0)
2340        {
2341            iterator __oen = __old_end - __n;
2342            for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size())
2343                __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));
2344            if (__n < __de)
2345                __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);
2346            _VSTD::copy_backward(__f, __m, __old_end);
2347        }
2348    }
2349    return __base::begin() + __pos;
2350}
2351
2352template <class _Tp, class _Allocator>
2353template <class _InpIter>
2354void
2355deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
2356                                 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value &&
2357                                                   !__is_cpp17_forward_iterator<_InpIter>::value>::type*)
2358{
2359    for (; __f != __l; ++__f)
2360#ifdef _LIBCPP_CXX03_LANG
2361        push_back(*__f);
2362#else
2363        emplace_back(*__f);
2364#endif
2365}
2366
2367template <class _Tp, class _Allocator>
2368template <class _ForIter>
2369void
2370deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
2371                                 typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type*)
2372{
2373    size_type __n = _VSTD::distance(__f, __l);
2374    allocator_type& __a = __base::__alloc();
2375    size_type __back_capacity = __back_spare();
2376    if (__n > __back_capacity)
2377        __add_back_capacity(__n - __back_capacity);
2378    // __n <= __back_capacity
2379    for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
2380      _ConstructTransaction __tx(this, __br);
2381      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {
2382        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f);
2383      }
2384    }
2385}
2386
2387template <class _Tp, class _Allocator>
2388void
2389deque<_Tp, _Allocator>::__append(size_type __n)
2390{
2391    allocator_type& __a = __base::__alloc();
2392    size_type __back_capacity = __back_spare();
2393    if (__n > __back_capacity)
2394        __add_back_capacity(__n - __back_capacity);
2395    // __n <= __back_capacity
2396    for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
2397      _ConstructTransaction __tx(this, __br);
2398      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
2399        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_));
2400      }
2401    }
2402}
2403
2404template <class _Tp, class _Allocator>
2405void
2406deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
2407{
2408    allocator_type& __a = __base::__alloc();
2409    size_type __back_capacity = __back_spare();
2410    if (__n > __back_capacity)
2411        __add_back_capacity(__n - __back_capacity);
2412    // __n <= __back_capacity
2413    for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
2414      _ConstructTransaction __tx(this, __br);
2415      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
2416        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v);
2417      }
2418    }
2419
2420}
2421
2422// Create front capacity for one block of elements.
2423// Strong guarantee.  Either do it or don't touch anything.
2424template <class _Tp, class _Allocator>
2425void
2426deque<_Tp, _Allocator>::__add_front_capacity()
2427{
2428    allocator_type& __a = __base::__alloc();
2429    if (__back_spare() >= __base::__block_size)
2430    {
2431        __base::__start_ += __base::__block_size;
2432        pointer __pt = __base::__map_.back();
2433        __base::__map_.pop_back();
2434        __base::__map_.push_front(__pt);
2435    }
2436    // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer
2437    else if (__base::__map_.size() < __base::__map_.capacity())
2438    {   // we can put the new buffer into the map, but don't shift things around
2439        // until all buffers are allocated.  If we throw, we don't need to fix
2440        // anything up (any added buffers are undetectible)
2441        if (__base::__map_.__front_spare() > 0)
2442            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2443        else
2444        {
2445            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2446            // Done allocating, reorder capacity
2447            pointer __pt = __base::__map_.back();
2448            __base::__map_.pop_back();
2449            __base::__map_.push_front(__pt);
2450        }
2451        __base::__start_ = __base::__map_.size() == 1 ?
2452                               __base::__block_size / 2 :
2453                               __base::__start_ + __base::__block_size;
2454    }
2455    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2456    else
2457    {
2458        __split_buffer<pointer, typename __base::__pointer_allocator&>
2459            __buf(max<size_type>(2 * __base::__map_.capacity(), 1),
2460                  0, __base::__map_.__alloc());
2461
2462        typedef __allocator_destructor<_Allocator> _Dp;
2463        unique_ptr<pointer, _Dp> __hold(
2464            __alloc_traits::allocate(__a, __base::__block_size),
2465                _Dp(__a, __base::__block_size));
2466        __buf.push_back(__hold.get());
2467        __hold.release();
2468
2469        for (typename __base::__map_pointer __i = __base::__map_.begin();
2470                __i != __base::__map_.end(); ++__i)
2471            __buf.push_back(*__i);
2472        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2473        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2474        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2475        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2476        __base::__start_ = __base::__map_.size() == 1 ?
2477                               __base::__block_size / 2 :
2478                               __base::__start_ + __base::__block_size;
2479    }
2480}
2481
2482// Create front capacity for __n elements.
2483// Strong guarantee.  Either do it or don't touch anything.
2484template <class _Tp, class _Allocator>
2485void
2486deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
2487{
2488    allocator_type& __a = __base::__alloc();
2489    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2490    // Number of unused blocks at back:
2491    size_type __back_capacity = __back_spare() / __base::__block_size;
2492    __back_capacity = _VSTD::min(__back_capacity, __nb);  // don't take more than you need
2493    __nb -= __back_capacity;  // number of blocks need to allocate
2494    // If __nb == 0, then we have sufficient capacity.
2495    if (__nb == 0)
2496    {
2497        __base::__start_ += __base::__block_size * __back_capacity;
2498        for (; __back_capacity > 0; --__back_capacity)
2499        {
2500            pointer __pt = __base::__map_.back();
2501            __base::__map_.pop_back();
2502            __base::__map_.push_front(__pt);
2503        }
2504    }
2505    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2506    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2507    {   // we can put the new buffers into the map, but don't shift things around
2508        // until all buffers are allocated.  If we throw, we don't need to fix
2509        // anything up (any added buffers are undetectible)
2510        for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))
2511        {
2512            if (__base::__map_.__front_spare() == 0)
2513                break;
2514            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2515        }
2516        for (; __nb > 0; --__nb, ++__back_capacity)
2517            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2518        // Done allocating, reorder capacity
2519        __base::__start_ += __back_capacity * __base::__block_size;
2520        for (; __back_capacity > 0; --__back_capacity)
2521        {
2522            pointer __pt = __base::__map_.back();
2523            __base::__map_.pop_back();
2524            __base::__map_.push_front(__pt);
2525        }
2526    }
2527    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2528    else
2529    {
2530        size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();
2531        __split_buffer<pointer, typename __base::__pointer_allocator&>
2532            __buf(max<size_type>(2* __base::__map_.capacity(),
2533                                 __nb + __base::__map_.size()),
2534                  0, __base::__map_.__alloc());
2535#ifndef _LIBCPP_NO_EXCEPTIONS
2536        try
2537        {
2538#endif // _LIBCPP_NO_EXCEPTIONS
2539            for (; __nb > 0; --__nb)
2540                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2541#ifndef _LIBCPP_NO_EXCEPTIONS
2542        }
2543        catch (...)
2544        {
2545            for (typename __base::__map_pointer __i = __buf.begin();
2546                    __i != __buf.end(); ++__i)
2547                __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2548            throw;
2549        }
2550#endif // _LIBCPP_NO_EXCEPTIONS
2551        for (; __back_capacity > 0; --__back_capacity)
2552        {
2553            __buf.push_back(__base::__map_.back());
2554            __base::__map_.pop_back();
2555        }
2556        for (typename __base::__map_pointer __i = __base::__map_.begin();
2557                __i != __base::__map_.end(); ++__i)
2558            __buf.push_back(*__i);
2559        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2560        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2561        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2562        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2563        __base::__start_ += __ds;
2564    }
2565}
2566
2567// Create back capacity for one block of elements.
2568// Strong guarantee.  Either do it or don't touch anything.
2569template <class _Tp, class _Allocator>
2570void
2571deque<_Tp, _Allocator>::__add_back_capacity()
2572{
2573    allocator_type& __a = __base::__alloc();
2574    if (__front_spare() >= __base::__block_size)
2575    {
2576        __base::__start_ -= __base::__block_size;
2577        pointer __pt = __base::__map_.front();
2578        __base::__map_.pop_front();
2579        __base::__map_.push_back(__pt);
2580    }
2581    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2582    else if (__base::__map_.size() < __base::__map_.capacity())
2583    {   // we can put the new buffer into the map, but don't shift things around
2584        // until it is allocated.  If we throw, we don't need to fix
2585        // anything up (any added buffers are undetectible)
2586        if (__base::__map_.__back_spare() != 0)
2587            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2588        else
2589        {
2590            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2591            // Done allocating, reorder capacity
2592            pointer __pt = __base::__map_.front();
2593            __base::__map_.pop_front();
2594            __base::__map_.push_back(__pt);
2595        }
2596    }
2597    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2598    else
2599    {
2600        __split_buffer<pointer, typename __base::__pointer_allocator&>
2601            __buf(max<size_type>(2* __base::__map_.capacity(), 1),
2602                  __base::__map_.size(),
2603                  __base::__map_.__alloc());
2604
2605        typedef __allocator_destructor<_Allocator> _Dp;
2606        unique_ptr<pointer, _Dp> __hold(
2607            __alloc_traits::allocate(__a, __base::__block_size),
2608                _Dp(__a, __base::__block_size));
2609        __buf.push_back(__hold.get());
2610        __hold.release();
2611
2612        for (typename __base::__map_pointer __i = __base::__map_.end();
2613                __i != __base::__map_.begin();)
2614            __buf.push_front(*--__i);
2615        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2616        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2617        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2618        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2619    }
2620}
2621
2622// Create back capacity for __n elements.
2623// Strong guarantee.  Either do it or don't touch anything.
2624template <class _Tp, class _Allocator>
2625void
2626deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
2627{
2628    allocator_type& __a = __base::__alloc();
2629    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2630    // Number of unused blocks at front:
2631    size_type __front_capacity = __front_spare() / __base::__block_size;
2632    __front_capacity = _VSTD::min(__front_capacity, __nb);  // don't take more than you need
2633    __nb -= __front_capacity;  // number of blocks need to allocate
2634    // If __nb == 0, then we have sufficient capacity.
2635    if (__nb == 0)
2636    {
2637        __base::__start_ -= __base::__block_size * __front_capacity;
2638        for (; __front_capacity > 0; --__front_capacity)
2639        {
2640            pointer __pt = __base::__map_.front();
2641            __base::__map_.pop_front();
2642            __base::__map_.push_back(__pt);
2643        }
2644    }
2645    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2646    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2647    {   // we can put the new buffers into the map, but don't shift things around
2648        // until all buffers are allocated.  If we throw, we don't need to fix
2649        // anything up (any added buffers are undetectible)
2650        for (; __nb > 0; --__nb)
2651        {
2652            if (__base::__map_.__back_spare() == 0)
2653                break;
2654            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2655        }
2656        for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=
2657                                 __base::__block_size - (__base::__map_.size() == 1))
2658            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2659        // Done allocating, reorder capacity
2660        __base::__start_ -= __base::__block_size * __front_capacity;
2661        for (; __front_capacity > 0; --__front_capacity)
2662        {
2663            pointer __pt = __base::__map_.front();
2664            __base::__map_.pop_front();
2665            __base::__map_.push_back(__pt);
2666        }
2667    }
2668    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2669    else
2670    {
2671        size_type __ds = __front_capacity * __base::__block_size;
2672        __split_buffer<pointer, typename __base::__pointer_allocator&>
2673            __buf(max<size_type>(2* __base::__map_.capacity(),
2674                                 __nb + __base::__map_.size()),
2675                  __base::__map_.size() - __front_capacity,
2676                  __base::__map_.__alloc());
2677#ifndef _LIBCPP_NO_EXCEPTIONS
2678        try
2679        {
2680#endif // _LIBCPP_NO_EXCEPTIONS
2681            for (; __nb > 0; --__nb)
2682                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2683#ifndef _LIBCPP_NO_EXCEPTIONS
2684        }
2685        catch (...)
2686        {
2687            for (typename __base::__map_pointer __i = __buf.begin();
2688                    __i != __buf.end(); ++__i)
2689                __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2690            throw;
2691        }
2692#endif // _LIBCPP_NO_EXCEPTIONS
2693        for (; __front_capacity > 0; --__front_capacity)
2694        {
2695            __buf.push_back(__base::__map_.front());
2696            __base::__map_.pop_front();
2697        }
2698        for (typename __base::__map_pointer __i = __base::__map_.end();
2699                __i != __base::__map_.begin();)
2700            __buf.push_front(*--__i);
2701        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2702        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2703        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2704        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2705        __base::__start_ -= __ds;
2706    }
2707}
2708
2709template <class _Tp, class _Allocator>
2710void
2711deque<_Tp, _Allocator>::pop_front()
2712{
2713    allocator_type& __a = __base::__alloc();
2714    __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() +
2715                                                    __base::__start_ / __base::__block_size) +
2716                                                    __base::__start_ % __base::__block_size));
2717    --__base::size();
2718    ++__base::__start_;
2719    __maybe_remove_front_spare();
2720}
2721
2722template <class _Tp, class _Allocator>
2723void
2724deque<_Tp, _Allocator>::pop_back()
2725{
2726    _LIBCPP_ASSERT(!empty(), "deque::pop_back called on an empty deque");
2727    allocator_type& __a = __base::__alloc();
2728    size_type __p = __base::size() + __base::__start_ - 1;
2729    __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() +
2730                                                    __p / __base::__block_size) +
2731                                                    __p % __base::__block_size));
2732    --__base::size();
2733    __maybe_remove_back_spare();
2734}
2735
2736// move assign [__f, __l) to [__r, __r + (__l-__f)).
2737// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
2738template <class _Tp, class _Allocator>
2739typename deque<_Tp, _Allocator>::iterator
2740deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
2741                                         const_pointer& __vt)
2742{
2743    // as if
2744    //   for (; __f != __l; ++__f, ++__r)
2745    //       *__r = _VSTD::move(*__f);
2746    difference_type __n = __l - __f;
2747    while (__n > 0)
2748    {
2749        pointer __fb = __f.__ptr_;
2750        pointer __fe = *__f.__m_iter_ + __base::__block_size;
2751        difference_type __bs = __fe - __fb;
2752        if (__bs > __n)
2753        {
2754            __bs = __n;
2755            __fe = __fb + __bs;
2756        }
2757        if (__fb <= __vt && __vt < __fe)
2758            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
2759        __r = _VSTD::move(__fb, __fe, __r);
2760        __n -= __bs;
2761        __f += __bs;
2762    }
2763    return __r;
2764}
2765
2766// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
2767// If __vt points into [__f, __l), then add (__r - __l) to __vt.
2768template <class _Tp, class _Allocator>
2769typename deque<_Tp, _Allocator>::iterator
2770deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
2771                                                  const_pointer& __vt)
2772{
2773    // as if
2774    //   while (__f != __l)
2775    //       *--__r = _VSTD::move(*--__l);
2776    difference_type __n = __l - __f;
2777    while (__n > 0)
2778    {
2779        --__l;
2780        pointer __lb = *__l.__m_iter_;
2781        pointer __le = __l.__ptr_ + 1;
2782        difference_type __bs = __le - __lb;
2783        if (__bs > __n)
2784        {
2785            __bs = __n;
2786            __lb = __le - __bs;
2787        }
2788        if (__lb <= __vt && __vt < __le)
2789            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
2790        __r = _VSTD::move_backward(__lb, __le, __r);
2791        __n -= __bs;
2792        __l -= __bs - 1;
2793    }
2794    return __r;
2795}
2796
2797// move construct [__f, __l) to [__r, __r + (__l-__f)).
2798// If __vt points into [__f, __l), then add (__r - __f) to __vt.
2799template <class _Tp, class _Allocator>
2800void
2801deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
2802                                                   iterator __r, const_pointer& __vt)
2803{
2804    allocator_type& __a = __base::__alloc();
2805    // as if
2806    //   for (; __f != __l; ++__r, ++__f, ++__base::size())
2807    //       __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));
2808    difference_type __n = __l - __f;
2809    while (__n > 0)
2810    {
2811        pointer __fb = __f.__ptr_;
2812        pointer __fe = *__f.__m_iter_ + __base::__block_size;
2813        difference_type __bs = __fe - __fb;
2814        if (__bs > __n)
2815        {
2816            __bs = __n;
2817            __fe = __fb + __bs;
2818        }
2819        if (__fb <= __vt && __vt < __fe)
2820            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
2821        for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
2822            __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
2823        __n -= __bs;
2824        __f += __bs;
2825    }
2826}
2827
2828// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
2829// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
2830template <class _Tp, class _Allocator>
2831void
2832deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
2833                                                            iterator __r, const_pointer& __vt)
2834{
2835    allocator_type& __a = __base::__alloc();
2836    // as if
2837    //   for (iterator __j = __l; __j != __f;)
2838    //   {
2839    //       __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));
2840    //       --__base::__start_;
2841    //       ++__base::size();
2842    //   }
2843    difference_type __n = __l - __f;
2844    while (__n > 0)
2845    {
2846        --__l;
2847        pointer __lb = *__l.__m_iter_;
2848        pointer __le = __l.__ptr_ + 1;
2849        difference_type __bs = __le - __lb;
2850        if (__bs > __n)
2851        {
2852            __bs = __n;
2853            __lb = __le - __bs;
2854        }
2855        if (__lb <= __vt && __vt < __le)
2856            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
2857        while (__le != __lb)
2858        {
2859            __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
2860            --__base::__start_;
2861            ++__base::size();
2862        }
2863        __n -= __bs;
2864        __l -= __bs - 1;
2865    }
2866}
2867
2868template <class _Tp, class _Allocator>
2869typename deque<_Tp, _Allocator>::iterator
2870deque<_Tp, _Allocator>::erase(const_iterator __f)
2871{
2872    iterator __b = __base::begin();
2873    difference_type __pos = __f - __b;
2874    iterator __p = __b + __pos;
2875    allocator_type& __a = __base::__alloc();
2876    if (static_cast<size_t>(__pos) <= (__base::size() - 1) / 2)
2877    {   // erase from front
2878        _VSTD::move_backward(__b, __p, _VSTD::next(__p));
2879        __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
2880        --__base::size();
2881        ++__base::__start_;
2882        __maybe_remove_front_spare();
2883    }
2884    else
2885    {   // erase from back
2886        iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p);
2887        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2888        --__base::size();
2889        __maybe_remove_back_spare();
2890    }
2891    return __base::begin() + __pos;
2892}
2893
2894template <class _Tp, class _Allocator>
2895typename deque<_Tp, _Allocator>::iterator
2896deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
2897{
2898    difference_type __n = __l - __f;
2899    iterator __b = __base::begin();
2900    difference_type __pos = __f - __b;
2901    iterator __p = __b + __pos;
2902    if (__n > 0)
2903    {
2904        allocator_type& __a = __base::__alloc();
2905        if (static_cast<size_t>(__pos) <= (__base::size() - __n) / 2)
2906        {   // erase from front
2907            iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
2908            for (; __b != __i; ++__b)
2909                __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
2910            __base::size() -= __n;
2911            __base::__start_ += __n;
2912            while (__maybe_remove_front_spare()) {
2913            }
2914        }
2915        else
2916        {   // erase from back
2917            iterator __i = _VSTD::move(__p + __n, __base::end(), __p);
2918            for (iterator __e = __base::end(); __i != __e; ++__i)
2919                __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2920            __base::size() -= __n;
2921            while (__maybe_remove_back_spare()) {
2922            }
2923        }
2924    }
2925    return __base::begin() + __pos;
2926}
2927
2928template <class _Tp, class _Allocator>
2929void
2930deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
2931{
2932    iterator __e = __base::end();
2933    difference_type __n = __e - __f;
2934    if (__n > 0)
2935    {
2936        allocator_type& __a = __base::__alloc();
2937        iterator __b = __base::begin();
2938        difference_type __pos = __f - __b;
2939        for (iterator __p = __b + __pos; __p != __e; ++__p)
2940            __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
2941        __base::size() -= __n;
2942        while (__maybe_remove_back_spare()) {
2943        }
2944    }
2945}
2946
2947template <class _Tp, class _Allocator>
2948inline
2949void
2950deque<_Tp, _Allocator>::swap(deque& __c)
2951#if _LIBCPP_STD_VER >= 14
2952        _NOEXCEPT
2953#else
2954        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
2955                    __is_nothrow_swappable<allocator_type>::value)
2956#endif
2957{
2958    __base::swap(__c);
2959}
2960
2961template <class _Tp, class _Allocator>
2962inline
2963void
2964deque<_Tp, _Allocator>::clear() _NOEXCEPT
2965{
2966    __base::clear();
2967}
2968
2969template <class _Tp, class _Allocator>
2970inline _LIBCPP_INLINE_VISIBILITY
2971bool
2972operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2973{
2974    const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
2975    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
2976}
2977
2978template <class _Tp, class _Allocator>
2979inline _LIBCPP_INLINE_VISIBILITY
2980bool
2981operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2982{
2983    return !(__x == __y);
2984}
2985
2986template <class _Tp, class _Allocator>
2987inline _LIBCPP_INLINE_VISIBILITY
2988bool
2989operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2990{
2991    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
2992}
2993
2994template <class _Tp, class _Allocator>
2995inline _LIBCPP_INLINE_VISIBILITY
2996bool
2997operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2998{
2999    return __y < __x;
3000}
3001
3002template <class _Tp, class _Allocator>
3003inline _LIBCPP_INLINE_VISIBILITY
3004bool
3005operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
3006{
3007    return !(__x < __y);
3008}
3009
3010template <class _Tp, class _Allocator>
3011inline _LIBCPP_INLINE_VISIBILITY
3012bool
3013operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
3014{
3015    return !(__y < __x);
3016}
3017
3018template <class _Tp, class _Allocator>
3019inline _LIBCPP_INLINE_VISIBILITY
3020void
3021swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
3022    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
3023{
3024    __x.swap(__y);
3025}
3026
3027#if _LIBCPP_STD_VER > 17
3028template <class _Tp, class _Allocator, class _Up>
3029inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
3030erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
3031  auto __old_size = __c.size();
3032  __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end());
3033  return __old_size - __c.size();
3034}
3035
3036template <class _Tp, class _Allocator, class _Predicate>
3037inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
3038erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
3039  auto __old_size = __c.size();
3040  __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
3041  return __old_size - __c.size();
3042}
3043#endif
3044
3045
3046_LIBCPP_END_NAMESPACE_STD
3047
3048_LIBCPP_POP_MACROS
3049
3050#endif // _LIBCPP_DEQUE
3051