1*700637cbSDimitry Andric// -*- C++ -*- 2*700637cbSDimitry Andric//===----------------------------------------------------------------------===// 3*700637cbSDimitry Andric// 4*700637cbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*700637cbSDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*700637cbSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*700637cbSDimitry Andric// 8*700637cbSDimitry Andric//===----------------------------------------------------------------------===// 9*700637cbSDimitry Andric 10*700637cbSDimitry Andric#ifndef _LIBCPP___CXX03_DEQUE 11*700637cbSDimitry Andric#define _LIBCPP___CXX03_DEQUE 12*700637cbSDimitry Andric 13*700637cbSDimitry Andric/* 14*700637cbSDimitry Andric deque synopsis 15*700637cbSDimitry Andric 16*700637cbSDimitry Andricnamespace std 17*700637cbSDimitry Andric{ 18*700637cbSDimitry Andric 19*700637cbSDimitry Andrictemplate <class T, class Allocator = allocator<T> > 20*700637cbSDimitry Andricclass deque 21*700637cbSDimitry Andric{ 22*700637cbSDimitry Andricpublic: 23*700637cbSDimitry Andric // types: 24*700637cbSDimitry Andric typedef T value_type; 25*700637cbSDimitry Andric typedef Allocator allocator_type; 26*700637cbSDimitry Andric 27*700637cbSDimitry Andric typedef typename allocator_type::reference reference; 28*700637cbSDimitry Andric typedef typename allocator_type::const_reference const_reference; 29*700637cbSDimitry Andric typedef implementation-defined iterator; 30*700637cbSDimitry Andric typedef implementation-defined const_iterator; 31*700637cbSDimitry Andric typedef typename allocator_type::size_type size_type; 32*700637cbSDimitry Andric typedef typename allocator_type::difference_type difference_type; 33*700637cbSDimitry Andric 34*700637cbSDimitry Andric typedef typename allocator_type::pointer pointer; 35*700637cbSDimitry Andric typedef typename allocator_type::const_pointer const_pointer; 36*700637cbSDimitry Andric typedef std::reverse_iterator<iterator> reverse_iterator; 37*700637cbSDimitry Andric typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 38*700637cbSDimitry Andric 39*700637cbSDimitry Andric // construct/copy/destroy: 40*700637cbSDimitry Andric deque() noexcept(is_nothrow_default_constructible<allocator_type>::value); 41*700637cbSDimitry Andric explicit deque(const allocator_type& a); 42*700637cbSDimitry Andric explicit deque(size_type n); 43*700637cbSDimitry Andric explicit deque(size_type n, const allocator_type& a); // C++14 44*700637cbSDimitry Andric deque(size_type n, const value_type& v); 45*700637cbSDimitry Andric deque(size_type n, const value_type& v, const allocator_type& a); 46*700637cbSDimitry Andric template <class InputIterator> 47*700637cbSDimitry Andric deque(InputIterator f, InputIterator l); 48*700637cbSDimitry Andric template <class InputIterator> 49*700637cbSDimitry Andric deque(InputIterator f, InputIterator l, const allocator_type& a); 50*700637cbSDimitry Andric template<container-compatible-range<T> R> 51*700637cbSDimitry Andric deque(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 52*700637cbSDimitry Andric deque(const deque& c); 53*700637cbSDimitry Andric deque(deque&& c) 54*700637cbSDimitry Andric noexcept(is_nothrow_move_constructible<allocator_type>::value); 55*700637cbSDimitry Andric deque(initializer_list<value_type> il, const Allocator& a = allocator_type()); 56*700637cbSDimitry Andric deque(const deque& c, const allocator_type& a); 57*700637cbSDimitry Andric deque(deque&& c, const allocator_type& a); 58*700637cbSDimitry Andric ~deque(); 59*700637cbSDimitry Andric 60*700637cbSDimitry Andric deque& operator=(const deque& c); 61*700637cbSDimitry Andric deque& operator=(deque&& c) 62*700637cbSDimitry Andric noexcept( 63*700637cbSDimitry Andric allocator_type::propagate_on_container_move_assignment::value && 64*700637cbSDimitry Andric is_nothrow_move_assignable<allocator_type>::value); 65*700637cbSDimitry Andric deque& operator=(initializer_list<value_type> il); 66*700637cbSDimitry Andric 67*700637cbSDimitry Andric template <class InputIterator> 68*700637cbSDimitry Andric void assign(InputIterator f, InputIterator l); 69*700637cbSDimitry Andric template<container-compatible-range<T> R> 70*700637cbSDimitry Andric void assign_range(R&& rg); // C++23 71*700637cbSDimitry Andric void assign(size_type n, const value_type& v); 72*700637cbSDimitry Andric void assign(initializer_list<value_type> il); 73*700637cbSDimitry Andric 74*700637cbSDimitry Andric allocator_type get_allocator() const noexcept; 75*700637cbSDimitry Andric 76*700637cbSDimitry Andric // iterators: 77*700637cbSDimitry Andric 78*700637cbSDimitry Andric iterator begin() noexcept; 79*700637cbSDimitry Andric const_iterator begin() const noexcept; 80*700637cbSDimitry Andric iterator end() noexcept; 81*700637cbSDimitry Andric const_iterator end() const noexcept; 82*700637cbSDimitry Andric 83*700637cbSDimitry Andric reverse_iterator rbegin() noexcept; 84*700637cbSDimitry Andric const_reverse_iterator rbegin() const noexcept; 85*700637cbSDimitry Andric reverse_iterator rend() noexcept; 86*700637cbSDimitry Andric const_reverse_iterator rend() const noexcept; 87*700637cbSDimitry Andric 88*700637cbSDimitry Andric const_iterator cbegin() const noexcept; 89*700637cbSDimitry Andric const_iterator cend() const noexcept; 90*700637cbSDimitry Andric const_reverse_iterator crbegin() const noexcept; 91*700637cbSDimitry Andric const_reverse_iterator crend() const noexcept; 92*700637cbSDimitry Andric 93*700637cbSDimitry Andric // capacity: 94*700637cbSDimitry Andric size_type size() const noexcept; 95*700637cbSDimitry Andric size_type max_size() const noexcept; 96*700637cbSDimitry Andric void resize(size_type n); 97*700637cbSDimitry Andric void resize(size_type n, const value_type& v); 98*700637cbSDimitry Andric void shrink_to_fit(); 99*700637cbSDimitry Andric bool empty() const noexcept; 100*700637cbSDimitry Andric 101*700637cbSDimitry Andric // element access: 102*700637cbSDimitry Andric reference operator[](size_type i); 103*700637cbSDimitry Andric const_reference operator[](size_type i) const; 104*700637cbSDimitry Andric reference at(size_type i); 105*700637cbSDimitry Andric const_reference at(size_type i) const; 106*700637cbSDimitry Andric reference front(); 107*700637cbSDimitry Andric const_reference front() const; 108*700637cbSDimitry Andric reference back(); 109*700637cbSDimitry Andric const_reference back() const; 110*700637cbSDimitry Andric 111*700637cbSDimitry Andric // modifiers: 112*700637cbSDimitry Andric void push_front(const value_type& v); 113*700637cbSDimitry Andric void push_front(value_type&& v); 114*700637cbSDimitry Andric template<container-compatible-range<T> R> 115*700637cbSDimitry Andric void prepend_range(R&& rg); // C++23 116*700637cbSDimitry Andric void push_back(const value_type& v); 117*700637cbSDimitry Andric void push_back(value_type&& v); 118*700637cbSDimitry Andric template<container-compatible-range<T> R> 119*700637cbSDimitry Andric void append_range(R&& rg); // C++23 120*700637cbSDimitry Andric template <class... Args> reference emplace_front(Args&&... args); // reference in C++17 121*700637cbSDimitry Andric template <class... Args> reference emplace_back(Args&&... args); // reference in C++17 122*700637cbSDimitry Andric template <class... Args> iterator emplace(const_iterator p, Args&&... args); 123*700637cbSDimitry Andric iterator insert(const_iterator p, const value_type& v); 124*700637cbSDimitry Andric iterator insert(const_iterator p, value_type&& v); 125*700637cbSDimitry Andric iterator insert(const_iterator p, size_type n, const value_type& v); 126*700637cbSDimitry Andric template <class InputIterator> 127*700637cbSDimitry Andric iterator insert(const_iterator p, InputIterator f, InputIterator l); 128*700637cbSDimitry Andric template<container-compatible-range<T> R> 129*700637cbSDimitry Andric iterator insert_range(const_iterator position, R&& rg); // C++23 130*700637cbSDimitry Andric iterator insert(const_iterator p, initializer_list<value_type> il); 131*700637cbSDimitry Andric void pop_front(); 132*700637cbSDimitry Andric void pop_back(); 133*700637cbSDimitry Andric iterator erase(const_iterator p); 134*700637cbSDimitry Andric iterator erase(const_iterator f, const_iterator l); 135*700637cbSDimitry Andric void swap(deque& c) 136*700637cbSDimitry Andric noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17 137*700637cbSDimitry Andric void clear() noexcept; 138*700637cbSDimitry Andric}; 139*700637cbSDimitry Andric 140*700637cbSDimitry Andrictemplate <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> 141*700637cbSDimitry Andric deque(InputIterator, InputIterator, Allocator = Allocator()) 142*700637cbSDimitry Andric -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 143*700637cbSDimitry Andric 144*700637cbSDimitry Andrictemplate<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> 145*700637cbSDimitry Andric deque(from_range_t, R&&, Allocator = Allocator()) 146*700637cbSDimitry Andric -> deque<ranges::range_value_t<R>, Allocator>; // C++23 147*700637cbSDimitry Andric 148*700637cbSDimitry Andrictemplate <class T, class Allocator> 149*700637cbSDimitry Andric bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y); 150*700637cbSDimitry Andrictemplate <class T, class Allocator> 151*700637cbSDimitry Andric bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 152*700637cbSDimitry Andrictemplate <class T, class Allocator> 153*700637cbSDimitry Andric bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 154*700637cbSDimitry Andrictemplate <class T, class Allocator> 155*700637cbSDimitry Andric bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 156*700637cbSDimitry Andrictemplate <class T, class Allocator> 157*700637cbSDimitry Andric bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 158*700637cbSDimitry Andrictemplate <class T, class Allocator> 159*700637cbSDimitry Andric bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 160*700637cbSDimitry Andrictemplate<class T, class Allocator> 161*700637cbSDimitry Andric synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x, 162*700637cbSDimitry Andric const deque<T, Allocator>& y); // since C++20 163*700637cbSDimitry Andric 164*700637cbSDimitry Andric// specialized algorithms: 165*700637cbSDimitry Andrictemplate <class T, class Allocator> 166*700637cbSDimitry Andric void swap(deque<T,Allocator>& x, deque<T,Allocator>& y) 167*700637cbSDimitry Andric noexcept(noexcept(x.swap(y))); 168*700637cbSDimitry Andric 169*700637cbSDimitry Andrictemplate <class T, class Allocator, class U> 170*700637cbSDimitry Andric typename deque<T, Allocator>::size_type 171*700637cbSDimitry Andric erase(deque<T, Allocator>& c, const U& value); // C++20 172*700637cbSDimitry Andrictemplate <class T, class Allocator, class Predicate> 173*700637cbSDimitry Andric typename deque<T, Allocator>::size_type 174*700637cbSDimitry Andric erase_if(deque<T, Allocator>& c, Predicate pred); // C++20 175*700637cbSDimitry Andric 176*700637cbSDimitry Andric} // std 177*700637cbSDimitry Andric 178*700637cbSDimitry Andric*/ 179*700637cbSDimitry Andric 180*700637cbSDimitry Andric#include <__cxx03/__algorithm/copy.h> 181*700637cbSDimitry Andric#include <__cxx03/__algorithm/copy_backward.h> 182*700637cbSDimitry Andric#include <__cxx03/__algorithm/copy_n.h> 183*700637cbSDimitry Andric#include <__cxx03/__algorithm/equal.h> 184*700637cbSDimitry Andric#include <__cxx03/__algorithm/fill_n.h> 185*700637cbSDimitry Andric#include <__cxx03/__algorithm/lexicographical_compare.h> 186*700637cbSDimitry Andric#include <__cxx03/__algorithm/min.h> 187*700637cbSDimitry Andric#include <__cxx03/__algorithm/remove.h> 188*700637cbSDimitry Andric#include <__cxx03/__algorithm/remove_if.h> 189*700637cbSDimitry Andric#include <__cxx03/__algorithm/unwrap_iter.h> 190*700637cbSDimitry Andric#include <__cxx03/__assert> 191*700637cbSDimitry Andric#include <__cxx03/__config> 192*700637cbSDimitry Andric#include <__cxx03/__debug_utils/sanitizers.h> 193*700637cbSDimitry Andric#include <__cxx03/__fwd/deque.h> 194*700637cbSDimitry Andric#include <__cxx03/__iterator/distance.h> 195*700637cbSDimitry Andric#include <__cxx03/__iterator/iterator_traits.h> 196*700637cbSDimitry Andric#include <__cxx03/__iterator/next.h> 197*700637cbSDimitry Andric#include <__cxx03/__iterator/prev.h> 198*700637cbSDimitry Andric#include <__cxx03/__iterator/reverse_iterator.h> 199*700637cbSDimitry Andric#include <__cxx03/__iterator/segmented_iterator.h> 200*700637cbSDimitry Andric#include <__cxx03/__memory/addressof.h> 201*700637cbSDimitry Andric#include <__cxx03/__memory/allocator_destructor.h> 202*700637cbSDimitry Andric#include <__cxx03/__memory/pointer_traits.h> 203*700637cbSDimitry Andric#include <__cxx03/__memory/temp_value.h> 204*700637cbSDimitry Andric#include <__cxx03/__memory/unique_ptr.h> 205*700637cbSDimitry Andric#include <__cxx03/__split_buffer> 206*700637cbSDimitry Andric#include <__cxx03/__type_traits/is_allocator.h> 207*700637cbSDimitry Andric#include <__cxx03/__type_traits/is_convertible.h> 208*700637cbSDimitry Andric#include <__cxx03/__type_traits/is_same.h> 209*700637cbSDimitry Andric#include <__cxx03/__type_traits/is_swappable.h> 210*700637cbSDimitry Andric#include <__cxx03/__type_traits/type_identity.h> 211*700637cbSDimitry Andric#include <__cxx03/__utility/forward.h> 212*700637cbSDimitry Andric#include <__cxx03/__utility/move.h> 213*700637cbSDimitry Andric#include <__cxx03/__utility/pair.h> 214*700637cbSDimitry Andric#include <__cxx03/__utility/swap.h> 215*700637cbSDimitry Andric#include <__cxx03/limits> 216*700637cbSDimitry Andric#include <__cxx03/stdexcept> 217*700637cbSDimitry Andric#include <__cxx03/version> 218*700637cbSDimitry Andric 219*700637cbSDimitry Andric// standard-mandated includes 220*700637cbSDimitry Andric 221*700637cbSDimitry Andric// [iterator.range] 222*700637cbSDimitry Andric#include <__cxx03/__iterator/access.h> 223*700637cbSDimitry Andric 224*700637cbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 225*700637cbSDimitry Andric# pragma GCC system_header 226*700637cbSDimitry Andric#endif 227*700637cbSDimitry Andric 228*700637cbSDimitry Andric_LIBCPP_PUSH_MACROS 229*700637cbSDimitry Andric#include <__cxx03/__undef_macros> 230*700637cbSDimitry Andric 231*700637cbSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 232*700637cbSDimitry Andric 233*700637cbSDimitry Andrictemplate <class _ValueType, class _DiffType> 234*700637cbSDimitry Andricstruct __deque_block_size { 235*700637cbSDimitry Andric static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16; 236*700637cbSDimitry Andric}; 237*700637cbSDimitry Andric 238*700637cbSDimitry Andrictemplate <class _ValueType, 239*700637cbSDimitry Andric class _Pointer, 240*700637cbSDimitry Andric class _Reference, 241*700637cbSDimitry Andric class _MapPointer, 242*700637cbSDimitry Andric class _DiffType, 243*700637cbSDimitry Andric _DiffType _BS = 244*700637cbSDimitry Andric#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE 245*700637cbSDimitry Andric // Keep template parameter to avoid changing all template declarations thoughout 246*700637cbSDimitry Andric // this file. 247*700637cbSDimitry Andric 0 248*700637cbSDimitry Andric#else 249*700637cbSDimitry Andric __deque_block_size<_ValueType, _DiffType>::value 250*700637cbSDimitry Andric#endif 251*700637cbSDimitry Andric > 252*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __deque_iterator { 253*700637cbSDimitry Andric typedef _MapPointer __map_iterator; 254*700637cbSDimitry Andric 255*700637cbSDimitry Andricpublic: 256*700637cbSDimitry Andric typedef _Pointer pointer; 257*700637cbSDimitry Andric typedef _DiffType difference_type; 258*700637cbSDimitry Andric 259*700637cbSDimitry Andricprivate: 260*700637cbSDimitry Andric __map_iterator __m_iter_; 261*700637cbSDimitry Andric pointer __ptr_; 262*700637cbSDimitry Andric 263*700637cbSDimitry Andric static const difference_type __block_size; 264*700637cbSDimitry Andric 265*700637cbSDimitry Andricpublic: 266*700637cbSDimitry Andric typedef _ValueType value_type; 267*700637cbSDimitry Andric typedef random_access_iterator_tag iterator_category; 268*700637cbSDimitry Andric typedef _Reference reference; 269*700637cbSDimitry Andric 270*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT {} 271*700637cbSDimitry Andric 272*700637cbSDimitry Andric template <class _Pp, class _Rp, class _MP, __enable_if_t<is_convertible<_Pp, pointer>::value, int> = 0> 273*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI 274*700637cbSDimitry Andric __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it) _NOEXCEPT 275*700637cbSDimitry Andric : __m_iter_(__it.__m_iter_), 276*700637cbSDimitry Andric __ptr_(__it.__ptr_) {} 277*700637cbSDimitry Andric 278*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__ptr_; } 279*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return __ptr_; } 280*700637cbSDimitry Andric 281*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++() { 282*700637cbSDimitry Andric if (++__ptr_ - *__m_iter_ == __block_size) { 283*700637cbSDimitry Andric ++__m_iter_; 284*700637cbSDimitry Andric __ptr_ = *__m_iter_; 285*700637cbSDimitry Andric } 286*700637cbSDimitry Andric return *this; 287*700637cbSDimitry Andric } 288*700637cbSDimitry Andric 289*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int) { 290*700637cbSDimitry Andric __deque_iterator __tmp = *this; 291*700637cbSDimitry Andric ++(*this); 292*700637cbSDimitry Andric return __tmp; 293*700637cbSDimitry Andric } 294*700637cbSDimitry Andric 295*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--() { 296*700637cbSDimitry Andric if (__ptr_ == *__m_iter_) { 297*700637cbSDimitry Andric --__m_iter_; 298*700637cbSDimitry Andric __ptr_ = *__m_iter_ + __block_size; 299*700637cbSDimitry Andric } 300*700637cbSDimitry Andric --__ptr_; 301*700637cbSDimitry Andric return *this; 302*700637cbSDimitry Andric } 303*700637cbSDimitry Andric 304*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int) { 305*700637cbSDimitry Andric __deque_iterator __tmp = *this; 306*700637cbSDimitry Andric --(*this); 307*700637cbSDimitry Andric return __tmp; 308*700637cbSDimitry Andric } 309*700637cbSDimitry Andric 310*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n) { 311*700637cbSDimitry Andric if (__n != 0) { 312*700637cbSDimitry Andric __n += __ptr_ - *__m_iter_; 313*700637cbSDimitry Andric if (__n > 0) { 314*700637cbSDimitry Andric __m_iter_ += __n / __block_size; 315*700637cbSDimitry Andric __ptr_ = *__m_iter_ + __n % __block_size; 316*700637cbSDimitry Andric } else // (__n < 0) 317*700637cbSDimitry Andric { 318*700637cbSDimitry Andric difference_type __z = __block_size - 1 - __n; 319*700637cbSDimitry Andric __m_iter_ -= __z / __block_size; 320*700637cbSDimitry Andric __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size); 321*700637cbSDimitry Andric } 322*700637cbSDimitry Andric } 323*700637cbSDimitry Andric return *this; 324*700637cbSDimitry Andric } 325*700637cbSDimitry Andric 326*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n) { return *this += -__n; } 327*700637cbSDimitry Andric 328*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const { 329*700637cbSDimitry Andric __deque_iterator __t(*this); 330*700637cbSDimitry Andric __t += __n; 331*700637cbSDimitry Andric return __t; 332*700637cbSDimitry Andric } 333*700637cbSDimitry Andric 334*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const { 335*700637cbSDimitry Andric __deque_iterator __t(*this); 336*700637cbSDimitry Andric __t -= __n; 337*700637cbSDimitry Andric return __t; 338*700637cbSDimitry Andric } 339*700637cbSDimitry Andric 340*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) { 341*700637cbSDimitry Andric return __it + __n; 342*700637cbSDimitry Andric } 343*700637cbSDimitry Andric 344*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) { 345*700637cbSDimitry Andric if (__x != __y) 346*700637cbSDimitry Andric return (__x.__m_iter_ - __y.__m_iter_) * __block_size + (__x.__ptr_ - *__x.__m_iter_) - 347*700637cbSDimitry Andric (__y.__ptr_ - *__y.__m_iter_); 348*700637cbSDimitry Andric return 0; 349*700637cbSDimitry Andric } 350*700637cbSDimitry Andric 351*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const { return *(*this + __n); } 352*700637cbSDimitry Andric 353*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) { 354*700637cbSDimitry Andric return __x.__ptr_ == __y.__ptr_; 355*700637cbSDimitry Andric } 356*700637cbSDimitry Andric 357*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) { 358*700637cbSDimitry Andric return !(__x == __y); 359*700637cbSDimitry Andric } 360*700637cbSDimitry Andric 361*700637cbSDimitry Andric // TODO(mordante) disable these overloads in the LLVM 20 release. 362*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) { 363*700637cbSDimitry Andric return __x.__m_iter_ < __y.__m_iter_ || (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_); 364*700637cbSDimitry Andric } 365*700637cbSDimitry Andric 366*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) { 367*700637cbSDimitry Andric return __y < __x; 368*700637cbSDimitry Andric } 369*700637cbSDimitry Andric 370*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) { 371*700637cbSDimitry Andric return !(__y < __x); 372*700637cbSDimitry Andric } 373*700637cbSDimitry Andric 374*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) { 375*700637cbSDimitry Andric return !(__x < __y); 376*700637cbSDimitry Andric } 377*700637cbSDimitry Andric 378*700637cbSDimitry Andricprivate: 379*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT 380*700637cbSDimitry Andric : __m_iter_(__m), 381*700637cbSDimitry Andric __ptr_(__p) {} 382*700637cbSDimitry Andric 383*700637cbSDimitry Andric template <class _Tp, class _Ap> 384*700637cbSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS deque; 385*700637cbSDimitry Andric template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp> 386*700637cbSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __deque_iterator; 387*700637cbSDimitry Andric 388*700637cbSDimitry Andric template <class> 389*700637cbSDimitry Andric friend struct __segmented_iterator_traits; 390*700637cbSDimitry Andric}; 391*700637cbSDimitry Andric 392*700637cbSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 393*700637cbSDimitry Andricstruct __segmented_iterator_traits< 394*700637cbSDimitry Andric __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > { 395*700637cbSDimitry Andricprivate: 396*700637cbSDimitry Andric using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; 397*700637cbSDimitry Andric 398*700637cbSDimitry Andricpublic: 399*700637cbSDimitry Andric using __is_segmented_iterator = true_type; 400*700637cbSDimitry Andric using __segment_iterator = _MapPointer; 401*700637cbSDimitry Andric using __local_iterator = _Pointer; 402*700637cbSDimitry Andric 403*700637cbSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } 404*700637cbSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } 405*700637cbSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; } 406*700637cbSDimitry Andric 407*700637cbSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) { 408*700637cbSDimitry Andric return *__iter + _Iterator::__block_size; 409*700637cbSDimitry Andric } 410*700637cbSDimitry Andric 411*700637cbSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) { 412*700637cbSDimitry Andric if (__segment && __local == __end(__segment)) { 413*700637cbSDimitry Andric ++__segment; 414*700637cbSDimitry Andric return _Iterator(__segment, *__segment); 415*700637cbSDimitry Andric } 416*700637cbSDimitry Andric return _Iterator(__segment, __local); 417*700637cbSDimitry Andric } 418*700637cbSDimitry Andric}; 419*700637cbSDimitry Andric 420*700637cbSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 421*700637cbSDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>::__block_size = 422*700637cbSDimitry Andric __deque_block_size<_ValueType, _DiffType>::value; 423*700637cbSDimitry Andric 424*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/> 425*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque { 426*700637cbSDimitry Andricpublic: 427*700637cbSDimitry Andric // types: 428*700637cbSDimitry Andric 429*700637cbSDimitry Andric using value_type = _Tp; 430*700637cbSDimitry Andric 431*700637cbSDimitry Andric using allocator_type = _Allocator; 432*700637cbSDimitry Andric using __alloc_traits = allocator_traits<allocator_type>; 433*700637cbSDimitry Andric static_assert(__check_valid_allocator<allocator_type>::value, ""); 434*700637cbSDimitry Andric static_assert(is_same<typename allocator_type::value_type, value_type>::value, 435*700637cbSDimitry Andric "Allocator::value_type must be same type as value_type"); 436*700637cbSDimitry Andric 437*700637cbSDimitry Andric using size_type = typename __alloc_traits::size_type; 438*700637cbSDimitry Andric using difference_type = typename __alloc_traits::difference_type; 439*700637cbSDimitry Andric 440*700637cbSDimitry Andric using pointer = typename __alloc_traits::pointer; 441*700637cbSDimitry Andric using const_pointer = typename __alloc_traits::const_pointer; 442*700637cbSDimitry Andric 443*700637cbSDimitry Andric using __pointer_allocator = __rebind_alloc<__alloc_traits, pointer>; 444*700637cbSDimitry Andric using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>; 445*700637cbSDimitry Andric using __map = __split_buffer<pointer, __pointer_allocator>; 446*700637cbSDimitry Andric using __map_alloc_traits = allocator_traits<__pointer_allocator>; 447*700637cbSDimitry Andric using __map_pointer = typename __map_alloc_traits::pointer; 448*700637cbSDimitry Andric using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer; 449*700637cbSDimitry Andric using __map_const_iterator = typename __map::const_iterator; 450*700637cbSDimitry Andric 451*700637cbSDimitry Andric using reference = value_type&; 452*700637cbSDimitry Andric using const_reference = const value_type&; 453*700637cbSDimitry Andric 454*700637cbSDimitry Andric using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>; 455*700637cbSDimitry Andric using const_iterator = 456*700637cbSDimitry Andric __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>; 457*700637cbSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 458*700637cbSDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>; 459*700637cbSDimitry Andric 460*700637cbSDimitry Andric // A deque contains the following members which may be trivially relocatable: 461*700637cbSDimitry Andric // - __map: is a `__split_buffer`, see `__split_buffer` for more information on when it is trivially relocatable 462*700637cbSDimitry Andric // - size_type: is always trivially relocatable, since it is required to be an integral type 463*700637cbSDimitry Andric // - allocator_type: may not be trivially relocatable, so it's checked 464*700637cbSDimitry Andric // None of these are referencing the `deque` itself, so if all of them are trivially relocatable, `deque` is too. 465*700637cbSDimitry Andric using __trivially_relocatable = __conditional_t< 466*700637cbSDimitry Andric __libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, 467*700637cbSDimitry Andric deque, 468*700637cbSDimitry Andric void>; 469*700637cbSDimitry Andric 470*700637cbSDimitry Andric static_assert(is_nothrow_default_constructible<allocator_type>::value == 471*700637cbSDimitry Andric is_nothrow_default_constructible<__pointer_allocator>::value, 472*700637cbSDimitry Andric "rebinding an allocator should not change exception guarantees"); 473*700637cbSDimitry Andric static_assert(is_nothrow_move_constructible<allocator_type>::value == 474*700637cbSDimitry Andric is_nothrow_move_constructible<typename __map::allocator_type>::value, 475*700637cbSDimitry Andric "rebinding an allocator should not change exception guarantees"); 476*700637cbSDimitry Andric 477*700637cbSDimitry Andricprivate: 478*700637cbSDimitry Andric struct __deque_block_range { 479*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI __deque_block_range(pointer __b, pointer __e) _NOEXCEPT 480*700637cbSDimitry Andric : __begin_(__b), 481*700637cbSDimitry Andric __end_(__e) {} 482*700637cbSDimitry Andric const pointer __begin_; 483*700637cbSDimitry Andric const pointer __end_; 484*700637cbSDimitry Andric }; 485*700637cbSDimitry Andric 486*700637cbSDimitry Andric struct __deque_range { 487*700637cbSDimitry Andric iterator __pos_; 488*700637cbSDimitry Andric const iterator __end_; 489*700637cbSDimitry Andric 490*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT : __pos_(__pos), __end_(__e) {} 491*700637cbSDimitry Andric 492*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { return __pos_ != __end_; } 493*700637cbSDimitry Andric 494*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { return *this; } 495*700637cbSDimitry Andric 496*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range end() const { return __deque_range(__end_, __end_); } 497*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT { 498*700637cbSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 499*700637cbSDimitry Andric return __deque_block_range(__pos_.__ptr_, __end_.__ptr_); 500*700637cbSDimitry Andric } 501*700637cbSDimitry Andric return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size); 502*700637cbSDimitry Andric } 503*700637cbSDimitry Andric 504*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT { 505*700637cbSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 506*700637cbSDimitry Andric __pos_ = __end_; 507*700637cbSDimitry Andric } else { 508*700637cbSDimitry Andric ++__pos_.__m_iter_; 509*700637cbSDimitry Andric __pos_.__ptr_ = *__pos_.__m_iter_; 510*700637cbSDimitry Andric } 511*700637cbSDimitry Andric return *this; 512*700637cbSDimitry Andric } 513*700637cbSDimitry Andric 514*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) { 515*700637cbSDimitry Andric return __lhs.__pos_ == __rhs.__pos_; 516*700637cbSDimitry Andric } 517*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) { 518*700637cbSDimitry Andric return !(__lhs == __rhs); 519*700637cbSDimitry Andric } 520*700637cbSDimitry Andric }; 521*700637cbSDimitry Andric 522*700637cbSDimitry Andric struct _ConstructTransaction { 523*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r) 524*700637cbSDimitry Andric : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} 525*700637cbSDimitry Andric 526*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { __base_->__size() += (__pos_ - __begin_); } 527*700637cbSDimitry Andric 528*700637cbSDimitry Andric pointer __pos_; 529*700637cbSDimitry Andric const pointer __end_; 530*700637cbSDimitry Andric 531*700637cbSDimitry Andric private: 532*700637cbSDimitry Andric const pointer __begin_; 533*700637cbSDimitry Andric deque* const __base_; 534*700637cbSDimitry Andric }; 535*700637cbSDimitry Andric 536*700637cbSDimitry Andric static const difference_type __block_size; 537*700637cbSDimitry Andric 538*700637cbSDimitry Andric __map __map_; 539*700637cbSDimitry Andric size_type __start_; 540*700637cbSDimitry Andric __compressed_pair<size_type, allocator_type> __size_; 541*700637cbSDimitry Andric 542*700637cbSDimitry Andricpublic: 543*700637cbSDimitry Andric // construct/copy/destroy: 544*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque() : __start_(0), __size_(0, __default_init_tag()) { __annotate_new(0); } 545*700637cbSDimitry Andric 546*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~deque() { 547*700637cbSDimitry Andric clear(); 548*700637cbSDimitry Andric __annotate_delete(); 549*700637cbSDimitry Andric typename __map::iterator __i = __map_.begin(); 550*700637cbSDimitry Andric typename __map::iterator __e = __map_.end(); 551*700637cbSDimitry Andric for (; __i != __e; ++__i) 552*700637cbSDimitry Andric __alloc_traits::deallocate(__alloc(), *__i, __block_size); 553*700637cbSDimitry Andric } 554*700637cbSDimitry Andric 555*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) 556*700637cbSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 557*700637cbSDimitry Andric __annotate_new(0); 558*700637cbSDimitry Andric } 559*700637cbSDimitry Andric 560*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); 561*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); 562*700637cbSDimitry Andric 563*700637cbSDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 564*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) 565*700637cbSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 566*700637cbSDimitry Andric __annotate_new(0); 567*700637cbSDimitry Andric if (__n > 0) 568*700637cbSDimitry Andric __append(__n, __v); 569*700637cbSDimitry Andric } 570*700637cbSDimitry Andric 571*700637cbSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 572*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l); 573*700637cbSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 574*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a); 575*700637cbSDimitry Andric 576*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); 577*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); 578*700637cbSDimitry Andric 579*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c); 580*700637cbSDimitry Andric 581*700637cbSDimitry Andric template <class _InputIter, 582*700637cbSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIter>::value && 583*700637cbSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, 584*700637cbSDimitry Andric int> = 0> 585*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l); 586*700637cbSDimitry Andric template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> = 0> 587*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l); 588*700637cbSDimitry Andric 589*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); 590*700637cbSDimitry Andric 591*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; 592*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); } 593*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); } 594*700637cbSDimitry Andric 595*700637cbSDimitry Andric // iterators: 596*700637cbSDimitry Andric 597*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { 598*700637cbSDimitry Andric __map_pointer __mp = __map_.begin() + __start_ / __block_size; 599*700637cbSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 600*700637cbSDimitry Andric } 601*700637cbSDimitry Andric 602*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { 603*700637cbSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); 604*700637cbSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 605*700637cbSDimitry Andric } 606*700637cbSDimitry Andric 607*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { 608*700637cbSDimitry Andric size_type __p = size() + __start_; 609*700637cbSDimitry Andric __map_pointer __mp = __map_.begin() + __p / __block_size; 610*700637cbSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 611*700637cbSDimitry Andric } 612*700637cbSDimitry Andric 613*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { 614*700637cbSDimitry Andric size_type __p = size() + __start_; 615*700637cbSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); 616*700637cbSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 617*700637cbSDimitry Andric } 618*700637cbSDimitry Andric 619*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } 620*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 621*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } 622*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 623*700637cbSDimitry Andric 624*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } 625*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } 626*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 627*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 628*700637cbSDimitry Andric 629*700637cbSDimitry Andric // capacity: 630*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); } 631*700637cbSDimitry Andric 632*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); } 633*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); } 634*700637cbSDimitry Andric 635*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { 636*700637cbSDimitry Andric return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max()); 637*700637cbSDimitry Andric } 638*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); 639*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); 640*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; 641*700637cbSDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; } 642*700637cbSDimitry Andric 643*700637cbSDimitry Andric // element access: 644*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT; 645*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT; 646*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference at(size_type __i); 647*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const; 648*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT; 649*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT; 650*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT; 651*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT; 652*700637cbSDimitry Andric 653*700637cbSDimitry Andric // 23.2.2.3 modifiers: 654*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); 655*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); 656*700637cbSDimitry Andric 657*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v); 658*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); 659*700637cbSDimitry Andric template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0> 660*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l); 661*700637cbSDimitry Andric template <class _ForwardIterator, 662*700637cbSDimitry Andric __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> = 0> 663*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l); 664*700637cbSDimitry Andric template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> = 0> 665*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l); 666*700637cbSDimitry Andric 667*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_front(); 668*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_back(); 669*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); 670*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); 671*700637cbSDimitry Andric 672*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(deque& __c); 673*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; 674*700637cbSDimitry Andric 675*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __invariants() const { 676*700637cbSDimitry Andric if (!__map_.__invariants()) 677*700637cbSDimitry Andric return false; 678*700637cbSDimitry Andric if (__map_.size() >= size_type(-1) / __block_size) 679*700637cbSDimitry Andric return false; 680*700637cbSDimitry Andric for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); __i != __e; ++__i) 681*700637cbSDimitry Andric if (*__i == nullptr) 682*700637cbSDimitry Andric return false; 683*700637cbSDimitry Andric if (__map_.size() != 0) { 684*700637cbSDimitry Andric if (size() >= __map_.size() * __block_size) 685*700637cbSDimitry Andric return false; 686*700637cbSDimitry Andric if (__start_ >= __map_.size() * __block_size - size()) 687*700637cbSDimitry Andric return false; 688*700637cbSDimitry Andric } else { 689*700637cbSDimitry Andric if (size() != 0) 690*700637cbSDimitry Andric return false; 691*700637cbSDimitry Andric if (__start_ != 0) 692*700637cbSDimitry Andric return false; 693*700637cbSDimitry Andric } 694*700637cbSDimitry Andric return true; 695*700637cbSDimitry Andric } 696*700637cbSDimitry Andric 697*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c) { 698*700637cbSDimitry Andric __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 699*700637cbSDimitry Andric } 700*700637cbSDimitry Andric 701*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c, true_type) { __alloc() = std::move(__c.__alloc()); } 702*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque&, false_type) _NOEXCEPT {} 703*700637cbSDimitry Andric 704*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c) { 705*700637cbSDimitry Andric __map_ = std::move(__c.__map_); 706*700637cbSDimitry Andric __start_ = __c.__start_; 707*700637cbSDimitry Andric __size() = __c.size(); 708*700637cbSDimitry Andric __move_assign_alloc(__c); 709*700637cbSDimitry Andric __c.__start_ = __c.__size() = 0; 710*700637cbSDimitry Andric } 711*700637cbSDimitry Andric 712*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static size_type __recommend_blocks(size_type __n) { 713*700637cbSDimitry Andric return __n / __block_size + (__n % __block_size != 0); 714*700637cbSDimitry Andric } 715*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __capacity() const { 716*700637cbSDimitry Andric return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1; 717*700637cbSDimitry Andric } 718*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __block_count() const { return __map_.size(); } 719*700637cbSDimitry Andric 720*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const { return __start_; } 721*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __front_spare_blocks() const { return __front_spare() / __block_size; } 722*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const { return __capacity() - (__start_ + size()); } 723*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __back_spare_blocks() const { return __back_spare() / __block_size; } 724*700637cbSDimitry Andric 725*700637cbSDimitry Andricprivate: 726*700637cbSDimitry Andric enum __asan_annotation_type { __asan_unposion, __asan_poison }; 727*700637cbSDimitry Andric 728*700637cbSDimitry Andric enum __asan_annotation_place { 729*700637cbSDimitry Andric __asan_front_moved, 730*700637cbSDimitry Andric __asan_back_moved, 731*700637cbSDimitry Andric }; 732*700637cbSDimitry Andric 733*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_from_to( 734*700637cbSDimitry Andric size_type __beg, 735*700637cbSDimitry Andric size_type __end, 736*700637cbSDimitry Andric __asan_annotation_type __annotation_type, 737*700637cbSDimitry Andric __asan_annotation_place __place) const _NOEXCEPT { 738*700637cbSDimitry Andric (void)__beg; 739*700637cbSDimitry Andric (void)__end; 740*700637cbSDimitry Andric (void)__annotation_type; 741*700637cbSDimitry Andric (void)__place; 742*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 743*700637cbSDimitry Andric // __beg - index of the first item to annotate 744*700637cbSDimitry Andric // __end - index behind the last item to annotate (so last item + 1) 745*700637cbSDimitry Andric // __annotation_type - __asan_unposion or __asan_poison 746*700637cbSDimitry Andric // __place - __asan_front_moved or __asan_back_moved 747*700637cbSDimitry Andric // Note: All indexes in __map_ 748*700637cbSDimitry Andric if (__beg == __end) 749*700637cbSDimitry Andric return; 750*700637cbSDimitry Andric // __annotations_beg_map - first chunk which annotations we want to modify 751*700637cbSDimitry Andric // __annotations_end_map - last chunk which annotations we want to modify 752*700637cbSDimitry Andric // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist 753*700637cbSDimitry Andric __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; 754*700637cbSDimitry Andric __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; 755*700637cbSDimitry Andric 756*700637cbSDimitry Andric bool const __poisoning = __annotation_type == __asan_poison; 757*700637cbSDimitry Andric // __old_c_beg_index - index of the first element in old container 758*700637cbSDimitry Andric // __old_c_end_index - index of the end of old container (last + 1) 759*700637cbSDimitry Andric // Note: may be outside the area we are annotating 760*700637cbSDimitry Andric size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; 761*700637cbSDimitry Andric size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); 762*700637cbSDimitry Andric bool const __front = __place == __asan_front_moved; 763*700637cbSDimitry Andric 764*700637cbSDimitry Andric if (__poisoning && empty()) { 765*700637cbSDimitry Andric // Special case: we shouldn't trust __start_ 766*700637cbSDimitry Andric __old_c_beg_index = __beg; 767*700637cbSDimitry Andric __old_c_end_index = __end; 768*700637cbSDimitry Andric } 769*700637cbSDimitry Andric // __old_c_beg_map - memory block (chunk) with first element 770*700637cbSDimitry Andric // __old_c_end_map - memory block (chunk) with end of old container 771*700637cbSDimitry Andric // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, 772*700637cbSDimitry Andric // which may not exist 773*700637cbSDimitry Andric __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; 774*700637cbSDimitry Andric __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; 775*700637cbSDimitry Andric 776*700637cbSDimitry Andric // One edge (front/end) of the container was moved and one was not modified. 777*700637cbSDimitry Andric // __new_edge_index - index of new edge 778*700637cbSDimitry Andric // __new_edge_map - memory block (chunk) with new edge, it always equals to 779*700637cbSDimitry Andric // __annotations_beg_map or __annotations_end_map 780*700637cbSDimitry Andric // __old_edge_map - memory block (chunk) with old edge, it always equals to 781*700637cbSDimitry Andric // __old_c_beg_map or __old_c_end_map 782*700637cbSDimitry Andric size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; 783*700637cbSDimitry Andric __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; 784*700637cbSDimitry Andric __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; 785*700637cbSDimitry Andric 786*700637cbSDimitry Andric // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. 787*700637cbSDimitry Andric // First and last chunk may be partially poisoned. 788*700637cbSDimitry Andric // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. 789*700637cbSDimitry Andric for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { 790*700637cbSDimitry Andric if (__map_it == __annotations_end_map && __end % __block_size == 0) 791*700637cbSDimitry Andric // Chunk may not exist, but nothing to do here anyway 792*700637cbSDimitry Andric break; 793*700637cbSDimitry Andric 794*700637cbSDimitry Andric // The beginning and the end of the current memory block 795*700637cbSDimitry Andric const void* __mem_beg = std::__to_address(*__map_it); 796*700637cbSDimitry Andric const void* __mem_end = std::__to_address(*__map_it + __block_size); 797*700637cbSDimitry Andric 798*700637cbSDimitry Andric // The beginning of memory-in-use in the memory block before container modification 799*700637cbSDimitry Andric const void* __old_beg = 800*700637cbSDimitry Andric (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; 801*700637cbSDimitry Andric 802*700637cbSDimitry Andric // The end of memory-in-use in the memory block before container modification 803*700637cbSDimitry Andric const void* __old_end; 804*700637cbSDimitry Andric if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) 805*700637cbSDimitry Andric __old_end = __old_beg; 806*700637cbSDimitry Andric else 807*700637cbSDimitry Andric __old_end = (__map_it == __old_c_end_map) 808*700637cbSDimitry Andric ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) 809*700637cbSDimitry Andric : __mem_end; 810*700637cbSDimitry Andric 811*700637cbSDimitry Andric // New edge of the container in current memory block 812*700637cbSDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 813*700637cbSDimitry Andric const void* __new_edge; 814*700637cbSDimitry Andric if (__map_it == __new_edge_map) 815*700637cbSDimitry Andric __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); 816*700637cbSDimitry Andric else 817*700637cbSDimitry Andric __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; 818*700637cbSDimitry Andric 819*700637cbSDimitry Andric // Not modified edge of the container 820*700637cbSDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 821*700637cbSDimitry Andric const void* __old_edge; 822*700637cbSDimitry Andric if (__map_it == __old_edge_map) 823*700637cbSDimitry Andric __old_edge = __front ? __old_end : __old_beg; 824*700637cbSDimitry Andric else 825*700637cbSDimitry Andric __old_edge = __front ? __mem_end : __mem_beg; 826*700637cbSDimitry Andric 827*700637cbSDimitry Andric // __new_beg - the beginning of memory-in-use in the memory block after container modification 828*700637cbSDimitry Andric // __new_end - the end of memory-in-use in the memory block after container modification 829*700637cbSDimitry Andric const void* __new_beg = __front ? __new_edge : __old_edge; 830*700637cbSDimitry Andric const void* __new_end = __front ? __old_edge : __new_edge; 831*700637cbSDimitry Andric 832*700637cbSDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>( 833*700637cbSDimitry Andric __mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); 834*700637cbSDimitry Andric } 835*700637cbSDimitry Andric#endif // !_LIBCPP_HAS_NO_ASAN 836*700637cbSDimitry Andric } 837*700637cbSDimitry Andric 838*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT { 839*700637cbSDimitry Andric (void)__current_size; 840*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 841*700637cbSDimitry Andric if (__current_size == 0) 842*700637cbSDimitry Andric __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 843*700637cbSDimitry Andric else { 844*700637cbSDimitry Andric __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); 845*700637cbSDimitry Andric __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 846*700637cbSDimitry Andric } 847*700637cbSDimitry Andric#endif 848*700637cbSDimitry Andric } 849*700637cbSDimitry Andric 850*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT { 851*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 852*700637cbSDimitry Andric if (empty()) { 853*700637cbSDimitry Andric for (size_t __i = 0; __i < __map_.size(); ++__i) { 854*700637cbSDimitry Andric __annotate_whole_block(__i, __asan_unposion); 855*700637cbSDimitry Andric } 856*700637cbSDimitry Andric } else { 857*700637cbSDimitry Andric __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); 858*700637cbSDimitry Andric __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); 859*700637cbSDimitry Andric } 860*700637cbSDimitry Andric#endif 861*700637cbSDimitry Andric } 862*700637cbSDimitry Andric 863*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_increase_front(size_type __n) const _NOEXCEPT { 864*700637cbSDimitry Andric (void)__n; 865*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 866*700637cbSDimitry Andric __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); 867*700637cbSDimitry Andric#endif 868*700637cbSDimitry Andric } 869*700637cbSDimitry Andric 870*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_increase_back(size_type __n) const _NOEXCEPT { 871*700637cbSDimitry Andric (void)__n; 872*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 873*700637cbSDimitry Andric __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); 874*700637cbSDimitry Andric#endif 875*700637cbSDimitry Andric } 876*700637cbSDimitry Andric 877*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { 878*700637cbSDimitry Andric (void)__old_size; 879*700637cbSDimitry Andric (void)__old_start; 880*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 881*700637cbSDimitry Andric __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); 882*700637cbSDimitry Andric#endif 883*700637cbSDimitry Andric } 884*700637cbSDimitry Andric 885*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { 886*700637cbSDimitry Andric (void)__old_size; 887*700637cbSDimitry Andric (void)__old_start; 888*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 889*700637cbSDimitry Andric __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); 890*700637cbSDimitry Andric#endif 891*700637cbSDimitry Andric } 892*700637cbSDimitry Andric 893*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_poison_block(const void* __beginning, const void* __end) const _NOEXCEPT { 894*700637cbSDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>(__beginning, __end, __beginning, __end, __end, __end); 895*700637cbSDimitry Andric } 896*700637cbSDimitry Andric 897*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 898*700637cbSDimitry Andric __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { 899*700637cbSDimitry Andric (void)__block_index; 900*700637cbSDimitry Andric (void)__annotation_type; 901*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 902*700637cbSDimitry Andric __map_const_iterator __block_it = __map_.begin() + __block_index; 903*700637cbSDimitry Andric const void* __block_start = std::__to_address(*__block_it); 904*700637cbSDimitry Andric const void* __block_end = std::__to_address(*__block_it + __block_size); 905*700637cbSDimitry Andric 906*700637cbSDimitry Andric if (__annotation_type == __asan_poison) 907*700637cbSDimitry Andric __annotate_poison_block(__block_start, __block_end); 908*700637cbSDimitry Andric else { 909*700637cbSDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>( 910*700637cbSDimitry Andric __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); 911*700637cbSDimitry Andric } 912*700637cbSDimitry Andric#endif 913*700637cbSDimitry Andric } 914*700637cbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) 915*700637cbSDimitry Andric 916*700637cbSDimitry Andricpublic: 917*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __verify_asan_annotations() const _NOEXCEPT { 918*700637cbSDimitry Andric // This function tests deque object annotations. 919*700637cbSDimitry Andric if (empty()) { 920*700637cbSDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 921*700637cbSDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 922*700637cbSDimitry Andric std::__to_address(*__it), 923*700637cbSDimitry Andric std::__to_address(*__it), 924*700637cbSDimitry Andric std::__to_address(*__it), 925*700637cbSDimitry Andric std::__to_address(*__it + __block_size))) 926*700637cbSDimitry Andric return false; 927*700637cbSDimitry Andric } 928*700637cbSDimitry Andric 929*700637cbSDimitry Andric return true; 930*700637cbSDimitry Andric } 931*700637cbSDimitry Andric 932*700637cbSDimitry Andric size_type __end = __start_ + size(); 933*700637cbSDimitry Andric __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; 934*700637cbSDimitry Andric __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; 935*700637cbSDimitry Andric 936*700637cbSDimitry Andric // Pointers to first and after last elements 937*700637cbSDimitry Andric // Those can be in different deque blocks 938*700637cbSDimitry Andric const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); 939*700637cbSDimitry Andric const void* __p_end = 940*700637cbSDimitry Andric std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); 941*700637cbSDimitry Andric 942*700637cbSDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 943*700637cbSDimitry Andric // Go over all blocks, find the place we are in and verify its annotations 944*700637cbSDimitry Andric // Note that __p_end points *behind* the last item. 945*700637cbSDimitry Andric 946*700637cbSDimitry Andric // - blocks before the first block with container elements 947*700637cbSDimitry Andric // - first block with items 948*700637cbSDimitry Andric // - last block with items 949*700637cbSDimitry Andric // - blocks after last block with ciontainer elements 950*700637cbSDimitry Andric 951*700637cbSDimitry Andric // Is the block before or after deque blocks that contain elements? 952*700637cbSDimitry Andric if (__it < __first_mp || __it > __last_mp) { 953*700637cbSDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 954*700637cbSDimitry Andric std::__to_address(*__it), 955*700637cbSDimitry Andric std::__to_address(*__it), 956*700637cbSDimitry Andric std::__to_address(*__it), 957*700637cbSDimitry Andric std::__to_address(*__it + __block_size))) 958*700637cbSDimitry Andric return false; 959*700637cbSDimitry Andric } else { 960*700637cbSDimitry Andric const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); 961*700637cbSDimitry Andric const void* __containers_buffer_end = 962*700637cbSDimitry Andric (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); 963*700637cbSDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 964*700637cbSDimitry Andric std::__to_address(*__it), 965*700637cbSDimitry Andric __containers_buffer_beg, 966*700637cbSDimitry Andric __containers_buffer_end, 967*700637cbSDimitry Andric std::__to_address(*__it + __block_size))) { 968*700637cbSDimitry Andric return false; 969*700637cbSDimitry Andric } 970*700637cbSDimitry Andric } 971*700637cbSDimitry Andric } 972*700637cbSDimitry Andric return true; 973*700637cbSDimitry Andric } 974*700637cbSDimitry Andric 975*700637cbSDimitry Andricprivate: 976*700637cbSDimitry Andric#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS 977*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_front_spare(bool __keep_one = true) { 978*700637cbSDimitry Andric if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { 979*700637cbSDimitry Andric __annotate_whole_block(0, __asan_unposion); 980*700637cbSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.front(), __block_size); 981*700637cbSDimitry Andric __map_.pop_front(); 982*700637cbSDimitry Andric __start_ -= __block_size; 983*700637cbSDimitry Andric return true; 984*700637cbSDimitry Andric } 985*700637cbSDimitry Andric return false; 986*700637cbSDimitry Andric } 987*700637cbSDimitry Andric 988*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_back_spare(bool __keep_one = true) { 989*700637cbSDimitry Andric if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { 990*700637cbSDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_unposion); 991*700637cbSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.back(), __block_size); 992*700637cbSDimitry Andric __map_.pop_back(); 993*700637cbSDimitry Andric return true; 994*700637cbSDimitry Andric } 995*700637cbSDimitry Andric return false; 996*700637cbSDimitry Andric } 997*700637cbSDimitry Andric 998*700637cbSDimitry Andric template <class _Iterator, class _Sentinel> 999*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __f, _Sentinel __l); 1000*700637cbSDimitry Andric 1001*700637cbSDimitry Andric template <class _RandomAccessIterator> 1002*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); 1003*700637cbSDimitry Andric template <class _Iterator> 1004*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_size(_Iterator __f, difference_type __n); 1005*700637cbSDimitry Andric 1006*700637cbSDimitry Andric template <class _Iterator, class _Sentinel> 1007*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); 1008*700637cbSDimitry Andric 1009*700637cbSDimitry Andric template <class _Iterator> 1010*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); 1011*700637cbSDimitry Andric 1012*700637cbSDimitry Andric template <class _BiIter, class _Sentinel> 1013*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 1014*700637cbSDimitry Andric __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); 1015*700637cbSDimitry Andric template <class _BiIter> 1016*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); 1017*700637cbSDimitry Andric 1018*700637cbSDimitry Andric template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> = 0> 1019*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l); 1020*700637cbSDimitry Andric template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> = 0> 1021*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l); 1022*700637cbSDimitry Andric 1023*700637cbSDimitry Andric template <class _InputIterator> 1024*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); 1025*700637cbSDimitry Andric template <class _InputIterator, class _Sentinel> 1026*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); 1027*700637cbSDimitry Andric 1028*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); 1029*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); 1030*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); 1031*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(); 1032*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n); 1033*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(); 1034*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n); 1035*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1036*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 1037*700637cbSDimitry Andric __move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1038*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1039*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 1040*700637cbSDimitry Andric __move_construct_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1041*700637cbSDimitry Andric 1042*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c) { 1043*700637cbSDimitry Andric __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); 1044*700637cbSDimitry Andric } 1045*700637cbSDimitry Andric 1046*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c, true_type) { 1047*700637cbSDimitry Andric if (__alloc() != __c.__alloc()) { 1048*700637cbSDimitry Andric clear(); 1049*700637cbSDimitry Andric shrink_to_fit(); 1050*700637cbSDimitry Andric } 1051*700637cbSDimitry Andric __alloc() = __c.__alloc(); 1052*700637cbSDimitry Andric __map_.__alloc() = __c.__map_.__alloc(); 1053*700637cbSDimitry Andric } 1054*700637cbSDimitry Andric 1055*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {} 1056*700637cbSDimitry Andric 1057*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type); 1058*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type); 1059*700637cbSDimitry Andric}; 1060*700637cbSDimitry Andric 1061*700637cbSDimitry Andrictemplate <class _Tp, class _Alloc> 1062*700637cbSDimitry Andricconst typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size = 1063*700637cbSDimitry Andric __deque_block_size<value_type, difference_type>::value; 1064*700637cbSDimitry Andric 1065*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1066*700637cbSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n) : __start_(0), __size_(0, __default_init_tag()) { 1067*700637cbSDimitry Andric __annotate_new(0); 1068*700637cbSDimitry Andric if (__n > 0) 1069*700637cbSDimitry Andric __append(__n); 1070*700637cbSDimitry Andric} 1071*700637cbSDimitry Andric 1072*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1073*700637cbSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) : __start_(0), __size_(0, __default_init_tag()) { 1074*700637cbSDimitry Andric __annotate_new(0); 1075*700637cbSDimitry Andric if (__n > 0) 1076*700637cbSDimitry Andric __append(__n, __v); 1077*700637cbSDimitry Andric} 1078*700637cbSDimitry Andric 1079*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1080*700637cbSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 1081*700637cbSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l) : __start_(0), __size_(0, __default_init_tag()) { 1082*700637cbSDimitry Andric __annotate_new(0); 1083*700637cbSDimitry Andric __append(__f, __l); 1084*700637cbSDimitry Andric} 1085*700637cbSDimitry Andric 1086*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1087*700637cbSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 1088*700637cbSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a) 1089*700637cbSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 1090*700637cbSDimitry Andric __annotate_new(0); 1091*700637cbSDimitry Andric __append(__f, __l); 1092*700637cbSDimitry Andric} 1093*700637cbSDimitry Andric 1094*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1095*700637cbSDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c) 1096*700637cbSDimitry Andric : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))), 1097*700637cbSDimitry Andric __start_(0), 1098*700637cbSDimitry Andric __size_(0, __map_.__alloc()) { 1099*700637cbSDimitry Andric __annotate_new(0); 1100*700637cbSDimitry Andric __append(__c.begin(), __c.end()); 1101*700637cbSDimitry Andric} 1102*700637cbSDimitry Andric 1103*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1104*700637cbSDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a) 1105*700637cbSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 1106*700637cbSDimitry Andric __annotate_new(0); 1107*700637cbSDimitry Andric __append(__c.begin(), __c.end()); 1108*700637cbSDimitry Andric} 1109*700637cbSDimitry Andric 1110*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1111*700637cbSDimitry Andricdeque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(const deque& __c) { 1112*700637cbSDimitry Andric if (this != std::addressof(__c)) { 1113*700637cbSDimitry Andric __copy_assign_alloc(__c); 1114*700637cbSDimitry Andric assign(__c.begin(), __c.end()); 1115*700637cbSDimitry Andric } 1116*700637cbSDimitry Andric return *this; 1117*700637cbSDimitry Andric} 1118*700637cbSDimitry Andric 1119*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1120*700637cbSDimitry Andrictemplate <class _InputIter, 1121*700637cbSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIter>::value && 1122*700637cbSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, 1123*700637cbSDimitry Andric int> > 1124*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l) { 1125*700637cbSDimitry Andric __assign_with_sentinel(__f, __l); 1126*700637cbSDimitry Andric} 1127*700637cbSDimitry Andric 1128*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1129*700637cbSDimitry Andrictemplate <class _Iterator, class _Sentinel> 1130*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { 1131*700637cbSDimitry Andric iterator __i = begin(); 1132*700637cbSDimitry Andric iterator __e = end(); 1133*700637cbSDimitry Andric for (; __f != __l && __i != __e; ++__f, (void)++__i) 1134*700637cbSDimitry Andric *__i = *__f; 1135*700637cbSDimitry Andric if (__f != __l) 1136*700637cbSDimitry Andric __append_with_sentinel(std::move(__f), std::move(__l)); 1137*700637cbSDimitry Andric else 1138*700637cbSDimitry Andric __erase_to_end(__i); 1139*700637cbSDimitry Andric} 1140*700637cbSDimitry Andric 1141*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1142*700637cbSDimitry Andrictemplate <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> > 1143*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l) { 1144*700637cbSDimitry Andric __assign_with_size_random_access(__f, __l - __f); 1145*700637cbSDimitry Andric} 1146*700637cbSDimitry Andric 1147*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1148*700637cbSDimitry Andrictemplate <class _RandomAccessIterator> 1149*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI void 1150*700637cbSDimitry Andricdeque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { 1151*700637cbSDimitry Andric if (static_cast<size_type>(__n) > size()) { 1152*700637cbSDimitry Andric auto __l = __f + size(); 1153*700637cbSDimitry Andric std::copy(__f, __l, begin()); 1154*700637cbSDimitry Andric __append_with_size(__l, __n - size()); 1155*700637cbSDimitry Andric } else 1156*700637cbSDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 1157*700637cbSDimitry Andric} 1158*700637cbSDimitry Andric 1159*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1160*700637cbSDimitry Andrictemplate <class _Iterator> 1161*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { 1162*700637cbSDimitry Andric if (static_cast<size_type>(__n) > size()) { 1163*700637cbSDimitry Andric auto __added_size = __n - size(); 1164*700637cbSDimitry Andric 1165*700637cbSDimitry Andric auto __i = begin(); 1166*700637cbSDimitry Andric for (auto __count = size(); __count != 0; --__count) { 1167*700637cbSDimitry Andric *__i++ = *__f++; 1168*700637cbSDimitry Andric } 1169*700637cbSDimitry Andric 1170*700637cbSDimitry Andric __append_with_size(__f, __added_size); 1171*700637cbSDimitry Andric 1172*700637cbSDimitry Andric } else { 1173*700637cbSDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 1174*700637cbSDimitry Andric } 1175*700637cbSDimitry Andric} 1176*700637cbSDimitry Andric 1177*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1178*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) { 1179*700637cbSDimitry Andric if (__n > size()) { 1180*700637cbSDimitry Andric std::fill_n(begin(), size(), __v); 1181*700637cbSDimitry Andric __n -= size(); 1182*700637cbSDimitry Andric __append(__n, __v); 1183*700637cbSDimitry Andric } else 1184*700637cbSDimitry Andric __erase_to_end(std::fill_n(begin(), __n, __v)); 1185*700637cbSDimitry Andric} 1186*700637cbSDimitry Andric 1187*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1188*700637cbSDimitry Andricinline _Allocator deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT { 1189*700637cbSDimitry Andric return __alloc(); 1190*700637cbSDimitry Andric} 1191*700637cbSDimitry Andric 1192*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1193*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::resize(size_type __n) { 1194*700637cbSDimitry Andric if (__n > size()) 1195*700637cbSDimitry Andric __append(__n - size()); 1196*700637cbSDimitry Andric else if (__n < size()) 1197*700637cbSDimitry Andric __erase_to_end(begin() + __n); 1198*700637cbSDimitry Andric} 1199*700637cbSDimitry Andric 1200*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1201*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) { 1202*700637cbSDimitry Andric if (__n > size()) 1203*700637cbSDimitry Andric __append(__n - size(), __v); 1204*700637cbSDimitry Andric else if (__n < size()) 1205*700637cbSDimitry Andric __erase_to_end(begin() + __n); 1206*700637cbSDimitry Andric} 1207*700637cbSDimitry Andric 1208*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1209*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT { 1210*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1211*700637cbSDimitry Andric if (empty()) { 1212*700637cbSDimitry Andric __annotate_delete(); 1213*700637cbSDimitry Andric while (__map_.size() > 0) { 1214*700637cbSDimitry Andric __alloc_traits::deallocate(__a, __map_.back(), __block_size); 1215*700637cbSDimitry Andric __map_.pop_back(); 1216*700637cbSDimitry Andric } 1217*700637cbSDimitry Andric __start_ = 0; 1218*700637cbSDimitry Andric } else { 1219*700637cbSDimitry Andric __maybe_remove_front_spare(/*__keep_one=*/false); 1220*700637cbSDimitry Andric __maybe_remove_back_spare(/*__keep_one=*/false); 1221*700637cbSDimitry Andric } 1222*700637cbSDimitry Andric __map_.shrink_to_fit(); 1223*700637cbSDimitry Andric} 1224*700637cbSDimitry Andric 1225*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1226*700637cbSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT { 1227*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "deque::operator[] index out of bounds"); 1228*700637cbSDimitry Andric size_type __p = __start_ + __i; 1229*700637cbSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 1230*700637cbSDimitry Andric} 1231*700637cbSDimitry Andric 1232*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1233*700637cbSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference 1234*700637cbSDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT { 1235*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "deque::operator[] index out of bounds"); 1236*700637cbSDimitry Andric size_type __p = __start_ + __i; 1237*700637cbSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 1238*700637cbSDimitry Andric} 1239*700637cbSDimitry Andric 1240*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1241*700637cbSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::at(size_type __i) { 1242*700637cbSDimitry Andric if (__i >= size()) 1243*700637cbSDimitry Andric std::__throw_out_of_range("deque"); 1244*700637cbSDimitry Andric size_type __p = __start_ + __i; 1245*700637cbSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 1246*700637cbSDimitry Andric} 1247*700637cbSDimitry Andric 1248*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1249*700637cbSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::at(size_type __i) const { 1250*700637cbSDimitry Andric if (__i >= size()) 1251*700637cbSDimitry Andric std::__throw_out_of_range("deque"); 1252*700637cbSDimitry Andric size_type __p = __start_ + __i; 1253*700637cbSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 1254*700637cbSDimitry Andric} 1255*700637cbSDimitry Andric 1256*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1257*700637cbSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::front() _NOEXCEPT { 1258*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::front called on an empty deque"); 1259*700637cbSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); 1260*700637cbSDimitry Andric} 1261*700637cbSDimitry Andric 1262*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1263*700637cbSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::front() const _NOEXCEPT { 1264*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::front called on an empty deque"); 1265*700637cbSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); 1266*700637cbSDimitry Andric} 1267*700637cbSDimitry Andric 1268*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1269*700637cbSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::back() _NOEXCEPT { 1270*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::back called on an empty deque"); 1271*700637cbSDimitry Andric size_type __p = size() + __start_ - 1; 1272*700637cbSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 1273*700637cbSDimitry Andric} 1274*700637cbSDimitry Andric 1275*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1276*700637cbSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::back() const _NOEXCEPT { 1277*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::back called on an empty deque"); 1278*700637cbSDimitry Andric size_type __p = size() + __start_ - 1; 1279*700637cbSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 1280*700637cbSDimitry Andric} 1281*700637cbSDimitry Andric 1282*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1283*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::push_back(const value_type& __v) { 1284*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1285*700637cbSDimitry Andric if (__back_spare() == 0) 1286*700637cbSDimitry Andric __add_back_capacity(); 1287*700637cbSDimitry Andric // __back_spare() >= 1 1288*700637cbSDimitry Andric __annotate_increase_back(1); 1289*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1290*700637cbSDimitry Andric ++__size(); 1291*700637cbSDimitry Andric} 1292*700637cbSDimitry Andric 1293*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1294*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::push_front(const value_type& __v) { 1295*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1296*700637cbSDimitry Andric if (__front_spare() == 0) 1297*700637cbSDimitry Andric __add_front_capacity(); 1298*700637cbSDimitry Andric // __front_spare() >= 1 1299*700637cbSDimitry Andric __annotate_increase_front(1); 1300*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1301*700637cbSDimitry Andric --__start_; 1302*700637cbSDimitry Andric ++__size(); 1303*700637cbSDimitry Andric} 1304*700637cbSDimitry Andric 1305*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1306*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) { 1307*700637cbSDimitry Andric size_type __pos = __p - begin(); 1308*700637cbSDimitry Andric size_type __to_end = size() - __pos; 1309*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1310*700637cbSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 1311*700637cbSDimitry Andric if (__front_spare() == 0) 1312*700637cbSDimitry Andric __add_front_capacity(); 1313*700637cbSDimitry Andric // __front_spare() >= 1 1314*700637cbSDimitry Andric __annotate_increase_front(1); 1315*700637cbSDimitry Andric if (__pos == 0) { 1316*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1317*700637cbSDimitry Andric --__start_; 1318*700637cbSDimitry Andric ++__size(); 1319*700637cbSDimitry Andric } else { 1320*700637cbSDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1321*700637cbSDimitry Andric iterator __b = begin(); 1322*700637cbSDimitry Andric iterator __bm1 = std::prev(__b); 1323*700637cbSDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__b)) 1324*700637cbSDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__bm1); 1325*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1326*700637cbSDimitry Andric --__start_; 1327*700637cbSDimitry Andric ++__size(); 1328*700637cbSDimitry Andric if (__pos > 1) 1329*700637cbSDimitry Andric __b = __move_and_check(std::next(__b), __b + __pos, __b, __vt); 1330*700637cbSDimitry Andric *__b = *__vt; 1331*700637cbSDimitry Andric } 1332*700637cbSDimitry Andric } else { // insert by shifting things forward 1333*700637cbSDimitry Andric if (__back_spare() == 0) 1334*700637cbSDimitry Andric __add_back_capacity(); 1335*700637cbSDimitry Andric // __back_capacity >= 1 1336*700637cbSDimitry Andric __annotate_increase_back(1); 1337*700637cbSDimitry Andric size_type __de = size() - __pos; 1338*700637cbSDimitry Andric if (__de == 0) { 1339*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1340*700637cbSDimitry Andric ++__size(); 1341*700637cbSDimitry Andric } else { 1342*700637cbSDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1343*700637cbSDimitry Andric iterator __e = end(); 1344*700637cbSDimitry Andric iterator __em1 = std::prev(__e); 1345*700637cbSDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1)) 1346*700637cbSDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__e); 1347*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1348*700637cbSDimitry Andric ++__size(); 1349*700637cbSDimitry Andric if (__de > 1) 1350*700637cbSDimitry Andric __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); 1351*700637cbSDimitry Andric *--__e = *__vt; 1352*700637cbSDimitry Andric } 1353*700637cbSDimitry Andric } 1354*700637cbSDimitry Andric return begin() + __pos; 1355*700637cbSDimitry Andric} 1356*700637cbSDimitry Andric 1357*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1358*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1359*700637cbSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) { 1360*700637cbSDimitry Andric size_type __pos = __p - begin(); 1361*700637cbSDimitry Andric size_type __to_end = __size() - __pos; 1362*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1363*700637cbSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 1364*700637cbSDimitry Andric if (__n > __front_spare()) 1365*700637cbSDimitry Andric __add_front_capacity(__n - __front_spare()); 1366*700637cbSDimitry Andric // __n <= __front_spare() 1367*700637cbSDimitry Andric __annotate_increase_front(__n); 1368*700637cbSDimitry Andric iterator __old_begin = begin(); 1369*700637cbSDimitry Andric iterator __i = __old_begin; 1370*700637cbSDimitry Andric if (__n > __pos) { 1371*700637cbSDimitry Andric for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size()) 1372*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), __v); 1373*700637cbSDimitry Andric __n = __pos; 1374*700637cbSDimitry Andric } 1375*700637cbSDimitry Andric if (__n > 0) { 1376*700637cbSDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1377*700637cbSDimitry Andric iterator __obn = __old_begin + __n; 1378*700637cbSDimitry Andric __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); 1379*700637cbSDimitry Andric if (__n < __pos) 1380*700637cbSDimitry Andric __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); 1381*700637cbSDimitry Andric std::fill_n(__old_begin, __n, *__vt); 1382*700637cbSDimitry Andric } 1383*700637cbSDimitry Andric } else { // insert by shifting things forward 1384*700637cbSDimitry Andric size_type __back_capacity = __back_spare(); 1385*700637cbSDimitry Andric if (__n > __back_capacity) 1386*700637cbSDimitry Andric __add_back_capacity(__n - __back_capacity); 1387*700637cbSDimitry Andric // __n <= __back_capacity 1388*700637cbSDimitry Andric __annotate_increase_back(__n); 1389*700637cbSDimitry Andric iterator __old_end = end(); 1390*700637cbSDimitry Andric iterator __i = __old_end; 1391*700637cbSDimitry Andric size_type __de = size() - __pos; 1392*700637cbSDimitry Andric if (__n > __de) { 1393*700637cbSDimitry Andric for (size_type __m = __n - __de; __m; --__m, (void)++__i, ++__size()) 1394*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), __v); 1395*700637cbSDimitry Andric __n = __de; 1396*700637cbSDimitry Andric } 1397*700637cbSDimitry Andric if (__n > 0) { 1398*700637cbSDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1399*700637cbSDimitry Andric iterator __oen = __old_end - __n; 1400*700637cbSDimitry Andric __move_construct_and_check(__oen, __old_end, __i, __vt); 1401*700637cbSDimitry Andric if (__n < __de) 1402*700637cbSDimitry Andric __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); 1403*700637cbSDimitry Andric std::fill_n(__old_end - __n, __n, *__vt); 1404*700637cbSDimitry Andric } 1405*700637cbSDimitry Andric } 1406*700637cbSDimitry Andric return begin() + __pos; 1407*700637cbSDimitry Andric} 1408*700637cbSDimitry Andric 1409*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1410*700637cbSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> > 1411*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1412*700637cbSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l) { 1413*700637cbSDimitry Andric return __insert_with_sentinel(__p, __f, __l); 1414*700637cbSDimitry Andric} 1415*700637cbSDimitry Andric 1416*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1417*700637cbSDimitry Andrictemplate <class _Iterator, class _Sentinel> 1418*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 1419*700637cbSDimitry Andricdeque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { 1420*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__alloc()); 1421*700637cbSDimitry Andric __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); 1422*700637cbSDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; 1423*700637cbSDimitry Andric return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); 1424*700637cbSDimitry Andric} 1425*700637cbSDimitry Andric 1426*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1427*700637cbSDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> > 1428*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1429*700637cbSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l) { 1430*700637cbSDimitry Andric return __insert_with_size(__p, __f, std::distance(__f, __l)); 1431*700637cbSDimitry Andric} 1432*700637cbSDimitry Andric 1433*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1434*700637cbSDimitry Andrictemplate <class _Iterator> 1435*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 1436*700637cbSDimitry Andricdeque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) { 1437*700637cbSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); 1438*700637cbSDimitry Andric __buf.__construct_at_end_with_size(__f, __n); 1439*700637cbSDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; 1440*700637cbSDimitry Andric return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); 1441*700637cbSDimitry Andric} 1442*700637cbSDimitry Andric 1443*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1444*700637cbSDimitry Andrictemplate <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> > 1445*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l) { 1446*700637cbSDimitry Andric return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l)); 1447*700637cbSDimitry Andric} 1448*700637cbSDimitry Andric 1449*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1450*700637cbSDimitry Andrictemplate <class _BiIter, class _Sentinel> 1451*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 1452*700637cbSDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) { 1453*700637cbSDimitry Andric return __insert_bidirectional(__p, __f, std::next(__f, __n), __n); 1454*700637cbSDimitry Andric} 1455*700637cbSDimitry Andric 1456*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1457*700637cbSDimitry Andrictemplate <class _BiIter> 1458*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 1459*700637cbSDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) { 1460*700637cbSDimitry Andric size_type __pos = __p - begin(); 1461*700637cbSDimitry Andric size_type __to_end = size() - __pos; 1462*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1463*700637cbSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 1464*700637cbSDimitry Andric if (__n > __front_spare()) 1465*700637cbSDimitry Andric __add_front_capacity(__n - __front_spare()); 1466*700637cbSDimitry Andric // __n <= __front_spare() 1467*700637cbSDimitry Andric __annotate_increase_front(__n); 1468*700637cbSDimitry Andric iterator __old_begin = begin(); 1469*700637cbSDimitry Andric iterator __i = __old_begin; 1470*700637cbSDimitry Andric _BiIter __m = __f; 1471*700637cbSDimitry Andric if (__n > __pos) { 1472*700637cbSDimitry Andric __m = __pos < __n / 2 ? std::prev(__l, __pos) : std::next(__f, __n - __pos); 1473*700637cbSDimitry Andric for (_BiIter __j = __m; __j != __f; --__start_, ++__size()) 1474*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), *--__j); 1475*700637cbSDimitry Andric __n = __pos; 1476*700637cbSDimitry Andric } 1477*700637cbSDimitry Andric if (__n > 0) { 1478*700637cbSDimitry Andric iterator __obn = __old_begin + __n; 1479*700637cbSDimitry Andric for (iterator __j = __obn; __j != __old_begin;) { 1480*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), std::move(*--__j)); 1481*700637cbSDimitry Andric --__start_; 1482*700637cbSDimitry Andric ++__size(); 1483*700637cbSDimitry Andric } 1484*700637cbSDimitry Andric if (__n < __pos) 1485*700637cbSDimitry Andric __old_begin = std::move(__obn, __old_begin + __pos, __old_begin); 1486*700637cbSDimitry Andric std::copy(__m, __l, __old_begin); 1487*700637cbSDimitry Andric } 1488*700637cbSDimitry Andric } else { // insert by shifting things forward 1489*700637cbSDimitry Andric size_type __back_capacity = __back_spare(); 1490*700637cbSDimitry Andric if (__n > __back_capacity) 1491*700637cbSDimitry Andric __add_back_capacity(__n - __back_capacity); 1492*700637cbSDimitry Andric // __n <= __back_capacity 1493*700637cbSDimitry Andric __annotate_increase_back(__n); 1494*700637cbSDimitry Andric iterator __old_end = end(); 1495*700637cbSDimitry Andric iterator __i = __old_end; 1496*700637cbSDimitry Andric _BiIter __m = __l; 1497*700637cbSDimitry Andric size_type __de = size() - __pos; 1498*700637cbSDimitry Andric if (__n > __de) { 1499*700637cbSDimitry Andric __m = __de < __n / 2 ? std::next(__f, __de) : std::prev(__l, __n - __de); 1500*700637cbSDimitry Andric for (_BiIter __j = __m; __j != __l; ++__i, (void)++__j, ++__size()) 1501*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), *__j); 1502*700637cbSDimitry Andric __n = __de; 1503*700637cbSDimitry Andric } 1504*700637cbSDimitry Andric if (__n > 0) { 1505*700637cbSDimitry Andric iterator __oen = __old_end - __n; 1506*700637cbSDimitry Andric for (iterator __j = __oen; __j != __old_end; ++__i, (void)++__j, ++__size()) 1507*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), std::move(*__j)); 1508*700637cbSDimitry Andric if (__n < __de) 1509*700637cbSDimitry Andric __old_end = std::move_backward(__old_end - __de, __oen, __old_end); 1510*700637cbSDimitry Andric std::copy_backward(__f, __m, __old_end); 1511*700637cbSDimitry Andric } 1512*700637cbSDimitry Andric } 1513*700637cbSDimitry Andric return begin() + __pos; 1514*700637cbSDimitry Andric} 1515*700637cbSDimitry Andric 1516*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1517*700637cbSDimitry Andrictemplate <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> > 1518*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l) { 1519*700637cbSDimitry Andric __append_with_sentinel(__f, __l); 1520*700637cbSDimitry Andric} 1521*700637cbSDimitry Andric 1522*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1523*700637cbSDimitry Andrictemplate <class _InputIterator, class _Sentinel> 1524*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { 1525*700637cbSDimitry Andric for (; __f != __l; ++__f) 1526*700637cbSDimitry Andric push_back(*__f); 1527*700637cbSDimitry Andric} 1528*700637cbSDimitry Andric 1529*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1530*700637cbSDimitry Andrictemplate <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> > 1531*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l) { 1532*700637cbSDimitry Andric __append_with_size(__f, std::distance(__f, __l)); 1533*700637cbSDimitry Andric} 1534*700637cbSDimitry Andric 1535*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1536*700637cbSDimitry Andrictemplate <class _InputIterator> 1537*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { 1538*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1539*700637cbSDimitry Andric size_type __back_capacity = __back_spare(); 1540*700637cbSDimitry Andric if (__n > __back_capacity) 1541*700637cbSDimitry Andric __add_back_capacity(__n - __back_capacity); 1542*700637cbSDimitry Andric 1543*700637cbSDimitry Andric // __n <= __back_capacity 1544*700637cbSDimitry Andric __annotate_increase_back(__n); 1545*700637cbSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1546*700637cbSDimitry Andric _ConstructTransaction __tx(this, __br); 1547*700637cbSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { 1548*700637cbSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); 1549*700637cbSDimitry Andric } 1550*700637cbSDimitry Andric } 1551*700637cbSDimitry Andric} 1552*700637cbSDimitry Andric 1553*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1554*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__append(size_type __n) { 1555*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1556*700637cbSDimitry Andric size_type __back_capacity = __back_spare(); 1557*700637cbSDimitry Andric if (__n > __back_capacity) 1558*700637cbSDimitry Andric __add_back_capacity(__n - __back_capacity); 1559*700637cbSDimitry Andric // __n <= __back_capacity 1560*700637cbSDimitry Andric __annotate_increase_back(__n); 1561*700637cbSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1562*700637cbSDimitry Andric _ConstructTransaction __tx(this, __br); 1563*700637cbSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 1564*700637cbSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); 1565*700637cbSDimitry Andric } 1566*700637cbSDimitry Andric } 1567*700637cbSDimitry Andric} 1568*700637cbSDimitry Andric 1569*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1570*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) { 1571*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1572*700637cbSDimitry Andric size_type __back_capacity = __back_spare(); 1573*700637cbSDimitry Andric if (__n > __back_capacity) 1574*700637cbSDimitry Andric __add_back_capacity(__n - __back_capacity); 1575*700637cbSDimitry Andric // __n <= __back_capacity 1576*700637cbSDimitry Andric __annotate_increase_back(__n); 1577*700637cbSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1578*700637cbSDimitry Andric _ConstructTransaction __tx(this, __br); 1579*700637cbSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 1580*700637cbSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); 1581*700637cbSDimitry Andric } 1582*700637cbSDimitry Andric } 1583*700637cbSDimitry Andric} 1584*700637cbSDimitry Andric 1585*700637cbSDimitry Andric// Create front capacity for one block of elements. 1586*700637cbSDimitry Andric// Strong guarantee. Either do it or don't touch anything. 1587*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1588*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__add_front_capacity() { 1589*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1590*700637cbSDimitry Andric if (__back_spare() >= __block_size) { 1591*700637cbSDimitry Andric __start_ += __block_size; 1592*700637cbSDimitry Andric pointer __pt = __map_.back(); 1593*700637cbSDimitry Andric __map_.pop_back(); 1594*700637cbSDimitry Andric __map_.push_front(__pt); 1595*700637cbSDimitry Andric } 1596*700637cbSDimitry Andric // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer 1597*700637cbSDimitry Andric else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around 1598*700637cbSDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 1599*700637cbSDimitry Andric // anything up (any added buffers are undetectible) 1600*700637cbSDimitry Andric if (__map_.__front_spare() > 0) 1601*700637cbSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 1602*700637cbSDimitry Andric else { 1603*700637cbSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 1604*700637cbSDimitry Andric // Done allocating, reorder capacity 1605*700637cbSDimitry Andric pointer __pt = __map_.back(); 1606*700637cbSDimitry Andric __map_.pop_back(); 1607*700637cbSDimitry Andric __map_.push_front(__pt); 1608*700637cbSDimitry Andric } 1609*700637cbSDimitry Andric __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; 1610*700637cbSDimitry Andric } 1611*700637cbSDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 1612*700637cbSDimitry Andric else { 1613*700637cbSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 1614*700637cbSDimitry Andric std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__alloc()); 1615*700637cbSDimitry Andric 1616*700637cbSDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 1617*700637cbSDimitry Andric unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); 1618*700637cbSDimitry Andric __buf.push_back(__hold.get()); 1619*700637cbSDimitry Andric __hold.release(); 1620*700637cbSDimitry Andric 1621*700637cbSDimitry Andric for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) 1622*700637cbSDimitry Andric __buf.push_back(*__i); 1623*700637cbSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 1624*700637cbSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 1625*700637cbSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 1626*700637cbSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 1627*700637cbSDimitry Andric __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; 1628*700637cbSDimitry Andric } 1629*700637cbSDimitry Andric __annotate_whole_block(0, __asan_poison); 1630*700637cbSDimitry Andric} 1631*700637cbSDimitry Andric 1632*700637cbSDimitry Andric// Create front capacity for __n elements. 1633*700637cbSDimitry Andric// Strong guarantee. Either do it or don't touch anything. 1634*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1635*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) { 1636*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1637*700637cbSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 1638*700637cbSDimitry Andric // Number of unused blocks at back: 1639*700637cbSDimitry Andric size_type __back_capacity = __back_spare() / __block_size; 1640*700637cbSDimitry Andric __back_capacity = std::min(__back_capacity, __nb); // don't take more than you need 1641*700637cbSDimitry Andric __nb -= __back_capacity; // number of blocks need to allocate 1642*700637cbSDimitry Andric // If __nb == 0, then we have sufficient capacity. 1643*700637cbSDimitry Andric if (__nb == 0) { 1644*700637cbSDimitry Andric __start_ += __block_size * __back_capacity; 1645*700637cbSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 1646*700637cbSDimitry Andric pointer __pt = __map_.back(); 1647*700637cbSDimitry Andric __map_.pop_back(); 1648*700637cbSDimitry Andric __map_.push_front(__pt); 1649*700637cbSDimitry Andric } 1650*700637cbSDimitry Andric } 1651*700637cbSDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 1652*700637cbSDimitry Andric else if (__nb <= __map_.capacity() - 1653*700637cbSDimitry Andric __map_.size()) { // we can put the new buffers into the map, but don't shift things around 1654*700637cbSDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 1655*700637cbSDimitry Andric // anything up (any added buffers are undetectible) 1656*700637cbSDimitry Andric for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) { 1657*700637cbSDimitry Andric if (__map_.__front_spare() == 0) 1658*700637cbSDimitry Andric break; 1659*700637cbSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 1660*700637cbSDimitry Andric __annotate_whole_block(0, __asan_poison); 1661*700637cbSDimitry Andric } 1662*700637cbSDimitry Andric for (; __nb > 0; --__nb, ++__back_capacity) 1663*700637cbSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 1664*700637cbSDimitry Andric // Done allocating, reorder capacity 1665*700637cbSDimitry Andric __start_ += __back_capacity * __block_size; 1666*700637cbSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 1667*700637cbSDimitry Andric pointer __pt = __map_.back(); 1668*700637cbSDimitry Andric __map_.pop_back(); 1669*700637cbSDimitry Andric __map_.push_front(__pt); 1670*700637cbSDimitry Andric __annotate_whole_block(0, __asan_poison); 1671*700637cbSDimitry Andric } 1672*700637cbSDimitry Andric } 1673*700637cbSDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 1674*700637cbSDimitry Andric else { 1675*700637cbSDimitry Andric size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty(); 1676*700637cbSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 1677*700637cbSDimitry Andric std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__alloc()); 1678*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1679*700637cbSDimitry Andric try { 1680*700637cbSDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1681*700637cbSDimitry Andric for (; __nb > 0; --__nb) { 1682*700637cbSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 1683*700637cbSDimitry Andric // ASan: this is empty container, we have to poison whole block 1684*700637cbSDimitry Andric __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); 1685*700637cbSDimitry Andric } 1686*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1687*700637cbSDimitry Andric } catch (...) { 1688*700637cbSDimitry Andric __annotate_delete(); 1689*700637cbSDimitry Andric for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) 1690*700637cbSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 1691*700637cbSDimitry Andric throw; 1692*700637cbSDimitry Andric } 1693*700637cbSDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1694*700637cbSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 1695*700637cbSDimitry Andric __buf.push_back(__map_.back()); 1696*700637cbSDimitry Andric __map_.pop_back(); 1697*700637cbSDimitry Andric } 1698*700637cbSDimitry Andric for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) 1699*700637cbSDimitry Andric __buf.push_back(*__i); 1700*700637cbSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 1701*700637cbSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 1702*700637cbSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 1703*700637cbSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 1704*700637cbSDimitry Andric __start_ += __ds; 1705*700637cbSDimitry Andric } 1706*700637cbSDimitry Andric} 1707*700637cbSDimitry Andric 1708*700637cbSDimitry Andric// Create back capacity for one block of elements. 1709*700637cbSDimitry Andric// Strong guarantee. Either do it or don't touch anything. 1710*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1711*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__add_back_capacity() { 1712*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1713*700637cbSDimitry Andric if (__front_spare() >= __block_size) { 1714*700637cbSDimitry Andric __start_ -= __block_size; 1715*700637cbSDimitry Andric pointer __pt = __map_.front(); 1716*700637cbSDimitry Andric __map_.pop_front(); 1717*700637cbSDimitry Andric __map_.push_back(__pt); 1718*700637cbSDimitry Andric } 1719*700637cbSDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 1720*700637cbSDimitry Andric else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around 1721*700637cbSDimitry Andric // until it is allocated. If we throw, we don't need to fix 1722*700637cbSDimitry Andric // anything up (any added buffers are undetectible) 1723*700637cbSDimitry Andric if (__map_.__back_spare() != 0) 1724*700637cbSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 1725*700637cbSDimitry Andric else { 1726*700637cbSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 1727*700637cbSDimitry Andric // Done allocating, reorder capacity 1728*700637cbSDimitry Andric pointer __pt = __map_.front(); 1729*700637cbSDimitry Andric __map_.pop_front(); 1730*700637cbSDimitry Andric __map_.push_back(__pt); 1731*700637cbSDimitry Andric } 1732*700637cbSDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 1733*700637cbSDimitry Andric } 1734*700637cbSDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 1735*700637cbSDimitry Andric else { 1736*700637cbSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 1737*700637cbSDimitry Andric std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__alloc()); 1738*700637cbSDimitry Andric 1739*700637cbSDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 1740*700637cbSDimitry Andric unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); 1741*700637cbSDimitry Andric __buf.push_back(__hold.get()); 1742*700637cbSDimitry Andric __hold.release(); 1743*700637cbSDimitry Andric 1744*700637cbSDimitry Andric for (__map_pointer __i = __map_.end(); __i != __map_.begin();) 1745*700637cbSDimitry Andric __buf.push_front(*--__i); 1746*700637cbSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 1747*700637cbSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 1748*700637cbSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 1749*700637cbSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 1750*700637cbSDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 1751*700637cbSDimitry Andric } 1752*700637cbSDimitry Andric} 1753*700637cbSDimitry Andric 1754*700637cbSDimitry Andric// Create back capacity for __n elements. 1755*700637cbSDimitry Andric// Strong guarantee. Either do it or don't touch anything. 1756*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1757*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) { 1758*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1759*700637cbSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 1760*700637cbSDimitry Andric // Number of unused blocks at front: 1761*700637cbSDimitry Andric size_type __front_capacity = __front_spare() / __block_size; 1762*700637cbSDimitry Andric __front_capacity = std::min(__front_capacity, __nb); // don't take more than you need 1763*700637cbSDimitry Andric __nb -= __front_capacity; // number of blocks need to allocate 1764*700637cbSDimitry Andric // If __nb == 0, then we have sufficient capacity. 1765*700637cbSDimitry Andric if (__nb == 0) { 1766*700637cbSDimitry Andric __start_ -= __block_size * __front_capacity; 1767*700637cbSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 1768*700637cbSDimitry Andric pointer __pt = __map_.front(); 1769*700637cbSDimitry Andric __map_.pop_front(); 1770*700637cbSDimitry Andric __map_.push_back(__pt); 1771*700637cbSDimitry Andric } 1772*700637cbSDimitry Andric } 1773*700637cbSDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 1774*700637cbSDimitry Andric else if (__nb <= __map_.capacity() - 1775*700637cbSDimitry Andric __map_.size()) { // we can put the new buffers into the map, but don't shift things around 1776*700637cbSDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 1777*700637cbSDimitry Andric // anything up (any added buffers are undetectible) 1778*700637cbSDimitry Andric for (; __nb > 0; --__nb) { 1779*700637cbSDimitry Andric if (__map_.__back_spare() == 0) 1780*700637cbSDimitry Andric break; 1781*700637cbSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 1782*700637cbSDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 1783*700637cbSDimitry Andric } 1784*700637cbSDimitry Andric for (; __nb > 0; --__nb, ++__front_capacity, __start_ += __block_size - (__map_.size() == 1)) { 1785*700637cbSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 1786*700637cbSDimitry Andric __annotate_whole_block(0, __asan_poison); 1787*700637cbSDimitry Andric } 1788*700637cbSDimitry Andric // Done allocating, reorder capacity 1789*700637cbSDimitry Andric __start_ -= __block_size * __front_capacity; 1790*700637cbSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 1791*700637cbSDimitry Andric pointer __pt = __map_.front(); 1792*700637cbSDimitry Andric __map_.pop_front(); 1793*700637cbSDimitry Andric __map_.push_back(__pt); 1794*700637cbSDimitry Andric } 1795*700637cbSDimitry Andric } 1796*700637cbSDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 1797*700637cbSDimitry Andric else { 1798*700637cbSDimitry Andric size_type __ds = __front_capacity * __block_size; 1799*700637cbSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 1800*700637cbSDimitry Andric std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 1801*700637cbSDimitry Andric __map_.size() - __front_capacity, 1802*700637cbSDimitry Andric __map_.__alloc()); 1803*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1804*700637cbSDimitry Andric try { 1805*700637cbSDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1806*700637cbSDimitry Andric for (; __nb > 0; --__nb) { 1807*700637cbSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 1808*700637cbSDimitry Andric // ASan: this is an empty container, we have to poison the whole block 1809*700637cbSDimitry Andric __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); 1810*700637cbSDimitry Andric } 1811*700637cbSDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1812*700637cbSDimitry Andric } catch (...) { 1813*700637cbSDimitry Andric __annotate_delete(); 1814*700637cbSDimitry Andric for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) 1815*700637cbSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 1816*700637cbSDimitry Andric throw; 1817*700637cbSDimitry Andric } 1818*700637cbSDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1819*700637cbSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 1820*700637cbSDimitry Andric __buf.push_back(__map_.front()); 1821*700637cbSDimitry Andric __map_.pop_front(); 1822*700637cbSDimitry Andric } 1823*700637cbSDimitry Andric for (__map_pointer __i = __map_.end(); __i != __map_.begin();) 1824*700637cbSDimitry Andric __buf.push_front(*--__i); 1825*700637cbSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 1826*700637cbSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 1827*700637cbSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 1828*700637cbSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 1829*700637cbSDimitry Andric __start_ -= __ds; 1830*700637cbSDimitry Andric } 1831*700637cbSDimitry Andric} 1832*700637cbSDimitry Andric 1833*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1834*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::pop_front() { 1835*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_front called on an empty deque"); 1836*700637cbSDimitry Andric size_type __old_sz = size(); 1837*700637cbSDimitry Andric size_type __old_start = __start_; 1838*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1839*700637cbSDimitry Andric __alloc_traits::destroy( 1840*700637cbSDimitry Andric __a, std::__to_address(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size)); 1841*700637cbSDimitry Andric --__size(); 1842*700637cbSDimitry Andric ++__start_; 1843*700637cbSDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 1844*700637cbSDimitry Andric __maybe_remove_front_spare(); 1845*700637cbSDimitry Andric} 1846*700637cbSDimitry Andric 1847*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1848*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::pop_back() { 1849*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); 1850*700637cbSDimitry Andric size_type __old_sz = size(); 1851*700637cbSDimitry Andric size_type __old_start = __start_; 1852*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1853*700637cbSDimitry Andric size_type __p = size() + __start_ - 1; 1854*700637cbSDimitry Andric __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() + __p / __block_size) + __p % __block_size)); 1855*700637cbSDimitry Andric --__size(); 1856*700637cbSDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 1857*700637cbSDimitry Andric __maybe_remove_back_spare(); 1858*700637cbSDimitry Andric} 1859*700637cbSDimitry Andric 1860*700637cbSDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)). 1861*700637cbSDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt. 1862*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1863*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1864*700637cbSDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 1865*700637cbSDimitry Andric // as if 1866*700637cbSDimitry Andric // for (; __f != __l; ++__f, ++__r) 1867*700637cbSDimitry Andric // *__r = std::move(*__f); 1868*700637cbSDimitry Andric difference_type __n = __l - __f; 1869*700637cbSDimitry Andric while (__n > 0) { 1870*700637cbSDimitry Andric pointer __fb = __f.__ptr_; 1871*700637cbSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 1872*700637cbSDimitry Andric difference_type __bs = __fe - __fb; 1873*700637cbSDimitry Andric if (__bs > __n) { 1874*700637cbSDimitry Andric __bs = __n; 1875*700637cbSDimitry Andric __fe = __fb + __bs; 1876*700637cbSDimitry Andric } 1877*700637cbSDimitry Andric if (__fb <= __vt && __vt < __fe) 1878*700637cbSDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; 1879*700637cbSDimitry Andric __r = std::move(__fb, __fe, __r); 1880*700637cbSDimitry Andric __n -= __bs; 1881*700637cbSDimitry Andric __f += __bs; 1882*700637cbSDimitry Andric } 1883*700637cbSDimitry Andric return __r; 1884*700637cbSDimitry Andric} 1885*700637cbSDimitry Andric 1886*700637cbSDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards. 1887*700637cbSDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt. 1888*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1889*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1890*700637cbSDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 1891*700637cbSDimitry Andric // as if 1892*700637cbSDimitry Andric // while (__f != __l) 1893*700637cbSDimitry Andric // *--__r = std::move(*--__l); 1894*700637cbSDimitry Andric difference_type __n = __l - __f; 1895*700637cbSDimitry Andric while (__n > 0) { 1896*700637cbSDimitry Andric --__l; 1897*700637cbSDimitry Andric pointer __lb = *__l.__m_iter_; 1898*700637cbSDimitry Andric pointer __le = __l.__ptr_ + 1; 1899*700637cbSDimitry Andric difference_type __bs = __le - __lb; 1900*700637cbSDimitry Andric if (__bs > __n) { 1901*700637cbSDimitry Andric __bs = __n; 1902*700637cbSDimitry Andric __lb = __le - __bs; 1903*700637cbSDimitry Andric } 1904*700637cbSDimitry Andric if (__lb <= __vt && __vt < __le) 1905*700637cbSDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; 1906*700637cbSDimitry Andric __r = std::move_backward(__lb, __le, __r); 1907*700637cbSDimitry Andric __n -= __bs; 1908*700637cbSDimitry Andric __l -= __bs - 1; 1909*700637cbSDimitry Andric } 1910*700637cbSDimitry Andric return __r; 1911*700637cbSDimitry Andric} 1912*700637cbSDimitry Andric 1913*700637cbSDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)). 1914*700637cbSDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt. 1915*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1916*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 1917*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1918*700637cbSDimitry Andric // as if 1919*700637cbSDimitry Andric // for (; __f != __l; ++__r, ++__f, ++__size()) 1920*700637cbSDimitry Andric // __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__f)); 1921*700637cbSDimitry Andric difference_type __n = __l - __f; 1922*700637cbSDimitry Andric while (__n > 0) { 1923*700637cbSDimitry Andric pointer __fb = __f.__ptr_; 1924*700637cbSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 1925*700637cbSDimitry Andric difference_type __bs = __fe - __fb; 1926*700637cbSDimitry Andric if (__bs > __n) { 1927*700637cbSDimitry Andric __bs = __n; 1928*700637cbSDimitry Andric __fe = __fb + __bs; 1929*700637cbSDimitry Andric } 1930*700637cbSDimitry Andric if (__fb <= __vt && __vt < __fe) 1931*700637cbSDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; 1932*700637cbSDimitry Andric for (; __fb != __fe; ++__fb, ++__r, ++__size()) 1933*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__fb)); 1934*700637cbSDimitry Andric __n -= __bs; 1935*700637cbSDimitry Andric __f += __bs; 1936*700637cbSDimitry Andric } 1937*700637cbSDimitry Andric} 1938*700637cbSDimitry Andric 1939*700637cbSDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards. 1940*700637cbSDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt. 1941*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1942*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__move_construct_backward_and_check( 1943*700637cbSDimitry Andric iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 1944*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1945*700637cbSDimitry Andric // as if 1946*700637cbSDimitry Andric // for (iterator __j = __l; __j != __f;) 1947*700637cbSDimitry Andric // { 1948*700637cbSDimitry Andric // __alloc_traitsconstruct(__a, std::addressof(*--__r), std::move(*--__j)); 1949*700637cbSDimitry Andric // --__start_; 1950*700637cbSDimitry Andric // ++__size(); 1951*700637cbSDimitry Andric // } 1952*700637cbSDimitry Andric difference_type __n = __l - __f; 1953*700637cbSDimitry Andric while (__n > 0) { 1954*700637cbSDimitry Andric --__l; 1955*700637cbSDimitry Andric pointer __lb = *__l.__m_iter_; 1956*700637cbSDimitry Andric pointer __le = __l.__ptr_ + 1; 1957*700637cbSDimitry Andric difference_type __bs = __le - __lb; 1958*700637cbSDimitry Andric if (__bs > __n) { 1959*700637cbSDimitry Andric __bs = __n; 1960*700637cbSDimitry Andric __lb = __le - __bs; 1961*700637cbSDimitry Andric } 1962*700637cbSDimitry Andric if (__lb <= __vt && __vt < __le) 1963*700637cbSDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; 1964*700637cbSDimitry Andric while (__le != __lb) { 1965*700637cbSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__r), std::move(*--__le)); 1966*700637cbSDimitry Andric --__start_; 1967*700637cbSDimitry Andric ++__size(); 1968*700637cbSDimitry Andric } 1969*700637cbSDimitry Andric __n -= __bs; 1970*700637cbSDimitry Andric __l -= __bs - 1; 1971*700637cbSDimitry Andric } 1972*700637cbSDimitry Andric} 1973*700637cbSDimitry Andric 1974*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 1975*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f) { 1976*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 1977*700637cbSDimitry Andric __f != end(), "deque::erase(iterator) called with a non-dereferenceable iterator"); 1978*700637cbSDimitry Andric size_type __old_sz = size(); 1979*700637cbSDimitry Andric size_type __old_start = __start_; 1980*700637cbSDimitry Andric iterator __b = begin(); 1981*700637cbSDimitry Andric difference_type __pos = __f - __b; 1982*700637cbSDimitry Andric iterator __p = __b + __pos; 1983*700637cbSDimitry Andric allocator_type& __a = __alloc(); 1984*700637cbSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - 1) / 2) { // erase from front 1985*700637cbSDimitry Andric std::move_backward(__b, __p, std::next(__p)); 1986*700637cbSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 1987*700637cbSDimitry Andric --__size(); 1988*700637cbSDimitry Andric ++__start_; 1989*700637cbSDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 1990*700637cbSDimitry Andric __maybe_remove_front_spare(); 1991*700637cbSDimitry Andric } else { // erase from back 1992*700637cbSDimitry Andric iterator __i = std::move(std::next(__p), end(), __p); 1993*700637cbSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 1994*700637cbSDimitry Andric --__size(); 1995*700637cbSDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 1996*700637cbSDimitry Andric __maybe_remove_back_spare(); 1997*700637cbSDimitry Andric } 1998*700637cbSDimitry Andric return begin() + __pos; 1999*700637cbSDimitry Andric} 2000*700637cbSDimitry Andric 2001*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2002*700637cbSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) { 2003*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__f <= __l, "deque::erase(first, last) called with an invalid range"); 2004*700637cbSDimitry Andric size_type __old_sz = size(); 2005*700637cbSDimitry Andric size_type __old_start = __start_; 2006*700637cbSDimitry Andric difference_type __n = __l - __f; 2007*700637cbSDimitry Andric iterator __b = begin(); 2008*700637cbSDimitry Andric difference_type __pos = __f - __b; 2009*700637cbSDimitry Andric iterator __p = __b + __pos; 2010*700637cbSDimitry Andric if (__n > 0) { 2011*700637cbSDimitry Andric allocator_type& __a = __alloc(); 2012*700637cbSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - __n) / 2) { // erase from front 2013*700637cbSDimitry Andric iterator __i = std::move_backward(__b, __p, __p + __n); 2014*700637cbSDimitry Andric for (; __b != __i; ++__b) 2015*700637cbSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2016*700637cbSDimitry Andric __size() -= __n; 2017*700637cbSDimitry Andric __start_ += __n; 2018*700637cbSDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2019*700637cbSDimitry Andric while (__maybe_remove_front_spare()) { 2020*700637cbSDimitry Andric } 2021*700637cbSDimitry Andric } else { // erase from back 2022*700637cbSDimitry Andric iterator __i = std::move(__p + __n, end(), __p); 2023*700637cbSDimitry Andric for (iterator __e = end(); __i != __e; ++__i) 2024*700637cbSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2025*700637cbSDimitry Andric __size() -= __n; 2026*700637cbSDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2027*700637cbSDimitry Andric while (__maybe_remove_back_spare()) { 2028*700637cbSDimitry Andric } 2029*700637cbSDimitry Andric } 2030*700637cbSDimitry Andric } 2031*700637cbSDimitry Andric return begin() + __pos; 2032*700637cbSDimitry Andric} 2033*700637cbSDimitry Andric 2034*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2035*700637cbSDimitry Andricvoid deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) { 2036*700637cbSDimitry Andric size_type __old_sz = size(); 2037*700637cbSDimitry Andric size_type __old_start = __start_; 2038*700637cbSDimitry Andric iterator __e = end(); 2039*700637cbSDimitry Andric difference_type __n = __e - __f; 2040*700637cbSDimitry Andric if (__n > 0) { 2041*700637cbSDimitry Andric allocator_type& __a = __alloc(); 2042*700637cbSDimitry Andric iterator __b = begin(); 2043*700637cbSDimitry Andric difference_type __pos = __f - __b; 2044*700637cbSDimitry Andric for (iterator __p = __b + __pos; __p != __e; ++__p) 2045*700637cbSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__p)); 2046*700637cbSDimitry Andric __size() -= __n; 2047*700637cbSDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2048*700637cbSDimitry Andric while (__maybe_remove_back_spare()) { 2049*700637cbSDimitry Andric } 2050*700637cbSDimitry Andric } 2051*700637cbSDimitry Andric} 2052*700637cbSDimitry Andric 2053*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2054*700637cbSDimitry Andricinline void deque<_Tp, _Allocator>::swap(deque& __c) { 2055*700637cbSDimitry Andric __map_.swap(__c.__map_); 2056*700637cbSDimitry Andric std::swap(__start_, __c.__start_); 2057*700637cbSDimitry Andric std::swap(__size(), __c.__size()); 2058*700637cbSDimitry Andric std::__swap_allocator(__alloc(), __c.__alloc()); 2059*700637cbSDimitry Andric} 2060*700637cbSDimitry Andric 2061*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2062*700637cbSDimitry Andricinline void deque<_Tp, _Allocator>::clear() _NOEXCEPT { 2063*700637cbSDimitry Andric __annotate_delete(); 2064*700637cbSDimitry Andric allocator_type& __a = __alloc(); 2065*700637cbSDimitry Andric for (iterator __i = begin(), __e = end(); __i != __e; ++__i) 2066*700637cbSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2067*700637cbSDimitry Andric __size() = 0; 2068*700637cbSDimitry Andric while (__map_.size() > 2) { 2069*700637cbSDimitry Andric __alloc_traits::deallocate(__a, __map_.front(), __block_size); 2070*700637cbSDimitry Andric __map_.pop_front(); 2071*700637cbSDimitry Andric } 2072*700637cbSDimitry Andric switch (__map_.size()) { 2073*700637cbSDimitry Andric case 1: 2074*700637cbSDimitry Andric __start_ = __block_size / 2; 2075*700637cbSDimitry Andric break; 2076*700637cbSDimitry Andric case 2: 2077*700637cbSDimitry Andric __start_ = __block_size; 2078*700637cbSDimitry Andric break; 2079*700637cbSDimitry Andric } 2080*700637cbSDimitry Andric __annotate_new(0); 2081*700637cbSDimitry Andric} 2082*700637cbSDimitry Andric 2083*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2084*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 2085*700637cbSDimitry Andric const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); 2086*700637cbSDimitry Andric return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); 2087*700637cbSDimitry Andric} 2088*700637cbSDimitry Andric 2089*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2090*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 2091*700637cbSDimitry Andric return !(__x == __y); 2092*700637cbSDimitry Andric} 2093*700637cbSDimitry Andric 2094*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2095*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 2096*700637cbSDimitry Andric return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 2097*700637cbSDimitry Andric} 2098*700637cbSDimitry Andric 2099*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2100*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 2101*700637cbSDimitry Andric return __y < __x; 2102*700637cbSDimitry Andric} 2103*700637cbSDimitry Andric 2104*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2105*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 2106*700637cbSDimitry Andric return !(__x < __y); 2107*700637cbSDimitry Andric} 2108*700637cbSDimitry Andric 2109*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2110*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 2111*700637cbSDimitry Andric return !(__y < __x); 2112*700637cbSDimitry Andric} 2113*700637cbSDimitry Andric 2114*700637cbSDimitry Andrictemplate <class _Tp, class _Allocator> 2115*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) { 2116*700637cbSDimitry Andric __x.swap(__y); 2117*700637cbSDimitry Andric} 2118*700637cbSDimitry Andric 2119*700637cbSDimitry Andric_LIBCPP_END_NAMESPACE_STD 2120*700637cbSDimitry Andric 2121*700637cbSDimitry Andric_LIBCPP_POP_MACROS 2122*700637cbSDimitry Andric 2123*700637cbSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) 2124*700637cbSDimitry Andric# include <__cxx03/algorithm> 2125*700637cbSDimitry Andric# include <__cxx03/atomic> 2126*700637cbSDimitry Andric# include <__cxx03/cstdlib> 2127*700637cbSDimitry Andric# include <__cxx03/functional> 2128*700637cbSDimitry Andric# include <__cxx03/iosfwd> 2129*700637cbSDimitry Andric# include <__cxx03/iterator> 2130*700637cbSDimitry Andric# include <__cxx03/type_traits> 2131*700637cbSDimitry Andric# include <__cxx03/typeinfo> 2132*700637cbSDimitry Andric#endif 2133*700637cbSDimitry Andric 2134*700637cbSDimitry Andric#endif // _LIBCPP___CXX03_DEQUE 2135