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