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