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