diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-04-26 15:33:29 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-05-08 19:37:29 -0700 |
| commit | 06ee65af9ed6aa5ee4d1d7f4fab9d7acecf66e76 (patch) | |
| tree | 1316711b92a43dd5c599e425b8693fa8e1e0c0b7 /lib/libcxx/include/deque | |
| parent | bc6ebc6f2597fda1f98842c6f545751fef2a5334 (diff) | |
| download | zig-06ee65af9ed6aa5ee4d1d7f4fab9d7acecf66e76.tar.gz zig-06ee65af9ed6aa5ee4d1d7f4fab9d7acecf66e76.zip | |
libcxx: update to LLVM 18
release/18.x branch, commit 78b99c73ee4b96fe9ce0e294d4632326afb2db42
This adds the flag `-D_LIBCPP_HARDENING_MODE` which is determined based
on the Zig optimization mode.
This commit also fixes libunwind, libcxx, and libcxxabi to properly
report sub compilation errors.
Diffstat (limited to 'lib/libcxx/include/deque')
| -rw-r--r-- | lib/libcxx/include/deque | 3763 |
1 files changed, 1683 insertions, 2080 deletions
diff --git a/lib/libcxx/include/deque b/lib/libcxx/include/deque index 8ca59438db..fca8b3d6e2 100644 --- a/lib/libcxx/include/deque +++ b/lib/libcxx/include/deque @@ -242,183 +242,173 @@ template <class T, class Allocator, class Predicate> _LIBCPP_PUSH_MACROS #include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque; +template <class _Tp, class _Allocator = allocator<_Tp> > +class _LIBCPP_TEMPLATE_VIS deque; template <class _ValueType, class _DiffType> struct __deque_block_size { static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16; }; -template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, - class _DiffType, _DiffType _BS = +template <class _ValueType, + class _Pointer, + class _Reference, + class _MapPointer, + class _DiffType, + _DiffType _BS = #ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE -// Keep template parameter to avoid changing all template declarations thoughout -// this file. - 0 + // Keep template parameter to avoid changing all template declarations thoughout + // this file. + 0 #else - __deque_block_size<_ValueType, _DiffType>::value + __deque_block_size<_ValueType, _DiffType>::value #endif > -class _LIBCPP_TEMPLATE_VIS __deque_iterator -{ - typedef _MapPointer __map_iterator; +class _LIBCPP_TEMPLATE_VIS __deque_iterator { + typedef _MapPointer __map_iterator; + public: - typedef _Pointer pointer; - typedef _DiffType difference_type; + typedef _Pointer pointer; + typedef _DiffType difference_type; + private: - __map_iterator __m_iter_; - pointer __ptr_; + __map_iterator __m_iter_; + pointer __ptr_; + + static const difference_type __block_size; - static const difference_type __block_size; public: - typedef _ValueType value_type; - typedef random_access_iterator_tag iterator_category; - typedef _Reference reference; + typedef _ValueType value_type; + typedef random_access_iterator_tag iterator_category; + typedef _Reference reference; - _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT #if _LIBCPP_STD_VER >= 14 - : __m_iter_(nullptr), __ptr_(nullptr) + : __m_iter_(nullptr), + __ptr_(nullptr) #endif - {} - - template <class _Pp, class _Rp, class _MP> - _LIBCPP_HIDE_FROM_ABI - __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it, - typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT - : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {} - - _LIBCPP_HIDE_FROM_ABI reference operator*() const {return *__ptr_;} - _LIBCPP_HIDE_FROM_ABI pointer operator->() const {return __ptr_;} - - _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++() - { - if (++__ptr_ - *__m_iter_ == __block_size) - { - ++__m_iter_; - __ptr_ = *__m_iter_; - } - return *this; - } + { + } - _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int) - { - __deque_iterator __tmp = *this; - ++(*this); - return __tmp; - } + template <class _Pp, class _Rp, class _MP, __enable_if_t<is_convertible<_Pp, pointer>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI + __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it) _NOEXCEPT + : __m_iter_(__it.__m_iter_), + __ptr_(__it.__ptr_) {} - _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--() - { - if (__ptr_ == *__m_iter_) - { - --__m_iter_; - __ptr_ = *__m_iter_ + __block_size; - } - --__ptr_; - return *this; - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__ptr_; } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return __ptr_; } - _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int) - { - __deque_iterator __tmp = *this; - --(*this); - return __tmp; + _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++() { + if (++__ptr_ - *__m_iter_ == __block_size) { + ++__m_iter_; + __ptr_ = *__m_iter_; } + return *this; + } - _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n) - { - if (__n != 0) - { - __n += __ptr_ - *__m_iter_; - if (__n > 0) - { - __m_iter_ += __n / __block_size; - __ptr_ = *__m_iter_ + __n % __block_size; - } - else // (__n < 0) - { - difference_type __z = __block_size - 1 - __n; - __m_iter_ -= __z / __block_size; - __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size); - } - } - return *this; - } + _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int) { + __deque_iterator __tmp = *this; + ++(*this); + return __tmp; + } - _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n) - { - return *this += -__n; + _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--() { + if (__ptr_ == *__m_iter_) { + --__m_iter_; + __ptr_ = *__m_iter_ + __block_size; } + --__ptr_; + return *this; + } - _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const - { - __deque_iterator __t(*this); - __t += __n; - return __t; - } + _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int) { + __deque_iterator __tmp = *this; + --(*this); + return __tmp; + } - _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const - { - __deque_iterator __t(*this); - __t -= __n; - return __t; + _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n) { + if (__n != 0) { + __n += __ptr_ - *__m_iter_; + if (__n > 0) { + __m_iter_ += __n / __block_size; + __ptr_ = *__m_iter_ + __n % __block_size; + } else // (__n < 0) + { + difference_type __z = __block_size - 1 - __n; + __m_iter_ -= __z / __block_size; + __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size); + } } + return *this; + } - _LIBCPP_HIDE_FROM_ABI - friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) - {return __it + __n;} - - _LIBCPP_HIDE_FROM_ABI - friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) - { - if (__x != __y) - return (__x.__m_iter_ - __y.__m_iter_) * __block_size - + (__x.__ptr_ - *__x.__m_iter_) - - (__y.__ptr_ - *__y.__m_iter_); - return 0; - } + _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n) { return *this += -__n; } + + _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const { + __deque_iterator __t(*this); + __t += __n; + return __t; + } + + _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const { + __deque_iterator __t(*this); + __t -= __n; + return __t; + } - _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const - {return *(*this + __n);} + _LIBCPP_HIDE_FROM_ABI friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) { + return __it + __n; + } - _LIBCPP_HIDE_FROM_ABI friend - bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) - {return __x.__ptr_ == __y.__ptr_;} + _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) { + if (__x != __y) + return (__x.__m_iter_ - __y.__m_iter_) * __block_size + (__x.__ptr_ - *__x.__m_iter_) - + (__y.__ptr_ - *__y.__m_iter_); + return 0; + } - _LIBCPP_HIDE_FROM_ABI friend - bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) - {return !(__x == __y);} + _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const { return *(*this + __n); } - _LIBCPP_HIDE_FROM_ABI friend - bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) - {return __x.__m_iter_ < __y.__m_iter_ || - (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);} + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) { + return __x.__ptr_ == __y.__ptr_; + } - _LIBCPP_HIDE_FROM_ABI friend - bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) - {return __y < __x;} + _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) { + return !(__x == __y); + } - _LIBCPP_HIDE_FROM_ABI friend - bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) - {return !(__y < __x);} + _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) { + return __x.__m_iter_ < __y.__m_iter_ || (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_); + } - _LIBCPP_HIDE_FROM_ABI friend - bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) - {return !(__x < __y);} + _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) { + return __y < __x; + } + + _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) { + return !(__y < __x); + } + + _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) { + return !(__x < __y); + } private: - _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT - : __m_iter_(__m), __ptr_(__p) {} + _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT + : __m_iter_(__m), + __ptr_(__p) {} - template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque; - template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp> - friend class _LIBCPP_TEMPLATE_VIS __deque_iterator; + template <class _Tp, class _Ap> + friend class _LIBCPP_TEMPLATE_VIS deque; + template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp> + friend class _LIBCPP_TEMPLATE_VIS __deque_iterator; - template <class> - friend struct __segmented_iterator_traits; + template <class> + friend struct __segmented_iterator_traits; }; template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> @@ -429,37 +419,34 @@ private: public: using __is_segmented_iterator = true_type; - using __segment_iterator = _MapPointer; - using __local_iterator = _Pointer; + using __segment_iterator = _MapPointer; + using __local_iterator = _Pointer; static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; } static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) { - return *__iter + _Iterator::__block_size; + return *__iter + _Iterator::__block_size; } static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) { - if (__local == __end(__segment)) { - ++__segment; - return _Iterator(__segment, *__segment); - } - return _Iterator(__segment, __local); + if (__segment && __local == __end(__segment)) { + ++__segment; + return _Iterator(__segment, *__segment); + } + return _Iterator(__segment, __local); } }; -template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, - class _DiffType, _DiffType _BlockSize> -const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, - _DiffType, _BlockSize>::__block_size = +template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> +const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>::__block_size = __deque_block_size<_ValueType, _DiffType>::value; template <class _Tp, class _Allocator /*= allocator<_Tp>*/> -class _LIBCPP_TEMPLATE_VIS deque -{ +class _LIBCPP_TEMPLATE_VIS deque { public: - // types: + // types: using value_type = _Tp; @@ -504,8 +491,9 @@ public: private: struct __deque_block_range { - explicit _LIBCPP_HIDE_FROM_ABI - __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {} + explicit _LIBCPP_HIDE_FROM_ABI __deque_block_range(pointer __b, pointer __e) _NOEXCEPT + : __begin_(__b), + __end_(__e) {} const pointer __begin_; const pointer __end_; }; @@ -514,22 +502,15 @@ private: iterator __pos_; const iterator __end_; - _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT - : __pos_(__pos), __end_(__e) {} + _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT : __pos_(__pos), __end_(__e) {} - explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { - return __pos_ != __end_; - } + explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { return __pos_ != __end_; } - _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { - return *this; - } + _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { return *this; } - _LIBCPP_HIDE_FROM_ABI __deque_range end() const { - return __deque_range(__end_, __end_); - } + _LIBCPP_HIDE_FROM_ABI __deque_range end() const { return __deque_range(__end_, __end_); } _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT { - if (__pos_.__m_iter_ == __end_.__m_iter_) { + if (__pos_.__m_iter_ == __end_.__m_iter_) { return __deque_block_range(__pos_.__ptr_, __end_.__ptr_); } return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size); @@ -545,7 +526,6 @@ private: return *this; } - _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) { return __lhs.__pos_ == __rhs.__pos_; } @@ -556,15 +536,13 @@ private: struct _ConstructTransaction { _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r) - : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} - + : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} - _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { - __base_->__size() += (__pos_ - __begin_); - } + _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { __base_->__size() += (__pos_ - __begin_); } pointer __pos_; const pointer __end_; + private: const pointer __begin_; deque* const __base_; @@ -577,55 +555,49 @@ private: __compressed_pair<size_type, allocator_type> __size_; public: + // construct/copy/destroy: + _LIBCPP_HIDE_FROM_ABI deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) + : __start_(0), __size_(0, __default_init_tag()) { + __annotate_new(0); + } - // construct/copy/destroy: - _LIBCPP_HIDE_FROM_ABI - deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) - : __start_(0), __size_(0, __default_init_tag()) { - __annotate_new(0); - } - - _LIBCPP_HIDE_FROM_ABI ~deque() { - clear(); - __annotate_delete(); - typename __map::iterator __i = __map_.begin(); - typename __map::iterator __e = __map_.end(); - for (; __i != __e; ++__i) - __alloc_traits::deallocate(__alloc(), *__i, __block_size); - } + _LIBCPP_HIDE_FROM_ABI ~deque() { + clear(); + __annotate_delete(); + typename __map::iterator __i = __map_.begin(); + typename __map::iterator __e = __map_.end(); + for (; __i != __e; ++__i) + __alloc_traits::deallocate(__alloc(), *__i, __block_size); + } - _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) - : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { - __annotate_new(0); - } + _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) + : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { + __annotate_new(0); + } - explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); + explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); #if _LIBCPP_STD_VER >= 14 - explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); + explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); #endif - _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); - - template <class = __enable_if_t<__is_allocator<_Allocator>::value> > - _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) - : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) - { - __annotate_new(0); - if (__n > 0) - __append(__n, __v); - } + _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); + + template <class = __enable_if_t<__is_allocator<_Allocator>::value> > + _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) + : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { + __annotate_new(0); + if (__n > 0) + __append(__n, __v); + } - template <class _InputIter> - _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, - typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0); - template <class _InputIter> - _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a, - typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0); + template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l); + template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a); #if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, - const allocator_type& __a = allocator_type()) - : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { + _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) + : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { __append_with_size(ranges::begin(__range), ranges::distance(__range)); @@ -637,683 +609,620 @@ public: } #endif - _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); - _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); + _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); + _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); - _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c); + _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il); - _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a); - - _LIBCPP_HIDE_FROM_ABI - deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;} - - _LIBCPP_HIDE_FROM_ABI - deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); - _LIBCPP_HIDE_FROM_ABI - deque(deque&& __c, const __type_identity_t<allocator_type>& __a); - _LIBCPP_HIDE_FROM_ABI - deque& operator=(deque&& __c) - _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); - - _LIBCPP_HIDE_FROM_ABI - void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());} + _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il); + _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a); + + _LIBCPP_HIDE_FROM_ABI deque& operator=(initializer_list<value_type> __il) { + assign(__il); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); + _LIBCPP_HIDE_FROM_ABI deque(deque&& __c, const __type_identity_t<allocator_type>& __a); + _LIBCPP_HIDE_FROM_ABI deque& operator=(deque&& __c) + _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value&& + is_nothrow_move_assignable<allocator_type>::value); + + _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) { assign(__il.begin(), __il.end()); } #endif // _LIBCPP_CXX03_LANG - template <class _InputIter> - _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l, - typename enable_if<__has_input_iterator_category<_InputIter>::value && - !__has_random_access_iterator_category<_InputIter>::value>::type* = 0); - template <class _RAIter> - _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l, - typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type* = 0); + template <class _InputIter, + __enable_if_t<__has_input_iterator_category<_InputIter>::value && + !__has_random_access_iterator_category<_InputIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l); + template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l); #if _LIBCPP_STD_VER >= 23 - template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI - void assign_range(_Range&& __range) { - if constexpr (ranges::random_access_range<_Range>) { - auto __n = static_cast<size_type>(ranges::distance(__range)); - __assign_with_size_random_access(ranges::begin(__range), __n); + template <_ContainerCompatibleRange<_Tp> _Range> + _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) { + if constexpr (ranges::random_access_range<_Range>) { + auto __n = static_cast<size_type>(ranges::distance(__range)); + __assign_with_size_random_access(ranges::begin(__range), __n); - } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { - auto __n = static_cast<size_type>(ranges::distance(__range)); - __assign_with_size(ranges::begin(__range), __n); + } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { + auto __n = static_cast<size_type>(ranges::distance(__range)); + __assign_with_size(ranges::begin(__range), __n); - } else { - __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); - } + } else { + __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); } + } #endif - _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); + _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); - _LIBCPP_HIDE_FROM_ABI - allocator_type get_allocator() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); } _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); } // iterators: _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { - __map_pointer __mp = __map_.begin() + __start_ / __block_size; - return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); + __map_pointer __mp = __map_.begin() + __start_ / __block_size; + return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); } _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { - __map_const_pointer __mp = - static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); - return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); + __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); + return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); } _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { - size_type __p = size() + __start_; - __map_pointer __mp = __map_.begin() + __p / __block_size; - return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); + size_type __p = size() + __start_; + __map_pointer __mp = __map_.begin() + __p / __block_size; + return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); } _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { - size_type __p = size() + __start_; - __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); - return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); - } - - _LIBCPP_HIDE_FROM_ABI - reverse_iterator rbegin() _NOEXCEPT - {return reverse_iterator(end());} - _LIBCPP_HIDE_FROM_ABI - const_reverse_iterator rbegin() const _NOEXCEPT - {return const_reverse_iterator(end());} - _LIBCPP_HIDE_FROM_ABI - reverse_iterator rend() _NOEXCEPT - {return reverse_iterator(begin());} - _LIBCPP_HIDE_FROM_ABI - const_reverse_iterator rend() const _NOEXCEPT - {return const_reverse_iterator(begin());} - - _LIBCPP_HIDE_FROM_ABI - const_iterator cbegin() const _NOEXCEPT - {return begin();} - _LIBCPP_HIDE_FROM_ABI - const_iterator cend() const _NOEXCEPT - {return end();} - _LIBCPP_HIDE_FROM_ABI - const_reverse_iterator crbegin() const _NOEXCEPT - {return const_reverse_iterator(end());} - _LIBCPP_HIDE_FROM_ABI - const_reverse_iterator crend() const _NOEXCEPT - {return const_reverse_iterator(begin());} + size_type __p = size() + __start_; + __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); + return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); + } - // capacity: - _LIBCPP_HIDE_FROM_ABI - size_type size() const _NOEXCEPT {return __size();} + _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } + _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } + _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } + _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } + + _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } + _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } + _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } + _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); } + + // capacity: + _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); } _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); } _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); } - _LIBCPP_HIDE_FROM_ABI - size_type max_size() const _NOEXCEPT - {return _VSTD::min<size_type>( - __alloc_traits::max_size(__alloc()), - numeric_limits<difference_type>::max());} - _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); - _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); - _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI - bool empty() const _NOEXCEPT {return size() == 0;} - - // element access: - _LIBCPP_HIDE_FROM_ABI - reference operator[](size_type __i) _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI - const_reference operator[](size_type __i) const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI - reference at(size_type __i); - _LIBCPP_HIDE_FROM_ABI - const_reference at(size_type __i) const; - _LIBCPP_HIDE_FROM_ABI - reference front() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI - const_reference front() const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI - reference back() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI - const_reference back() const _NOEXCEPT; - - // 23.2.2.3 modifiers: - _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); - _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); + _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max()); + } + _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); + _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); + _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; } + + // element access: + _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI reference at(size_type __i); + _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const; + _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT; + + // 23.2.2.3 modifiers: + _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); + _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); #ifndef _LIBCPP_CXX03_LANG -#if _LIBCPP_STD_VER >= 17 - template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); - template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args); -#else - template <class... _Args> _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); - template <class... _Args> _LIBCPP_HIDE_FROM_ABI void emplace_back (_Args&&... __args); -#endif - template <class... _Args> _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); - - _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); - _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v); - -#if _LIBCPP_STD_VER >= 23 - template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI - void prepend_range(_Range&& __range) { - insert_range(begin(), std::forward<_Range>(__range)); - } +# if _LIBCPP_STD_VER >= 17 + template <class... _Args> + _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); + template <class... _Args> + _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args); +# else + template <class... _Args> + _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); + template <class... _Args> + _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args); +# endif + template <class... _Args> + _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); + + _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); + _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v); + +# if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<_Tp> _Range> + _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) { + insert_range(begin(), std::forward<_Range>(__range)); + } - template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI - void append_range(_Range&& __range) { - insert_range(end(), std::forward<_Range>(__range)); - } -#endif + template <_ContainerCompatibleRange<_Tp> _Range> + _LIBCPP_HIDE_FROM_ABI void append_range(_Range&& __range) { + insert_range(end(), std::forward<_Range>(__range)); + } +# endif - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v); + _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v); - _LIBCPP_HIDE_FROM_ABI - iterator insert(const_iterator __p, initializer_list<value_type> __il) - {return insert(__p, __il.begin(), __il.end());} + _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, initializer_list<value_type> __il) { + return insert(__p, __il.begin(), __il.end()); + } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v); - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); - template <class _InputIter> - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l, - typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type* = 0); - template <class _ForwardIterator> - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, - typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type* = 0); - template <class _BiIter> - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l, - typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type* = 0); + _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v); + _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); + template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l); + template <class _ForwardIterator, + __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l); + template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l); #if _LIBCPP_STD_VER >= 23 - template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI - iterator insert_range(const_iterator __position, _Range&& __range) { - if constexpr (ranges::bidirectional_range<_Range>) { - auto __n = static_cast<size_type>(ranges::distance(__range)); - return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n); + template <_ContainerCompatibleRange<_Tp> _Range> + _LIBCPP_HIDE_FROM_ABI iterator insert_range(const_iterator __position, _Range&& __range) { + if constexpr (ranges::bidirectional_range<_Range>) { + auto __n = static_cast<size_type>(ranges::distance(__range)); + return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n); - } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { - auto __n = static_cast<size_type>(ranges::distance(__range)); - return __insert_with_size(__position, ranges::begin(__range), __n); + } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { + auto __n = static_cast<size_type>(ranges::distance(__range)); + return __insert_with_size(__position, ranges::begin(__range), __n); - } else { - return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); - } + } else { + return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); } + } #endif - _LIBCPP_HIDE_FROM_ABI void pop_front(); - _LIBCPP_HIDE_FROM_ABI void pop_back(); - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); + _LIBCPP_HIDE_FROM_ABI void pop_front(); + _LIBCPP_HIDE_FROM_ABI void pop_back(); + _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); + _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); - _LIBCPP_HIDE_FROM_ABI - void swap(deque& __c) + _LIBCPP_HIDE_FROM_ABI void swap(deque& __c) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; + _NOEXCEPT; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable<allocator_type>::value); + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif - _LIBCPP_HIDE_FROM_ABI - void clear() _NOEXCEPT; - - _LIBCPP_HIDE_FROM_ABI - bool __invariants() const { - if (!__map_.__invariants()) - return false; - if (__map_.size() >= size_type(-1) / __block_size) - return false; - for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); - __i != __e; ++__i) - if (*__i == nullptr) - return false; - if (__map_.size() != 0) - { - if (size() >= __map_.size() * __block_size) - return false; - if (__start_ >= __map_.size() * __block_size - size()) - return false; - } - else - { - if (size() != 0) - return false; - if (__start_ != 0) - return false; - } - return true; + _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; + + _LIBCPP_HIDE_FROM_ABI bool __invariants() const { + if (!__map_.__invariants()) + return false; + if (__map_.size() >= size_type(-1) / __block_size) + return false; + for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); __i != __e; ++__i) + if (*__i == nullptr) + return false; + if (__map_.size() != 0) { + if (size() >= __map_.size() * __block_size) + return false; + if (__start_ >= __map_.size() * __block_size - size()) + return false; + } else { + if (size() != 0) + return false; + if (__start_ != 0) + return false; } + return true; + } - _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(deque& __c) - _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || - is_nothrow_move_assignable<allocator_type>::value) - {__move_assign_alloc(__c, integral_constant<bool, - __alloc_traits::propagate_on_container_move_assignment::value>());} - - _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(deque& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) - { - __alloc() = _VSTD::move(__c.__alloc()); - } + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable<allocator_type>::value) { + __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); + } - _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(deque&, false_type) _NOEXCEPT - {} - - _LIBCPP_HIDE_FROM_ABI - void __move_assign(deque& __c) - _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value) - { - __map_ = _VSTD::move(__c.__map_); - __start_ = __c.__start_; - __size() = __c.size(); - __move_assign_alloc(__c); - __c.__start_ = __c.__size() = 0; - } + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { + __alloc() = std::move(__c.__alloc()); + } - _LIBCPP_HIDE_FROM_ABI - static size_type __recommend_blocks(size_type __n) - { - return __n / __block_size + (__n % __block_size != 0); - } - _LIBCPP_HIDE_FROM_ABI - size_type __capacity() const - { - return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1; - } - _LIBCPP_HIDE_FROM_ABI - size_type __block_count() const - { - return __map_.size(); - } + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque&, false_type) _NOEXCEPT {} - _LIBCPP_HIDE_FROM_ABI - size_type __front_spare() const - { - return __start_; - } - _LIBCPP_HIDE_FROM_ABI - size_type __front_spare_blocks() const { - return __front_spare() / __block_size; - } - _LIBCPP_HIDE_FROM_ABI - size_type __back_spare() const - { - return __capacity() - (__start_ + size()); - } - _LIBCPP_HIDE_FROM_ABI - size_type __back_spare_blocks() const { - return __back_spare() / __block_size; - } + _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c) + _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value&& + is_nothrow_move_assignable<allocator_type>::value) { + __map_ = std::move(__c.__map_); + __start_ = __c.__start_; + __size() = __c.size(); + __move_assign_alloc(__c); + __c.__start_ = __c.__size() = 0; + } - private: - enum __asan_annotation_type { - __asan_unposion, - __asan_poison - }; + _LIBCPP_HIDE_FROM_ABI static size_type __recommend_blocks(size_type __n) { + return __n / __block_size + (__n % __block_size != 0); + } + _LIBCPP_HIDE_FROM_ABI size_type __capacity() const { + return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1; + } + _LIBCPP_HIDE_FROM_ABI size_type __block_count() const { return __map_.size(); } - enum __asan_annotation_place { - __asan_front_moved, - __asan_back_moved, - }; + _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const { return __start_; } + _LIBCPP_HIDE_FROM_ABI size_type __front_spare_blocks() const { return __front_spare() / __block_size; } + _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const { return __capacity() - (__start_ + size()); } + _LIBCPP_HIDE_FROM_ABI size_type __back_spare_blocks() const { return __back_spare() / __block_size; } -// The following functions are no-ops outside of AddressSanitizer mode. -// We call annotations for every allocator, unless explicitly disabled. -// -// To disable annotations for a particular allocator, change value of -// __asan_annotate_container_with_allocator to false. -// For more details, see the "Using libc++" documentation page or -// the documentation for __sanitizer_annotate_contiguous_container. -#if !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600 - // TODO LLVM18: Remove the special-casing - _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( - const void* __beg, - const void* __end, - const void* __old_con_beg, - const void* __old_con_end, - const void* __new_con_beg, - const void* __new_con_end) const { - if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value) - __sanitizer_annotate_double_ended_contiguous_container( - __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end); - } -#else - _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( - const void*, const void*, const void*, const void*, const void*, const void*) const _NOEXCEPT {} -#endif // !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600 - - _LIBCPP_HIDE_FROM_ABI - void __annotate_from_to(size_type __beg, size_type __end, __asan_annotation_type __annotation_type, __asan_annotation_place __place) const _NOEXCEPT { - // __beg - index of the first item to annotate - // __end - index behind the last item to annotate (so last item + 1) - // __annotation_type - __asan_unposion or __asan_poison - // __place - __asan_front_moved or __asan_back_moved - // Note: All indexes in __map_ - if (__beg == __end) - return; - // __annotations_beg_map - first chunk which annotations we want to modify - // __annotations_end_map - last chunk which annotations we want to modify - // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist - __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; - __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; - - bool const __poisoning = __annotation_type == __asan_poison; - // __old_c_beg_index - index of the first element in old container - // __old_c_end_index - index of the end of old container (last + 1) - // Note: may be outside the area we are annotating - size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; - size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); - bool const __front = __place == __asan_front_moved; - - if (__poisoning && empty()) { - // Special case: we shouldn't trust __start_ - __old_c_beg_index = __beg; - __old_c_end_index = __end; - } - // __old_c_beg_map - memory block (chunk) with first element - // __old_c_end_map - memory block (chunk) with end of old container - // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, - // which may not exist - __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; - __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; - - // One edge (front/end) of the container was moved and one was not modified. - // __new_edge_index - index of new edge - // __new_edge_map - memory block (chunk) with new edge, it always equals to - // __annotations_beg_map or __annotations_end_map - // __old_edge_map - memory block (chunk) with old edge, it always equals to - // __old_c_beg_map or __old_c_end_map - size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; - __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; - __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; - - // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. - // First and last chunk may be partially poisoned. - // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. - for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { - if (__map_it == __annotations_end_map && __end % __block_size == 0) - // Chunk may not exist, but nothing to do here anyway - break; - - // The beginning and the end of the current memory block - const void* __mem_beg = std::__to_address(*__map_it); - const void* __mem_end = std::__to_address(*__map_it + __block_size); - - // The beginning of memory-in-use in the memory block before container modification - const void* __old_beg = - (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; - - // The end of memory-in-use in the memory block before container modification - const void* __old_end; - if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) - __old_end = __old_beg; - else - __old_end = (__map_it == __old_c_end_map) ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) - : __mem_end; - - // New edge of the container in current memory block - // If the edge is in a different chunk it points on corresponding end of the memory block - const void* __new_edge; - if (__map_it == __new_edge_map) - __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); - else - __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; - - // Not modified edge of the container - // If the edge is in a different chunk it points on corresponding end of the memory block - const void* __old_edge; - if (__map_it == __old_edge_map) - __old_edge = __front ? __old_end : __old_beg; - else - __old_edge = __front ? __mem_end : __mem_beg; - - // __new_beg - the beginning of memory-in-use in the memory block after container modification - // __new_end - the end of memory-in-use in the memory block after container modification - const void* __new_beg = __front ? __new_edge : __old_edge; - const void* __new_end = __front ? __old_edge : __new_edge; - - __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); - } - } +private: + enum __asan_annotation_type { __asan_unposion, __asan_poison }; - _LIBCPP_HIDE_FROM_ABI - void __annotate_new(size_type __current_size) const _NOEXCEPT { - if (__current_size == 0) - __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); - else { - __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); - __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); - } - } + enum __asan_annotation_place { + __asan_front_moved, + __asan_back_moved, + }; - _LIBCPP_HIDE_FROM_ABI - void __annotate_delete() const _NOEXCEPT { - if (empty()) { - for(size_t __i = 0; __i < __map_.size(); ++__i) { - __annotate_whole_block(__i, __asan_unposion); - } - } - else { - __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); - __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); - } - } + // The following functions are no-ops outside of AddressSanitizer mode. + // We call annotations for every allocator, unless explicitly disabled. + // + // To disable annotations for a particular allocator, change value of + // __asan_annotate_container_with_allocator to false. + // For more details, see the "Using libc++" documentation page or + // the documentation for __sanitizer_annotate_contiguous_container. + _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( + const void* __beg, + const void* __end, + const void* __old_con_beg, + const void* __old_con_end, + const void* __new_con_beg, + const void* __new_con_end) const { + (void)__beg; + (void)__end; + (void)__old_con_beg; + (void)__old_con_end; + (void)__new_con_beg; + (void)__new_con_end; +#ifndef _LIBCPP_HAS_NO_ASAN + if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value) + __sanitizer_annotate_double_ended_contiguous_container( + __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end); +#endif + } - _LIBCPP_HIDE_FROM_ABI - void __annotate_increase_front(size_type __n) const _NOEXCEPT { - __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); - } + _LIBCPP_HIDE_FROM_ABI void __annotate_from_to( + size_type __beg, + size_type __end, + __asan_annotation_type __annotation_type, + __asan_annotation_place __place) const _NOEXCEPT { + (void)__beg; + (void)__end; + (void)__annotation_type; + (void)__place; +#ifndef _LIBCPP_HAS_NO_ASAN + // __beg - index of the first item to annotate + // __end - index behind the last item to annotate (so last item + 1) + // __annotation_type - __asan_unposion or __asan_poison + // __place - __asan_front_moved or __asan_back_moved + // Note: All indexes in __map_ + if (__beg == __end) + return; + // __annotations_beg_map - first chunk which annotations we want to modify + // __annotations_end_map - last chunk which annotations we want to modify + // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist + __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; + __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; + + bool const __poisoning = __annotation_type == __asan_poison; + // __old_c_beg_index - index of the first element in old container + // __old_c_end_index - index of the end of old container (last + 1) + // Note: may be outside the area we are annotating + size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; + size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); + bool const __front = __place == __asan_front_moved; + + if (__poisoning && empty()) { + // Special case: we shouldn't trust __start_ + __old_c_beg_index = __beg; + __old_c_end_index = __end; + } + // __old_c_beg_map - memory block (chunk) with first element + // __old_c_end_map - memory block (chunk) with end of old container + // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, + // which may not exist + __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; + __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; + + // One edge (front/end) of the container was moved and one was not modified. + // __new_edge_index - index of new edge + // __new_edge_map - memory block (chunk) with new edge, it always equals to + // __annotations_beg_map or __annotations_end_map + // __old_edge_map - memory block (chunk) with old edge, it always equals to + // __old_c_beg_map or __old_c_end_map + size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; + __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; + __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; + + // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. + // First and last chunk may be partially poisoned. + // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. + for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { + if (__map_it == __annotations_end_map && __end % __block_size == 0) + // Chunk may not exist, but nothing to do here anyway + break; - _LIBCPP_HIDE_FROM_ABI - void __annotate_increase_back(size_type __n) const _NOEXCEPT { - __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); - } + // The beginning and the end of the current memory block + const void* __mem_beg = std::__to_address(*__map_it); + const void* __mem_end = std::__to_address(*__map_it + __block_size); + + // The beginning of memory-in-use in the memory block before container modification + const void* __old_beg = + (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; + + // The end of memory-in-use in the memory block before container modification + const void* __old_end; + if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) + __old_end = __old_beg; + else + __old_end = (__map_it == __old_c_end_map) + ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) + : __mem_end; + + // New edge of the container in current memory block + // If the edge is in a different chunk it points on corresponding end of the memory block + const void* __new_edge; + if (__map_it == __new_edge_map) + __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); + else + __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; + + // Not modified edge of the container + // If the edge is in a different chunk it points on corresponding end of the memory block + const void* __old_edge; + if (__map_it == __old_edge_map) + __old_edge = __front ? __old_end : __old_beg; + else + __old_edge = __front ? __mem_end : __mem_beg; + + // __new_beg - the beginning of memory-in-use in the memory block after container modification + // __new_end - the end of memory-in-use in the memory block after container modification + const void* __new_beg = __front ? __new_edge : __old_edge; + const void* __new_end = __front ? __old_edge : __new_edge; + + __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); + } +#endif // !_LIBCPP_HAS_NO_ASAN + } - _LIBCPP_HIDE_FROM_ABI - void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { - __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); + _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT { + (void)__current_size; +#ifndef _LIBCPP_HAS_NO_ASAN + if (__current_size == 0) + __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); + else { + __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); + __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); } +#endif + } - _LIBCPP_HIDE_FROM_ABI - void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { - __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); + _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT { +#ifndef _LIBCPP_HAS_NO_ASAN + if (empty()) { + for (size_t __i = 0; __i < __map_.size(); ++__i) { + __annotate_whole_block(__i, __asan_unposion); + } + } else { + __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); + __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); } +#endif + } - _LIBCPP_HIDE_FROM_ABI - void __annotate_poison_block(const void *__beginning, const void *__end) const _NOEXCEPT { - __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end); - } + _LIBCPP_HIDE_FROM_ABI void __annotate_increase_front(size_type __n) const _NOEXCEPT { + (void)__n; +#ifndef _LIBCPP_HAS_NO_ASAN + __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); +#endif + } - _LIBCPP_HIDE_FROM_ABI - void __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { - __map_const_iterator __block_it = __map_.begin() + __block_index; - const void* __block_start = std::__to_address(*__block_it); - const void* __block_end = std::__to_address(*__block_it + __block_size); - - if(__annotation_type == __asan_poison) - __annotate_poison_block(__block_start, __block_end); - else { - __annotate_double_ended_contiguous_container( - __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); - } + _LIBCPP_HIDE_FROM_ABI void __annotate_increase_back(size_type __n) const _NOEXCEPT { + (void)__n; +#ifndef _LIBCPP_HAS_NO_ASAN + __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); +#endif + } + + _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { + (void)__old_size; + (void)__old_start; +#ifndef _LIBCPP_HAS_NO_ASAN + __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); +#endif + } + + _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { + (void)__old_size; + (void)__old_start; +#ifndef _LIBCPP_HAS_NO_ASAN + __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); +#endif + } + + _LIBCPP_HIDE_FROM_ABI void __annotate_poison_block(const void* __beginning, const void* __end) const _NOEXCEPT { + (void)__beginning; + (void)__end; +#ifndef _LIBCPP_HAS_NO_ASAN + __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end); +#endif + } + + _LIBCPP_HIDE_FROM_ABI void + __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { + (void)__block_index; + (void)__annotation_type; +#ifndef _LIBCPP_HAS_NO_ASAN + __map_const_iterator __block_it = __map_.begin() + __block_index; + const void* __block_start = std::__to_address(*__block_it); + const void* __block_end = std::__to_address(*__block_it + __block_size); + + if (__annotation_type == __asan_poison) + __annotate_poison_block(__block_start, __block_end); + else { + __annotate_double_ended_contiguous_container( + __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); } +#endif + } #if !defined(_LIBCPP_HAS_NO_ASAN) - public: - _LIBCPP_HIDE_FROM_ABI - bool __verify_asan_annotations() const _NOEXCEPT { - // This function tests deque object annotations. - if (empty()) { - for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { - if (!__sanitizer_verify_double_ended_contiguous_container( - std::__to_address(*__it), - std::__to_address(*__it), - std::__to_address(*__it), - std::__to_address(*__it + __block_size))) - return false; - } - - return true; - } +public: + _LIBCPP_HIDE_FROM_ABI bool __verify_asan_annotations() const _NOEXCEPT { + // This function tests deque object annotations. + if (empty()) { + for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { + if (!__sanitizer_verify_double_ended_contiguous_container( + std::__to_address(*__it), + std::__to_address(*__it), + std::__to_address(*__it), + std::__to_address(*__it + __block_size))) + return false; + } - size_type __end = __start_ + size(); - __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; - __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; - - // Pointers to first and after last elements - // Those can be in different deque blocks - const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); - const void* __p_end = - std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); - - for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { - // Go over all blocks, find the place we are in and verify its annotations - // Note that __p_end points *behind* the last item. - - // - blocks before the first block with container elements - // - first block with items - // - last block with items - // - blocks after last block with ciontainer elements - - // Is the block before or after deque blocks that contain elements? - if (__it < __first_mp || __it > __last_mp) { - if (!__sanitizer_verify_double_ended_contiguous_container( - std::__to_address(*__it), - std::__to_address(*__it), - std::__to_address(*__it), - std::__to_address(*__it + __block_size))) - return false; - } else { - const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); - const void* __containers_buffer_end = - (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); - if (!__sanitizer_verify_double_ended_contiguous_container( - std::__to_address(*__it), - __containers_buffer_beg, - __containers_buffer_end, - std::__to_address(*__it + __block_size))) { - return false; - } - } - } - return true; + return true; } - private: -#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS - _LIBCPP_HIDE_FROM_ABI - bool __maybe_remove_front_spare(bool __keep_one = true) { - if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { - __annotate_whole_block(0, __asan_unposion); - __alloc_traits::deallocate(__alloc(), __map_.front(), - __block_size); - __map_.pop_front(); - __start_ -= __block_size; - return true; + size_type __end = __start_ + size(); + __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; + __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; + + // Pointers to first and after last elements + // Those can be in different deque blocks + const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); + const void* __p_end = + std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); + + for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { + // Go over all blocks, find the place we are in and verify its annotations + // Note that __p_end points *behind* the last item. + + // - blocks before the first block with container elements + // - first block with items + // - last block with items + // - blocks after last block with ciontainer elements + + // Is the block before or after deque blocks that contain elements? + if (__it < __first_mp || __it > __last_mp) { + if (!__sanitizer_verify_double_ended_contiguous_container( + std::__to_address(*__it), + std::__to_address(*__it), + std::__to_address(*__it), + std::__to_address(*__it + __block_size))) + return false; + } else { + const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); + const void* __containers_buffer_end = + (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); + if (!__sanitizer_verify_double_ended_contiguous_container( + std::__to_address(*__it), + __containers_buffer_beg, + __containers_buffer_end, + std::__to_address(*__it + __block_size))) { + return false; + } } - return false; } + return true; + } - _LIBCPP_HIDE_FROM_ABI - bool __maybe_remove_back_spare(bool __keep_one = true) { - if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { - __annotate_whole_block(__map_.size() - 1, __asan_unposion); - __alloc_traits::deallocate(__alloc(), __map_.back(), - __block_size); - __map_.pop_back(); - return true; - } - return false; +private: +#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS + _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_front_spare(bool __keep_one = true) { + if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { + __annotate_whole_block(0, __asan_unposion); + __alloc_traits::deallocate(__alloc(), __map_.front(), __block_size); + __map_.pop_front(); + __start_ -= __block_size; + return true; + } + return false; + } + + _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_back_spare(bool __keep_one = true) { + if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { + __annotate_whole_block(__map_.size() - 1, __asan_unposion); + __alloc_traits::deallocate(__alloc(), __map_.back(), __block_size); + __map_.pop_back(); + return true; } + return false; + } - template <class _Iterator, class _Sentinel> - _LIBCPP_HIDE_FROM_ABI - void __assign_with_sentinel(_Iterator __f, _Sentinel __l); - - template <class _RandomAccessIterator> - _LIBCPP_HIDE_FROM_ABI - void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); - template <class _Iterator> - _LIBCPP_HIDE_FROM_ABI - void __assign_with_size(_Iterator __f, difference_type __n); - - template <class _Iterator, class _Sentinel> - _LIBCPP_HIDE_FROM_ABI - iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); - - template <class _Iterator> - _LIBCPP_HIDE_FROM_ABI - iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); - - template <class _BiIter, class _Sentinel> - _LIBCPP_HIDE_FROM_ABI - iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); - template <class _BiIter> - _LIBCPP_HIDE_FROM_ABI - iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); - - template <class _InpIter> - _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l, - typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type* = 0); - template <class _ForIter> - _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l, - typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type* = 0); - - template <class _InputIterator> - _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); - template <class _InputIterator, class _Sentinel> - _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); - - _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); - _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); - _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); - _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(); - _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n); - _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(); - _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n); - _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, - const_pointer& __vt); - _LIBCPP_HIDE_FROM_ABI iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r, - const_pointer& __vt); - _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, - iterator __r, const_pointer& __vt); - _LIBCPP_HIDE_FROM_ABI void __move_construct_backward_and_check(iterator __f, iterator __l, - iterator __r, const_pointer& __vt); - - _LIBCPP_HIDE_FROM_ABI - void __copy_assign_alloc(const deque& __c) - {__copy_assign_alloc(__c, integral_constant<bool, - __alloc_traits::propagate_on_container_copy_assignment::value>());} - - _LIBCPP_HIDE_FROM_ABI - void __copy_assign_alloc(const deque& __c, true_type) - { - if (__alloc() != __c.__alloc()) - { - clear(); - shrink_to_fit(); - } - __alloc() = __c.__alloc(); - __map_.__alloc() = __c.__map_.__alloc(); - } + template <class _Iterator, class _Sentinel> + _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __f, _Sentinel __l); + + template <class _RandomAccessIterator> + _LIBCPP_HIDE_FROM_ABI void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); + template <class _Iterator> + _LIBCPP_HIDE_FROM_ABI void __assign_with_size(_Iterator __f, difference_type __n); + + template <class _Iterator, class _Sentinel> + _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); + + template <class _Iterator> + _LIBCPP_HIDE_FROM_ABI iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); + + template <class _BiIter, class _Sentinel> + _LIBCPP_HIDE_FROM_ABI iterator + __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); + template <class _BiIter> + _LIBCPP_HIDE_FROM_ABI iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); + + template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l); + template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l); + + template <class _InputIterator> + _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); + template <class _InputIterator, class _Sentinel> + _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); + + _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); + _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); + _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); + _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(); + _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n); + _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(); + _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n); + _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); + _LIBCPP_HIDE_FROM_ABI iterator + __move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); + _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); + _LIBCPP_HIDE_FROM_ABI void + __move_construct_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); + + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c) { + __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); + } + + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c, true_type) { + if (__alloc() != __c.__alloc()) { + clear(); + shrink_to_fit(); + } + __alloc() = __c.__alloc(); + __map_.__alloc() = __c.__map_.__alloc(); + } - _LIBCPP_HIDE_FROM_ABI - void __copy_assign_alloc(const deque&, false_type) - {} + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {} - _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); - _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type); + _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); + _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type); }; template <class _Tp, class _Alloc> @@ -1321,249 +1230,198 @@ _LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque __deque_block_size<value_type, difference_type>::value; #if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Alloc = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -deque(_InputIterator, _InputIterator) - -> deque<__iter_value_type<_InputIterator>, _Alloc>; - -template<class _InputIterator, - class _Alloc, - class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -deque(_InputIterator, _InputIterator, _Alloc) - -> deque<__iter_value_type<_InputIterator>, _Alloc>; +template <class _InputIterator, + class _Alloc = allocator<__iter_value_type<_InputIterator>>, + class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, + class = enable_if_t<__is_allocator<_Alloc>::value> > +deque(_InputIterator, _InputIterator) -> deque<__iter_value_type<_InputIterator>, _Alloc>; + +template <class _InputIterator, + class _Alloc, + class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, + class = enable_if_t<__is_allocator<_Alloc>::value> > +deque(_InputIterator, _InputIterator, _Alloc) -> deque<__iter_value_type<_InputIterator>, _Alloc>; #endif #if _LIBCPP_STD_VER >= 23 template <ranges::input_range _Range, class _Alloc = allocator<ranges::range_value_t<_Range>>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -deque(from_range_t, _Range&&, _Alloc = _Alloc()) - -> deque<ranges::range_value_t<_Range>, _Alloc>; + class = enable_if_t<__is_allocator<_Alloc>::value> > +deque(from_range_t, _Range&&, _Alloc = _Alloc()) -> deque<ranges::range_value_t<_Range>, _Alloc>; #endif template <class _Tp, class _Allocator> -deque<_Tp, _Allocator>::deque(size_type __n) - : __start_(0), __size_(0, __default_init_tag()) -{ - __annotate_new(0); - if (__n > 0) - __append(__n); +deque<_Tp, _Allocator>::deque(size_type __n) : __start_(0), __size_(0, __default_init_tag()) { + __annotate_new(0); + if (__n > 0) + __append(__n); } #if _LIBCPP_STD_VER >= 14 template <class _Tp, class _Allocator> deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) - : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) -{ - __annotate_new(0); - if (__n > 0) - __append(__n); + : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { + __annotate_new(0); + if (__n > 0) + __append(__n); } #endif template <class _Tp, class _Allocator> -deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) - : __start_(0), __size_(0, __default_init_tag()) -{ - __annotate_new(0); - if (__n > 0) - __append(__n, __v); +deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) : __start_(0), __size_(0, __default_init_tag()) { + __annotate_new(0); + if (__n > 0) + __append(__n, __v); } template <class _Tp, class _Allocator> -template <class _InputIter> -deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, - typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*) - : __start_(0), __size_(0, __default_init_tag()) -{ - __annotate_new(0); - __append(__f, __l); +template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > +deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l) : __start_(0), __size_(0, __default_init_tag()) { + __annotate_new(0); + __append(__f, __l); } template <class _Tp, class _Allocator> -template <class _InputIter> -deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a, - typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*) - : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) -{ - __annotate_new(0); - __append(__f, __l); +template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > +deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a) + : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { + __annotate_new(0); + __append(__f, __l); } template <class _Tp, class _Allocator> deque<_Tp, _Allocator>::deque(const deque& __c) : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))), __start_(0), - __size_(0, __map_.__alloc()) -{ - __annotate_new(0); - __append(__c.begin(), __c.end()); + __size_(0, __map_.__alloc()) { + __annotate_new(0); + __append(__c.begin(), __c.end()); } template <class _Tp, class _Allocator> deque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a) - : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) -{ - __annotate_new(0); - __append(__c.begin(), __c.end()); + : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { + __annotate_new(0); + __append(__c.begin(), __c.end()); } template <class _Tp, class _Allocator> -deque<_Tp, _Allocator>& -deque<_Tp, _Allocator>::operator=(const deque& __c) -{ - if (this != _VSTD::addressof(__c)) - { - __copy_assign_alloc(__c); - assign(__c.begin(), __c.end()); - } - return *this; +deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(const deque& __c) { + if (this != std::addressof(__c)) { + __copy_assign_alloc(__c); + assign(__c.begin(), __c.end()); + } + return *this; } #ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Allocator> -deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il) - : __start_(0), __size_(0, __default_init_tag()) -{ - __annotate_new(0); - __append(__il.begin(), __il.end()); +deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il) : __start_(0), __size_(0, __default_init_tag()) { + __annotate_new(0); + __append(__il.begin(), __il.end()); } template <class _Tp, class _Allocator> deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a) - : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) -{ - __annotate_new(0); - __append(__il.begin(), __il.end()); + : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { + __annotate_new(0); + __append(__il.begin(), __il.end()); } template <class _Tp, class _Allocator> -inline -deque<_Tp, _Allocator>::deque(deque&& __c) - _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) - : __map_(std::move(__c.__map_)), __start_(std::move(__c.__start_)), __size_(std::move(__c.__size_)) -{ +inline deque<_Tp, _Allocator>::deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) + : __map_(std::move(__c.__map_)), __start_(std::move(__c.__start_)), __size_(std::move(__c.__size_)) { __c.__start_ = 0; __c.__size() = 0; } template <class _Tp, class _Allocator> -inline -deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a) +inline deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a) : __map_(std::move(__c.__map_), __pointer_allocator(__a)), __start_(std::move(__c.__start_)), - __size_(std::move(__c.__size()), __a) -{ - if (__a == __c.__alloc()) - { - __c.__start_ = 0; - __c.__size() = 0; - } - else - { - __map_.clear(); - __start_ = 0; - __size() = 0; - typedef move_iterator<iterator> _Ip; - assign(_Ip(__c.begin()), _Ip(__c.end())); - } + __size_(std::move(__c.__size()), __a) { + if (__a == __c.__alloc()) { + __c.__start_ = 0; + __c.__size() = 0; + } else { + __map_.clear(); + __start_ = 0; + __size() = 0; + typedef move_iterator<iterator> _Ip; + assign(_Ip(__c.begin()), _Ip(__c.end())); + } } template <class _Tp, class _Allocator> -inline -deque<_Tp, _Allocator>& -deque<_Tp, _Allocator>::operator=(deque&& __c) - _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value) -{ - __move_assign(__c, integral_constant<bool, - __alloc_traits::propagate_on_container_move_assignment::value>()); - return *this; +inline deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(deque&& __c) _NOEXCEPT_( + __alloc_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<allocator_type>::value) { + __move_assign(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); + return *this; } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) -{ - if (__alloc() != __c.__alloc()) - { - typedef move_iterator<iterator> _Ip; - assign(_Ip(__c.begin()), _Ip(__c.end())); - } - else - __move_assign(__c, true_type()); +void deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) { + if (__alloc() != __c.__alloc()) { + typedef move_iterator<iterator> _Ip; + assign(_Ip(__c.begin()), _Ip(__c.end())); + } else + __move_assign(__c, true_type()); } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) -{ - clear(); - shrink_to_fit(); - __move_assign(__c); +void deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { + clear(); + shrink_to_fit(); + __move_assign(__c); } #endif // _LIBCPP_CXX03_LANG template <class _Tp, class _Allocator> -template <class _InputIter> -void -deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l, - typename enable_if<__has_input_iterator_category<_InputIter>::value && - !__has_random_access_iterator_category<_InputIter>::value>::type*) -{ +template <class _InputIter, + __enable_if_t<__has_input_iterator_category<_InputIter>::value && + !__has_random_access_iterator_category<_InputIter>::value, + int> > +void deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l) { __assign_with_sentinel(__f, __l); } template <class _Tp, class _Allocator> template <class _Iterator, class _Sentinel> -_LIBCPP_HIDE_FROM_ABI -void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { - iterator __i = begin(); - iterator __e = end(); - for (; __f != __l && __i != __e; ++__f, (void) ++__i) - *__i = *__f; - if (__f != __l) - __append_with_sentinel(std::move(__f), std::move(__l)); - else - __erase_to_end(__i); +_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { + iterator __i = begin(); + iterator __e = end(); + for (; __f != __l && __i != __e; ++__f, (void)++__i) + *__i = *__f; + if (__f != __l) + __append_with_sentinel(std::move(__f), std::move(__l)); + else + __erase_to_end(__i); } template <class _Tp, class _Allocator> -template <class _RAIter> -void -deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l, - typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type*) -{ +template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> > +void deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l) { __assign_with_size_random_access(__f, __l - __f); } template <class _Tp, class _Allocator> template <class _RandomAccessIterator> -_LIBCPP_HIDE_FROM_ABI -void deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { - if (static_cast<size_type>(__n) > size()) - { - auto __l = __f + size(); - std::copy(__f, __l, begin()); - __append_with_size(__l, __n - size()); - } - else - __erase_to_end(std::copy_n(__f, __n, begin())); +_LIBCPP_HIDE_FROM_ABI void +deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { + if (static_cast<size_type>(__n) > size()) { + auto __l = __f + size(); + std::copy(__f, __l, begin()); + __append_with_size(__l, __n - size()); + } else + __erase_to_end(std::copy_n(__f, __n, begin())); } template <class _Tp, class _Allocator> template <class _Iterator> -_LIBCPP_HIDE_FROM_ABI -void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { +_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { if (static_cast<size_type>(__n) > size()) { auto __added_size = __n - size(); @@ -1580,1356 +1438,1104 @@ void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type _ } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) -{ - if (__n > size()) - { - _VSTD::fill_n(begin(), size(), __v); - __n -= size(); - __append(__n, __v); - } - else - __erase_to_end(_VSTD::fill_n(begin(), __n, __v)); +void deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) { + if (__n > size()) { + std::fill_n(begin(), size(), __v); + __n -= size(); + __append(__n, __v); + } else + __erase_to_end(std::fill_n(begin(), __n, __v)); } template <class _Tp, class _Allocator> -inline -_Allocator -deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT -{ - return __alloc(); +inline _Allocator deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT { + return __alloc(); } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::resize(size_type __n) -{ - if (__n > size()) - __append(__n - size()); - else if (__n < size()) - __erase_to_end(begin() + __n); +void deque<_Tp, _Allocator>::resize(size_type __n) { + if (__n > size()) + __append(__n - size()); + else if (__n < size()) + __erase_to_end(begin() + __n); } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) -{ - if (__n > size()) - __append(__n - size(), __v); - else if (__n < size()) - __erase_to_end(begin() + __n); +void deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) { + if (__n > size()) + __append(__n - size(), __v); + else if (__n < size()) + __erase_to_end(begin() + __n); } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT -{ - allocator_type& __a = __alloc(); - if (empty()) - { - __annotate_delete(); - while (__map_.size() > 0) - { - __alloc_traits::deallocate(__a, __map_.back(), __block_size); - __map_.pop_back(); - } - __start_ = 0; - } - else - { - __maybe_remove_front_spare(/*__keep_one=*/false); - __maybe_remove_back_spare(/*__keep_one=*/false); +void deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT { + allocator_type& __a = __alloc(); + if (empty()) { + __annotate_delete(); + while (__map_.size() > 0) { + __alloc_traits::deallocate(__a, __map_.back(), __block_size); + __map_.pop_back(); } - __map_.shrink_to_fit(); + __start_ = 0; + } else { + __maybe_remove_front_spare(/*__keep_one=*/false); + __maybe_remove_back_spare(/*__keep_one=*/false); + } + __map_.shrink_to_fit(); } template <class _Tp, class _Allocator> -inline -typename deque<_Tp, _Allocator>::reference -deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT -{ - size_type __p = __start_ + __i; - return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); +inline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT { + size_type __p = __start_ + __i; + return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); } template <class _Tp, class _Allocator> -inline -typename deque<_Tp, _Allocator>::const_reference -deque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT -{ - size_type __p = __start_ + __i; - return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); +inline typename deque<_Tp, _Allocator>::const_reference +deque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT { + size_type __p = __start_ + __i; + return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); } template <class _Tp, class _Allocator> -inline -typename deque<_Tp, _Allocator>::reference -deque<_Tp, _Allocator>::at(size_type __i) -{ - if (__i >= size()) - _VSTD::__throw_out_of_range("deque"); - size_type __p = __start_ + __i; - return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); +inline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::at(size_type __i) { + if (__i >= size()) + std::__throw_out_of_range("deque"); + size_type __p = __start_ + __i; + return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); } template <class _Tp, class _Allocator> -inline -typename deque<_Tp, _Allocator>::const_reference -deque<_Tp, _Allocator>::at(size_type __i) const -{ - if (__i >= size()) - _VSTD::__throw_out_of_range("deque"); - size_type __p = __start_ + __i; - return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); +inline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::at(size_type __i) const { + if (__i >= size()) + std::__throw_out_of_range("deque"); + size_type __p = __start_ + __i; + return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); } template <class _Tp, class _Allocator> -inline -typename deque<_Tp, _Allocator>::reference -deque<_Tp, _Allocator>::front() _NOEXCEPT -{ - return *(*(__map_.begin() + __start_ / __block_size) - + __start_ % __block_size); +inline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::front() _NOEXCEPT { + return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); } template <class _Tp, class _Allocator> -inline -typename deque<_Tp, _Allocator>::const_reference -deque<_Tp, _Allocator>::front() const _NOEXCEPT -{ - return *(*(__map_.begin() + __start_ / __block_size) - + __start_ % __block_size); +inline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::front() const _NOEXCEPT { + return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); } template <class _Tp, class _Allocator> -inline -typename deque<_Tp, _Allocator>::reference -deque<_Tp, _Allocator>::back() _NOEXCEPT -{ - size_type __p = size() + __start_ - 1; - return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); +inline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::back() _NOEXCEPT { + size_type __p = size() + __start_ - 1; + return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); } template <class _Tp, class _Allocator> -inline -typename deque<_Tp, _Allocator>::const_reference -deque<_Tp, _Allocator>::back() const _NOEXCEPT -{ - size_type __p = size() + __start_ - 1; - return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); +inline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::back() const _NOEXCEPT { + size_type __p = size() + __start_ - 1; + return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::push_back(const value_type& __v) -{ - allocator_type& __a = __alloc(); - if (__back_spare() == 0) - __add_back_capacity(); - // __back_spare() >= 1 - __annotate_increase_back(1); - __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v); - ++__size(); +void deque<_Tp, _Allocator>::push_back(const value_type& __v) { + allocator_type& __a = __alloc(); + if (__back_spare() == 0) + __add_back_capacity(); + // __back_spare() >= 1 + __annotate_increase_back(1); + __alloc_traits::construct(__a, std::addressof(*end()), __v); + ++__size(); } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::push_front(const value_type& __v) -{ - allocator_type& __a = __alloc(); - if (__front_spare() == 0) - __add_front_capacity(); - // __front_spare() >= 1 - __annotate_increase_front(1); - __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v); - --__start_; - ++__size(); +void deque<_Tp, _Allocator>::push_front(const value_type& __v) { + allocator_type& __a = __alloc(); + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + __annotate_increase_front(1); + __alloc_traits::construct(__a, std::addressof(*--begin()), __v); + --__start_; + ++__size(); } #ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::push_back(value_type&& __v) -{ - allocator_type& __a = __alloc(); - if (__back_spare() == 0) - __add_back_capacity(); - // __back_spare() >= 1 - __annotate_increase_back(1); - __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v)); - ++__size(); +void deque<_Tp, _Allocator>::push_back(value_type&& __v) { + allocator_type& __a = __alloc(); + if (__back_spare() == 0) + __add_back_capacity(); + // __back_spare() >= 1 + __annotate_increase_back(1); + __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); + ++__size(); } template <class _Tp, class _Allocator> template <class... _Args> -#if _LIBCPP_STD_VER >= 17 +# if _LIBCPP_STD_VER >= 17 typename deque<_Tp, _Allocator>::reference -#else +# else void -#endif -deque<_Tp, _Allocator>::emplace_back(_Args&&... __args) -{ - allocator_type& __a = __alloc(); - if (__back_spare() == 0) - __add_back_capacity(); - // __back_spare() >= 1 - __annotate_increase_back(1); - __alloc_traits::construct(__a, _VSTD::addressof(*end()), - _VSTD::forward<_Args>(__args)...); - ++__size(); -#if _LIBCPP_STD_VER >= 17 - return *--end(); -#endif +# endif +deque<_Tp, _Allocator>::emplace_back(_Args&&... __args) { + allocator_type& __a = __alloc(); + if (__back_spare() == 0) + __add_back_capacity(); + // __back_spare() >= 1 + __annotate_increase_back(1); + __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); + ++__size(); +# if _LIBCPP_STD_VER >= 17 + return *--end(); +# endif } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::push_front(value_type&& __v) -{ - allocator_type& __a = __alloc(); - if (__front_spare() == 0) - __add_front_capacity(); - // __front_spare() >= 1 - __annotate_increase_front(1); - __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v)); - --__start_; - ++__size(); +void deque<_Tp, _Allocator>::push_front(value_type&& __v) { + allocator_type& __a = __alloc(); + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + __annotate_increase_front(1); + __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); + --__start_; + ++__size(); } - template <class _Tp, class _Allocator> template <class... _Args> -#if _LIBCPP_STD_VER >= 17 +# if _LIBCPP_STD_VER >= 17 typename deque<_Tp, _Allocator>::reference -#else +# else void -#endif -deque<_Tp, _Allocator>::emplace_front(_Args&&... __args) -{ - allocator_type& __a = __alloc(); +# endif +deque<_Tp, _Allocator>::emplace_front(_Args&&... __args) { + allocator_type& __a = __alloc(); + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + __annotate_increase_front(1); + __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); + --__start_; + ++__size(); +# if _LIBCPP_STD_VER >= 17 + return *begin(); +# endif +} + +template <class _Tp, class _Allocator> +typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) { + size_type __pos = __p - begin(); + size_type __to_end = size() - __pos; + allocator_type& __a = __alloc(); + if (__pos < __to_end) { // insert by shifting things backward if (__front_spare() == 0) - __add_front_capacity(); + __add_front_capacity(); // __front_spare() >= 1 __annotate_increase_front(1); - __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...); - --__start_; - ++__size(); -#if _LIBCPP_STD_VER >= 17 - return *begin(); -#endif -} - -template <class _Tp, class _Allocator> -typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) -{ - size_type __pos = __p - begin(); - size_type __to_end = size() - __pos; - allocator_type& __a = __alloc(); - if (__pos < __to_end) - { // insert by shifting things backward - if (__front_spare() == 0) - __add_front_capacity(); - // __front_spare() >= 1 - __annotate_increase_front(1); - if (__pos == 0) - { - __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v)); - --__start_; - ++__size(); - } - else - { - iterator __b = begin(); - iterator __bm1 = _VSTD::prev(__b); - __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); - --__start_; - ++__size(); - if (__pos > 1) - __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); - *__b = _VSTD::move(__v); - } - } - else - { // insert by shifting things forward - if (__back_spare() == 0) - __add_back_capacity(); - // __back_capacity >= 1 - __annotate_increase_back(1); - size_type __de = size() - __pos; - if (__de == 0) - { - __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v)); - ++__size(); - } - else - { - iterator __e = end(); - iterator __em1 = _VSTD::prev(__e); - __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); - ++__size(); - if (__de > 1) - __e = _VSTD::move_backward(__e - __de, __em1, __e); - *--__e = _VSTD::move(__v); - } + if (__pos == 0) { + __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); + --__start_; + ++__size(); + } else { + iterator __b = begin(); + iterator __bm1 = std::prev(__b); + __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); + --__start_; + ++__size(); + if (__pos > 1) + __b = std::move(std::next(__b), __b + __pos, __b); + *__b = std::move(__v); + } + } else { // insert by shifting things forward + if (__back_spare() == 0) + __add_back_capacity(); + // __back_capacity >= 1 + __annotate_increase_back(1); + size_type __de = size() - __pos; + if (__de == 0) { + __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); + ++__size(); + } else { + iterator __e = end(); + iterator __em1 = std::prev(__e); + __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); + ++__size(); + if (__de > 1) + __e = std::move_backward(__e - __de, __em1, __e); + *--__e = std::move(__v); } - return begin() + __pos; + } + return begin() + __pos; } template <class _Tp, class _Allocator> template <class... _Args> -typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) -{ - size_type __pos = __p - begin(); - size_type __to_end = size() - __pos; - allocator_type& __a = __alloc(); - if (__pos < __to_end) - { // insert by shifting things backward - if (__front_spare() == 0) - __add_front_capacity(); - // __front_spare() >= 1 - __annotate_increase_front(1); - if (__pos == 0) - { - __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...); - --__start_; - ++__size(); - } - else - { - __temp_value<value_type, _Allocator> __tmp(__alloc(), _VSTD::forward<_Args>(__args)...); - iterator __b = begin(); - iterator __bm1 = _VSTD::prev(__b); - __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); - --__start_; - ++__size(); - if (__pos > 1) - __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); - *__b = _VSTD::move(__tmp.get()); - } - } - else - { // insert by shifting things forward - if (__back_spare() == 0) - __add_back_capacity(); - // __back_capacity >= 1 - __annotate_increase_back(1); - size_type __de = size() - __pos; - if (__de == 0) - { - __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::forward<_Args>(__args)...); - ++__size(); - } - else - { - __temp_value<value_type, _Allocator> __tmp(__alloc(), _VSTD::forward<_Args>(__args)...); - iterator __e = end(); - iterator __em1 = _VSTD::prev(__e); - __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); - ++__size(); - if (__de > 1) - __e = _VSTD::move_backward(__e - __de, __em1, __e); - *--__e = _VSTD::move(__tmp.get()); - } +typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) { + size_type __pos = __p - begin(); + size_type __to_end = size() - __pos; + allocator_type& __a = __alloc(); + if (__pos < __to_end) { // insert by shifting things backward + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + __annotate_increase_front(1); + if (__pos == 0) { + __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); + --__start_; + ++__size(); + } else { + __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); + iterator __b = begin(); + iterator __bm1 = std::prev(__b); + __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); + --__start_; + ++__size(); + if (__pos > 1) + __b = std::move(std::next(__b), __b + __pos, __b); + *__b = std::move(__tmp.get()); + } + } else { // insert by shifting things forward + if (__back_spare() == 0) + __add_back_capacity(); + // __back_capacity >= 1 + __annotate_increase_back(1); + size_type __de = size() - __pos; + if (__de == 0) { + __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); + ++__size(); + } else { + __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); + iterator __e = end(); + iterator __em1 = std::prev(__e); + __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); + ++__size(); + if (__de > 1) + __e = std::move_backward(__e - __de, __em1, __e); + *--__e = std::move(__tmp.get()); } - return begin() + __pos; + } + return begin() + __pos; } #endif // _LIBCPP_CXX03_LANG - template <class _Tp, class _Allocator> -typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) -{ - size_type __pos = __p - begin(); - size_type __to_end = size() - __pos; - allocator_type& __a = __alloc(); - if (__pos < __to_end) - { // insert by shifting things backward - if (__front_spare() == 0) - __add_front_capacity(); - // __front_spare() >= 1 - __annotate_increase_front(1); - if (__pos == 0) - { - __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v); - --__start_; - ++__size(); - } - else - { - const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); - iterator __b = begin(); - iterator __bm1 = _VSTD::prev(__b); - if (__vt == pointer_traits<const_pointer>::pointer_to(*__b)) - __vt = pointer_traits<const_pointer>::pointer_to(*__bm1); - __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); - --__start_; - ++__size(); - if (__pos > 1) - __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt); - *__b = *__vt; - } - } - else - { // insert by shifting things forward - if (__back_spare() == 0) - __add_back_capacity(); - // __back_capacity >= 1 - __annotate_increase_back(1); - size_type __de = size() - __pos; - if (__de == 0) - { - __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v); - ++__size(); - } - else - { - const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); - iterator __e = end(); - iterator __em1 = _VSTD::prev(__e); - if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1)) - __vt = pointer_traits<const_pointer>::pointer_to(*__e); - __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); - ++__size(); - if (__de > 1) - __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); - *--__e = *__vt; - } +typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) { + size_type __pos = __p - begin(); + size_type __to_end = size() - __pos; + allocator_type& __a = __alloc(); + if (__pos < __to_end) { // insert by shifting things backward + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + __annotate_increase_front(1); + if (__pos == 0) { + __alloc_traits::construct(__a, std::addressof(*--begin()), __v); + --__start_; + ++__size(); + } else { + const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); + iterator __b = begin(); + iterator __bm1 = std::prev(__b); + if (__vt == pointer_traits<const_pointer>::pointer_to(*__b)) + __vt = pointer_traits<const_pointer>::pointer_to(*__bm1); + __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); + --__start_; + ++__size(); + if (__pos > 1) + __b = __move_and_check(std::next(__b), __b + __pos, __b, __vt); + *__b = *__vt; + } + } else { // insert by shifting things forward + if (__back_spare() == 0) + __add_back_capacity(); + // __back_capacity >= 1 + __annotate_increase_back(1); + size_type __de = size() - __pos; + if (__de == 0) { + __alloc_traits::construct(__a, std::addressof(*end()), __v); + ++__size(); + } else { + const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); + iterator __e = end(); + iterator __em1 = std::prev(__e); + if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1)) + __vt = pointer_traits<const_pointer>::pointer_to(*__e); + __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); + ++__size(); + if (__de > 1) + __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); + *--__e = *__vt; } - return begin() + __pos; + } + return begin() + __pos; } template <class _Tp, class _Allocator> typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) -{ - size_type __pos = __p - begin(); - size_type __to_end = __size() - __pos; - allocator_type& __a = __alloc(); - if (__pos < __to_end) - { // insert by shifting things backward - if (__n > __front_spare()) - __add_front_capacity(__n - __front_spare()); - // __n <= __front_spare() - __annotate_increase_front(__n); - iterator __old_begin = begin(); - iterator __i = __old_begin; - if (__n > __pos) - { - for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size()) - __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v); - __n = __pos; - } - if (__n > 0) - { - const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); - iterator __obn = __old_begin + __n; - __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); - if (__n < __pos) - __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); - _VSTD::fill_n(__old_begin, __n, *__vt); - } - } - else - { // insert by shifting things forward - size_type __back_capacity = __back_spare(); - if (__n > __back_capacity) - __add_back_capacity(__n - __back_capacity); - // __n <= __back_capacity - __annotate_increase_back(__n); - iterator __old_end = end(); - iterator __i = __old_end; - size_type __de = size() - __pos; - if (__n > __de) - { - for (size_type __m = __n - __de; __m; --__m, (void) ++__i, ++__size()) - __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v); - __n = __de; - } - if (__n > 0) - { - const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); - iterator __oen = __old_end - __n; - __move_construct_and_check(__oen, __old_end, __i, __vt); - if (__n < __de) - __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); - _VSTD::fill_n(__old_end - __n, __n, *__vt); - } +deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) { + size_type __pos = __p - begin(); + size_type __to_end = __size() - __pos; + allocator_type& __a = __alloc(); + if (__pos < __to_end) { // insert by shifting things backward + if (__n > __front_spare()) + __add_front_capacity(__n - __front_spare()); + // __n <= __front_spare() + __annotate_increase_front(__n); + iterator __old_begin = begin(); + iterator __i = __old_begin; + if (__n > __pos) { + for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size()) + __alloc_traits::construct(__a, std::addressof(*--__i), __v); + __n = __pos; + } + if (__n > 0) { + const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); + iterator __obn = __old_begin + __n; + __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); + if (__n < __pos) + __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); + std::fill_n(__old_begin, __n, *__vt); + } + } else { // insert by shifting things forward + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + __annotate_increase_back(__n); + iterator __old_end = end(); + iterator __i = __old_end; + size_type __de = size() - __pos; + if (__n > __de) { + for (size_type __m = __n - __de; __m; --__m, (void)++__i, ++__size()) + __alloc_traits::construct(__a, std::addressof(*__i), __v); + __n = __de; + } + if (__n > 0) { + const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); + iterator __oen = __old_end - __n; + __move_construct_and_check(__oen, __old_end, __i, __vt); + if (__n < __de) + __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); + std::fill_n(__old_end - __n, __n, *__vt); } - return begin() + __pos; + } + return begin() + __pos; } template <class _Tp, class _Allocator> -template <class _InputIter> +template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> > typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l, - typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type*) -{ +deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l) { return __insert_with_sentinel(__p, __f, __l); } template <class _Tp, class _Allocator> template <class _Iterator, class _Sentinel> -_LIBCPP_HIDE_FROM_ABI -typename deque<_Tp, _Allocator>::iterator +_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { - __split_buffer<value_type, allocator_type&> __buf(__alloc()); - __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); - typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; - return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); + __split_buffer<value_type, allocator_type&> __buf(__alloc()); + __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); + typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; + return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); } template <class _Tp, class _Allocator> -template <class _ForwardIterator> +template <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> > typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, - typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type*) -{ +deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l) { return __insert_with_size(__p, __f, std::distance(__f, __l)); } template <class _Tp, class _Allocator> template <class _Iterator> -_LIBCPP_HIDE_FROM_ABI -typename deque<_Tp, _Allocator>::iterator +_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) { - __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); - __buf.__construct_at_end_with_size(__f, __n); - typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; - return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); + __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); + __buf.__construct_at_end_with_size(__f, __n); + typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; + return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); } template <class _Tp, class _Allocator> -template <class _BiIter> -typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l, - typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type*) -{ +template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> > +typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l) { return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l)); } template <class _Tp, class _Allocator> template <class _BiIter, class _Sentinel> -_LIBCPP_HIDE_FROM_ABI -typename deque<_Tp, _Allocator>::iterator +_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) { return __insert_bidirectional(__p, __f, std::next(__f, __n), __n); } template <class _Tp, class _Allocator> template <class _BiIter> -_LIBCPP_HIDE_FROM_ABI -typename deque<_Tp, _Allocator>::iterator +_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) { - size_type __pos = __p - begin(); - size_type __to_end = size() - __pos; - allocator_type& __a = __alloc(); - if (__pos < __to_end) - { // insert by shifting things backward - if (__n > __front_spare()) - __add_front_capacity(__n - __front_spare()); - // __n <= __front_spare() - __annotate_increase_front(__n); - iterator __old_begin = begin(); - iterator __i = __old_begin; - _BiIter __m = __f; - if (__n > __pos) - { - __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos); - for (_BiIter __j = __m; __j != __f; --__start_, ++__size()) - __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j); - __n = __pos; - } - if (__n > 0) - { - iterator __obn = __old_begin + __n; - for (iterator __j = __obn; __j != __old_begin;) - { - __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j)); - --__start_; - ++__size(); - } - if (__n < __pos) - __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin); - _VSTD::copy(__m, __l, __old_begin); - } + size_type __pos = __p - begin(); + size_type __to_end = size() - __pos; + allocator_type& __a = __alloc(); + if (__pos < __to_end) { // insert by shifting things backward + if (__n > __front_spare()) + __add_front_capacity(__n - __front_spare()); + // __n <= __front_spare() + __annotate_increase_front(__n); + iterator __old_begin = begin(); + iterator __i = __old_begin; + _BiIter __m = __f; + if (__n > __pos) { + __m = __pos < __n / 2 ? std::prev(__l, __pos) : std::next(__f, __n - __pos); + for (_BiIter __j = __m; __j != __f; --__start_, ++__size()) + __alloc_traits::construct(__a, std::addressof(*--__i), *--__j); + __n = __pos; + } + if (__n > 0) { + iterator __obn = __old_begin + __n; + for (iterator __j = __obn; __j != __old_begin;) { + __alloc_traits::construct(__a, std::addressof(*--__i), std::move(*--__j)); + --__start_; + ++__size(); + } + if (__n < __pos) + __old_begin = std::move(__obn, __old_begin + __pos, __old_begin); + std::copy(__m, __l, __old_begin); } - else - { // insert by shifting things forward - size_type __back_capacity = __back_spare(); - if (__n > __back_capacity) - __add_back_capacity(__n - __back_capacity); - // __n <= __back_capacity - __annotate_increase_back(__n); - iterator __old_end = end(); - iterator __i = __old_end; - _BiIter __m = __l; - size_type __de = size() - __pos; - if (__n > __de) - { - __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de); - for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__size()) - __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j); - __n = __de; - } - if (__n > 0) - { - iterator __oen = __old_end - __n; - for (iterator __j = __oen; __j != __old_end; ++__i, (void) ++__j, ++__size()) - __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j)); - if (__n < __de) - __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end); - _VSTD::copy_backward(__f, __m, __old_end); - } + } else { // insert by shifting things forward + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + __annotate_increase_back(__n); + iterator __old_end = end(); + iterator __i = __old_end; + _BiIter __m = __l; + size_type __de = size() - __pos; + if (__n > __de) { + __m = __de < __n / 2 ? std::next(__f, __de) : std::prev(__l, __n - __de); + for (_BiIter __j = __m; __j != __l; ++__i, (void)++__j, ++__size()) + __alloc_traits::construct(__a, std::addressof(*__i), *__j); + __n = __de; + } + if (__n > 0) { + iterator __oen = __old_end - __n; + for (iterator __j = __oen; __j != __old_end; ++__i, (void)++__j, ++__size()) + __alloc_traits::construct(__a, std::addressof(*__i), std::move(*__j)); + if (__n < __de) + __old_end = std::move_backward(__old_end - __de, __oen, __old_end); + std::copy_backward(__f, __m, __old_end); } - return begin() + __pos; + } + return begin() + __pos; } template <class _Tp, class _Allocator> -template <class _InpIter> -void -deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l, - typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type*) -{ +template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> > +void deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l) { __append_with_sentinel(__f, __l); } template <class _Tp, class _Allocator> template <class _InputIterator, class _Sentinel> -_LIBCPP_HIDE_FROM_ABI -void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { - for (; __f != __l; ++__f) +_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { + for (; __f != __l; ++__f) #ifdef _LIBCPP_CXX03_LANG - push_back(*__f); + push_back(*__f); #else - emplace_back(*__f); + emplace_back(*__f); #endif } template <class _Tp, class _Allocator> -template <class _ForIter> -void -deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l, - typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type*) -{ - __append_with_size(__f, std::distance(__f, __l)); +template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> > +void deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l) { + __append_with_size(__f, std::distance(__f, __l)); } template <class _Tp, class _Allocator> template <class _InputIterator> -_LIBCPP_HIDE_FROM_ABI -void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { - allocator_type& __a = __alloc(); - size_type __back_capacity = __back_spare(); - if (__n > __back_capacity) - __add_back_capacity(__n - __back_capacity); - - // __n <= __back_capacity - __annotate_increase_back(__n); - for (__deque_block_range __br : __deque_range(end(), end() + __n)) { - _ConstructTransaction __tx(this, __br); - for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { - __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f); - } +_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { + allocator_type& __a = __alloc(); + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + + // __n <= __back_capacity + __annotate_increase_back(__n); + for (__deque_block_range __br : __deque_range(end(), end() + __n)) { + _ConstructTransaction __tx(this, __br); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { + __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); } + } } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__append(size_type __n) -{ - allocator_type& __a = __alloc(); - size_type __back_capacity = __back_spare(); - if (__n > __back_capacity) - __add_back_capacity(__n - __back_capacity); - // __n <= __back_capacity - __annotate_increase_back(__n); - for (__deque_block_range __br : __deque_range(end(), end() + __n)) { - _ConstructTransaction __tx(this, __br); - for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { - __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_)); - } +void deque<_Tp, _Allocator>::__append(size_type __n) { + allocator_type& __a = __alloc(); + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + __annotate_increase_back(__n); + for (__deque_block_range __br : __deque_range(end(), end() + __n)) { + _ConstructTransaction __tx(this, __br); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { + __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); } + } } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) -{ - allocator_type& __a = __alloc(); - size_type __back_capacity = __back_spare(); - if (__n > __back_capacity) - __add_back_capacity(__n - __back_capacity); - // __n <= __back_capacity - __annotate_increase_back(__n); - for (__deque_block_range __br : __deque_range(end(), end() + __n)) { - _ConstructTransaction __tx(this, __br); - for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { - __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v); - } +void deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) { + allocator_type& __a = __alloc(); + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + __annotate_increase_back(__n); + for (__deque_block_range __br : __deque_range(end(), end() + __n)) { + _ConstructTransaction __tx(this, __br); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { + __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); } - + } } // Create front capacity for one block of elements. // Strong guarantee. Either do it or don't touch anything. template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__add_front_capacity() -{ - allocator_type& __a = __alloc(); - if (__back_spare() >= __block_size) - { - __start_ += __block_size; - pointer __pt = __map_.back(); - __map_.pop_back(); - __map_.push_front(__pt); - } - // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer - else if (__map_.size() < __map_.capacity()) - { // we can put the new buffer into the map, but don't shift things around - // until all buffers are allocated. If we throw, we don't need to fix - // anything up (any added buffers are undetectible) - if (__map_.__front_spare() > 0) - __map_.push_front(__alloc_traits::allocate(__a, __block_size)); - else - { - __map_.push_back(__alloc_traits::allocate(__a, __block_size)); - // Done allocating, reorder capacity - pointer __pt = __map_.back(); - __map_.pop_back(); - __map_.push_front(__pt); - } - __start_ = __map_.size() == 1 ? - __block_size / 2 : - __start_ + __block_size; - } - // Else need to allocate 1 buffer, *and* we need to reallocate __map_. - else - { - __split_buffer<pointer, __pointer_allocator&> - __buf(std::max<size_type>(2 * __map_.capacity(), 1), - 0, __map_.__alloc()); - - typedef __allocator_destructor<_Allocator> _Dp; - unique_ptr<pointer, _Dp> __hold( - __alloc_traits::allocate(__a, __block_size), - _Dp(__a, __block_size)); - __buf.push_back(__hold.get()); - __hold.release(); - - for (__map_pointer __i = __map_.begin(); - __i != __map_.end(); ++__i) - __buf.push_back(*__i); - _VSTD::swap(__map_.__first_, __buf.__first_); - _VSTD::swap(__map_.__begin_, __buf.__begin_); - _VSTD::swap(__map_.__end_, __buf.__end_); - _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); - __start_ = __map_.size() == 1 ? - __block_size / 2 : - __start_ + __block_size; - } - __annotate_whole_block(0, __asan_poison); +void deque<_Tp, _Allocator>::__add_front_capacity() { + allocator_type& __a = __alloc(); + if (__back_spare() >= __block_size) { + __start_ += __block_size; + pointer __pt = __map_.back(); + __map_.pop_back(); + __map_.push_front(__pt); + } + // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer + else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around + // until all buffers are allocated. If we throw, we don't need to fix + // anything up (any added buffers are undetectible) + if (__map_.__front_spare() > 0) + __map_.push_front(__alloc_traits::allocate(__a, __block_size)); + else { + __map_.push_back(__alloc_traits::allocate(__a, __block_size)); + // Done allocating, reorder capacity + pointer __pt = __map_.back(); + __map_.pop_back(); + __map_.push_front(__pt); + } + __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; + } + // Else need to allocate 1 buffer, *and* we need to reallocate __map_. + else { + __split_buffer<pointer, __pointer_allocator&> __buf( + std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__alloc()); + + typedef __allocator_destructor<_Allocator> _Dp; + unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); + __buf.push_back(__hold.get()); + __hold.release(); + + for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) + __buf.push_back(*__i); + std::swap(__map_.__first_, __buf.__first_); + std::swap(__map_.__begin_, __buf.__begin_); + std::swap(__map_.__end_, __buf.__end_); + std::swap(__map_.__end_cap(), __buf.__end_cap()); + __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; + } + __annotate_whole_block(0, __asan_poison); } // Create front capacity for __n elements. // Strong guarantee. Either do it or don't touch anything. template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) -{ - allocator_type& __a = __alloc(); - size_type __nb = __recommend_blocks(__n + __map_.empty()); - // Number of unused blocks at back: - size_type __back_capacity = __back_spare() / __block_size; - __back_capacity = _VSTD::min(__back_capacity, __nb); // don't take more than you need - __nb -= __back_capacity; // number of blocks need to allocate - // If __nb == 0, then we have sufficient capacity. - if (__nb == 0) - { - __start_ += __block_size * __back_capacity; - for (; __back_capacity > 0; --__back_capacity) - { - pointer __pt = __map_.back(); - __map_.pop_back(); - __map_.push_front(__pt); - } +void deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) { + allocator_type& __a = __alloc(); + size_type __nb = __recommend_blocks(__n + __map_.empty()); + // Number of unused blocks at back: + size_type __back_capacity = __back_spare() / __block_size; + __back_capacity = std::min(__back_capacity, __nb); // don't take more than you need + __nb -= __back_capacity; // number of blocks need to allocate + // If __nb == 0, then we have sufficient capacity. + if (__nb == 0) { + __start_ += __block_size * __back_capacity; + for (; __back_capacity > 0; --__back_capacity) { + pointer __pt = __map_.back(); + __map_.pop_back(); + __map_.push_front(__pt); } - // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers - else if (__nb <= __map_.capacity() - __map_.size()) - { // we can put the new buffers into the map, but don't shift things around - // until all buffers are allocated. If we throw, we don't need to fix - // anything up (any added buffers are undetectible) - for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) - { - if (__map_.__front_spare() == 0) - break; - __map_.push_front(__alloc_traits::allocate(__a, __block_size)); - __annotate_whole_block(0, __asan_poison); - } - for (; __nb > 0; --__nb, ++__back_capacity) - __map_.push_back(__alloc_traits::allocate(__a, __block_size)); - // Done allocating, reorder capacity - __start_ += __back_capacity * __block_size; - for (; __back_capacity > 0; --__back_capacity) - { - pointer __pt = __map_.back(); - __map_.pop_back(); - __map_.push_front(__pt); - __annotate_whole_block(0, __asan_poison); - } + } + // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers + else if (__nb <= __map_.capacity() - + __map_.size()) { // we can put the new buffers into the map, but don't shift things around + // until all buffers are allocated. If we throw, we don't need to fix + // anything up (any added buffers are undetectible) + for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) { + if (__map_.__front_spare() == 0) + break; + __map_.push_front(__alloc_traits::allocate(__a, __block_size)); + __annotate_whole_block(0, __asan_poison); + } + for (; __nb > 0; --__nb, ++__back_capacity) + __map_.push_back(__alloc_traits::allocate(__a, __block_size)); + // Done allocating, reorder capacity + __start_ += __back_capacity * __block_size; + for (; __back_capacity > 0; --__back_capacity) { + pointer __pt = __map_.back(); + __map_.pop_back(); + __map_.push_front(__pt); + __annotate_whole_block(0, __asan_poison); } - // Else need to allocate __nb buffers, *and* we need to reallocate __map_. - else - { - size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty(); - __split_buffer<pointer, __pointer_allocator&> - __buf(std::max<size_type>(2* __map_.capacity(), - __nb + __map_.size()), - 0, __map_.__alloc()); + } + // Else need to allocate __nb buffers, *and* we need to reallocate __map_. + else { + size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty(); + __split_buffer<pointer, __pointer_allocator&> __buf( + std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__alloc()); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __nb > 0; --__nb) { - __buf.push_back(__alloc_traits::allocate(__a, __block_size)); - // ASan: this is empty container, we have to poison whole block - __annotate_poison_block( - std::__to_address(__buf.back()), - std::__to_address(__buf.back() + __block_size)); - } + for (; __nb > 0; --__nb) { + __buf.push_back(__alloc_traits::allocate(__a, __block_size)); + // ASan: this is empty container, we have to poison whole block + __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); + } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - __annotate_delete(); - for (__map_pointer __i = __buf.begin(); - __i != __buf.end(); ++__i) - __alloc_traits::deallocate(__a, *__i, __block_size); - throw; - } -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __back_capacity > 0; --__back_capacity) - { - __buf.push_back(__map_.back()); - __map_.pop_back(); - } - for (__map_pointer __i = __map_.begin(); - __i != __map_.end(); ++__i) - __buf.push_back(*__i); - _VSTD::swap(__map_.__first_, __buf.__first_); - _VSTD::swap(__map_.__begin_, __buf.__begin_); - _VSTD::swap(__map_.__end_, __buf.__end_); - _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); - __start_ += __ds; + } catch (...) { + __annotate_delete(); + for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) + __alloc_traits::deallocate(__a, *__i, __block_size); + throw; } +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + for (; __back_capacity > 0; --__back_capacity) { + __buf.push_back(__map_.back()); + __map_.pop_back(); + } + for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) + __buf.push_back(*__i); + std::swap(__map_.__first_, __buf.__first_); + std::swap(__map_.__begin_, __buf.__begin_); + std::swap(__map_.__end_, __buf.__end_); + std::swap(__map_.__end_cap(), __buf.__end_cap()); + __start_ += __ds; + } } // Create back capacity for one block of elements. // Strong guarantee. Either do it or don't touch anything. template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__add_back_capacity() -{ - allocator_type& __a = __alloc(); - if (__front_spare() >= __block_size) - { - __start_ -= __block_size; - pointer __pt = __map_.front(); - __map_.pop_front(); - __map_.push_back(__pt); - } - // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers - else if (__map_.size() < __map_.capacity()) - { // we can put the new buffer into the map, but don't shift things around - // until it is allocated. If we throw, we don't need to fix - // anything up (any added buffers are undetectible) - if (__map_.__back_spare() != 0) - __map_.push_back(__alloc_traits::allocate(__a, __block_size)); - else - { - __map_.push_front(__alloc_traits::allocate(__a, __block_size)); - // Done allocating, reorder capacity - pointer __pt = __map_.front(); - __map_.pop_front(); - __map_.push_back(__pt); - } - __annotate_whole_block(__map_.size() - 1, __asan_poison); - } - // Else need to allocate 1 buffer, *and* we need to reallocate __map_. - else - { - __split_buffer<pointer, __pointer_allocator&> - __buf(std::max<size_type>(2* __map_.capacity(), 1), - __map_.size(), - __map_.__alloc()); - - typedef __allocator_destructor<_Allocator> _Dp; - unique_ptr<pointer, _Dp> __hold( - __alloc_traits::allocate(__a, __block_size), - _Dp(__a, __block_size)); - __buf.push_back(__hold.get()); - __hold.release(); - - for (__map_pointer __i = __map_.end(); - __i != __map_.begin();) - __buf.push_front(*--__i); - _VSTD::swap(__map_.__first_, __buf.__first_); - _VSTD::swap(__map_.__begin_, __buf.__begin_); - _VSTD::swap(__map_.__end_, __buf.__end_); - _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); - __annotate_whole_block(__map_.size() - 1, __asan_poison); - } +void deque<_Tp, _Allocator>::__add_back_capacity() { + allocator_type& __a = __alloc(); + if (__front_spare() >= __block_size) { + __start_ -= __block_size; + pointer __pt = __map_.front(); + __map_.pop_front(); + __map_.push_back(__pt); + } + // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers + else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around + // until it is allocated. If we throw, we don't need to fix + // anything up (any added buffers are undetectible) + if (__map_.__back_spare() != 0) + __map_.push_back(__alloc_traits::allocate(__a, __block_size)); + else { + __map_.push_front(__alloc_traits::allocate(__a, __block_size)); + // Done allocating, reorder capacity + pointer __pt = __map_.front(); + __map_.pop_front(); + __map_.push_back(__pt); + } + __annotate_whole_block(__map_.size() - 1, __asan_poison); + } + // Else need to allocate 1 buffer, *and* we need to reallocate __map_. + else { + __split_buffer<pointer, __pointer_allocator&> __buf( + std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__alloc()); + + typedef __allocator_destructor<_Allocator> _Dp; + unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); + __buf.push_back(__hold.get()); + __hold.release(); + + for (__map_pointer __i = __map_.end(); __i != __map_.begin();) + __buf.push_front(*--__i); + std::swap(__map_.__first_, __buf.__first_); + std::swap(__map_.__begin_, __buf.__begin_); + std::swap(__map_.__end_, __buf.__end_); + std::swap(__map_.__end_cap(), __buf.__end_cap()); + __annotate_whole_block(__map_.size() - 1, __asan_poison); + } } // Create back capacity for __n elements. // Strong guarantee. Either do it or don't touch anything. template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) -{ - allocator_type& __a = __alloc(); - size_type __nb = __recommend_blocks(__n + __map_.empty()); - // Number of unused blocks at front: - size_type __front_capacity = __front_spare() / __block_size; - __front_capacity = _VSTD::min(__front_capacity, __nb); // don't take more than you need - __nb -= __front_capacity; // number of blocks need to allocate - // If __nb == 0, then we have sufficient capacity. - if (__nb == 0) - { - __start_ -= __block_size * __front_capacity; - for (; __front_capacity > 0; --__front_capacity) - { - pointer __pt = __map_.front(); - __map_.pop_front(); - __map_.push_back(__pt); - } +void deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) { + allocator_type& __a = __alloc(); + size_type __nb = __recommend_blocks(__n + __map_.empty()); + // Number of unused blocks at front: + size_type __front_capacity = __front_spare() / __block_size; + __front_capacity = std::min(__front_capacity, __nb); // don't take more than you need + __nb -= __front_capacity; // number of blocks need to allocate + // If __nb == 0, then we have sufficient capacity. + if (__nb == 0) { + __start_ -= __block_size * __front_capacity; + for (; __front_capacity > 0; --__front_capacity) { + pointer __pt = __map_.front(); + __map_.pop_front(); + __map_.push_back(__pt); } - // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers - else if (__nb <= __map_.capacity() - __map_.size()) - { // we can put the new buffers into the map, but don't shift things around - // until all buffers are allocated. If we throw, we don't need to fix - // anything up (any added buffers are undetectible) - for (; __nb > 0; --__nb) - { - if (__map_.__back_spare() == 0) - break; - __map_.push_back(__alloc_traits::allocate(__a, __block_size)); - __annotate_whole_block(__map_.size() - 1, __asan_poison); - } - for (; __nb > 0; --__nb, ++__front_capacity, __start_ += - __block_size - (__map_.size() == 1)) { - __map_.push_front(__alloc_traits::allocate(__a, __block_size)); - __annotate_whole_block(0, __asan_poison); - } - // Done allocating, reorder capacity - __start_ -= __block_size * __front_capacity; - for (; __front_capacity > 0; --__front_capacity) - { - pointer __pt = __map_.front(); - __map_.pop_front(); - __map_.push_back(__pt); - } + } + // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers + else if (__nb <= __map_.capacity() - + __map_.size()) { // we can put the new buffers into the map, but don't shift things around + // until all buffers are allocated. If we throw, we don't need to fix + // anything up (any added buffers are undetectible) + for (; __nb > 0; --__nb) { + if (__map_.__back_spare() == 0) + break; + __map_.push_back(__alloc_traits::allocate(__a, __block_size)); + __annotate_whole_block(__map_.size() - 1, __asan_poison); + } + for (; __nb > 0; --__nb, ++__front_capacity, __start_ += __block_size - (__map_.size() == 1)) { + __map_.push_front(__alloc_traits::allocate(__a, __block_size)); + __annotate_whole_block(0, __asan_poison); } - // Else need to allocate __nb buffers, *and* we need to reallocate __map_. - else - { - size_type __ds = __front_capacity * __block_size; - __split_buffer<pointer, __pointer_allocator&> - __buf(std::max<size_type>(2* __map_.capacity(), - __nb + __map_.size()), - __map_.size() - __front_capacity, - __map_.__alloc()); + // Done allocating, reorder capacity + __start_ -= __block_size * __front_capacity; + for (; __front_capacity > 0; --__front_capacity) { + pointer __pt = __map_.front(); + __map_.pop_front(); + __map_.push_back(__pt); + } + } + // Else need to allocate __nb buffers, *and* we need to reallocate __map_. + else { + size_type __ds = __front_capacity * __block_size; + __split_buffer<pointer, __pointer_allocator&> __buf( + std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), + __map_.size() - __front_capacity, + __map_.__alloc()); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __nb > 0; --__nb) { - __buf.push_back(__alloc_traits::allocate(__a, __block_size)); - // ASan: this is an empty container, we have to poison the whole block - __annotate_poison_block( - std::__to_address(__buf.back()), - std::__to_address(__buf.back() + __block_size)); - } + for (; __nb > 0; --__nb) { + __buf.push_back(__alloc_traits::allocate(__a, __block_size)); + // ASan: this is an empty container, we have to poison the whole block + __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); + } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - __annotate_delete(); - for (__map_pointer __i = __buf.begin(); - __i != __buf.end(); ++__i) - __alloc_traits::deallocate(__a, *__i, __block_size); - throw; - } -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __front_capacity > 0; --__front_capacity) - { - __buf.push_back(__map_.front()); - __map_.pop_front(); - } - for (__map_pointer __i = __map_.end(); - __i != __map_.begin();) - __buf.push_front(*--__i); - _VSTD::swap(__map_.__first_, __buf.__first_); - _VSTD::swap(__map_.__begin_, __buf.__begin_); - _VSTD::swap(__map_.__end_, __buf.__end_); - _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); - __start_ -= __ds; + } catch (...) { + __annotate_delete(); + for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) + __alloc_traits::deallocate(__a, *__i, __block_size); + throw; } +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + for (; __front_capacity > 0; --__front_capacity) { + __buf.push_back(__map_.front()); + __map_.pop_front(); + } + for (__map_pointer __i = __map_.end(); __i != __map_.begin();) + __buf.push_front(*--__i); + std::swap(__map_.__first_, __buf.__first_); + std::swap(__map_.__begin_, __buf.__begin_); + std::swap(__map_.__end_, __buf.__end_); + std::swap(__map_.__end_cap(), __buf.__end_cap()); + __start_ -= __ds; + } } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::pop_front() -{ - size_type __old_sz = size(); - size_type __old_start = __start_; - allocator_type& __a = __alloc(); - __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() + - __start_ / __block_size) + - __start_ % __block_size)); - --__size(); - ++__start_; - __annotate_shrink_front(__old_sz, __old_start); - __maybe_remove_front_spare(); +void deque<_Tp, _Allocator>::pop_front() { + size_type __old_sz = size(); + size_type __old_start = __start_; + allocator_type& __a = __alloc(); + __alloc_traits::destroy( + __a, std::__to_address(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size)); + --__size(); + ++__start_; + __annotate_shrink_front(__old_sz, __old_start); + __maybe_remove_front_spare(); } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::pop_back() -{ - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); - size_type __old_sz = size(); - size_type __old_start = __start_; - allocator_type& __a = __alloc(); - size_type __p = size() + __start_ - 1; - __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() + - __p / __block_size) + - __p % __block_size)); - --__size(); - __annotate_shrink_back(__old_sz, __old_start); - __maybe_remove_back_spare(); +void deque<_Tp, _Allocator>::pop_back() { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); + size_type __old_sz = size(); + size_type __old_start = __start_; + allocator_type& __a = __alloc(); + size_type __p = size() + __start_ - 1; + __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() + __p / __block_size) + __p % __block_size)); + --__size(); + __annotate_shrink_back(__old_sz, __old_start); + __maybe_remove_back_spare(); } // move assign [__f, __l) to [__r, __r + (__l-__f)). // If __vt points into [__f, __l), then subtract (__f - __r) from __vt. template <class _Tp, class _Allocator> typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, - const_pointer& __vt) -{ - // as if - // for (; __f != __l; ++__f, ++__r) - // *__r = _VSTD::move(*__f); - difference_type __n = __l - __f; - while (__n > 0) - { - pointer __fb = __f.__ptr_; - pointer __fe = *__f.__m_iter_ + __block_size; - difference_type __bs = __fe - __fb; - if (__bs > __n) - { - __bs = __n; - __fe = __fb + __bs; - } - if (__fb <= __vt && __vt < __fe) - __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; - __r = _VSTD::move(__fb, __fe, __r); - __n -= __bs; - __f += __bs; - } - return __r; +deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { + // as if + // for (; __f != __l; ++__f, ++__r) + // *__r = std::move(*__f); + difference_type __n = __l - __f; + while (__n > 0) { + pointer __fb = __f.__ptr_; + pointer __fe = *__f.__m_iter_ + __block_size; + difference_type __bs = __fe - __fb; + if (__bs > __n) { + __bs = __n; + __fe = __fb + __bs; + } + if (__fb <= __vt && __vt < __fe) + __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; + __r = std::move(__fb, __fe, __r); + __n -= __bs; + __f += __bs; + } + return __r; } // move assign [__f, __l) to [__r - (__l-__f), __r) backwards. // If __vt points into [__f, __l), then add (__r - __l) to __vt. template <class _Tp, class _Allocator> typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, - const_pointer& __vt) -{ - // as if - // while (__f != __l) - // *--__r = _VSTD::move(*--__l); - difference_type __n = __l - __f; - while (__n > 0) - { - --__l; - pointer __lb = *__l.__m_iter_; - pointer __le = __l.__ptr_ + 1; - difference_type __bs = __le - __lb; - if (__bs > __n) - { - __bs = __n; - __lb = __le - __bs; - } - if (__lb <= __vt && __vt < __le) - __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; - __r = _VSTD::move_backward(__lb, __le, __r); - __n -= __bs; - __l -= __bs - 1; - } - return __r; +deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { + // as if + // while (__f != __l) + // *--__r = std::move(*--__l); + difference_type __n = __l - __f; + while (__n > 0) { + --__l; + pointer __lb = *__l.__m_iter_; + pointer __le = __l.__ptr_ + 1; + difference_type __bs = __le - __lb; + if (__bs > __n) { + __bs = __n; + __lb = __le - __bs; + } + if (__lb <= __vt && __vt < __le) + __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; + __r = std::move_backward(__lb, __le, __r); + __n -= __bs; + __l -= __bs - 1; + } + return __r; } // move construct [__f, __l) to [__r, __r + (__l-__f)). // If __vt points into [__f, __l), then add (__r - __f) to __vt. template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, - iterator __r, const_pointer& __vt) -{ - allocator_type& __a = __alloc(); - // as if - // for (; __f != __l; ++__r, ++__f, ++__size()) - // __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f)); - difference_type __n = __l - __f; - while (__n > 0) - { - pointer __fb = __f.__ptr_; - pointer __fe = *__f.__m_iter_ + __block_size; - difference_type __bs = __fe - __fb; - if (__bs > __n) - { - __bs = __n; - __fe = __fb + __bs; - } - if (__fb <= __vt && __vt < __fe) - __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; - for (; __fb != __fe; ++__fb, ++__r, ++__size()) - __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb)); - __n -= __bs; - __f += __bs; - } +void deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { + allocator_type& __a = __alloc(); + // as if + // for (; __f != __l; ++__r, ++__f, ++__size()) + // __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__f)); + difference_type __n = __l - __f; + while (__n > 0) { + pointer __fb = __f.__ptr_; + pointer __fe = *__f.__m_iter_ + __block_size; + difference_type __bs = __fe - __fb; + if (__bs > __n) { + __bs = __n; + __fe = __fb + __bs; + } + if (__fb <= __vt && __vt < __fe) + __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; + for (; __fb != __fe; ++__fb, ++__r, ++__size()) + __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__fb)); + __n -= __bs; + __f += __bs; + } } // move construct [__f, __l) to [__r - (__l-__f), __r) backwards. // If __vt points into [__f, __l), then subtract (__l - __r) from __vt. template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l, - iterator __r, const_pointer& __vt) -{ - allocator_type& __a = __alloc(); - // as if - // for (iterator __j = __l; __j != __f;) - // { - // __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j)); - // --__start_; - // ++__size(); - // } - difference_type __n = __l - __f; - while (__n > 0) - { - --__l; - pointer __lb = *__l.__m_iter_; - pointer __le = __l.__ptr_ + 1; - difference_type __bs = __le - __lb; - if (__bs > __n) - { - __bs = __n; - __lb = __le - __bs; - } - if (__lb <= __vt && __vt < __le) - __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; - while (__le != __lb) - { - __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le)); - --__start_; - ++__size(); - } - __n -= __bs; - __l -= __bs - 1; - } +void deque<_Tp, _Allocator>::__move_construct_backward_and_check( + iterator __f, iterator __l, iterator __r, const_pointer& __vt) { + allocator_type& __a = __alloc(); + // as if + // for (iterator __j = __l; __j != __f;) + // { + // __alloc_traitsconstruct(__a, std::addressof(*--__r), std::move(*--__j)); + // --__start_; + // ++__size(); + // } + difference_type __n = __l - __f; + while (__n > 0) { + --__l; + pointer __lb = *__l.__m_iter_; + pointer __le = __l.__ptr_ + 1; + difference_type __bs = __le - __lb; + if (__bs > __n) { + __bs = __n; + __lb = __le - __bs; + } + if (__lb <= __vt && __vt < __le) + __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; + while (__le != __lb) { + __alloc_traits::construct(__a, std::addressof(*--__r), std::move(*--__le)); + --__start_; + ++__size(); + } + __n -= __bs; + __l -= __bs - 1; + } } template <class _Tp, class _Allocator> -typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::erase(const_iterator __f) -{ - size_type __old_sz = size(); - size_type __old_start = __start_; - iterator __b = begin(); - difference_type __pos = __f - __b; - iterator __p = __b + __pos; - allocator_type& __a = __alloc(); - if (static_cast<size_t>(__pos) <= (size() - 1) / 2) - { // erase from front - _VSTD::move_backward(__b, __p, _VSTD::next(__p)); - __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); - --__size(); - ++__start_; - __annotate_shrink_front(__old_sz, __old_start); - __maybe_remove_front_spare(); - } - else - { // erase from back - iterator __i = _VSTD::move(_VSTD::next(__p), end(), __p); - __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); - --__size(); - __annotate_shrink_back(__old_sz, __old_start); - __maybe_remove_back_spare(); - } - return begin() + __pos; +typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f) { + size_type __old_sz = size(); + size_type __old_start = __start_; + iterator __b = begin(); + difference_type __pos = __f - __b; + iterator __p = __b + __pos; + allocator_type& __a = __alloc(); + if (static_cast<size_t>(__pos) <= (size() - 1) / 2) { // erase from front + std::move_backward(__b, __p, std::next(__p)); + __alloc_traits::destroy(__a, std::addressof(*__b)); + --__size(); + ++__start_; + __annotate_shrink_front(__old_sz, __old_start); + __maybe_remove_front_spare(); + } else { // erase from back + iterator __i = std::move(std::next(__p), end(), __p); + __alloc_traits::destroy(__a, std::addressof(*__i)); + --__size(); + __annotate_shrink_back(__old_sz, __old_start); + __maybe_remove_back_spare(); + } + return begin() + __pos; } template <class _Tp, class _Allocator> -typename deque<_Tp, _Allocator>::iterator -deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) -{ - size_type __old_sz = size(); - size_type __old_start = __start_; - difference_type __n = __l - __f; - iterator __b = begin(); - difference_type __pos = __f - __b; - iterator __p = __b + __pos; - if (__n > 0) - { - allocator_type& __a = __alloc(); - if (static_cast<size_t>(__pos) <= (size() - __n) / 2) - { // erase from front - iterator __i = _VSTD::move_backward(__b, __p, __p + __n); - for (; __b != __i; ++__b) - __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); - __size() -= __n; - __start_ += __n; - __annotate_shrink_front(__old_sz, __old_start); - while (__maybe_remove_front_spare()) { - } - } - else - { // erase from back - iterator __i = _VSTD::move(__p + __n, end(), __p); - for (iterator __e = end(); __i != __e; ++__i) - __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); - __size() -= __n; - __annotate_shrink_back(__old_sz, __old_start); - while (__maybe_remove_back_spare()) { - } - } +typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) { + size_type __old_sz = size(); + size_type __old_start = __start_; + difference_type __n = __l - __f; + iterator __b = begin(); + difference_type __pos = __f - __b; + iterator __p = __b + __pos; + if (__n > 0) { + allocator_type& __a = __alloc(); + if (static_cast<size_t>(__pos) <= (size() - __n) / 2) { // erase from front + iterator __i = std::move_backward(__b, __p, __p + __n); + for (; __b != __i; ++__b) + __alloc_traits::destroy(__a, std::addressof(*__b)); + __size() -= __n; + __start_ += __n; + __annotate_shrink_front(__old_sz, __old_start); + while (__maybe_remove_front_spare()) { + } + } else { // erase from back + iterator __i = std::move(__p + __n, end(), __p); + for (iterator __e = end(); __i != __e; ++__i) + __alloc_traits::destroy(__a, std::addressof(*__i)); + __size() -= __n; + __annotate_shrink_back(__old_sz, __old_start); + while (__maybe_remove_back_spare()) { + } } - return begin() + __pos; + } + return begin() + __pos; } template <class _Tp, class _Allocator> -void -deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) -{ - size_type __old_sz = size(); - size_type __old_start = __start_; - iterator __e = end(); - difference_type __n = __e - __f; - if (__n > 0) - { - allocator_type& __a = __alloc(); - iterator __b = begin(); - difference_type __pos = __f - __b; - for (iterator __p = __b + __pos; __p != __e; ++__p) - __alloc_traits::destroy(__a, _VSTD::addressof(*__p)); - __size() -= __n; - __annotate_shrink_back(__old_sz, __old_start); - while (__maybe_remove_back_spare()) { - } +void deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) { + size_type __old_sz = size(); + size_type __old_start = __start_; + iterator __e = end(); + difference_type __n = __e - __f; + if (__n > 0) { + allocator_type& __a = __alloc(); + iterator __b = begin(); + difference_type __pos = __f - __b; + for (iterator __p = __b + __pos; __p != __e; ++__p) + __alloc_traits::destroy(__a, std::addressof(*__p)); + __size() -= __n; + __annotate_shrink_back(__old_sz, __old_start); + while (__maybe_remove_back_spare()) { } + } } template <class _Tp, class _Allocator> -inline -void -deque<_Tp, _Allocator>::swap(deque& __c) +inline void deque<_Tp, _Allocator>::swap(deque& __c) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT + _NOEXCEPT #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable<allocator_type>::value) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { - __map_.swap(__c.__map_); - _VSTD::swap(__start_, __c.__start_); - _VSTD::swap(__size(), __c.__size()); - _VSTD::__swap_allocator(__alloc(), __c.__alloc()); + __map_.swap(__c.__map_); + std::swap(__start_, __c.__start_); + std::swap(__size(), __c.__size()); + std::__swap_allocator(__alloc(), __c.__alloc()); } template <class _Tp, class _Allocator> -inline -void -deque<_Tp, _Allocator>::clear() _NOEXCEPT -{ - __annotate_delete(); - allocator_type& __a = __alloc(); - for (iterator __i = begin(), __e = end(); __i != __e; ++__i) - __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); - __size() = 0; - while (__map_.size() > 2) - { - __alloc_traits::deallocate(__a, __map_.front(), __block_size); - __map_.pop_front(); - } - switch (__map_.size()) - { - case 1: - __start_ = __block_size / 2; - break; - case 2: - __start_ = __block_size; - break; - } - __annotate_new(0); +inline void deque<_Tp, _Allocator>::clear() _NOEXCEPT { + __annotate_delete(); + allocator_type& __a = __alloc(); + for (iterator __i = begin(), __e = end(); __i != __e; ++__i) + __alloc_traits::destroy(__a, std::addressof(*__i)); + __size() = 0; + while (__map_.size() > 2) { + __alloc_traits::deallocate(__a, __map_.front(), __block_size); + __map_.pop_front(); + } + switch (__map_.size()) { + case 1: + __start_ = __block_size / 2; + break; + case 2: + __start_ = __block_size; + break; + } + __annotate_new(0); } template <class _Tp, class _Allocator> -inline _LIBCPP_HIDE_FROM_ABI -bool -operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) -{ - const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); - return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { + const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); + return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); } #if _LIBCPP_STD_VER <= 17 template <class _Tp, class _Allocator> -inline _LIBCPP_HIDE_FROM_ABI -bool -operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) -{ - return !(__x == __y); +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { + return !(__x == __y); } template <class _Tp, class _Allocator> -inline _LIBCPP_HIDE_FROM_ABI -bool -operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) -{ - return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); +inline _LIBCPP_HIDE_FROM_ABI bool operator<(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { + return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } template <class _Tp, class _Allocator> -inline _LIBCPP_HIDE_FROM_ABI -bool -operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) -{ - return __y < __x; +inline _LIBCPP_HIDE_FROM_ABI bool operator>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { + return __y < __x; } template <class _Tp, class _Allocator> -inline _LIBCPP_HIDE_FROM_ABI -bool -operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) -{ - return !(__x < __y); +inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { + return !(__x < __y); } template <class _Tp, class _Allocator> -inline _LIBCPP_HIDE_FROM_ABI -bool -operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) -{ - return !(__y < __x); +inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { + return !(__y < __x); } #else // _LIBCPP_STD_VER <= 17 @@ -2937,19 +2543,16 @@ operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) template <class _Tp, class _Allocator> _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { - return std::lexicographical_compare_three_way( - __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); + return std::lexicographical_compare_three_way( + __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); } #endif // _LIBCPP_STD_VER <= 17 template <class _Tp, class _Allocator> -inline _LIBCPP_HIDE_FROM_ABI -void -swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); +inline _LIBCPP_HIDE_FROM_ABI void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { + __x.swap(__y); } #if _LIBCPP_STD_VER >= 20 @@ -2957,7 +2560,7 @@ template <class _Tp, class _Allocator, class _Up> inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type erase(deque<_Tp, _Allocator>& __c, const _Up& __v) { auto __old_size = __c.size(); - __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); + __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end()); return __old_size - __c.size(); } @@ -2965,16 +2568,16 @@ template <class _Tp, class _Allocator, class _Predicate> inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) { auto __old_size = __c.size(); - __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); + __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end()); return __old_size - __c.size(); } template <> inline constexpr bool __format::__enable_insertable<std::deque<char>> = true; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> inline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true; -#endif +# endif #endif // _LIBCPP_STD_VER >= 20 |
