brintos

brintos / llvm-project-archived public Read only

0
0
Text · 99.1 KiB · ad2d759 Raw
2554 lines · plain
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP_DEQUE11#define _LIBCPP_DEQUE12 13/*14    deque synopsis15 16namespace std17{18 19template <class T, class Allocator = allocator<T> >20class deque21{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++1444    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++2352    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((allocator_traits<allocator_type>::propagate_on_container_move_assignment::value &&63                  is_nothrow_move_assignable<allocator_type>::value) ||64                 allocator_traits<allocator_type>::is_always_equal::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++2371    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++23116    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++23120    template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17121    template <class... Args> reference emplace_back(Args&&... args);   // reference in C++17122    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++23130    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++17137    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++17143 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++23147 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++20152template <class T, class Allocator>153    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20154template <class T, class Allocator>155    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20156template <class T, class Allocator>157    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20158template <class T, class Allocator>159    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20160template<class T, class Allocator>161    synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x,162                                          const deque<T, Allocator>& y);       // since C++20163 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_type171    erase(deque<T, Allocator>& c, const U& value);       // C++20172template <class T, class Allocator, class Predicate>173    typename deque<T, Allocator>::size_type174    erase_if(deque<T, Allocator>& c, Predicate pred);    // C++20175 176}  // std177 178*/179 180#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)181#  include <__cxx03/deque>182#else183#  include <__algorithm/copy.h>184#  include <__algorithm/copy_backward.h>185#  include <__algorithm/copy_n.h>186#  include <__algorithm/equal.h>187#  include <__algorithm/fill_n.h>188#  include <__algorithm/lexicographical_compare.h>189#  include <__algorithm/lexicographical_compare_three_way.h>190#  include <__algorithm/max.h>191#  include <__algorithm/min.h>192#  include <__algorithm/move.h>193#  include <__algorithm/move_backward.h>194#  include <__algorithm/remove.h>195#  include <__algorithm/remove_if.h>196#  include <__assert>197#  include <__config>198#  include <__debug_utils/sanitizers.h>199#  include <__format/enable_insertable.h>200#  include <__fwd/deque.h>201#  include <__iterator/distance.h>202#  include <__iterator/iterator_traits.h>203#  include <__iterator/move_iterator.h>204#  include <__iterator/next.h>205#  include <__iterator/prev.h>206#  include <__iterator/reverse_iterator.h>207#  include <__iterator/segmented_iterator.h>208#  include <__memory/addressof.h>209#  include <__memory/allocator.h>210#  include <__memory/allocator_destructor.h>211#  include <__memory/allocator_traits.h>212#  include <__memory/compressed_pair.h>213#  include <__memory/pointer_traits.h>214#  include <__memory/swap_allocator.h>215#  include <__memory/temp_value.h>216#  include <__memory/unique_ptr.h>217#  include <__memory_resource/polymorphic_allocator.h>218#  include <__ranges/access.h>219#  include <__ranges/concepts.h>220#  include <__ranges/container_compatible_range.h>221#  include <__ranges/from_range.h>222#  include <__split_buffer>223#  include <__type_traits/conditional.h>224#  include <__type_traits/container_traits.h>225#  include <__type_traits/enable_if.h>226#  include <__type_traits/is_allocator.h>227#  include <__type_traits/is_convertible.h>228#  include <__type_traits/is_nothrow_assignable.h>229#  include <__type_traits/is_nothrow_constructible.h>230#  include <__type_traits/is_same.h>231#  include <__type_traits/is_swappable.h>232#  include <__type_traits/is_trivially_relocatable.h>233#  include <__type_traits/type_identity.h>234#  include <__utility/exception_guard.h>235#  include <__utility/forward.h>236#  include <__utility/move.h>237#  include <__utility/pair.h>238#  include <__utility/swap.h>239#  include <limits>240#  include <stdexcept>241#  include <version>242 243// standard-mandated includes244 245// [iterator.range]246#  include <__iterator/access.h>247#  include <__iterator/data.h>248#  include <__iterator/empty.h>249#  include <__iterator/reverse_access.h>250#  include <__iterator/size.h>251 252// [deque.syn]253#  include <compare>254#  include <initializer_list>255 256#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)257#    pragma GCC system_header258#  endif259 260_LIBCPP_PUSH_MACROS261#  include <__undef_macros>262 263_LIBCPP_BEGIN_NAMESPACE_STD264 265template <class _ValueType, class _DiffType>266struct __deque_block_size {267  static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;268};269 270template <class _ValueType,271          class _Pointer,272          class _Reference,273          class _MapPointer,274          class _DiffType,275          _DiffType _BS =276#  ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE277              // Keep template parameter to avoid changing all template declarations thoughout278              // this file.279          0280#  else281              __deque_block_size<_ValueType, _DiffType>::value282#  endif283          >284class __deque_iterator {285  typedef _MapPointer __map_iterator;286 287public:288  typedef _Pointer pointer;289  typedef _DiffType difference_type;290 291private:292  __map_iterator __m_iter_;293  pointer __ptr_;294 295  static const difference_type __block_size;296 297public:298  typedef _ValueType value_type;299  typedef random_access_iterator_tag iterator_category;300  typedef _Reference reference;301 302  _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT303#  if _LIBCPP_STD_VER >= 14304      : __m_iter_(nullptr),305        __ptr_(nullptr)306#  endif307  {308  }309 310  template <class _Pp, class _Rp, class _MP, __enable_if_t<is_convertible<_Pp, pointer>::value, int> = 0>311  _LIBCPP_HIDE_FROM_ABI312  __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it) _NOEXCEPT313      : __m_iter_(__it.__m_iter_),314        __ptr_(__it.__ptr_) {}315 316  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__ptr_; }317  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return __ptr_; }318 319  _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++() {320    if (++__ptr_ - *__m_iter_ == __block_size) {321      ++__m_iter_;322      __ptr_ = *__m_iter_;323    }324    return *this;325  }326 327  _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int) {328    __deque_iterator __tmp = *this;329    ++(*this);330    return __tmp;331  }332 333  _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--() {334    if (__ptr_ == *__m_iter_) {335      --__m_iter_;336      __ptr_ = *__m_iter_ + __block_size;337    }338    --__ptr_;339    return *this;340  }341 342  _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int) {343    __deque_iterator __tmp = *this;344    --(*this);345    return __tmp;346  }347 348  _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n) {349    if (__n != 0) {350      __n += __ptr_ - *__m_iter_;351      if (__n > 0) {352        __m_iter_ += __n / __block_size;353        __ptr_ = *__m_iter_ + __n % __block_size;354      } else // (__n < 0)355      {356        difference_type __z = __block_size - 1 - __n;357        __m_iter_ -= __z / __block_size;358        __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);359      }360    }361    return *this;362  }363 364  _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n) { return *this += -__n; }365 366  _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const {367    __deque_iterator __t(*this);368    __t += __n;369    return __t;370  }371 372  _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const {373    __deque_iterator __t(*this);374    __t -= __n;375    return __t;376  }377 378  _LIBCPP_HIDE_FROM_ABI friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) {379    return __it + __n;380  }381 382  _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) {383    if (__x != __y)384      return (__x.__m_iter_ - __y.__m_iter_) * __block_size + (__x.__ptr_ - *__x.__m_iter_) -385             (__y.__ptr_ - *__y.__m_iter_);386    return 0;387  }388 389  _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const { return *(*this + __n); }390 391  _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) {392    return __x.__ptr_ == __y.__ptr_;393  }394 395#  if _LIBCPP_STD_VER <= 17396  _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) {397    return !(__x == __y);398  }399  _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) {400    return __x.__m_iter_ < __y.__m_iter_ || (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);401  }402 403  _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) {404    return __y < __x;405  }406 407  _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) {408    return !(__y < __x);409  }410 411  _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) {412    return !(__x < __y);413  }414 415#  else416 417  _LIBCPP_HIDE_FROM_ABI friend strong_ordering operator<=>(const __deque_iterator& __x, const __deque_iterator& __y) {418    if (__x.__m_iter_ < __y.__m_iter_)419      return strong_ordering::less;420 421    if (__x.__m_iter_ == __y.__m_iter_) {422      if constexpr (three_way_comparable<pointer, strong_ordering>) {423        return __x.__ptr_ <=> __y.__ptr_;424      } else {425        if (__x.__ptr_ < __y.__ptr_)426          return strong_ordering::less;427 428        if (__x.__ptr_ == __y.__ptr_)429          return strong_ordering::equal;430 431        return strong_ordering::greater;432      }433    }434 435    return strong_ordering::greater;436  }437#  endif // _LIBCPP_STD_VER >= 20438 439private:440  _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT441      : __m_iter_(__m),442        __ptr_(__p) {}443 444  template <class _Tp, class _Ap>445  friend class deque;446  template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>447  friend class __deque_iterator;448 449  template <class>450  friend struct __segmented_iterator_traits;451};452 453template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize>454struct __segmented_iterator_traits<455    __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > {456private:457  using _Iterator _LIBCPP_NODEBUG =458      __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>;459 460public:461  using __segment_iterator _LIBCPP_NODEBUG = _MapPointer;462  using __local_iterator _LIBCPP_NODEBUG   = _Pointer;463 464  static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; }465  static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; }466  static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; }467 468  static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {469    return *__iter + _Iterator::__block_size;470  }471 472  static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) {473    if (__segment && __local == __end(__segment)) {474      ++__segment;475      return _Iterator(__segment, *__segment);476    }477    return _Iterator(__segment, __local);478  }479};480 481template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize>482const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>::__block_size =483    __deque_block_size<_ValueType, _DiffType>::value;484 485template <class _Tp, class _Allocator /*= allocator<_Tp>*/>486class deque {487  template <class _Up, class _Alloc>488  using __split_buffer _LIBCPP_NODEBUG = std::__split_buffer<_Up, _Alloc, __split_buffer_pointer_layout>;489 490public:491  // types:492 493  using value_type = _Tp;494 495  using allocator_type                 = _Allocator;496  using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;497  static_assert(__check_valid_allocator<allocator_type>::value, "");498  static_assert(is_same<typename allocator_type::value_type, value_type>::value,499                "Allocator::value_type must be same type as value_type");500 501  using size_type       = typename __alloc_traits::size_type;502  using difference_type = typename __alloc_traits::difference_type;503 504  using pointer       = typename __alloc_traits::pointer;505  using const_pointer = typename __alloc_traits::const_pointer;506 507  using __pointer_allocator _LIBCPP_NODEBUG       = __rebind_alloc<__alloc_traits, pointer>;508  using __const_pointer_allocator _LIBCPP_NODEBUG = __rebind_alloc<__alloc_traits, const_pointer>;509  using __map _LIBCPP_NODEBUG                     = __split_buffer<pointer, __pointer_allocator>;510  using __map_alloc_traits _LIBCPP_NODEBUG        = allocator_traits<__pointer_allocator>;511  using __map_pointer _LIBCPP_NODEBUG             = typename __map_alloc_traits::pointer;512  using __map_const_pointer _LIBCPP_NODEBUG       = typename allocator_traits<__const_pointer_allocator>::const_pointer;513  using __map_const_iterator _LIBCPP_NODEBUG      = typename __map::const_iterator;514 515  using reference       = value_type&;516  using const_reference = const value_type&;517 518  using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>;519  using const_iterator =520      __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>;521  using reverse_iterator       = std::reverse_iterator<iterator>;522  using const_reverse_iterator = std::reverse_iterator<const_iterator>;523 524  // A deque contains the following members which may be trivially relocatable:525  // - __map: is a `__split_buffer`, see `__split_buffer` for more information on when it is trivially relocatable526  // - size_type: is always trivially relocatable, since it is required to be an integral type527  // - allocator_type: may not be trivially relocatable, so it's checked528  // None of these are referencing the `deque` itself, so if all of them are trivially relocatable, `deque` is too.529  using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<530      __libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,531      deque,532      void>;533 534  static_assert(is_nothrow_default_constructible<allocator_type>::value ==535                    is_nothrow_default_constructible<__pointer_allocator>::value,536                "rebinding an allocator should not change exception guarantees");537  static_assert(is_nothrow_move_constructible<allocator_type>::value ==538                    is_nothrow_move_constructible<typename __map::allocator_type>::value,539                "rebinding an allocator should not change exception guarantees");540 541private:542  struct __deque_block_range {543    explicit _LIBCPP_HIDE_FROM_ABI __deque_block_range(pointer __b, pointer __e) _NOEXCEPT544        : __begin_(__b),545          __end_(__e) {}546    const pointer __begin_;547    const pointer __end_;548  };549 550  struct __deque_range {551    iterator __pos_;552    const iterator __end_;553 554    _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT : __pos_(__pos), __end_(__e) {}555 556    explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { return __pos_ != __end_; }557 558    _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { return *this; }559 560    _LIBCPP_HIDE_FROM_ABI __deque_range end() const { return __deque_range(__end_, __end_); }561    _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT {562      if (__pos_.__m_iter_ == __end_.__m_iter_) {563        return __deque_block_range(__pos_.__ptr_, __end_.__ptr_);564      }565      return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size);566    }567 568    _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT {569      if (__pos_.__m_iter_ == __end_.__m_iter_) {570        __pos_ = __end_;571      } else {572        ++__pos_.__m_iter_;573        __pos_.__ptr_ = *__pos_.__m_iter_;574      }575      return *this;576    }577 578    _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) {579      return __lhs.__pos_ == __rhs.__pos_;580    }581    _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) {582      return !(__lhs == __rhs);583    }584  };585 586  struct _ConstructTransaction {587    _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r)588        : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {}589 590    _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { __base_->__size() += (__pos_ - __begin_); }591 592    pointer __pos_;593    const pointer __end_;594 595  private:596    const pointer __begin_;597    deque* const __base_;598  };599 600  static const difference_type __block_size;601 602  __map __map_;603  size_type __start_;604  _LIBCPP_COMPRESSED_PAIR(size_type, __size_, allocator_type, __alloc_);605 606public:607  // construct/copy/destroy:608  _LIBCPP_HIDE_FROM_ABI deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)609      : __start_(0), __size_(0) {610    __annotate_new(0);611  }612 613  _LIBCPP_HIDE_FROM_ABI ~deque() {614    clear();615    __annotate_delete();616    typename __map::iterator __i = __map_.begin();617    typename __map::iterator __e = __map_.end();618    for (; __i != __e; ++__i)619      __alloc_traits::deallocate(__alloc(), *__i, __block_size);620  }621 622  _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a)623      : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) {624    __annotate_new(0);625  }626 627  explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n);628#  if _LIBCPP_STD_VER >= 14629  explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a);630#  endif631  _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v);632 633  template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0>634  _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a)635      : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) {636    __annotate_new(0);637    if (__n > 0)638      __append(__n, __v);639  }640 641  template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0>642  _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l);643  template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0>644  _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a);645 646#  if _LIBCPP_STD_VER >= 23647  template <_ContainerCompatibleRange<_Tp> _Range>648  _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())649      : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) {650    if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {651      __append_with_size(ranges::begin(__range), ranges::distance(__range));652 653    } else {654      for (auto&& __e : __range) {655        emplace_back(std::forward<decltype(__e)>(__e));656      }657    }658  }659#  endif660 661  _LIBCPP_HIDE_FROM_ABI deque(const deque& __c);662  _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a);663 664  _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c);665 666#  ifndef _LIBCPP_CXX03_LANG667  _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il);668  _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a);669 670  _LIBCPP_HIDE_FROM_ABI deque& operator=(initializer_list<value_type> __il) {671    assign(__il);672    return *this;673  }674 675  _LIBCPP_HIDE_FROM_ABI deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value);676  _LIBCPP_HIDE_FROM_ABI deque(deque&& __c, const __type_identity_t<allocator_type>& __a);677  _LIBCPP_HIDE_FROM_ABI deque& operator=(deque&& __c) noexcept(678      (__alloc_traits::propagate_on_container_move_assignment::value &&679       is_nothrow_move_assignable<allocator_type>::value) ||680      __alloc_traits::is_always_equal::value);681 682  _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) { assign(__il.begin(), __il.end()); }683#  endif // _LIBCPP_CXX03_LANG684 685  template <class _InputIter,686            __enable_if_t<__has_input_iterator_category<_InputIter>::value &&687                              !__has_random_access_iterator_category<_InputIter>::value,688                          int> = 0>689  _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l);690  template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> = 0>691  _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l);692 693#  if _LIBCPP_STD_VER >= 23694  template <_ContainerCompatibleRange<_Tp> _Range>695  _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) {696    if constexpr (ranges::random_access_range<_Range>) {697      auto __n = static_cast<size_type>(ranges::distance(__range));698      __assign_with_size_random_access(ranges::begin(__range), __n);699 700    } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {701      auto __n = static_cast<size_type>(ranges::distance(__range));702      __assign_with_size(ranges::begin(__range), __n);703 704    } else {705      __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));706    }707  }708#  endif709 710  _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);711 712  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT;713  _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __alloc_; }714  _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __alloc_; }715 716  // iterators:717 718  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {719    __map_pointer __mp = __map_.begin() + __start_ / __block_size;720    return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);721  }722 723  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {724    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);725    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);726  }727 728  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {729    size_type __p      = size() + __start_;730    __map_pointer __mp = __map_.begin() + __p / __block_size;731    return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);732  }733 734  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {735    size_type __p            = size() + __start_;736    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);737    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);738  }739 740  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }741  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {742    return const_reverse_iterator(end());743  }744  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }745  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {746    return const_reverse_iterator(begin());747  }748 749  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }750  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }751  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {752    return const_reverse_iterator(end());753  }754  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {755    return const_reverse_iterator(begin());756  }757 758  // capacity:759  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); }760 761  _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_; }762  _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_; }763 764  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {765    return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max());766  }767  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);768  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);769  _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;770  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; }771 772  // element access:773  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT;774  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT;775  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference at(size_type __i);776  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const;777  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT;778  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT;779  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT;780  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT;781 782  // 23.2.2.3 modifiers:783  _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);784  _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v);785 786  template <class... _Args>787  _LIBCPP_HIDE_FROM_ABI iterator __emplace(const_iterator __p, _Args&&... __args);788 789#  ifndef _LIBCPP_CXX03_LANG790#    if _LIBCPP_STD_VER >= 17791  template <class... _Args>792  _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);793  template <class... _Args>794  _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args);795#    else796  template <class... _Args>797  _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args);798  template <class... _Args>799  _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);800#    endif801 802  template <class... _Args>803  _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args) {804    return __emplace(__p, std::forward<_Args>(__args)...);805  }806 807  _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);808  _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v);809 810#    if _LIBCPP_STD_VER >= 23811  template <_ContainerCompatibleRange<_Tp> _Range>812  _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) {813    insert_range(begin(), std::forward<_Range>(__range));814  }815 816  template <_ContainerCompatibleRange<_Tp> _Range>817  _LIBCPP_HIDE_FROM_ABI void append_range(_Range&& __range) {818    insert_range(end(), std::forward<_Range>(__range));819  }820#    endif821 822  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) { return __emplace(__p, std::move(__v)); }823 824  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, initializer_list<value_type> __il) {825    return insert(__p, __il.begin(), __il.end());826  }827#  endif // _LIBCPP_CXX03_LANG828  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) { return __emplace(__p, __v); }829  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v);830  template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0>831  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l);832  template <class _ForwardIterator,833            __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> = 0>834  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l);835  template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> = 0>836  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l);837 838#  if _LIBCPP_STD_VER >= 23839  template <_ContainerCompatibleRange<_Tp> _Range>840  _LIBCPP_HIDE_FROM_ABI iterator insert_range(const_iterator __position, _Range&& __range) {841    if constexpr (ranges::bidirectional_range<_Range>) {842      auto __n = static_cast<size_type>(ranges::distance(__range));843      return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n);844 845    } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {846      auto __n = static_cast<size_type>(ranges::distance(__range));847      return __insert_with_size(__position, ranges::begin(__range), __n);848 849    } else {850      return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));851    }852  }853#  endif854 855  _LIBCPP_HIDE_FROM_ABI void pop_front();856  _LIBCPP_HIDE_FROM_ABI void pop_back();857  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);858  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);859 860  _LIBCPP_HIDE_FROM_ABI void swap(deque& __c)861#  if _LIBCPP_STD_VER >= 14862      _NOEXCEPT;863#  else864      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);865#  endif866  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;867 868  _LIBCPP_HIDE_FROM_ABI bool __invariants() const {869    if (!__map_.__invariants())870      return false;871    if (__map_.size() >= size_type(-1) / __block_size)872      return false;873    for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); __i != __e; ++__i)874      if (*__i == nullptr)875        return false;876    if (__map_.size() != 0) {877      if (size() >= __map_.size() * __block_size)878        return false;879      if (__start_ >= __map_.size() * __block_size - size())880        return false;881    } else {882      if (size() != 0)883        return false;884      if (__start_ != 0)885        return false;886    }887    return true;888  }889 890  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c)891      _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||892                 is_nothrow_move_assignable<allocator_type>::value) {893    __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());894  }895 896  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c, true_type)897      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {898    __alloc() = std::move(__c.__alloc());899  }900 901  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque&, false_type) _NOEXCEPT {}902 903  _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c)904      _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value&&905                     is_nothrow_move_assignable<allocator_type>::value) {906    __map_   = std::move(__c.__map_);907    __start_ = __c.__start_;908    __size() = __c.size();909    __move_assign_alloc(__c);910    __c.__start_ = __c.__size() = 0;911  }912 913  _LIBCPP_HIDE_FROM_ABI static size_type __recommend_blocks(size_type __n) {914    return __n / __block_size + (__n % __block_size != 0);915  }916  _LIBCPP_HIDE_FROM_ABI size_type __capacity() const {917    return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1;918  }919  _LIBCPP_HIDE_FROM_ABI size_type __block_count() const { return __map_.size(); }920 921  _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const { return __start_; }922  _LIBCPP_HIDE_FROM_ABI size_type __front_spare_blocks() const { return __front_spare() / __block_size; }923  _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const { return __capacity() - (__start_ + size()); }924  _LIBCPP_HIDE_FROM_ABI size_type __back_spare_blocks() const { return __back_spare() / __block_size; }925 926private:927  enum __asan_annotation_type { __asan_unposion, __asan_poison };928 929  enum __asan_annotation_place {930    __asan_front_moved,931    __asan_back_moved,932  };933 934  _LIBCPP_HIDE_FROM_ABI void __annotate_from_to(935      size_type __beg,936      size_type __end,937      __asan_annotation_type __annotation_type,938      __asan_annotation_place __place) const _NOEXCEPT {939    (void)__beg;940    (void)__end;941    (void)__annotation_type;942    (void)__place;943#  if __has_feature(address_sanitizer)944    // __beg - index of the first item to annotate945    // __end - index behind the last item to annotate (so last item + 1)946    // __annotation_type - __asan_unposion or __asan_poison947    // __place - __asan_front_moved or __asan_back_moved948    // Note: All indexes in __map_949    if (__beg == __end)950      return;951    // __annotations_beg_map - first chunk which annotations we want to modify952    // __annotations_end_map - last chunk which annotations we want to modify953    // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist954    __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size;955    __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size;956 957    bool const __poisoning = __annotation_type == __asan_poison;958    // __old_c_beg_index - index of the first element in old container959    // __old_c_end_index - index of the end of old container (last + 1)960    // Note: may be outside the area we are annotating961    size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_;962    size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size();963    bool const __front       = __place == __asan_front_moved;964 965    if (__poisoning && empty()) {966      // Special case: we shouldn't trust __start_967      __old_c_beg_index = __beg;968      __old_c_end_index = __end;969    }970    // __old_c_beg_map - memory block (chunk) with first element971    // __old_c_end_map - memory block (chunk) with end of old container972    // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block,973    // which may not exist974    __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size;975    __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size;976 977    // One edge (front/end) of the container was moved and one was not modified.978    // __new_edge_index - index of new edge979    // __new_edge_map    - memory block (chunk) with new edge, it always equals to980    //                    __annotations_beg_map or __annotations_end_map981    // __old_edge_map    - memory block (chunk) with old edge, it always equals to982    //                    __old_c_beg_map or __old_c_end_map983    size_t __new_edge_index             = (__poisoning ^ __front) ? __beg : __end;984    __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size;985    __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map;986 987    // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last.988    // First and last chunk may be partially poisoned.989    // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it.990    for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) {991      if (__map_it == __annotations_end_map && __end % __block_size == 0)992        // Chunk may not exist, but nothing to do here anyway993        break;994 995      // The beginning and the end of the current memory block996      const void* __mem_beg = std::__to_address(*__map_it);997      const void* __mem_end = std::__to_address(*__map_it + __block_size);998 999      // The beginning of memory-in-use in the memory block before container modification1000      const void* __old_beg =1001          (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg;1002 1003      // The end of memory-in-use in the memory block before container modification1004      const void* __old_end;1005      if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty()))1006        __old_end = __old_beg;1007      else1008        __old_end = (__map_it == __old_c_end_map)1009                      ? std::__to_address(*__map_it + (__old_c_end_index % __block_size))1010                      : __mem_end;1011 1012      // New edge of the container in current memory block1013      // If the edge is in a different chunk it points on corresponding end of the memory block1014      const void* __new_edge;1015      if (__map_it == __new_edge_map)1016        __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size));1017      else1018        __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end;1019 1020      // Not modified edge of the container1021      // If the edge is in a different chunk it points on corresponding end of the memory block1022      const void* __old_edge;1023      if (__map_it == __old_edge_map)1024        __old_edge = __front ? __old_end : __old_beg;1025      else1026        __old_edge = __front ? __mem_end : __mem_beg;1027 1028      // __new_beg - the beginning of memory-in-use in the memory block after container modification1029      // __new_end - the end of memory-in-use in the memory block after container modification1030      const void* __new_beg = __front ? __new_edge : __old_edge;1031      const void* __new_end = __front ? __old_edge : __new_edge;1032 1033      std::__annotate_double_ended_contiguous_container<_Allocator>(1034          __mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end);1035    }1036#  endif // __has_feature(address_sanitizer)1037  }1038 1039  _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT {1040    (void)__current_size;1041#  if __has_feature(address_sanitizer)1042    if (__current_size == 0)1043      __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved);1044    else {1045      __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved);1046      __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved);1047    }1048#  endif // __has_feature(address_sanitizer)1049  }1050 1051  _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT {1052#  if __has_feature(address_sanitizer)1053    if (empty()) {1054      for (size_t __i = 0; __i < __map_.size(); ++__i) {1055        __annotate_whole_block(__i, __asan_unposion);1056      }1057    } else {1058      __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved);1059      __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved);1060    }1061#  endif // __has_feature(address_sanitizer)1062  }1063 1064  _LIBCPP_HIDE_FROM_ABI void __annotate_increase_front(size_type __n) const _NOEXCEPT {1065    (void)__n;1066#  if __has_feature(address_sanitizer)1067    __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved);1068#  endif1069  }1070 1071  _LIBCPP_HIDE_FROM_ABI void __annotate_increase_back(size_type __n) const _NOEXCEPT {1072    (void)__n;1073#  if __has_feature(address_sanitizer)1074    __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved);1075#  endif1076  }1077 1078  _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT {1079    (void)__old_size;1080    (void)__old_start;1081#  if __has_feature(address_sanitizer)1082    __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved);1083#  endif1084  }1085 1086  _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT {1087    (void)__old_size;1088    (void)__old_start;1089#  if __has_feature(address_sanitizer)1090    __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved);1091#  endif1092  }1093 1094  _LIBCPP_HIDE_FROM_ABI void __annotate_poison_block(const void* __beginning, const void* __end) const _NOEXCEPT {1095    std::__annotate_double_ended_contiguous_container<_Allocator>(__beginning, __end, __beginning, __end, __end, __end);1096  }1097 1098  _LIBCPP_HIDE_FROM_ABI void1099  __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT {1100    (void)__block_index;1101    (void)__annotation_type;1102#  if __has_feature(address_sanitizer)1103    __map_const_iterator __block_it = __map_.begin() + __block_index;1104    const void* __block_start       = std::__to_address(*__block_it);1105    const void* __block_end         = std::__to_address(*__block_it + __block_size);1106 1107    if (__annotation_type == __asan_poison)1108      __annotate_poison_block(__block_start, __block_end);1109    else {1110      std::__annotate_double_ended_contiguous_container<_Allocator>(1111          __block_start, __block_end, __block_start, __block_start, __block_start, __block_end);1112    }1113#  endif1114  }1115#  if __has_feature(address_sanitizer)1116 1117public:1118  _LIBCPP_HIDE_FROM_ABI bool __verify_asan_annotations() const _NOEXCEPT {1119    // This function tests deque object annotations.1120    if (empty()) {1121      for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {1122        if (!__sanitizer_verify_double_ended_contiguous_container(1123                std::__to_address(*__it),1124                std::__to_address(*__it),1125                std::__to_address(*__it),1126                std::__to_address(*__it + __block_size)))1127          return false;1128      }1129 1130      return true;1131    }1132 1133    size_type __end                 = __start_ + size();1134    __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size;1135    __map_const_iterator __last_mp  = __map_.begin() + (__end - 1) / __block_size;1136 1137    // Pointers to first and after last elements1138    // Those can be in different deque blocks1139    const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size));1140    const void* __p_end =1141        std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size));1142 1143    for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {1144      // Go over all blocks, find the place we are in and verify its annotations1145      // Note that __p_end points *behind* the last item.1146 1147      // - blocks before the first block with container elements1148      // - first block with items1149      // - last block with items1150      // - blocks after last block with ciontainer elements1151 1152      // Is the block before or after deque blocks that contain elements?1153      if (__it < __first_mp || __it > __last_mp) {1154        if (!__sanitizer_verify_double_ended_contiguous_container(1155                std::__to_address(*__it),1156                std::__to_address(*__it),1157                std::__to_address(*__it),1158                std::__to_address(*__it + __block_size)))1159          return false;1160      } else {1161        const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it);1162        const void* __containers_buffer_end =1163            (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size);1164        if (!__sanitizer_verify_double_ended_contiguous_container(1165                std::__to_address(*__it),1166                __containers_buffer_beg,1167                __containers_buffer_end,1168                std::__to_address(*__it + __block_size))) {1169          return false;1170        }1171      }1172    }1173    return true;1174  }1175 1176private:1177#  endif // __has_feature(address_sanitizer)1178  _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_front_spare(bool __keep_one = true) {1179    if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {1180      __annotate_whole_block(0, __asan_unposion);1181      __alloc_traits::deallocate(__alloc(), __map_.front(), __block_size);1182      __map_.pop_front();1183      __start_ -= __block_size;1184      return true;1185    }1186    return false;1187  }1188 1189  _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_back_spare(bool __keep_one = true) {1190    if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {1191      __annotate_whole_block(__map_.size() - 1, __asan_unposion);1192      __alloc_traits::deallocate(__alloc(), __map_.back(), __block_size);1193      __map_.pop_back();1194      return true;1195    }1196    return false;1197  }1198 1199  template <class _Iterator, class _Sentinel>1200  _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __f, _Sentinel __l);1201 1202  template <class _RandomAccessIterator>1203  _LIBCPP_HIDE_FROM_ABI void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n);1204  template <class _Iterator>1205  _LIBCPP_HIDE_FROM_ABI void __assign_with_size(_Iterator __f, difference_type __n);1206 1207  template <class _Iterator, class _Sentinel>1208  _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l);1209 1210  template <class _Iterator>1211  _LIBCPP_HIDE_FROM_ABI iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n);1212 1213  template <class _BiIter, class _Sentinel>1214  _LIBCPP_HIDE_FROM_ABI iterator1215  __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n);1216  template <class _BiIter>1217  _LIBCPP_HIDE_FROM_ABI iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n);1218 1219  template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> = 0>1220  _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l);1221  template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> = 0>1222  _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l);1223 1224  template <class _InputIterator>1225  _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n);1226  template <class _InputIterator, class _Sentinel>1227  _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l);1228 1229  _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);1230  _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v);1231  _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f);1232  _LIBCPP_HIDE_FROM_ABI void __add_front_capacity();1233  _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n);1234  _LIBCPP_HIDE_FROM_ABI void __add_back_capacity();1235  _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n);1236  _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt);1237  _LIBCPP_HIDE_FROM_ABI iterator1238  __move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt);1239  _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt);1240  _LIBCPP_HIDE_FROM_ABI void1241  __move_construct_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt);1242 1243  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c) {1244    __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>());1245  }1246 1247  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c, true_type) {1248    if (__alloc() != __c.__alloc()) {1249      clear();1250      shrink_to_fit();1251    }1252    __alloc()                = __c.__alloc();1253    __map_.__get_allocator() = __c.__map_.__get_allocator();1254  }1255 1256  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {}1257 1258  _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type)1259      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);1260  _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type);1261};1262 1263template <class _Tp, class _Alloc>1264_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size =1265    __deque_block_size<value_type, difference_type>::value;1266 1267#  if _LIBCPP_STD_VER >= 171268template <class _InputIterator,1269          class _Alloc = allocator<__iterator_value_type<_InputIterator>>,1270          class        = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,1271          class        = enable_if_t<__is_allocator_v<_Alloc>>>1272deque(_InputIterator, _InputIterator) -> deque<__iterator_value_type<_InputIterator>, _Alloc>;1273 1274template <class _InputIterator,1275          class _Alloc,1276          class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,1277          class = enable_if_t<__is_allocator_v<_Alloc>>>1278deque(_InputIterator, _InputIterator, _Alloc) -> deque<__iterator_value_type<_InputIterator>, _Alloc>;1279#  endif1280 1281#  if _LIBCPP_STD_VER >= 231282template <ranges::input_range _Range,1283          class _Alloc = allocator<ranges::range_value_t<_Range>>,1284          class        = enable_if_t<__is_allocator_v<_Alloc>>>1285deque(from_range_t, _Range&&, _Alloc = _Alloc()) -> deque<ranges::range_value_t<_Range>, _Alloc>;1286#  endif1287 1288template <class _Tp, class _Allocator>1289deque<_Tp, _Allocator>::deque(size_type __n) : __start_(0), __size_(0) {1290  __annotate_new(0);1291  if (__n > 0)1292    __append(__n);1293}1294 1295#  if _LIBCPP_STD_VER >= 141296template <class _Tp, class _Allocator>1297deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)1298    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) {1299  __annotate_new(0);1300  if (__n > 0)1301    __append(__n);1302}1303#  endif1304 1305template <class _Tp, class _Allocator>1306deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) : __start_(0), __size_(0) {1307  __annotate_new(0);1308  if (__n > 0)1309    __append(__n, __v);1310}1311 1312template <class _Tp, class _Allocator>1313template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> >1314deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l) : __start_(0), __size_(0) {1315  __annotate_new(0);1316  __append(__f, __l);1317}1318 1319template <class _Tp, class _Allocator>1320template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> >1321deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a)1322    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) {1323  __annotate_new(0);1324  __append(__f, __l);1325}1326 1327template <class _Tp, class _Allocator>1328deque<_Tp, _Allocator>::deque(const deque& __c)1329    : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))),1330      __start_(0),1331      __size_(0),1332      __alloc_(__map_.__get_allocator()) {1333  __annotate_new(0);1334  __append(__c.begin(), __c.end());1335}1336 1337template <class _Tp, class _Allocator>1338deque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a)1339    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) {1340  __annotate_new(0);1341  __append(__c.begin(), __c.end());1342}1343 1344template <class _Tp, class _Allocator>1345deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(const deque& __c) {1346  if (this != std::addressof(__c)) {1347    __copy_assign_alloc(__c);1348    assign(__c.begin(), __c.end());1349  }1350  return *this;1351}1352 1353#  ifndef _LIBCPP_CXX03_LANG1354 1355template <class _Tp, class _Allocator>1356deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il) : __start_(0), __size_(0) {1357  __annotate_new(0);1358  __append(__il.begin(), __il.end());1359}1360 1361template <class _Tp, class _Allocator>1362deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)1363    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) {1364  __annotate_new(0);1365  __append(__il.begin(), __il.end());1366}1367 1368template <class _Tp, class _Allocator>1369inline deque<_Tp, _Allocator>::deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value)1370    : __map_(std::move(__c.__map_)),1371      __start_(std::move(__c.__start_)),1372      __size_(std::move(__c.__size_)),1373      __alloc_(std::move(__c.__alloc_)) {1374  __c.__start_ = 0;1375  __c.__size() = 0;1376}1377 1378template <class _Tp, class _Allocator>1379inline deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a)1380    : __map_(std::move(__c.__map_), __pointer_allocator(__a)),1381      __start_(std::move(__c.__start_)),1382      __size_(std::move(__c.__size_)),1383      __alloc_(__a) {1384  if (__a == __c.__alloc()) {1385    __c.__start_ = 0;1386    __c.__size() = 0;1387  } else {1388    __map_.clear();1389    __start_ = 0;1390    __size() = 0;1391    typedef move_iterator<iterator> _Ip;1392    assign(_Ip(__c.begin()), _Ip(__c.end()));1393  }1394}1395 1396template <class _Tp, class _Allocator>1397inline deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(deque&& __c) noexcept(1398    (__alloc_traits::propagate_on_container_move_assignment::value &&1399     is_nothrow_move_assignable<allocator_type>::value) ||1400    __alloc_traits::is_always_equal::value) {1401  __move_assign(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());1402  return *this;1403}1404 1405template <class _Tp, class _Allocator>1406void deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) {1407  if (__alloc() != __c.__alloc()) {1408    typedef move_iterator<iterator> _Ip;1409    assign(_Ip(__c.begin()), _Ip(__c.end()));1410  } else1411    __move_assign(__c, true_type());1412}1413 1414template <class _Tp, class _Allocator>1415void deque<_Tp, _Allocator>::__move_assign(deque& __c,1416                                           true_type) noexcept(is_nothrow_move_assignable<allocator_type>::value) {1417  clear();1418  shrink_to_fit();1419  __move_assign(__c);1420}1421 1422#  endif // _LIBCPP_CXX03_LANG1423 1424template <class _Tp, class _Allocator>1425template <class _InputIter,1426          __enable_if_t<__has_input_iterator_category<_InputIter>::value &&1427                            !__has_random_access_iterator_category<_InputIter>::value,1428                        int> >1429void deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l) {1430  __assign_with_sentinel(__f, __l);1431}1432 1433template <class _Tp, class _Allocator>1434template <class _Iterator, class _Sentinel>1435_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) {1436  iterator __i = begin();1437  iterator __e = end();1438  for (; __f != __l && __i != __e; ++__f, (void)++__i)1439    *__i = *__f;1440  if (__f != __l)1441    __append_with_sentinel(std::move(__f), std::move(__l));1442  else1443    __erase_to_end(__i);1444}1445 1446template <class _Tp, class _Allocator>1447template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> >1448void deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l) {1449  __assign_with_size_random_access(__f, __l - __f);1450}1451 1452template <class _Tp, class _Allocator>1453template <class _RandomAccessIterator>1454_LIBCPP_HIDE_FROM_ABI void1455deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) {1456  if (static_cast<size_type>(__n) > size()) {1457    auto __l = __f + size();1458    std::copy(__f, __l, begin());1459    __append_with_size(__l, __n - size());1460  } else1461    __erase_to_end(std::copy_n(__f, __n, begin()));1462}1463 1464template <class _Tp, class _Allocator>1465template <class _Iterator>1466_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) {1467  if (static_cast<size_type>(__n) > size()) {1468    auto __added_size = __n - size();1469 1470    auto __i = begin();1471    for (auto __count = size(); __count != 0; --__count) {1472      *__i++ = *__f++;1473    }1474 1475    __append_with_size(__f, __added_size);1476 1477  } else {1478    __erase_to_end(std::copy_n(__f, __n, begin()));1479  }1480}1481 1482template <class _Tp, class _Allocator>1483void deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) {1484  if (__n > size()) {1485    std::fill_n(begin(), size(), __v);1486    __n -= size();1487    __append(__n, __v);1488  } else1489    __erase_to_end(std::fill_n(begin(), __n, __v));1490}1491 1492template <class _Tp, class _Allocator>1493inline _Allocator deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT {1494  return __alloc();1495}1496 1497template <class _Tp, class _Allocator>1498void deque<_Tp, _Allocator>::resize(size_type __n) {1499  if (__n > size())1500    __append(__n - size());1501  else if (__n < size())1502    __erase_to_end(begin() + __n);1503}1504 1505template <class _Tp, class _Allocator>1506void deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) {1507  if (__n > size())1508    __append(__n - size(), __v);1509  else if (__n < size())1510    __erase_to_end(begin() + __n);1511}1512 1513template <class _Tp, class _Allocator>1514void deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT {1515  allocator_type& __a = __alloc();1516  if (empty()) {1517    __annotate_delete();1518    while (__map_.size() > 0) {1519      __alloc_traits::deallocate(__a, __map_.back(), __block_size);1520      __map_.pop_back();1521    }1522    __start_ = 0;1523  } else {1524    __maybe_remove_front_spare(/*__keep_one=*/false);1525    __maybe_remove_back_spare(/*__keep_one=*/false);1526  }1527  __map_.shrink_to_fit();1528}1529 1530template <class _Tp, class _Allocator>1531inline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT {1532  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "deque::operator[] index out of bounds");1533  size_type __p = __start_ + __i;1534  return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);1535}1536 1537template <class _Tp, class _Allocator>1538inline typename deque<_Tp, _Allocator>::const_reference1539deque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT {1540  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "deque::operator[] index out of bounds");1541  size_type __p = __start_ + __i;1542  return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);1543}1544 1545template <class _Tp, class _Allocator>1546inline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::at(size_type __i) {1547  if (__i >= size())1548    std::__throw_out_of_range("deque");1549  size_type __p = __start_ + __i;1550  return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);1551}1552 1553template <class _Tp, class _Allocator>1554inline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::at(size_type __i) const {1555  if (__i >= size())1556    std::__throw_out_of_range("deque");1557  size_type __p = __start_ + __i;1558  return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);1559}1560 1561template <class _Tp, class _Allocator>1562inline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::front() _NOEXCEPT {1563  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::front called on an empty deque");1564  return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size);1565}1566 1567template <class _Tp, class _Allocator>1568inline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::front() const _NOEXCEPT {1569  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::front called on an empty deque");1570  return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size);1571}1572 1573template <class _Tp, class _Allocator>1574inline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::back() _NOEXCEPT {1575  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::back called on an empty deque");1576  size_type __p = size() + __start_ - 1;1577  return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);1578}1579 1580template <class _Tp, class _Allocator>1581inline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::back() const _NOEXCEPT {1582  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::back called on an empty deque");1583  size_type __p = size() + __start_ - 1;1584  return *(*(__map_.begin() + __p / __block_size) + __p % __block_size);1585}1586 1587template <class _Tp, class _Allocator>1588void deque<_Tp, _Allocator>::push_back(const value_type& __v) {1589  allocator_type& __a = __alloc();1590  if (__back_spare() == 0)1591    __add_back_capacity();1592  // __back_spare() >= 11593  __annotate_increase_back(1);1594  __alloc_traits::construct(__a, std::addressof(*end()), __v);1595  ++__size();1596}1597 1598template <class _Tp, class _Allocator>1599void deque<_Tp, _Allocator>::push_front(const value_type& __v) {1600  allocator_type& __a = __alloc();1601  if (__front_spare() == 0)1602    __add_front_capacity();1603  // __front_spare() >= 11604  __annotate_increase_front(1);1605  __alloc_traits::construct(__a, std::addressof(*--begin()), __v);1606  --__start_;1607  ++__size();1608}1609 1610#  ifndef _LIBCPP_CXX03_LANG1611template <class _Tp, class _Allocator>1612void deque<_Tp, _Allocator>::push_back(value_type&& __v) {1613  allocator_type& __a = __alloc();1614  if (__back_spare() == 0)1615    __add_back_capacity();1616  // __back_spare() >= 11617  __annotate_increase_back(1);1618  __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v));1619  ++__size();1620}1621 1622template <class _Tp, class _Allocator>1623template <class... _Args>1624#    if _LIBCPP_STD_VER >= 171625typename deque<_Tp, _Allocator>::reference1626#    else1627void1628#    endif1629deque<_Tp, _Allocator>::emplace_back(_Args&&... __args) {1630  allocator_type& __a = __alloc();1631  if (__back_spare() == 0)1632    __add_back_capacity();1633  // __back_spare() >= 11634  __annotate_increase_back(1);1635  __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...);1636  ++__size();1637#    if _LIBCPP_STD_VER >= 171638  return *--end();1639#    endif1640}1641 1642template <class _Tp, class _Allocator>1643void deque<_Tp, _Allocator>::push_front(value_type&& __v) {1644  allocator_type& __a = __alloc();1645  if (__front_spare() == 0)1646    __add_front_capacity();1647  // __front_spare() >= 11648  __annotate_increase_front(1);1649  __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v));1650  --__start_;1651  ++__size();1652}1653 1654template <class _Tp, class _Allocator>1655template <class... _Args>1656#    if _LIBCPP_STD_VER >= 171657typename deque<_Tp, _Allocator>::reference1658#    else1659void1660#    endif1661deque<_Tp, _Allocator>::emplace_front(_Args&&... __args) {1662  allocator_type& __a = __alloc();1663  if (__front_spare() == 0)1664    __add_front_capacity();1665  // __front_spare() >= 11666  __annotate_increase_front(1);1667  __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...);1668  --__start_;1669  ++__size();1670#    if _LIBCPP_STD_VER >= 171671  return *begin();1672#    endif1673}1674#  endif // _LIBCPP_CXX03_LANG1675 1676template <class _Tp, class _Allocator>1677template <class... _Args>1678typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::__emplace(const_iterator __p, _Args&&... __args) {1679  size_type __pos     = __p - begin();1680  size_type __to_end  = size() - __pos;1681  allocator_type& __a = __alloc();1682  if (__pos < __to_end) { // insert by shifting things backward1683    if (__front_spare() == 0)1684      __add_front_capacity();1685    // __front_spare() >= 11686    __annotate_increase_front(1);1687    if (__pos == 0) {1688      __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...);1689      --__start_;1690      ++__size();1691    } else {1692      __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...);1693      iterator __b   = begin();1694      iterator __bm1 = std::prev(__b);1695      __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b));1696      --__start_;1697      ++__size();1698      if (__pos > 1)1699        __b = std::move(std::next(__b), __b + __pos, __b);1700      *__b = std::move(__tmp.get());1701    }1702  } else { // insert by shifting things forward1703    if (__back_spare() == 0)1704      __add_back_capacity();1705    // __back_capacity >= 11706    __annotate_increase_back(1);1707    size_type __de = size() - __pos;1708    if (__de == 0) {1709      __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...);1710      ++__size();1711    } else {1712      __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...);1713      iterator __e   = end();1714      iterator __em1 = std::prev(__e);1715      __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1));1716      ++__size();1717      if (__de > 1)1718        __e = std::move_backward(__e - __de, __em1, __e);1719      *--__e = std::move(__tmp.get());1720    }1721  }1722  return begin() + __pos;1723}1724 1725template <class _Tp, class _Allocator>1726typename deque<_Tp, _Allocator>::iterator1727deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) {1728  size_type __pos     = __p - begin();1729  size_type __to_end  = __size() - __pos;1730  allocator_type& __a = __alloc();1731  if (__pos < __to_end) { // insert by shifting things backward1732    if (__n > __front_spare())1733      __add_front_capacity(__n - __front_spare());1734    // __n <= __front_spare()1735    __annotate_increase_front(__n);1736    iterator __old_begin = begin();1737    iterator __i         = __old_begin;1738    if (__n > __pos) {1739      for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size())1740        __alloc_traits::construct(__a, std::addressof(*--__i), __v);1741      __n = __pos;1742    }1743    if (__n > 0) {1744      const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);1745      iterator __obn     = __old_begin + __n;1746      __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);1747      if (__n < __pos)1748        __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);1749      std::fill_n(__old_begin, __n, *__vt);1750    }1751  } else { // insert by shifting things forward1752    size_type __back_capacity = __back_spare();1753    if (__n > __back_capacity)1754      __add_back_capacity(__n - __back_capacity);1755    // __n <= __back_capacity1756    __annotate_increase_back(__n);1757    iterator __old_end = end();1758    iterator __i       = __old_end;1759    size_type __de     = size() - __pos;1760    if (__n > __de) {1761      for (size_type __m = __n - __de; __m; --__m, (void)++__i, ++__size())1762        __alloc_traits::construct(__a, std::addressof(*__i), __v);1763      __n = __de;1764    }1765    if (__n > 0) {1766      const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);1767      iterator __oen     = __old_end - __n;1768      __move_construct_and_check(__oen, __old_end, __i, __vt);1769      if (__n < __de)1770        __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);1771      std::fill_n(__old_end - __n, __n, *__vt);1772    }1773  }1774  return begin() + __pos;1775}1776 1777template <class _Tp, class _Allocator>1778template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> >1779typename deque<_Tp, _Allocator>::iterator1780deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l) {1781  return __insert_with_sentinel(__p, __f, __l);1782}1783 1784template <class _Tp, class _Allocator>1785template <class _Iterator, class _Sentinel>1786_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator1787deque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) {1788  __split_buffer<value_type, allocator_type&> __buf(__alloc());1789  __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l));1790  typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;1791  return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));1792}1793 1794template <class _Tp, class _Allocator>1795template <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> >1796typename deque<_Tp, _Allocator>::iterator1797deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l) {1798  return __insert_with_size(__p, __f, std::distance(__f, __l));1799}1800 1801template <class _Tp, class _Allocator>1802template <class _Iterator>1803_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator1804deque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) {1805  __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc());1806  __buf.__construct_at_end_with_size(__f, __n);1807  typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;1808  return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));1809}1810 1811template <class _Tp, class _Allocator>1812template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> >1813typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l) {1814  return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l));1815}1816 1817template <class _Tp, class _Allocator>1818template <class _BiIter, class _Sentinel>1819_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator1820deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) {1821  return __insert_bidirectional(__p, __f, std::next(__f, __n), __n);1822}1823 1824template <class _Tp, class _Allocator>1825template <class _BiIter>1826_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator1827deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) {1828  size_type __pos     = __p - begin();1829  size_type __to_end  = size() - __pos;1830  allocator_type& __a = __alloc();1831  if (__pos < __to_end) { // insert by shifting things backward1832    if (__n > __front_spare())1833      __add_front_capacity(__n - __front_spare());1834    // __n <= __front_spare()1835    __annotate_increase_front(__n);1836    iterator __old_begin = begin();1837    iterator __i         = __old_begin;1838    _BiIter __m          = __f;1839    if (__n > __pos) {1840      __m = __pos < __n / 2 ? std::prev(__l, __pos) : std::next(__f, __n - __pos);1841      for (_BiIter __j = __m; __j != __f; --__start_, ++__size())1842        __alloc_traits::construct(__a, std::addressof(*--__i), *--__j);1843      __n = __pos;1844    }1845    if (__n > 0) {1846      iterator __obn = __old_begin + __n;1847      for (iterator __j = __obn; __j != __old_begin;) {1848        __alloc_traits::construct(__a, std::addressof(*--__i), std::move(*--__j));1849        --__start_;1850        ++__size();1851      }1852      if (__n < __pos)1853        __old_begin = std::move(__obn, __old_begin + __pos, __old_begin);1854      std::copy(__m, __l, __old_begin);1855    }1856  } else { // insert by shifting things forward1857    size_type __back_capacity = __back_spare();1858    if (__n > __back_capacity)1859      __add_back_capacity(__n - __back_capacity);1860    // __n <= __back_capacity1861    __annotate_increase_back(__n);1862    iterator __old_end = end();1863    iterator __i       = __old_end;1864    _BiIter __m        = __l;1865    size_type __de     = size() - __pos;1866    if (__n > __de) {1867      __m = __de < __n / 2 ? std::next(__f, __de) : std::prev(__l, __n - __de);1868      for (_BiIter __j = __m; __j != __l; ++__i, (void)++__j, ++__size())1869        __alloc_traits::construct(__a, std::addressof(*__i), *__j);1870      __n = __de;1871    }1872    if (__n > 0) {1873      iterator __oen = __old_end - __n;1874      for (iterator __j = __oen; __j != __old_end; ++__i, (void)++__j, ++__size())1875        __alloc_traits::construct(__a, std::addressof(*__i), std::move(*__j));1876      if (__n < __de)1877        __old_end = std::move_backward(__old_end - __de, __oen, __old_end);1878      std::copy_backward(__f, __m, __old_end);1879    }1880  }1881  return begin() + __pos;1882}1883 1884template <class _Tp, class _Allocator>1885template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> >1886void deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l) {1887  __append_with_sentinel(__f, __l);1888}1889 1890template <class _Tp, class _Allocator>1891template <class _InputIterator, class _Sentinel>1892_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) {1893  for (; __f != __l; ++__f)1894#  ifdef _LIBCPP_CXX03_LANG1895    push_back(*__f);1896#  else1897    emplace_back(*__f);1898#  endif1899}1900 1901template <class _Tp, class _Allocator>1902template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> >1903void deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l) {1904  __append_with_size(__f, std::distance(__f, __l));1905}1906 1907template <class _Tp, class _Allocator>1908template <class _InputIterator>1909_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) {1910  allocator_type& __a       = __alloc();1911  size_type __back_capacity = __back_spare();1912  if (__n > __back_capacity)1913    __add_back_capacity(__n - __back_capacity);1914 1915  // __n <= __back_capacity1916  __annotate_increase_back(__n);1917  for (__deque_block_range __br : __deque_range(end(), end() + __n)) {1918    _ConstructTransaction __tx(this, __br);1919    for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {1920      __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f);1921    }1922  }1923}1924 1925template <class _Tp, class _Allocator>1926void deque<_Tp, _Allocator>::__append(size_type __n) {1927  allocator_type& __a       = __alloc();1928  size_type __back_capacity = __back_spare();1929  if (__n > __back_capacity)1930    __add_back_capacity(__n - __back_capacity);1931  // __n <= __back_capacity1932  __annotate_increase_back(__n);1933  for (__deque_block_range __br : __deque_range(end(), end() + __n)) {1934    _ConstructTransaction __tx(this, __br);1935    for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {1936      __alloc_traits::construct(__a, std::__to_address(__tx.__pos_));1937    }1938  }1939}1940 1941template <class _Tp, class _Allocator>1942void deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) {1943  allocator_type& __a       = __alloc();1944  size_type __back_capacity = __back_spare();1945  if (__n > __back_capacity)1946    __add_back_capacity(__n - __back_capacity);1947  // __n <= __back_capacity1948  __annotate_increase_back(__n);1949  for (__deque_block_range __br : __deque_range(end(), end() + __n)) {1950    _ConstructTransaction __tx(this, __br);1951    for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {1952      __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v);1953    }1954  }1955}1956 1957// Create front capacity for one block of elements.1958// Strong guarantee.  Either do it or don't touch anything.1959template <class _Tp, class _Allocator>1960void deque<_Tp, _Allocator>::__add_front_capacity() {1961  allocator_type& __a = __alloc();1962  if (__back_spare() >= __block_size) {1963    __start_ += __block_size;1964    pointer __pt = __map_.back();1965    __map_.pop_back();1966    __map_.emplace_front(__pt);1967  }1968  // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer1969  else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around1970    // until all buffers are allocated.  If we throw, we don't need to fix1971    // anything up (any added buffers are undetectible)1972    if (__map_.__front_spare() > 0)1973      __map_.emplace_front(__alloc_traits::allocate(__a, __block_size));1974    else {1975      __map_.emplace_back(__alloc_traits::allocate(__a, __block_size));1976      // Done allocating, reorder capacity1977      pointer __pt = __map_.back();1978      __map_.pop_back();1979      __map_.emplace_front(__pt);1980    }1981    __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size;1982  }1983  // Else need to allocate 1 buffer, *and* we need to reallocate __map_.1984  else {1985    __split_buffer<pointer, __pointer_allocator&> __buf(1986        std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__get_allocator());1987 1988    typedef __allocator_destructor<_Allocator> _Dp;1989    unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size));1990    __buf.emplace_back(__hold.get());1991    __hold.release();1992 1993    for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i)1994      __buf.emplace_back(*__i);1995    __map_.__swap_without_allocator(__buf);1996    __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size;1997  }1998  __annotate_whole_block(0, __asan_poison);1999}2000 2001// Create front capacity for __n elements.2002// Strong guarantee.  Either do it or don't touch anything.2003template <class _Tp, class _Allocator>2004void deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) {2005  allocator_type& __a = __alloc();2006  size_type __nb      = __recommend_blocks(__n + __map_.empty());2007  // Number of unused blocks at back:2008  size_type __back_capacity = __back_spare() / __block_size;2009  __back_capacity           = std::min(__back_capacity, __nb); // don't take more than you need2010  __nb -= __back_capacity;                                     // number of blocks need to allocate2011  // If __nb == 0, then we have sufficient capacity.2012  if (__nb == 0) {2013    __start_ += __block_size * __back_capacity;2014    for (; __back_capacity > 0; --__back_capacity) {2015      pointer __pt = __map_.back();2016      __map_.pop_back();2017      __map_.emplace_front(__pt);2018    }2019  }2020  // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers2021  else if (__nb <= __map_.capacity() -2022                       __map_.size()) { // we can put the new buffers into the map, but don't shift things around2023    // until all buffers are allocated.  If we throw, we don't need to fix2024    // anything up (any added buffers are undetectible)2025    for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) {2026      if (__map_.__front_spare() == 0)2027        break;2028      __map_.emplace_front(__alloc_traits::allocate(__a, __block_size));2029      __annotate_whole_block(0, __asan_poison);2030    }2031    for (; __nb > 0; --__nb, ++__back_capacity)2032      __map_.emplace_back(__alloc_traits::allocate(__a, __block_size));2033    // Done allocating, reorder capacity2034    __start_ += __back_capacity * __block_size;2035    for (; __back_capacity > 0; --__back_capacity) {2036      pointer __pt = __map_.back();2037      __map_.pop_back();2038      __map_.emplace_front(__pt);2039      __annotate_whole_block(0, __asan_poison);2040    }2041  }2042  // Else need to allocate __nb buffers, *and* we need to reallocate __map_.2043  else {2044    size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty();2045    __split_buffer<pointer, __pointer_allocator&> __buf(2046        std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__get_allocator());2047    auto __guard = std::__make_exception_guard([&] {2048      __annotate_delete();2049      for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i)2050        __alloc_traits::deallocate(__a, *__i, __block_size);2051    });2052    for (; __nb > 0; --__nb) {2053      __buf.emplace_back(__alloc_traits::allocate(__a, __block_size));2054      // ASan: this is empty container, we have to poison whole block2055      __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size));2056    }2057    __guard.__complete();2058    for (; __back_capacity > 0; --__back_capacity) {2059      __buf.emplace_back(__map_.back());2060      __map_.pop_back();2061    }2062    for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i)2063      __buf.emplace_back(*__i);2064    __map_.__swap_without_allocator(__buf);2065    __start_ += __ds;2066  }2067}2068 2069// Create back capacity for one block of elements.2070// Strong guarantee.  Either do it or don't touch anything.2071template <class _Tp, class _Allocator>2072void deque<_Tp, _Allocator>::__add_back_capacity() {2073  allocator_type& __a = __alloc();2074  if (__front_spare() >= __block_size) {2075    __start_ -= __block_size;2076    pointer __pt = __map_.front();2077    __map_.pop_front();2078    __map_.emplace_back(__pt);2079  }2080  // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers2081  else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around2082    // until it is allocated.  If we throw, we don't need to fix2083    // anything up (any added buffers are undetectible)2084    if (__map_.__back_spare() != 0)2085      __map_.emplace_back(__alloc_traits::allocate(__a, __block_size));2086    else {2087      __map_.emplace_front(__alloc_traits::allocate(__a, __block_size));2088      // Done allocating, reorder capacity2089      pointer __pt = __map_.front();2090      __map_.pop_front();2091      __map_.emplace_back(__pt);2092    }2093    __annotate_whole_block(__map_.size() - 1, __asan_poison);2094  }2095  // Else need to allocate 1 buffer, *and* we need to reallocate __map_.2096  else {2097    __split_buffer<pointer, __pointer_allocator&> __buf(2098        std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__get_allocator());2099 2100    typedef __allocator_destructor<_Allocator> _Dp;2101    unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size));2102    __buf.emplace_back(__hold.get());2103    __hold.release();2104 2105    for (__map_pointer __i = __map_.end(); __i != __map_.begin();)2106      __buf.emplace_front(*--__i);2107    __map_.__swap_without_allocator(__buf);2108    __annotate_whole_block(__map_.size() - 1, __asan_poison);2109  }2110}2111 2112// Create back capacity for __n elements.2113// Strong guarantee.  Either do it or don't touch anything.2114template <class _Tp, class _Allocator>2115void deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) {2116  allocator_type& __a = __alloc();2117  size_type __nb      = __recommend_blocks(__n + __map_.empty());2118  // Number of unused blocks at front:2119  size_type __front_capacity = __front_spare() / __block_size;2120  __front_capacity           = std::min(__front_capacity, __nb); // don't take more than you need2121  __nb -= __front_capacity;                                      // number of blocks need to allocate2122  // If __nb == 0, then we have sufficient capacity.2123  if (__nb == 0) {2124    __start_ -= __block_size * __front_capacity;2125    for (; __front_capacity > 0; --__front_capacity) {2126      pointer __pt = __map_.front();2127      __map_.pop_front();2128      __map_.emplace_back(__pt);2129    }2130  }2131  // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers2132  else if (__nb <= __map_.capacity() -2133                       __map_.size()) { // we can put the new buffers into the map, but don't shift things around2134    // until all buffers are allocated.  If we throw, we don't need to fix2135    // anything up (any added buffers are undetectible)2136    for (; __nb > 0; --__nb) {2137      if (__map_.__back_spare() == 0)2138        break;2139      __map_.emplace_back(__alloc_traits::allocate(__a, __block_size));2140      __annotate_whole_block(__map_.size() - 1, __asan_poison);2141    }2142    for (; __nb > 0; --__nb, ++__front_capacity, __start_ += __block_size - (__map_.size() == 1)) {2143      __map_.emplace_front(__alloc_traits::allocate(__a, __block_size));2144      __annotate_whole_block(0, __asan_poison);2145    }2146    // Done allocating, reorder capacity2147    __start_ -= __block_size * __front_capacity;2148    for (; __front_capacity > 0; --__front_capacity) {2149      pointer __pt = __map_.front();2150      __map_.pop_front();2151      __map_.emplace_back(__pt);2152    }2153  }2154  // Else need to allocate __nb buffers, *and* we need to reallocate __map_.2155  else {2156    size_type __ds = __front_capacity * __block_size;2157    __split_buffer<pointer, __pointer_allocator&> __buf(2158        std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()),2159        __map_.size() - __front_capacity,2160        __map_.__get_allocator());2161    auto __guard = std::__make_exception_guard([&] {2162      __annotate_delete();2163      for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i)2164        __alloc_traits::deallocate(__a, *__i, __block_size);2165    });2166    for (; __nb > 0; --__nb) {2167      __buf.emplace_back(__alloc_traits::allocate(__a, __block_size));2168      // ASan: this is an empty container, we have to poison the whole block2169      __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size));2170    }2171    __guard.__complete();2172    for (; __front_capacity > 0; --__front_capacity) {2173      __buf.emplace_back(__map_.front());2174      __map_.pop_front();2175    }2176    for (__map_pointer __i = __map_.end(); __i != __map_.begin();)2177      __buf.emplace_front(*--__i);2178    __map_.__swap_without_allocator(__buf);2179    __start_ -= __ds;2180  }2181}2182 2183template <class _Tp, class _Allocator>2184void deque<_Tp, _Allocator>::pop_front() {2185  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_front called on an empty deque");2186  size_type __old_sz    = size();2187  size_type __old_start = __start_;2188  allocator_type& __a   = __alloc();2189  __alloc_traits::destroy(2190      __a, std::__to_address(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size));2191  --__size();2192  ++__start_;2193  __annotate_shrink_front(__old_sz, __old_start);2194  __maybe_remove_front_spare();2195}2196 2197template <class _Tp, class _Allocator>2198void deque<_Tp, _Allocator>::pop_back() {2199  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque");2200  size_type __old_sz    = size();2201  size_type __old_start = __start_;2202  allocator_type& __a   = __alloc();2203  size_type __p         = size() + __start_ - 1;2204  __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() + __p / __block_size) + __p % __block_size));2205  --__size();2206  __annotate_shrink_back(__old_sz, __old_start);2207  __maybe_remove_back_spare();2208}2209 2210// move assign [__f, __l) to [__r, __r + (__l-__f)).2211// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.2212template <class _Tp, class _Allocator>2213typename deque<_Tp, _Allocator>::iterator2214deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) {2215  // as if2216  //   for (; __f != __l; ++__f, ++__r)2217  //       *__r = std::move(*__f);2218  difference_type __n = __l - __f;2219  while (__n > 0) {2220    pointer __fb         = __f.__ptr_;2221    pointer __fe         = *__f.__m_iter_ + __block_size;2222    difference_type __bs = __fe - __fb;2223    if (__bs > __n) {2224      __bs = __n;2225      __fe = __fb + __bs;2226    }2227    if (__fb <= __vt && __vt < __fe)2228      __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;2229    __r = std::move(__fb, __fe, __r);2230    __n -= __bs;2231    __f += __bs;2232  }2233  return __r;2234}2235 2236// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.2237// If __vt points into [__f, __l), then add (__r - __l) to __vt.2238template <class _Tp, class _Allocator>2239typename deque<_Tp, _Allocator>::iterator2240deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) {2241  // as if2242  //   while (__f != __l)2243  //       *--__r = std::move(*--__l);2244  difference_type __n = __l - __f;2245  while (__n > 0) {2246    --__l;2247    pointer __lb         = *__l.__m_iter_;2248    pointer __le         = __l.__ptr_ + 1;2249    difference_type __bs = __le - __lb;2250    if (__bs > __n) {2251      __bs = __n;2252      __lb = __le - __bs;2253    }2254    if (__lb <= __vt && __vt < __le)2255      __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;2256    __r = std::move_backward(__lb, __le, __r);2257    __n -= __bs;2258    __l -= __bs - 1;2259  }2260  return __r;2261}2262 2263// move construct [__f, __l) to [__r, __r + (__l-__f)).2264// If __vt points into [__f, __l), then add (__r - __f) to __vt.2265template <class _Tp, class _Allocator>2266void deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) {2267  allocator_type& __a = __alloc();2268  // as if2269  //   for (; __f != __l; ++__r, ++__f, ++__size())2270  //       __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__f));2271  difference_type __n = __l - __f;2272  while (__n > 0) {2273    pointer __fb         = __f.__ptr_;2274    pointer __fe         = *__f.__m_iter_ + __block_size;2275    difference_type __bs = __fe - __fb;2276    if (__bs > __n) {2277      __bs = __n;2278      __fe = __fb + __bs;2279    }2280    if (__fb <= __vt && __vt < __fe)2281      __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;2282    for (; __fb != __fe; ++__fb, ++__r, ++__size())2283      __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__fb));2284    __n -= __bs;2285    __f += __bs;2286  }2287}2288 2289// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.2290// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.2291template <class _Tp, class _Allocator>2292void deque<_Tp, _Allocator>::__move_construct_backward_and_check(2293    iterator __f, iterator __l, iterator __r, const_pointer& __vt) {2294  allocator_type& __a = __alloc();2295  // as if2296  //   for (iterator __j = __l; __j != __f;)2297  //   {2298  //       __alloc_traitsconstruct(__a, std::addressof(*--__r), std::move(*--__j));2299  //       --__start_;2300  //       ++__size();2301  //   }2302  difference_type __n = __l - __f;2303  while (__n > 0) {2304    --__l;2305    pointer __lb         = *__l.__m_iter_;2306    pointer __le         = __l.__ptr_ + 1;2307    difference_type __bs = __le - __lb;2308    if (__bs > __n) {2309      __bs = __n;2310      __lb = __le - __bs;2311    }2312    if (__lb <= __vt && __vt < __le)2313      __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;2314    while (__le != __lb) {2315      __alloc_traits::construct(__a, std::addressof(*--__r), std::move(*--__le));2316      --__start_;2317      ++__size();2318    }2319    __n -= __bs;2320    __l -= __bs - 1;2321  }2322}2323 2324template <class _Tp, class _Allocator>2325typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f) {2326  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(2327      __f != end(), "deque::erase(iterator) called with a non-dereferenceable iterator");2328  size_type __old_sz    = size();2329  size_type __old_start = __start_;2330  iterator __b          = begin();2331  difference_type __pos = __f - __b;2332  iterator __p          = __b + __pos;2333  allocator_type& __a   = __alloc();2334  if (static_cast<size_type>(__pos) <= (size() - 1) / 2) { // erase from front2335    std::move_backward(__b, __p, std::next(__p));2336    __alloc_traits::destroy(__a, std::addressof(*__b));2337    --__size();2338    ++__start_;2339    __annotate_shrink_front(__old_sz, __old_start);2340    __maybe_remove_front_spare();2341  } else { // erase from back2342    iterator __i = std::move(std::next(__p), end(), __p);2343    __alloc_traits::destroy(__a, std::addressof(*__i));2344    --__size();2345    __annotate_shrink_back(__old_sz, __old_start);2346    __maybe_remove_back_spare();2347  }2348  return begin() + __pos;2349}2350 2351template <class _Tp, class _Allocator>2352typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) {2353  _LIBCPP_ASSERT_VALID_INPUT_RANGE(__f <= __l, "deque::erase(first, last) called with an invalid range");2354  size_type __old_sz    = size();2355  size_type __old_start = __start_;2356  difference_type __n   = __l - __f;2357  iterator __b          = begin();2358  difference_type __pos = __f - __b;2359  iterator __p          = __b + __pos;2360  if (__n > 0) {2361    allocator_type& __a = __alloc();2362    if (static_cast<size_type>(__pos) <= (size() - __n) / 2) { // erase from front2363      iterator __i = std::move_backward(__b, __p, __p + __n);2364      for (; __b != __i; ++__b)2365        __alloc_traits::destroy(__a, std::addressof(*__b));2366      __size() -= __n;2367      __start_ += __n;2368      __annotate_shrink_front(__old_sz, __old_start);2369      while (__maybe_remove_front_spare()) {2370      }2371    } else { // erase from back2372      iterator __i = std::move(__p + __n, end(), __p);2373      for (iterator __e = end(); __i != __e; ++__i)2374        __alloc_traits::destroy(__a, std::addressof(*__i));2375      __size() -= __n;2376      __annotate_shrink_back(__old_sz, __old_start);2377      while (__maybe_remove_back_spare()) {2378      }2379    }2380  }2381  return begin() + __pos;2382}2383 2384template <class _Tp, class _Allocator>2385void deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) {2386  size_type __old_sz    = size();2387  size_type __old_start = __start_;2388  iterator __e          = end();2389  difference_type __n   = __e - __f;2390  if (__n > 0) {2391    allocator_type& __a   = __alloc();2392    iterator __b          = begin();2393    difference_type __pos = __f - __b;2394    for (iterator __p = __b + __pos; __p != __e; ++__p)2395      __alloc_traits::destroy(__a, std::addressof(*__p));2396    __size() -= __n;2397    __annotate_shrink_back(__old_sz, __old_start);2398    while (__maybe_remove_back_spare()) {2399    }2400  }2401}2402 2403template <class _Tp, class _Allocator>2404inline void deque<_Tp, _Allocator>::swap(deque& __c)2405#  if _LIBCPP_STD_VER >= 142406    _NOEXCEPT2407#  else2408    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>)2409#  endif2410{2411  __map_.swap(__c.__map_);2412  std::swap(__start_, __c.__start_);2413  std::swap(__size(), __c.__size());2414  std::__swap_allocator(__alloc(), __c.__alloc());2415}2416 2417template <class _Tp, class _Allocator>2418inline void deque<_Tp, _Allocator>::clear() _NOEXCEPT {2419  __annotate_delete();2420  allocator_type& __a = __alloc();2421  for (iterator __i = begin(), __e = end(); __i != __e; ++__i)2422    __alloc_traits::destroy(__a, std::addressof(*__i));2423  __size() = 0;2424  while (__map_.size() > 2) {2425    __alloc_traits::deallocate(__a, __map_.front(), __block_size);2426    __map_.pop_front();2427  }2428  switch (__map_.size()) {2429  case 1:2430    __start_ = __block_size / 2;2431    break;2432  case 2:2433    __start_ = __block_size;2434    break;2435  }2436  __annotate_new(0);2437}2438 2439template <class _Tp, class _Allocator>2440inline _LIBCPP_HIDE_FROM_ABI bool operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {2441  const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();2442  return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());2443}2444 2445#  if _LIBCPP_STD_VER <= 172446 2447template <class _Tp, class _Allocator>2448inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {2449  return !(__x == __y);2450}2451 2452template <class _Tp, class _Allocator>2453inline _LIBCPP_HIDE_FROM_ABI bool operator<(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {2454  return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());2455}2456 2457template <class _Tp, class _Allocator>2458inline _LIBCPP_HIDE_FROM_ABI bool operator>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {2459  return __y < __x;2460}2461 2462template <class _Tp, class _Allocator>2463inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {2464  return !(__x < __y);2465}2466 2467template <class _Tp, class _Allocator>2468inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {2469  return !(__y < __x);2470}2471 2472#  else // _LIBCPP_STD_VER <= 172473 2474template <class _Tp, class _Allocator>2475_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>2476operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {2477  return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);2478}2479 2480#  endif // _LIBCPP_STD_VER <= 172481 2482template <class _Tp, class _Allocator>2483inline _LIBCPP_HIDE_FROM_ABI void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)2484    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {2485  __x.swap(__y);2486}2487 2488#  if _LIBCPP_STD_VER >= 202489template <class _Tp, class _Allocator, class _Up>2490inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type2491erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {2492  auto __old_size = __c.size();2493  __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end());2494  return __old_size - __c.size();2495}2496 2497template <class _Tp, class _Allocator, class _Predicate>2498inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type2499erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {2500  auto __old_size = __c.size();2501  __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end());2502  return __old_size - __c.size();2503}2504 2505template <>2506inline constexpr bool __format::__enable_insertable<std::deque<char>> = true;2507#    if _LIBCPP_HAS_WIDE_CHARACTERS2508template <>2509inline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;2510#    endif2511 2512#  endif // _LIBCPP_STD_VER >= 202513 2514template <class _Tp, class _Allocator>2515struct __container_traits<deque<_Tp, _Allocator> > {2516  // http://eel.is/c++draft/deque.modifiers#32517  //  If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move2518  //  assignment operator of T, there are no effects. If an exception is thrown while inserting a single element at2519  //  either end, there are no effects. Otherwise, if an exception is thrown by the move constructor of a2520  //  non-Cpp17CopyInsertable T, the effects are unspecified.2521  static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee =2522      is_nothrow_move_constructible<_Tp>::value || __is_cpp17_copy_insertable_v<_Allocator>;2523 2524  static _LIBCPP_CONSTEXPR const bool __reservable = false;2525};2526 2527_LIBCPP_END_NAMESPACE_STD2528 2529#  if _LIBCPP_STD_VER >= 172530_LIBCPP_BEGIN_NAMESPACE_STD2531namespace pmr {2532template <class _ValueT>2533using deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;2534} // namespace pmr2535_LIBCPP_END_NAMESPACE_STD2536#  endif2537 2538_LIBCPP_POP_MACROS2539 2540#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 202541#    include <algorithm>2542#    include <atomic>2543#    include <concepts>2544#    include <cstdlib>2545#    include <functional>2546#    include <iosfwd>2547#    include <iterator>2548#    include <type_traits>2549#    include <typeinfo>2550#  endif2551#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)2552 2553#endif // _LIBCPP_DEQUE2554