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