xref: /llvm-project-15.0.7/libcxx/include/deque (revision 4e0ea2cf)
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 <class _Tp, class _Allocator>
912class __deque_base
913{
914    __deque_base(const __deque_base& __c);
915    __deque_base& operator=(const __deque_base& __c);
916public:
917    typedef _Allocator                               allocator_type;
918    typedef allocator_traits<allocator_type>         __alloc_traits;
919    typedef typename __alloc_traits::size_type       size_type;
920
921    typedef _Tp                                      value_type;
922    typedef value_type&                              reference;
923    typedef const value_type&                        const_reference;
924    typedef typename __alloc_traits::difference_type difference_type;
925    typedef typename __alloc_traits::pointer         pointer;
926    typedef typename __alloc_traits::const_pointer   const_pointer;
927
928    static const difference_type __block_size;
929
930    typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;
931    typedef allocator_traits<__pointer_allocator>        __map_traits;
932    typedef typename __map_traits::pointer               __map_pointer;
933    typedef typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type __const_pointer_allocator;
934    typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;
935    typedef __split_buffer<pointer, __pointer_allocator> __map;
936
937    typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
938                             difference_type>    iterator;
939    typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
940                             difference_type>    const_iterator;
941
942    struct __deque_block_range {
943      explicit __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {}
944      const pointer __begin_;
945      const pointer __end_;
946    };
947
948    struct __deque_range {
949      iterator __pos_;
950      const iterator __end_;
951
952      __deque_range(iterator __pos, iterator __e) _NOEXCEPT
953        : __pos_(__pos), __end_(__e) {}
954
955      explicit operator bool() const _NOEXCEPT {
956        return __pos_ != __end_;
957      }
958
959      __deque_range begin() const {
960        return *this;
961      }
962
963      __deque_range end() const {
964        return __deque_range(__end_, __end_);
965      }
966      __deque_block_range operator*() const _NOEXCEPT {
967         if (__pos_.__m_iter_ == __end_.__m_iter_) {
968          return __deque_block_range(__pos_.__ptr_, __end_.__ptr_);
969        }
970        return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size);
971      }
972
973      __deque_range& operator++() _NOEXCEPT {
974        if (__pos_.__m_iter_ == __end_.__m_iter_) {
975          __pos_ = __end_;
976        } else {
977          ++__pos_.__m_iter_;
978          __pos_.__ptr_ = *__pos_.__m_iter_;
979        }
980        return *this;
981      }
982
983
984      friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) {
985        return __lhs.__pos_ == __rhs.__pos_;
986      }
987      friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) {
988        return !(__lhs == __rhs);
989      }
990    };
991
992
993
994    struct _ConstructTransaction {
995      _ConstructTransaction(__deque_base* __db, __deque_block_range& __r)
996        : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {}
997
998
999      ~_ConstructTransaction() {
1000        __base_->size() += (__pos_ - __begin_);
1001      }
1002
1003      pointer __pos_;
1004      const pointer __end_;
1005    private:
1006      const pointer __begin_;
1007      __deque_base * const __base_;
1008    };
1009
1010protected:
1011    __map __map_;
1012    size_type __start_;
1013    __compressed_pair<size_type, allocator_type> __size_;
1014
1015    iterator       begin() _NOEXCEPT;
1016    const_iterator begin() const _NOEXCEPT;
1017    iterator       end() _NOEXCEPT;
1018    const_iterator end() const _NOEXCEPT;
1019
1020    _LIBCPP_INLINE_VISIBILITY size_type&            size()          {return __size_.first();}
1021    _LIBCPP_INLINE_VISIBILITY
1022    const size_type& size() const _NOEXCEPT {return __size_.first();}
1023    _LIBCPP_INLINE_VISIBILITY allocator_type&       __alloc()       {return __size_.second();}
1024    _LIBCPP_INLINE_VISIBILITY
1025    const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
1026
1027    _LIBCPP_INLINE_VISIBILITY
1028    __deque_base()
1029        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
1030    _LIBCPP_INLINE_VISIBILITY
1031    explicit __deque_base(const allocator_type& __a);
1032public:
1033    ~__deque_base();
1034
1035#ifndef _LIBCPP_CXX03_LANG
1036    __deque_base(__deque_base&& __c)
1037        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
1038    __deque_base(__deque_base&& __c, const allocator_type& __a);
1039#endif // _LIBCPP_CXX03_LANG
1040
1041    void swap(__deque_base& __c)
1042#if _LIBCPP_STD_VER >= 14
1043        _NOEXCEPT;
1044#else
1045        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1046                    __is_nothrow_swappable<allocator_type>::value);
1047#endif
1048protected:
1049    void clear() _NOEXCEPT;
1050
1051    bool __invariants() const;
1052
1053    _LIBCPP_INLINE_VISIBILITY
1054    void __move_assign(__deque_base& __c)
1055        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1056                   is_nothrow_move_assignable<allocator_type>::value)
1057    {
1058        __map_ = _VSTD::move(__c.__map_);
1059        __start_ = __c.__start_;
1060        size() = __c.size();
1061        __move_assign_alloc(__c);
1062        __c.__start_ = __c.size() = 0;
1063    }
1064
1065    _LIBCPP_INLINE_VISIBILITY
1066    void __move_assign_alloc(__deque_base& __c)
1067        _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
1068                   is_nothrow_move_assignable<allocator_type>::value)
1069        {__move_assign_alloc(__c, integral_constant<bool,
1070                      __alloc_traits::propagate_on_container_move_assignment::value>());}
1071
1072private:
1073    _LIBCPP_INLINE_VISIBILITY
1074    void __move_assign_alloc(__deque_base& __c, true_type)
1075        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1076        {
1077            __alloc() = _VSTD::move(__c.__alloc());
1078        }
1079
1080    _LIBCPP_INLINE_VISIBILITY
1081    void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT
1082        {}
1083};
1084
1085template <class _Tp, class _Allocator>
1086const typename __deque_base<_Tp, _Allocator>::difference_type
1087    __deque_base<_Tp, _Allocator>::__block_size =
1088        __deque_block_size<value_type, difference_type>::value;
1089
1090template <class _Tp, class _Allocator>
1091bool
1092__deque_base<_Tp, _Allocator>::__invariants() const
1093{
1094    if (!__map_.__invariants())
1095        return false;
1096    if (__map_.size() >= size_type(-1) / __block_size)
1097        return false;
1098    for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
1099         __i != __e; ++__i)
1100        if (*__i == nullptr)
1101            return false;
1102    if (__map_.size() != 0)
1103    {
1104        if (size() >= __map_.size() * __block_size)
1105            return false;
1106        if (__start_ >= __map_.size() * __block_size - size())
1107            return false;
1108    }
1109    else
1110    {
1111        if (size() != 0)
1112            return false;
1113        if (__start_ != 0)
1114            return false;
1115    }
1116    return true;
1117}
1118
1119template <class _Tp, class _Allocator>
1120typename __deque_base<_Tp, _Allocator>::iterator
1121__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT
1122{
1123    __map_pointer __mp = __map_.begin() + __start_ / __block_size;
1124    return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1125}
1126
1127template <class _Tp, class _Allocator>
1128typename __deque_base<_Tp, _Allocator>::const_iterator
1129__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
1130{
1131    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
1132    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1133}
1134
1135template <class _Tp, class _Allocator>
1136typename __deque_base<_Tp, _Allocator>::iterator
1137__deque_base<_Tp, _Allocator>::end() _NOEXCEPT
1138{
1139    size_type __p = size() + __start_;
1140    __map_pointer __mp = __map_.begin() + __p / __block_size;
1141    return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1142}
1143
1144template <class _Tp, class _Allocator>
1145typename __deque_base<_Tp, _Allocator>::const_iterator
1146__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
1147{
1148    size_type __p = size() + __start_;
1149    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
1150    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1151}
1152
1153template <class _Tp, class _Allocator>
1154inline
1155__deque_base<_Tp, _Allocator>::__deque_base()
1156    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
1157    : __start_(0), __size_(0, __default_init_tag()) {}
1158
1159template <class _Tp, class _Allocator>
1160inline
1161__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
1162    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
1163
1164template <class _Tp, class _Allocator>
1165__deque_base<_Tp, _Allocator>::~__deque_base()
1166{
1167    clear();
1168    typename __map::iterator __i = __map_.begin();
1169    typename __map::iterator __e = __map_.end();
1170    for (; __i != __e; ++__i)
1171        __alloc_traits::deallocate(__alloc(), *__i, __block_size);
1172}
1173
1174#ifndef _LIBCPP_CXX03_LANG
1175
1176template <class _Tp, class _Allocator>
1177__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)
1178    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
1179    : __map_(_VSTD::move(__c.__map_)),
1180      __start_(_VSTD::move(__c.__start_)),
1181      __size_(_VSTD::move(__c.__size_))
1182{
1183    __c.__start_ = 0;
1184    __c.size() = 0;
1185}
1186
1187template <class _Tp, class _Allocator>
1188__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)
1189    : __map_(_VSTD::move(__c.__map_), __pointer_allocator(__a)),
1190      __start_(_VSTD::move(__c.__start_)),
1191      __size_(_VSTD::move(__c.size()), __a)
1192{
1193    if (__a == __c.__alloc())
1194    {
1195        __c.__start_ = 0;
1196        __c.size() = 0;
1197    }
1198    else
1199    {
1200        __map_.clear();
1201        __start_ = 0;
1202        size() = 0;
1203    }
1204}
1205
1206#endif // _LIBCPP_CXX03_LANG
1207
1208template <class _Tp, class _Allocator>
1209void
1210__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
1211#if _LIBCPP_STD_VER >= 14
1212        _NOEXCEPT
1213#else
1214        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1215                    __is_nothrow_swappable<allocator_type>::value)
1216#endif
1217{
1218    __map_.swap(__c.__map_);
1219    _VSTD::swap(__start_, __c.__start_);
1220    _VSTD::swap(size(), __c.size());
1221    _VSTD::__swap_allocator(__alloc(), __c.__alloc());
1222}
1223
1224template <class _Tp, class _Allocator>
1225void
1226__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
1227{
1228    allocator_type& __a = __alloc();
1229    for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
1230        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
1231    size() = 0;
1232    while (__map_.size() > 2)
1233    {
1234        __alloc_traits::deallocate(__a, __map_.front(), __block_size);
1235        __map_.pop_front();
1236    }
1237    switch (__map_.size())
1238    {
1239    case 1:
1240        __start_ = __block_size / 2;
1241        break;
1242    case 2:
1243        __start_ = __block_size;
1244        break;
1245    }
1246}
1247
1248template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
1249class _LIBCPP_TEMPLATE_VIS deque
1250    : private __deque_base<_Tp, _Allocator>
1251{
1252public:
1253    // types:
1254
1255    typedef _Tp value_type;
1256    typedef _Allocator allocator_type;
1257
1258    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
1259                  "Allocator::value_type must be same type as value_type");
1260
1261    typedef __deque_base<value_type, allocator_type> __base;
1262
1263    typedef typename __base::__alloc_traits        __alloc_traits;
1264    typedef typename __base::reference             reference;
1265    typedef typename __base::const_reference       const_reference;
1266    typedef typename __base::iterator              iterator;
1267    typedef typename __base::const_iterator        const_iterator;
1268    typedef typename __base::size_type             size_type;
1269    typedef typename __base::difference_type       difference_type;
1270
1271    typedef typename __base::pointer               pointer;
1272    typedef typename __base::const_pointer         const_pointer;
1273    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
1274    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
1275
1276    using typename __base::__deque_range;
1277    using typename __base::__deque_block_range;
1278    using typename __base::_ConstructTransaction;
1279
1280    // construct/copy/destroy:
1281    _LIBCPP_INLINE_VISIBILITY
1282    deque()
1283        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
1284        {}
1285    _LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}
1286    explicit deque(size_type __n);
1287#if _LIBCPP_STD_VER > 11
1288    explicit deque(size_type __n, const _Allocator& __a);
1289#endif
1290    deque(size_type __n, const value_type& __v);
1291    deque(size_type __n, const value_type& __v, const allocator_type& __a);
1292    template <class _InputIter>
1293        deque(_InputIter __f, _InputIter __l,
1294              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
1295    template <class _InputIter>
1296        deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1297              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
1298    deque(const deque& __c);
1299    deque(const deque& __c, const __identity_t<allocator_type>& __a);
1300
1301    deque& operator=(const deque& __c);
1302
1303#ifndef _LIBCPP_CXX03_LANG
1304    deque(initializer_list<value_type> __il);
1305    deque(initializer_list<value_type> __il, const allocator_type& __a);
1306
1307    _LIBCPP_INLINE_VISIBILITY
1308    deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
1309
1310    _LIBCPP_INLINE_VISIBILITY
1311    deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
1312    _LIBCPP_INLINE_VISIBILITY
1313    deque(deque&& __c, const __identity_t<allocator_type>& __a);
1314    _LIBCPP_INLINE_VISIBILITY
1315    deque& operator=(deque&& __c)
1316        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1317                   is_nothrow_move_assignable<allocator_type>::value);
1318
1319    _LIBCPP_INLINE_VISIBILITY
1320    void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
1321#endif // _LIBCPP_CXX03_LANG
1322
1323    template <class _InputIter>
1324        void assign(_InputIter __f, _InputIter __l,
1325                    typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
1326                                      !__is_cpp17_random_access_iterator<_InputIter>::value>::type* = 0);
1327    template <class _RAIter>
1328        void assign(_RAIter __f, _RAIter __l,
1329                    typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
1330    void assign(size_type __n, const value_type& __v);
1331
1332    _LIBCPP_INLINE_VISIBILITY
1333    allocator_type get_allocator() const _NOEXCEPT;
1334
1335    // iterators:
1336
1337    _LIBCPP_INLINE_VISIBILITY
1338    iterator       begin() _NOEXCEPT       {return __base::begin();}
1339    _LIBCPP_INLINE_VISIBILITY
1340    const_iterator begin() const _NOEXCEPT {return __base::begin();}
1341    _LIBCPP_INLINE_VISIBILITY
1342    iterator       end() _NOEXCEPT         {return __base::end();}
1343    _LIBCPP_INLINE_VISIBILITY
1344    const_iterator end()   const _NOEXCEPT {return __base::end();}
1345
1346    _LIBCPP_INLINE_VISIBILITY
1347    reverse_iterator       rbegin() _NOEXCEPT
1348        {return       reverse_iterator(__base::end());}
1349    _LIBCPP_INLINE_VISIBILITY
1350    const_reverse_iterator rbegin() const _NOEXCEPT
1351        {return const_reverse_iterator(__base::end());}
1352    _LIBCPP_INLINE_VISIBILITY
1353    reverse_iterator       rend() _NOEXCEPT
1354        {return       reverse_iterator(__base::begin());}
1355    _LIBCPP_INLINE_VISIBILITY
1356    const_reverse_iterator rend()   const _NOEXCEPT
1357        {return const_reverse_iterator(__base::begin());}
1358
1359    _LIBCPP_INLINE_VISIBILITY
1360    const_iterator         cbegin()  const _NOEXCEPT
1361        {return __base::begin();}
1362    _LIBCPP_INLINE_VISIBILITY
1363    const_iterator         cend()    const _NOEXCEPT
1364        {return __base::end();}
1365    _LIBCPP_INLINE_VISIBILITY
1366    const_reverse_iterator crbegin() const _NOEXCEPT
1367        {return const_reverse_iterator(__base::end());}
1368    _LIBCPP_INLINE_VISIBILITY
1369    const_reverse_iterator crend()   const _NOEXCEPT
1370        {return const_reverse_iterator(__base::begin());}
1371
1372    // capacity:
1373    _LIBCPP_INLINE_VISIBILITY
1374    size_type size() const _NOEXCEPT {return __base::size();}
1375    _LIBCPP_INLINE_VISIBILITY
1376    size_type max_size() const _NOEXCEPT
1377        {return _VSTD::min<size_type>(
1378            __alloc_traits::max_size(__base::__alloc()),
1379            numeric_limits<difference_type>::max());}
1380    void resize(size_type __n);
1381    void resize(size_type __n, const value_type& __v);
1382    void shrink_to_fit() _NOEXCEPT;
1383    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1384    bool empty() const _NOEXCEPT {return __base::size() == 0;}
1385
1386    // element access:
1387    _LIBCPP_INLINE_VISIBILITY
1388    reference operator[](size_type __i) _NOEXCEPT;
1389    _LIBCPP_INLINE_VISIBILITY
1390    const_reference operator[](size_type __i) const _NOEXCEPT;
1391    _LIBCPP_INLINE_VISIBILITY
1392    reference at(size_type __i);
1393    _LIBCPP_INLINE_VISIBILITY
1394    const_reference at(size_type __i) const;
1395    _LIBCPP_INLINE_VISIBILITY
1396    reference front() _NOEXCEPT;
1397    _LIBCPP_INLINE_VISIBILITY
1398    const_reference front() const _NOEXCEPT;
1399    _LIBCPP_INLINE_VISIBILITY
1400    reference back() _NOEXCEPT;
1401    _LIBCPP_INLINE_VISIBILITY
1402    const_reference back() const _NOEXCEPT;
1403
1404    // 23.2.2.3 modifiers:
1405    void push_front(const value_type& __v);
1406    void push_back(const value_type& __v);
1407#ifndef _LIBCPP_CXX03_LANG
1408#if _LIBCPP_STD_VER > 14
1409    template <class... _Args> reference emplace_front(_Args&&... __args);
1410    template <class... _Args> reference emplace_back (_Args&&... __args);
1411#else
1412    template <class... _Args> void      emplace_front(_Args&&... __args);
1413    template <class... _Args> void      emplace_back (_Args&&... __args);
1414#endif
1415    template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);
1416
1417    void push_front(value_type&& __v);
1418    void push_back(value_type&& __v);
1419    iterator insert(const_iterator __p, value_type&& __v);
1420
1421    _LIBCPP_INLINE_VISIBILITY
1422    iterator insert(const_iterator __p, initializer_list<value_type> __il)
1423        {return insert(__p, __il.begin(), __il.end());}
1424#endif // _LIBCPP_CXX03_LANG
1425    iterator insert(const_iterator __p, const value_type& __v);
1426    iterator insert(const_iterator __p, size_type __n, const value_type& __v);
1427    template <class _InputIter>
1428        iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
1429                         typename enable_if<__is_cpp17_input_iterator<_InputIter>::value
1430                                         &&!__is_cpp17_forward_iterator<_InputIter>::value>::type* = 0);
1431    template <class _ForwardIterator>
1432        iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
1433                               typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value
1434                                         &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type* = 0);
1435    template <class _BiIter>
1436        iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
1437                         typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0);
1438
1439    void pop_front();
1440    void pop_back();
1441    iterator erase(const_iterator __p);
1442    iterator erase(const_iterator __f, const_iterator __l);
1443
1444    _LIBCPP_INLINE_VISIBILITY
1445    void swap(deque& __c)
1446#if _LIBCPP_STD_VER >= 14
1447        _NOEXCEPT;
1448#else
1449        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1450                   __is_nothrow_swappable<allocator_type>::value);
1451#endif
1452    _LIBCPP_INLINE_VISIBILITY
1453    void clear() _NOEXCEPT;
1454
1455    _LIBCPP_INLINE_VISIBILITY
1456    bool __invariants() const {return __base::__invariants();}
1457
1458    typedef typename __base::__map_const_pointer __map_const_pointer;
1459
1460    _LIBCPP_INLINE_VISIBILITY
1461    static size_type __recommend_blocks(size_type __n)
1462    {
1463        return __n / __base::__block_size + (__n % __base::__block_size != 0);
1464    }
1465    _LIBCPP_INLINE_VISIBILITY
1466    size_type __capacity() const
1467    {
1468        return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;
1469    }
1470    _LIBCPP_INLINE_VISIBILITY
1471    size_type __block_count() const
1472    {
1473        return __base::__map_.size();
1474    }
1475
1476    _LIBCPP_INLINE_VISIBILITY
1477    size_type __front_spare() const
1478    {
1479        return __base::__start_;
1480    }
1481    _LIBCPP_INLINE_VISIBILITY
1482    size_type __front_spare_blocks() const {
1483      return __front_spare() / __base::__block_size;
1484    }
1485    _LIBCPP_INLINE_VISIBILITY
1486    size_type __back_spare() const
1487    {
1488        return __capacity() - (__base::__start_ + __base::size());
1489    }
1490    _LIBCPP_INLINE_VISIBILITY
1491    size_type __back_spare_blocks() const {
1492      return __back_spare() / __base::__block_size;
1493    }
1494
1495 private:
1496    _LIBCPP_INLINE_VISIBILITY
1497    bool __maybe_remove_front_spare(bool __keep_one = true) {
1498      if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {
1499        __alloc_traits::deallocate(__base::__alloc(), __base::__map_.front(),
1500                                   __base::__block_size);
1501        __base::__map_.pop_front();
1502        __base::__start_ -= __base::__block_size;
1503        return true;
1504      }
1505      return false;
1506    }
1507
1508    _LIBCPP_INLINE_VISIBILITY
1509    bool __maybe_remove_back_spare(bool __keep_one = true) {
1510      if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {
1511        __alloc_traits::deallocate(__base::__alloc(), __base::__map_.back(),
1512                                   __base::__block_size);
1513        __base::__map_.pop_back();
1514        return true;
1515      }
1516      return false;
1517    }
1518
1519    template <class _InpIter>
1520        void __append(_InpIter __f, _InpIter __l,
1521                 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value &&
1522                                   !__is_cpp17_forward_iterator<_InpIter>::value>::type* = 0);
1523    template <class _ForIter>
1524        void __append(_ForIter __f, _ForIter __l,
1525                      typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0);
1526    void __append(size_type __n);
1527    void __append(size_type __n, const value_type& __v);
1528    void __erase_to_end(const_iterator __f);
1529    void __add_front_capacity();
1530    void __add_front_capacity(size_type __n);
1531    void __add_back_capacity();
1532    void __add_back_capacity(size_type __n);
1533    iterator __move_and_check(iterator __f, iterator __l, iterator __r,
1534                              const_pointer& __vt);
1535    iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
1536                                       const_pointer& __vt);
1537    void __move_construct_and_check(iterator __f, iterator __l,
1538                                    iterator __r, const_pointer& __vt);
1539    void __move_construct_backward_and_check(iterator __f, iterator __l,
1540                                             iterator __r, const_pointer& __vt);
1541
1542    _LIBCPP_INLINE_VISIBILITY
1543    void __copy_assign_alloc(const deque& __c)
1544        {__copy_assign_alloc(__c, integral_constant<bool,
1545                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
1546
1547    _LIBCPP_INLINE_VISIBILITY
1548    void __copy_assign_alloc(const deque& __c, true_type)
1549        {
1550            if (__base::__alloc() != __c.__alloc())
1551            {
1552                clear();
1553                shrink_to_fit();
1554            }
1555            __base::__alloc() = __c.__alloc();
1556            __base::__map_.__alloc() = __c.__map_.__alloc();
1557        }
1558
1559    _LIBCPP_INLINE_VISIBILITY
1560    void __copy_assign_alloc(const deque&, false_type)
1561        {}
1562
1563    void __move_assign(deque& __c, true_type)
1564        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
1565    void __move_assign(deque& __c, false_type);
1566};
1567
1568#if _LIBCPP_STD_VER >= 17
1569template<class _InputIterator,
1570         class _Alloc = allocator<__iter_value_type<_InputIterator>>,
1571         class = enable_if_t<__is_allocator<_Alloc>::value>
1572         >
1573deque(_InputIterator, _InputIterator)
1574  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
1575
1576template<class _InputIterator,
1577         class _Alloc,
1578         class = enable_if_t<__is_allocator<_Alloc>::value>
1579         >
1580deque(_InputIterator, _InputIterator, _Alloc)
1581  -> deque<__iter_value_type<_InputIterator>, _Alloc>;
1582#endif
1583
1584
1585template <class _Tp, class _Allocator>
1586deque<_Tp, _Allocator>::deque(size_type __n)
1587{
1588    if (__n > 0)
1589        __append(__n);
1590}
1591
1592#if _LIBCPP_STD_VER > 11
1593template <class _Tp, class _Allocator>
1594deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
1595    : __base(__a)
1596{
1597    if (__n > 0)
1598        __append(__n);
1599}
1600#endif
1601
1602template <class _Tp, class _Allocator>
1603deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
1604{
1605    if (__n > 0)
1606        __append(__n, __v);
1607}
1608
1609template <class _Tp, class _Allocator>
1610deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
1611    : __base(__a)
1612{
1613    if (__n > 0)
1614        __append(__n, __v);
1615}
1616
1617template <class _Tp, class _Allocator>
1618template <class _InputIter>
1619deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
1620              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
1621{
1622    __append(__f, __l);
1623}
1624
1625template <class _Tp, class _Allocator>
1626template <class _InputIter>
1627deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1628              typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
1629    : __base(__a)
1630{
1631    __append(__f, __l);
1632}
1633
1634template <class _Tp, class _Allocator>
1635deque<_Tp, _Allocator>::deque(const deque& __c)
1636    : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
1637{
1638    __append(__c.begin(), __c.end());
1639}
1640
1641template <class _Tp, class _Allocator>
1642deque<_Tp, _Allocator>::deque(const deque& __c, const __identity_t<allocator_type>& __a)
1643    : __base(__a)
1644{
1645    __append(__c.begin(), __c.end());
1646}
1647
1648template <class _Tp, class _Allocator>
1649deque<_Tp, _Allocator>&
1650deque<_Tp, _Allocator>::operator=(const deque& __c)
1651{
1652    if (this != &__c)
1653    {
1654        __copy_assign_alloc(__c);
1655        assign(__c.begin(), __c.end());
1656    }
1657    return *this;
1658}
1659
1660#ifndef _LIBCPP_CXX03_LANG
1661
1662template <class _Tp, class _Allocator>
1663deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
1664{
1665    __append(__il.begin(), __il.end());
1666}
1667
1668template <class _Tp, class _Allocator>
1669deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
1670    : __base(__a)
1671{
1672    __append(__il.begin(), __il.end());
1673}
1674
1675template <class _Tp, class _Allocator>
1676inline
1677deque<_Tp, _Allocator>::deque(deque&& __c)
1678    _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
1679    : __base(_VSTD::move(__c))
1680{
1681}
1682
1683template <class _Tp, class _Allocator>
1684inline
1685deque<_Tp, _Allocator>::deque(deque&& __c, const __identity_t<allocator_type>& __a)
1686    : __base(_VSTD::move(__c), __a)
1687{
1688    if (__a != __c.__alloc())
1689    {
1690        typedef move_iterator<iterator> _Ip;
1691        assign(_Ip(__c.begin()), _Ip(__c.end()));
1692    }
1693}
1694
1695template <class _Tp, class _Allocator>
1696inline
1697deque<_Tp, _Allocator>&
1698deque<_Tp, _Allocator>::operator=(deque&& __c)
1699        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1700                   is_nothrow_move_assignable<allocator_type>::value)
1701{
1702    __move_assign(__c, integral_constant<bool,
1703          __alloc_traits::propagate_on_container_move_assignment::value>());
1704    return *this;
1705}
1706
1707template <class _Tp, class _Allocator>
1708void
1709deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
1710{
1711    if (__base::__alloc() != __c.__alloc())
1712    {
1713        typedef move_iterator<iterator> _Ip;
1714        assign(_Ip(__c.begin()), _Ip(__c.end()));
1715    }
1716    else
1717        __move_assign(__c, true_type());
1718}
1719
1720template <class _Tp, class _Allocator>
1721void
1722deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
1723    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1724{
1725    clear();
1726    shrink_to_fit();
1727    __base::__move_assign(__c);
1728}
1729
1730#endif // _LIBCPP_CXX03_LANG
1731
1732template <class _Tp, class _Allocator>
1733template <class _InputIter>
1734void
1735deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
1736                               typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
1737                                                 !__is_cpp17_random_access_iterator<_InputIter>::value>::type*)
1738{
1739    iterator __i = __base::begin();
1740    iterator __e = __base::end();
1741    for (; __f != __l && __i != __e; ++__f, (void) ++__i)
1742        *__i = *__f;
1743    if (__f != __l)
1744        __append(__f, __l);
1745    else
1746        __erase_to_end(__i);
1747}
1748
1749template <class _Tp, class _Allocator>
1750template <class _RAIter>
1751void
1752deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
1753                               typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
1754{
1755    if (static_cast<size_type>(__l - __f) > __base::size())
1756    {
1757        _RAIter __m = __f + __base::size();
1758        _VSTD::copy(__f, __m, __base::begin());
1759        __append(__m, __l);
1760    }
1761    else
1762        __erase_to_end(_VSTD::copy(__f, __l, __base::begin()));
1763}
1764
1765template <class _Tp, class _Allocator>
1766void
1767deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
1768{
1769    if (__n > __base::size())
1770    {
1771        _VSTD::fill_n(__base::begin(), __base::size(), __v);
1772        __n -= __base::size();
1773        __append(__n, __v);
1774    }
1775    else
1776        __erase_to_end(_VSTD::fill_n(__base::begin(), __n, __v));
1777}
1778
1779template <class _Tp, class _Allocator>
1780inline
1781_Allocator
1782deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
1783{
1784    return __base::__alloc();
1785}
1786
1787template <class _Tp, class _Allocator>
1788void
1789deque<_Tp, _Allocator>::resize(size_type __n)
1790{
1791    if (__n > __base::size())
1792        __append(__n - __base::size());
1793    else if (__n < __base::size())
1794        __erase_to_end(__base::begin() + __n);
1795}
1796
1797template <class _Tp, class _Allocator>
1798void
1799deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
1800{
1801    if (__n > __base::size())
1802        __append(__n - __base::size(), __v);
1803    else if (__n < __base::size())
1804        __erase_to_end(__base::begin() + __n);
1805}
1806
1807template <class _Tp, class _Allocator>
1808void
1809deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
1810{
1811    allocator_type& __a = __base::__alloc();
1812    if (empty())
1813    {
1814        while (__base::__map_.size() > 0)
1815        {
1816            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
1817            __base::__map_.pop_back();
1818        }
1819        __base::__start_ = 0;
1820    }
1821    else
1822    {
1823      __maybe_remove_front_spare(/*__keep_one=*/false);
1824      __maybe_remove_back_spare(/*__keep_one=*/false);
1825    }
1826    __base::__map_.shrink_to_fit();
1827}
1828
1829template <class _Tp, class _Allocator>
1830inline
1831typename deque<_Tp, _Allocator>::reference
1832deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT
1833{
1834    size_type __p = __base::__start_ + __i;
1835    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1836}
1837
1838template <class _Tp, class _Allocator>
1839inline
1840typename deque<_Tp, _Allocator>::const_reference
1841deque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT
1842{
1843    size_type __p = __base::__start_ + __i;
1844    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1845}
1846
1847template <class _Tp, class _Allocator>
1848inline
1849typename deque<_Tp, _Allocator>::reference
1850deque<_Tp, _Allocator>::at(size_type __i)
1851{
1852    if (__i >= __base::size())
1853        _VSTD::__throw_out_of_range("deque");
1854    size_type __p = __base::__start_ + __i;
1855    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1856}
1857
1858template <class _Tp, class _Allocator>
1859inline
1860typename deque<_Tp, _Allocator>::const_reference
1861deque<_Tp, _Allocator>::at(size_type __i) const
1862{
1863    if (__i >= __base::size())
1864        _VSTD::__throw_out_of_range("deque");
1865    size_type __p = __base::__start_ + __i;
1866    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1867}
1868
1869template <class _Tp, class _Allocator>
1870inline
1871typename deque<_Tp, _Allocator>::reference
1872deque<_Tp, _Allocator>::front() _NOEXCEPT
1873{
1874    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1875                                      + __base::__start_ % __base::__block_size);
1876}
1877
1878template <class _Tp, class _Allocator>
1879inline
1880typename deque<_Tp, _Allocator>::const_reference
1881deque<_Tp, _Allocator>::front() const _NOEXCEPT
1882{
1883    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1884                                      + __base::__start_ % __base::__block_size);
1885}
1886
1887template <class _Tp, class _Allocator>
1888inline
1889typename deque<_Tp, _Allocator>::reference
1890deque<_Tp, _Allocator>::back() _NOEXCEPT
1891{
1892    size_type __p = __base::size() + __base::__start_ - 1;
1893    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1894}
1895
1896template <class _Tp, class _Allocator>
1897inline
1898typename deque<_Tp, _Allocator>::const_reference
1899deque<_Tp, _Allocator>::back() const _NOEXCEPT
1900{
1901    size_type __p = __base::size() + __base::__start_ - 1;
1902    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1903}
1904
1905template <class _Tp, class _Allocator>
1906void
1907deque<_Tp, _Allocator>::push_back(const value_type& __v)
1908{
1909    allocator_type& __a = __base::__alloc();
1910    if (__back_spare() == 0)
1911        __add_back_capacity();
1912    // __back_spare() >= 1
1913    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
1914    ++__base::size();
1915}
1916
1917template <class _Tp, class _Allocator>
1918void
1919deque<_Tp, _Allocator>::push_front(const value_type& __v)
1920{
1921    allocator_type& __a = __base::__alloc();
1922    if (__front_spare() == 0)
1923        __add_front_capacity();
1924    // __front_spare() >= 1
1925    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
1926    --__base::__start_;
1927    ++__base::size();
1928}
1929
1930#ifndef _LIBCPP_CXX03_LANG
1931template <class _Tp, class _Allocator>
1932void
1933deque<_Tp, _Allocator>::push_back(value_type&& __v)
1934{
1935    allocator_type& __a = __base::__alloc();
1936    if (__back_spare() == 0)
1937        __add_back_capacity();
1938    // __back_spare() >= 1
1939    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
1940    ++__base::size();
1941}
1942
1943template <class _Tp, class _Allocator>
1944template <class... _Args>
1945#if _LIBCPP_STD_VER > 14
1946typename deque<_Tp, _Allocator>::reference
1947#else
1948void
1949#endif
1950deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
1951{
1952    allocator_type& __a = __base::__alloc();
1953    if (__back_spare() == 0)
1954        __add_back_capacity();
1955    // __back_spare() >= 1
1956    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()),
1957                              _VSTD::forward<_Args>(__args)...);
1958    ++__base::size();
1959#if _LIBCPP_STD_VER > 14
1960    return *--__base::end();
1961#endif
1962}
1963
1964template <class _Tp, class _Allocator>
1965void
1966deque<_Tp, _Allocator>::push_front(value_type&& __v)
1967{
1968    allocator_type& __a = __base::__alloc();
1969    if (__front_spare() == 0)
1970        __add_front_capacity();
1971    // __front_spare() >= 1
1972    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
1973    --__base::__start_;
1974    ++__base::size();
1975}
1976
1977
1978template <class _Tp, class _Allocator>
1979template <class... _Args>
1980#if _LIBCPP_STD_VER > 14
1981typename deque<_Tp, _Allocator>::reference
1982#else
1983void
1984#endif
1985deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
1986{
1987    allocator_type& __a = __base::__alloc();
1988    if (__front_spare() == 0)
1989        __add_front_capacity();
1990    // __front_spare() >= 1
1991    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
1992    --__base::__start_;
1993    ++__base::size();
1994#if _LIBCPP_STD_VER > 14
1995    return *__base::begin();
1996#endif
1997}
1998
1999template <class _Tp, class _Allocator>
2000typename deque<_Tp, _Allocator>::iterator
2001deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
2002{
2003    size_type __pos = __p - __base::begin();
2004    size_type __to_end = __base::size() - __pos;
2005    allocator_type& __a = __base::__alloc();
2006    if (__pos < __to_end)
2007    {   // insert by shifting things backward
2008        if (__front_spare() == 0)
2009            __add_front_capacity();
2010        // __front_spare() >= 1
2011        if (__pos == 0)
2012        {
2013            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
2014            --__base::__start_;
2015            ++__base::size();
2016        }
2017        else
2018        {
2019            iterator __b = __base::begin();
2020            iterator __bm1 = _VSTD::prev(__b);
2021            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
2022            --__base::__start_;
2023            ++__base::size();
2024            if (__pos > 1)
2025                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
2026            *__b = _VSTD::move(__v);
2027        }
2028    }
2029    else
2030    {   // insert by shifting things forward
2031        if (__back_spare() == 0)
2032            __add_back_capacity();
2033        // __back_capacity >= 1
2034        size_type __de = __base::size() - __pos;
2035        if (__de == 0)
2036        {
2037            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
2038            ++__base::size();
2039        }
2040        else
2041        {
2042            iterator __e = __base::end();
2043            iterator __em1 = _VSTD::prev(__e);
2044            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
2045            ++__base::size();
2046            if (__de > 1)
2047                __e = _VSTD::move_backward(__e - __de, __em1, __e);
2048            *--__e = _VSTD::move(__v);
2049        }
2050    }
2051    return __base::begin() + __pos;
2052}
2053
2054template <class _Tp, class _Allocator>
2055template <class... _Args>
2056typename deque<_Tp, _Allocator>::iterator
2057deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
2058{
2059    size_type __pos = __p - __base::begin();
2060    size_type __to_end = __base::size() - __pos;
2061    allocator_type& __a = __base::__alloc();
2062    if (__pos < __to_end)
2063    {   // insert by shifting things backward
2064        if (__front_spare() == 0)
2065            __add_front_capacity();
2066        // __front_spare() >= 1
2067        if (__pos == 0)
2068        {
2069            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
2070            --__base::__start_;
2071            ++__base::size();
2072        }
2073        else
2074        {
2075            __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
2076            iterator __b = __base::begin();
2077            iterator __bm1 = _VSTD::prev(__b);
2078            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
2079            --__base::__start_;
2080            ++__base::size();
2081            if (__pos > 1)
2082                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
2083            *__b = _VSTD::move(__tmp.get());
2084        }
2085    }
2086    else
2087    {   // insert by shifting things forward
2088        if (__back_spare() == 0)
2089            __add_back_capacity();
2090        // __back_capacity >= 1
2091        size_type __de = __base::size() - __pos;
2092        if (__de == 0)
2093        {
2094            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);
2095            ++__base::size();
2096        }
2097        else
2098        {
2099            __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
2100            iterator __e = __base::end();
2101            iterator __em1 = _VSTD::prev(__e);
2102            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
2103            ++__base::size();
2104            if (__de > 1)
2105                __e = _VSTD::move_backward(__e - __de, __em1, __e);
2106            *--__e = _VSTD::move(__tmp.get());
2107        }
2108    }
2109    return __base::begin() + __pos;
2110}
2111
2112#endif // _LIBCPP_CXX03_LANG
2113
2114
2115template <class _Tp, class _Allocator>
2116typename deque<_Tp, _Allocator>::iterator
2117deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
2118{
2119    size_type __pos = __p - __base::begin();
2120    size_type __to_end = __base::size() - __pos;
2121    allocator_type& __a = __base::__alloc();
2122    if (__pos < __to_end)
2123    {   // insert by shifting things backward
2124        if (__front_spare() == 0)
2125            __add_front_capacity();
2126        // __front_spare() >= 1
2127        if (__pos == 0)
2128        {
2129            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
2130            --__base::__start_;
2131            ++__base::size();
2132        }
2133        else
2134        {
2135            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2136            iterator __b = __base::begin();
2137            iterator __bm1 = _VSTD::prev(__b);
2138            if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
2139                __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
2140            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
2141            --__base::__start_;
2142            ++__base::size();
2143            if (__pos > 1)
2144                __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);
2145            *__b = *__vt;
2146        }
2147    }
2148    else
2149    {   // insert by shifting things forward
2150        if (__back_spare() == 0)
2151            __add_back_capacity();
2152        // __back_capacity >= 1
2153        size_type __de = __base::size() - __pos;
2154        if (__de == 0)
2155        {
2156            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
2157            ++__base::size();
2158        }
2159        else
2160        {
2161            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2162            iterator __e = __base::end();
2163            iterator __em1 = _VSTD::prev(__e);
2164            if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
2165                __vt = pointer_traits<const_pointer>::pointer_to(*__e);
2166            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
2167            ++__base::size();
2168            if (__de > 1)
2169                __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
2170            *--__e = *__vt;
2171        }
2172    }
2173    return __base::begin() + __pos;
2174}
2175
2176template <class _Tp, class _Allocator>
2177typename deque<_Tp, _Allocator>::iterator
2178deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
2179{
2180    size_type __pos = __p - __base::begin();
2181    size_type __to_end = __base::size() - __pos;
2182    allocator_type& __a = __base::__alloc();
2183    if (__pos < __to_end)
2184    {   // insert by shifting things backward
2185        if (__n > __front_spare())
2186            __add_front_capacity(__n - __front_spare());
2187        // __n <= __front_spare()
2188        iterator __old_begin = __base::begin();
2189        iterator __i = __old_begin;
2190        if (__n > __pos)
2191        {
2192            for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())
2193                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);
2194            __n = __pos;
2195        }
2196        if (__n > 0)
2197        {
2198            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2199            iterator __obn = __old_begin + __n;
2200            __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
2201            if (__n < __pos)
2202                __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
2203            _VSTD::fill_n(__old_begin, __n, *__vt);
2204        }
2205    }
2206    else
2207    {   // insert by shifting things forward
2208        size_type __back_capacity = __back_spare();
2209        if (__n > __back_capacity)
2210            __add_back_capacity(__n - __back_capacity);
2211        // __n <= __back_capacity
2212        iterator __old_end = __base::end();
2213        iterator __i = __old_end;
2214        size_type __de = __base::size() - __pos;
2215        if (__n > __de)
2216        {
2217            for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size())
2218                __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
2219            __n = __de;
2220        }
2221        if (__n > 0)
2222        {
2223            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2224            iterator __oen = __old_end - __n;
2225            __move_construct_and_check(__oen, __old_end, __i, __vt);
2226            if (__n < __de)
2227                __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
2228            _VSTD::fill_n(__old_end - __n, __n, *__vt);
2229        }
2230    }
2231    return __base::begin() + __pos;
2232}
2233
2234template <class _Tp, class _Allocator>
2235template <class _InputIter>
2236typename deque<_Tp, _Allocator>::iterator
2237deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
2238                               typename enable_if<__is_cpp17_input_iterator<_InputIter>::value
2239                                               &&!__is_cpp17_forward_iterator<_InputIter>::value>::type*)
2240{
2241    __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
2242    __buf.__construct_at_end(__f, __l);
2243    typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
2244    return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
2245}
2246
2247template <class _Tp, class _Allocator>
2248template <class _ForwardIterator>
2249typename deque<_Tp, _Allocator>::iterator
2250deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
2251                               typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value
2252                                               &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type*)
2253{
2254    size_type __n = _VSTD::distance(__f, __l);
2255    __split_buffer<value_type, allocator_type&> __buf(__n, 0, __base::__alloc());
2256    __buf.__construct_at_end(__f, __l);
2257    typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
2258    return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
2259}
2260
2261template <class _Tp, class _Allocator>
2262template <class _BiIter>
2263typename deque<_Tp, _Allocator>::iterator
2264deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
2265                               typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type*)
2266{
2267    size_type __n = _VSTD::distance(__f, __l);
2268    size_type __pos = __p - __base::begin();
2269    size_type __to_end = __base::size() - __pos;
2270    allocator_type& __a = __base::__alloc();
2271    if (__pos < __to_end)
2272    {   // insert by shifting things backward
2273        if (__n > __front_spare())
2274            __add_front_capacity(__n - __front_spare());
2275        // __n <= __front_spare()
2276        iterator __old_begin = __base::begin();
2277        iterator __i = __old_begin;
2278        _BiIter __m = __f;
2279        if (__n > __pos)
2280        {
2281            __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);
2282            for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())
2283                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);
2284            __n = __pos;
2285        }
2286        if (__n > 0)
2287        {
2288            iterator __obn = __old_begin + __n;
2289            for (iterator __j = __obn; __j != __old_begin;)
2290            {
2291                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));
2292                --__base::__start_;
2293                ++__base::size();
2294            }
2295            if (__n < __pos)
2296                __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);
2297            _VSTD::copy(__m, __l, __old_begin);
2298        }
2299    }
2300    else
2301    {   // insert by shifting things forward
2302        size_type __back_capacity = __back_spare();
2303        if (__n > __back_capacity)
2304            __add_back_capacity(__n - __back_capacity);
2305        // __n <= __back_capacity
2306        iterator __old_end = __base::end();
2307        iterator __i = __old_end;
2308        _BiIter __m = __l;
2309        size_type __de = __base::size() - __pos;
2310        if (__n > __de)
2311        {
2312            __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
2313            for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__base::size())
2314                __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
2315            __n = __de;
2316        }
2317        if (__n > 0)
2318        {
2319            iterator __oen = __old_end - __n;
2320            for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size())
2321                __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));
2322            if (__n < __de)
2323                __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);
2324            _VSTD::copy_backward(__f, __m, __old_end);
2325        }
2326    }
2327    return __base::begin() + __pos;
2328}
2329
2330template <class _Tp, class _Allocator>
2331template <class _InpIter>
2332void
2333deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
2334                                 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value &&
2335                                                   !__is_cpp17_forward_iterator<_InpIter>::value>::type*)
2336{
2337    for (; __f != __l; ++__f)
2338#ifdef _LIBCPP_CXX03_LANG
2339        push_back(*__f);
2340#else
2341        emplace_back(*__f);
2342#endif
2343}
2344
2345template <class _Tp, class _Allocator>
2346template <class _ForIter>
2347void
2348deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
2349                                 typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type*)
2350{
2351    size_type __n = _VSTD::distance(__f, __l);
2352    allocator_type& __a = __base::__alloc();
2353    size_type __back_capacity = __back_spare();
2354    if (__n > __back_capacity)
2355        __add_back_capacity(__n - __back_capacity);
2356    // __n <= __back_capacity
2357    for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
2358      _ConstructTransaction __tx(this, __br);
2359      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {
2360        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f);
2361      }
2362    }
2363}
2364
2365template <class _Tp, class _Allocator>
2366void
2367deque<_Tp, _Allocator>::__append(size_type __n)
2368{
2369    allocator_type& __a = __base::__alloc();
2370    size_type __back_capacity = __back_spare();
2371    if (__n > __back_capacity)
2372        __add_back_capacity(__n - __back_capacity);
2373    // __n <= __back_capacity
2374    for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
2375      _ConstructTransaction __tx(this, __br);
2376      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
2377        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_));
2378      }
2379    }
2380}
2381
2382template <class _Tp, class _Allocator>
2383void
2384deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
2385{
2386    allocator_type& __a = __base::__alloc();
2387    size_type __back_capacity = __back_spare();
2388    if (__n > __back_capacity)
2389        __add_back_capacity(__n - __back_capacity);
2390    // __n <= __back_capacity
2391    for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
2392      _ConstructTransaction __tx(this, __br);
2393      for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
2394        __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v);
2395      }
2396    }
2397
2398}
2399
2400// Create front capacity for one block of elements.
2401// Strong guarantee.  Either do it or don't touch anything.
2402template <class _Tp, class _Allocator>
2403void
2404deque<_Tp, _Allocator>::__add_front_capacity()
2405{
2406    allocator_type& __a = __base::__alloc();
2407    if (__back_spare() >= __base::__block_size)
2408    {
2409        __base::__start_ += __base::__block_size;
2410        pointer __pt = __base::__map_.back();
2411        __base::__map_.pop_back();
2412        __base::__map_.push_front(__pt);
2413    }
2414    // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer
2415    else if (__base::__map_.size() < __base::__map_.capacity())
2416    {   // we can put the new buffer into the map, but don't shift things around
2417        // until all buffers are allocated.  If we throw, we don't need to fix
2418        // anything up (any added buffers are undetectible)
2419        if (__base::__map_.__front_spare() > 0)
2420            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2421        else
2422        {
2423            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2424            // Done allocating, reorder capacity
2425            pointer __pt = __base::__map_.back();
2426            __base::__map_.pop_back();
2427            __base::__map_.push_front(__pt);
2428        }
2429        __base::__start_ = __base::__map_.size() == 1 ?
2430                               __base::__block_size / 2 :
2431                               __base::__start_ + __base::__block_size;
2432    }
2433    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2434    else
2435    {
2436        __split_buffer<pointer, typename __base::__pointer_allocator&>
2437            __buf(max<size_type>(2 * __base::__map_.capacity(), 1),
2438                  0, __base::__map_.__alloc());
2439
2440        typedef __allocator_destructor<_Allocator> _Dp;
2441        unique_ptr<pointer, _Dp> __hold(
2442            __alloc_traits::allocate(__a, __base::__block_size),
2443                _Dp(__a, __base::__block_size));
2444        __buf.push_back(__hold.get());
2445        __hold.release();
2446
2447        for (typename __base::__map_pointer __i = __base::__map_.begin();
2448                __i != __base::__map_.end(); ++__i)
2449            __buf.push_back(*__i);
2450        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2451        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2452        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2453        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2454        __base::__start_ = __base::__map_.size() == 1 ?
2455                               __base::__block_size / 2 :
2456                               __base::__start_ + __base::__block_size;
2457    }
2458}
2459
2460// Create front capacity for __n elements.
2461// Strong guarantee.  Either do it or don't touch anything.
2462template <class _Tp, class _Allocator>
2463void
2464deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
2465{
2466    allocator_type& __a = __base::__alloc();
2467    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2468    // Number of unused blocks at back:
2469    size_type __back_capacity = __back_spare() / __base::__block_size;
2470    __back_capacity = _VSTD::min(__back_capacity, __nb);  // don't take more than you need
2471    __nb -= __back_capacity;  // number of blocks need to allocate
2472    // If __nb == 0, then we have sufficient capacity.
2473    if (__nb == 0)
2474    {
2475        __base::__start_ += __base::__block_size * __back_capacity;
2476        for (; __back_capacity > 0; --__back_capacity)
2477        {
2478            pointer __pt = __base::__map_.back();
2479            __base::__map_.pop_back();
2480            __base::__map_.push_front(__pt);
2481        }
2482    }
2483    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2484    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2485    {   // we can put the new buffers into the map, but don't shift things around
2486        // until all buffers are allocated.  If we throw, we don't need to fix
2487        // anything up (any added buffers are undetectible)
2488        for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))
2489        {
2490            if (__base::__map_.__front_spare() == 0)
2491                break;
2492            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2493        }
2494        for (; __nb > 0; --__nb, ++__back_capacity)
2495            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2496        // Done allocating, reorder capacity
2497        __base::__start_ += __back_capacity * __base::__block_size;
2498        for (; __back_capacity > 0; --__back_capacity)
2499        {
2500            pointer __pt = __base::__map_.back();
2501            __base::__map_.pop_back();
2502            __base::__map_.push_front(__pt);
2503        }
2504    }
2505    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2506    else
2507    {
2508        size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();
2509        __split_buffer<pointer, typename __base::__pointer_allocator&>
2510            __buf(max<size_type>(2* __base::__map_.capacity(),
2511                                 __nb + __base::__map_.size()),
2512                  0, __base::__map_.__alloc());
2513#ifndef _LIBCPP_NO_EXCEPTIONS
2514        try
2515        {
2516#endif // _LIBCPP_NO_EXCEPTIONS
2517            for (; __nb > 0; --__nb)
2518                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2519#ifndef _LIBCPP_NO_EXCEPTIONS
2520        }
2521        catch (...)
2522        {
2523            for (typename __base::__map_pointer __i = __buf.begin();
2524                    __i != __buf.end(); ++__i)
2525                __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2526            throw;
2527        }
2528#endif // _LIBCPP_NO_EXCEPTIONS
2529        for (; __back_capacity > 0; --__back_capacity)
2530        {
2531            __buf.push_back(__base::__map_.back());
2532            __base::__map_.pop_back();
2533        }
2534        for (typename __base::__map_pointer __i = __base::__map_.begin();
2535                __i != __base::__map_.end(); ++__i)
2536            __buf.push_back(*__i);
2537        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2538        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2539        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2540        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2541        __base::__start_ += __ds;
2542    }
2543}
2544
2545// Create back capacity for one block of elements.
2546// Strong guarantee.  Either do it or don't touch anything.
2547template <class _Tp, class _Allocator>
2548void
2549deque<_Tp, _Allocator>::__add_back_capacity()
2550{
2551    allocator_type& __a = __base::__alloc();
2552    if (__front_spare() >= __base::__block_size)
2553    {
2554        __base::__start_ -= __base::__block_size;
2555        pointer __pt = __base::__map_.front();
2556        __base::__map_.pop_front();
2557        __base::__map_.push_back(__pt);
2558    }
2559    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2560    else if (__base::__map_.size() < __base::__map_.capacity())
2561    {   // we can put the new buffer into the map, but don't shift things around
2562        // until it is allocated.  If we throw, we don't need to fix
2563        // anything up (any added buffers are undetectible)
2564        if (__base::__map_.__back_spare() != 0)
2565            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2566        else
2567        {
2568            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2569            // Done allocating, reorder capacity
2570            pointer __pt = __base::__map_.front();
2571            __base::__map_.pop_front();
2572            __base::__map_.push_back(__pt);
2573        }
2574    }
2575    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2576    else
2577    {
2578        __split_buffer<pointer, typename __base::__pointer_allocator&>
2579            __buf(max<size_type>(2* __base::__map_.capacity(), 1),
2580                  __base::__map_.size(),
2581                  __base::__map_.__alloc());
2582
2583        typedef __allocator_destructor<_Allocator> _Dp;
2584        unique_ptr<pointer, _Dp> __hold(
2585            __alloc_traits::allocate(__a, __base::__block_size),
2586                _Dp(__a, __base::__block_size));
2587        __buf.push_back(__hold.get());
2588        __hold.release();
2589
2590        for (typename __base::__map_pointer __i = __base::__map_.end();
2591                __i != __base::__map_.begin();)
2592            __buf.push_front(*--__i);
2593        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2594        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2595        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2596        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2597    }
2598}
2599
2600// Create back capacity for __n elements.
2601// Strong guarantee.  Either do it or don't touch anything.
2602template <class _Tp, class _Allocator>
2603void
2604deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
2605{
2606    allocator_type& __a = __base::__alloc();
2607    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2608    // Number of unused blocks at front:
2609    size_type __front_capacity = __front_spare() / __base::__block_size;
2610    __front_capacity = _VSTD::min(__front_capacity, __nb);  // don't take more than you need
2611    __nb -= __front_capacity;  // number of blocks need to allocate
2612    // If __nb == 0, then we have sufficient capacity.
2613    if (__nb == 0)
2614    {
2615        __base::__start_ -= __base::__block_size * __front_capacity;
2616        for (; __front_capacity > 0; --__front_capacity)
2617        {
2618            pointer __pt = __base::__map_.front();
2619            __base::__map_.pop_front();
2620            __base::__map_.push_back(__pt);
2621        }
2622    }
2623    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2624    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2625    {   // we can put the new buffers into the map, but don't shift things around
2626        // until all buffers are allocated.  If we throw, we don't need to fix
2627        // anything up (any added buffers are undetectible)
2628        for (; __nb > 0; --__nb)
2629        {
2630            if (__base::__map_.__back_spare() == 0)
2631                break;
2632            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2633        }
2634        for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=
2635                                 __base::__block_size - (__base::__map_.size() == 1))
2636            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2637        // Done allocating, reorder capacity
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 need to allocate __nb buffers, *and* we need to reallocate __map_.
2647    else
2648    {
2649        size_type __ds = __front_capacity * __base::__block_size;
2650        __split_buffer<pointer, typename __base::__pointer_allocator&>
2651            __buf(max<size_type>(2* __base::__map_.capacity(),
2652                                 __nb + __base::__map_.size()),
2653                  __base::__map_.size() - __front_capacity,
2654                  __base::__map_.__alloc());
2655#ifndef _LIBCPP_NO_EXCEPTIONS
2656        try
2657        {
2658#endif // _LIBCPP_NO_EXCEPTIONS
2659            for (; __nb > 0; --__nb)
2660                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2661#ifndef _LIBCPP_NO_EXCEPTIONS
2662        }
2663        catch (...)
2664        {
2665            for (typename __base::__map_pointer __i = __buf.begin();
2666                    __i != __buf.end(); ++__i)
2667                __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2668            throw;
2669        }
2670#endif // _LIBCPP_NO_EXCEPTIONS
2671        for (; __front_capacity > 0; --__front_capacity)
2672        {
2673            __buf.push_back(__base::__map_.front());
2674            __base::__map_.pop_front();
2675        }
2676        for (typename __base::__map_pointer __i = __base::__map_.end();
2677                __i != __base::__map_.begin();)
2678            __buf.push_front(*--__i);
2679        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2680        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2681        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2682        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2683        __base::__start_ -= __ds;
2684    }
2685}
2686
2687template <class _Tp, class _Allocator>
2688void
2689deque<_Tp, _Allocator>::pop_front()
2690{
2691    allocator_type& __a = __base::__alloc();
2692    __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() +
2693                                                    __base::__start_ / __base::__block_size) +
2694                                                    __base::__start_ % __base::__block_size));
2695    --__base::size();
2696    ++__base::__start_;
2697    __maybe_remove_front_spare();
2698}
2699
2700template <class _Tp, class _Allocator>
2701void
2702deque<_Tp, _Allocator>::pop_back()
2703{
2704    _LIBCPP_ASSERT(!empty(), "deque::pop_back called on an empty deque");
2705    allocator_type& __a = __base::__alloc();
2706    size_type __p = __base::size() + __base::__start_ - 1;
2707    __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() +
2708                                                    __p / __base::__block_size) +
2709                                                    __p % __base::__block_size));
2710    --__base::size();
2711    __maybe_remove_back_spare();
2712}
2713
2714// move assign [__f, __l) to [__r, __r + (__l-__f)).
2715// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
2716template <class _Tp, class _Allocator>
2717typename deque<_Tp, _Allocator>::iterator
2718deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
2719                                         const_pointer& __vt)
2720{
2721    // as if
2722    //   for (; __f != __l; ++__f, ++__r)
2723    //       *__r = _VSTD::move(*__f);
2724    difference_type __n = __l - __f;
2725    while (__n > 0)
2726    {
2727        pointer __fb = __f.__ptr_;
2728        pointer __fe = *__f.__m_iter_ + __base::__block_size;
2729        difference_type __bs = __fe - __fb;
2730        if (__bs > __n)
2731        {
2732            __bs = __n;
2733            __fe = __fb + __bs;
2734        }
2735        if (__fb <= __vt && __vt < __fe)
2736            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
2737        __r = _VSTD::move(__fb, __fe, __r);
2738        __n -= __bs;
2739        __f += __bs;
2740    }
2741    return __r;
2742}
2743
2744// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
2745// If __vt points into [__f, __l), then add (__r - __l) to __vt.
2746template <class _Tp, class _Allocator>
2747typename deque<_Tp, _Allocator>::iterator
2748deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
2749                                                  const_pointer& __vt)
2750{
2751    // as if
2752    //   while (__f != __l)
2753    //       *--__r = _VSTD::move(*--__l);
2754    difference_type __n = __l - __f;
2755    while (__n > 0)
2756    {
2757        --__l;
2758        pointer __lb = *__l.__m_iter_;
2759        pointer __le = __l.__ptr_ + 1;
2760        difference_type __bs = __le - __lb;
2761        if (__bs > __n)
2762        {
2763            __bs = __n;
2764            __lb = __le - __bs;
2765        }
2766        if (__lb <= __vt && __vt < __le)
2767            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
2768        __r = _VSTD::move_backward(__lb, __le, __r);
2769        __n -= __bs;
2770        __l -= __bs - 1;
2771    }
2772    return __r;
2773}
2774
2775// move construct [__f, __l) to [__r, __r + (__l-__f)).
2776// If __vt points into [__f, __l), then add (__r - __f) to __vt.
2777template <class _Tp, class _Allocator>
2778void
2779deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
2780                                                   iterator __r, const_pointer& __vt)
2781{
2782    allocator_type& __a = __base::__alloc();
2783    // as if
2784    //   for (; __f != __l; ++__r, ++__f, ++__base::size())
2785    //       __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));
2786    difference_type __n = __l - __f;
2787    while (__n > 0)
2788    {
2789        pointer __fb = __f.__ptr_;
2790        pointer __fe = *__f.__m_iter_ + __base::__block_size;
2791        difference_type __bs = __fe - __fb;
2792        if (__bs > __n)
2793        {
2794            __bs = __n;
2795            __fe = __fb + __bs;
2796        }
2797        if (__fb <= __vt && __vt < __fe)
2798            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
2799        for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
2800            __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
2801        __n -= __bs;
2802        __f += __bs;
2803    }
2804}
2805
2806// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
2807// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
2808template <class _Tp, class _Allocator>
2809void
2810deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
2811                                                            iterator __r, const_pointer& __vt)
2812{
2813    allocator_type& __a = __base::__alloc();
2814    // as if
2815    //   for (iterator __j = __l; __j != __f;)
2816    //   {
2817    //       __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));
2818    //       --__base::__start_;
2819    //       ++__base::size();
2820    //   }
2821    difference_type __n = __l - __f;
2822    while (__n > 0)
2823    {
2824        --__l;
2825        pointer __lb = *__l.__m_iter_;
2826        pointer __le = __l.__ptr_ + 1;
2827        difference_type __bs = __le - __lb;
2828        if (__bs > __n)
2829        {
2830            __bs = __n;
2831            __lb = __le - __bs;
2832        }
2833        if (__lb <= __vt && __vt < __le)
2834            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
2835        while (__le != __lb)
2836        {
2837            __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
2838            --__base::__start_;
2839            ++__base::size();
2840        }
2841        __n -= __bs;
2842        __l -= __bs - 1;
2843    }
2844}
2845
2846template <class _Tp, class _Allocator>
2847typename deque<_Tp, _Allocator>::iterator
2848deque<_Tp, _Allocator>::erase(const_iterator __f)
2849{
2850    iterator __b = __base::begin();
2851    difference_type __pos = __f - __b;
2852    iterator __p = __b + __pos;
2853    allocator_type& __a = __base::__alloc();
2854    if (static_cast<size_t>(__pos) <= (__base::size() - 1) / 2)
2855    {   // erase from front
2856        _VSTD::move_backward(__b, __p, _VSTD::next(__p));
2857        __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
2858        --__base::size();
2859        ++__base::__start_;
2860        __maybe_remove_front_spare();
2861    }
2862    else
2863    {   // erase from back
2864        iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p);
2865        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2866        --__base::size();
2867        __maybe_remove_back_spare();
2868    }
2869    return __base::begin() + __pos;
2870}
2871
2872template <class _Tp, class _Allocator>
2873typename deque<_Tp, _Allocator>::iterator
2874deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
2875{
2876    difference_type __n = __l - __f;
2877    iterator __b = __base::begin();
2878    difference_type __pos = __f - __b;
2879    iterator __p = __b + __pos;
2880    if (__n > 0)
2881    {
2882        allocator_type& __a = __base::__alloc();
2883        if (static_cast<size_t>(__pos) <= (__base::size() - __n) / 2)
2884        {   // erase from front
2885            iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
2886            for (; __b != __i; ++__b)
2887                __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
2888            __base::size() -= __n;
2889            __base::__start_ += __n;
2890            while (__maybe_remove_front_spare()) {
2891            }
2892        }
2893        else
2894        {   // erase from back
2895            iterator __i = _VSTD::move(__p + __n, __base::end(), __p);
2896            for (iterator __e = __base::end(); __i != __e; ++__i)
2897                __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
2898            __base::size() -= __n;
2899            while (__maybe_remove_back_spare()) {
2900            }
2901        }
2902    }
2903    return __base::begin() + __pos;
2904}
2905
2906template <class _Tp, class _Allocator>
2907void
2908deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
2909{
2910    iterator __e = __base::end();
2911    difference_type __n = __e - __f;
2912    if (__n > 0)
2913    {
2914        allocator_type& __a = __base::__alloc();
2915        iterator __b = __base::begin();
2916        difference_type __pos = __f - __b;
2917        for (iterator __p = __b + __pos; __p != __e; ++__p)
2918            __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
2919        __base::size() -= __n;
2920        while (__maybe_remove_back_spare()) {
2921        }
2922    }
2923}
2924
2925template <class _Tp, class _Allocator>
2926inline
2927void
2928deque<_Tp, _Allocator>::swap(deque& __c)
2929#if _LIBCPP_STD_VER >= 14
2930        _NOEXCEPT
2931#else
2932        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
2933                    __is_nothrow_swappable<allocator_type>::value)
2934#endif
2935{
2936    __base::swap(__c);
2937}
2938
2939template <class _Tp, class _Allocator>
2940inline
2941void
2942deque<_Tp, _Allocator>::clear() _NOEXCEPT
2943{
2944    __base::clear();
2945}
2946
2947template <class _Tp, class _Allocator>
2948inline _LIBCPP_INLINE_VISIBILITY
2949bool
2950operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2951{
2952    const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
2953    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
2954}
2955
2956template <class _Tp, class _Allocator>
2957inline _LIBCPP_INLINE_VISIBILITY
2958bool
2959operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2960{
2961    return !(__x == __y);
2962}
2963
2964template <class _Tp, class _Allocator>
2965inline _LIBCPP_INLINE_VISIBILITY
2966bool
2967operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2968{
2969    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
2970}
2971
2972template <class _Tp, class _Allocator>
2973inline _LIBCPP_INLINE_VISIBILITY
2974bool
2975operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2976{
2977    return __y < __x;
2978}
2979
2980template <class _Tp, class _Allocator>
2981inline _LIBCPP_INLINE_VISIBILITY
2982bool
2983operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2984{
2985    return !(__x < __y);
2986}
2987
2988template <class _Tp, class _Allocator>
2989inline _LIBCPP_INLINE_VISIBILITY
2990bool
2991operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2992{
2993    return !(__y < __x);
2994}
2995
2996template <class _Tp, class _Allocator>
2997inline _LIBCPP_INLINE_VISIBILITY
2998void
2999swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
3000    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
3001{
3002    __x.swap(__y);
3003}
3004
3005#if _LIBCPP_STD_VER > 17
3006template <class _Tp, class _Allocator, class _Up>
3007inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
3008erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
3009  auto __old_size = __c.size();
3010  __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end());
3011  return __old_size - __c.size();
3012}
3013
3014template <class _Tp, class _Allocator, class _Predicate>
3015inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
3016erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
3017  auto __old_size = __c.size();
3018  __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
3019  return __old_size - __c.size();
3020}
3021#endif
3022
3023
3024_LIBCPP_END_NAMESPACE_STD
3025
3026_LIBCPP_POP_MACROS
3027
3028#endif // _LIBCPP_DEQUE
3029