10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_DEQUE 110b57cec5SDimitry Andric#define _LIBCPP_DEQUE 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric deque synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std 170b57cec5SDimitry Andric{ 180b57cec5SDimitry Andric 190b57cec5SDimitry Andrictemplate <class T, class Allocator = allocator<T> > 200b57cec5SDimitry Andricclass deque 210b57cec5SDimitry Andric{ 220b57cec5SDimitry Andricpublic: 230b57cec5SDimitry Andric // types: 240b57cec5SDimitry Andric typedef T value_type; 250b57cec5SDimitry Andric typedef Allocator allocator_type; 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric typedef typename allocator_type::reference reference; 280b57cec5SDimitry Andric typedef typename allocator_type::const_reference const_reference; 290b57cec5SDimitry Andric typedef implementation-defined iterator; 300b57cec5SDimitry Andric typedef implementation-defined const_iterator; 310b57cec5SDimitry Andric typedef typename allocator_type::size_type size_type; 320b57cec5SDimitry Andric typedef typename allocator_type::difference_type difference_type; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric typedef typename allocator_type::pointer pointer; 350b57cec5SDimitry Andric typedef typename allocator_type::const_pointer const_pointer; 360b57cec5SDimitry Andric typedef std::reverse_iterator<iterator> reverse_iterator; 370b57cec5SDimitry Andric typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric // construct/copy/destroy: 400b57cec5SDimitry Andric deque() noexcept(is_nothrow_default_constructible<allocator_type>::value); 410b57cec5SDimitry Andric explicit deque(const allocator_type& a); 420b57cec5SDimitry Andric explicit deque(size_type n); 430b57cec5SDimitry Andric explicit deque(size_type n, const allocator_type& a); // C++14 440b57cec5SDimitry Andric deque(size_type n, const value_type& v); 450b57cec5SDimitry Andric deque(size_type n, const value_type& v, const allocator_type& a); 460b57cec5SDimitry Andric template <class InputIterator> 470b57cec5SDimitry Andric deque(InputIterator f, InputIterator l); 480b57cec5SDimitry Andric template <class InputIterator> 490b57cec5SDimitry Andric deque(InputIterator f, InputIterator l, const allocator_type& a); 50*06c3fb27SDimitry Andric template<container-compatible-range<T> R> 51*06c3fb27SDimitry Andric deque(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 520b57cec5SDimitry Andric deque(const deque& c); 530b57cec5SDimitry Andric deque(deque&& c) 540b57cec5SDimitry Andric noexcept(is_nothrow_move_constructible<allocator_type>::value); 550b57cec5SDimitry Andric deque(initializer_list<value_type> il, const Allocator& a = allocator_type()); 560b57cec5SDimitry Andric deque(const deque& c, const allocator_type& a); 570b57cec5SDimitry Andric deque(deque&& c, const allocator_type& a); 580b57cec5SDimitry Andric ~deque(); 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric deque& operator=(const deque& c); 610b57cec5SDimitry Andric deque& operator=(deque&& c) 620b57cec5SDimitry Andric noexcept( 630b57cec5SDimitry Andric allocator_type::propagate_on_container_move_assignment::value && 640b57cec5SDimitry Andric is_nothrow_move_assignable<allocator_type>::value); 650b57cec5SDimitry Andric deque& operator=(initializer_list<value_type> il); 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric template <class InputIterator> 680b57cec5SDimitry Andric void assign(InputIterator f, InputIterator l); 69*06c3fb27SDimitry Andric template<container-compatible-range<T> R> 70*06c3fb27SDimitry Andric void assign_range(R&& rg); // C++23 710b57cec5SDimitry Andric void assign(size_type n, const value_type& v); 720b57cec5SDimitry Andric void assign(initializer_list<value_type> il); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric allocator_type get_allocator() const noexcept; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric // iterators: 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric iterator begin() noexcept; 790b57cec5SDimitry Andric const_iterator begin() const noexcept; 800b57cec5SDimitry Andric iterator end() noexcept; 810b57cec5SDimitry Andric const_iterator end() const noexcept; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric reverse_iterator rbegin() noexcept; 840b57cec5SDimitry Andric const_reverse_iterator rbegin() const noexcept; 850b57cec5SDimitry Andric reverse_iterator rend() noexcept; 860b57cec5SDimitry Andric const_reverse_iterator rend() const noexcept; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric const_iterator cbegin() const noexcept; 890b57cec5SDimitry Andric const_iterator cend() const noexcept; 900b57cec5SDimitry Andric const_reverse_iterator crbegin() const noexcept; 910b57cec5SDimitry Andric const_reverse_iterator crend() const noexcept; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric // capacity: 940b57cec5SDimitry Andric size_type size() const noexcept; 950b57cec5SDimitry Andric size_type max_size() const noexcept; 960b57cec5SDimitry Andric void resize(size_type n); 970b57cec5SDimitry Andric void resize(size_type n, const value_type& v); 980b57cec5SDimitry Andric void shrink_to_fit(); 990b57cec5SDimitry Andric bool empty() const noexcept; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric // element access: 1020b57cec5SDimitry Andric reference operator[](size_type i); 1030b57cec5SDimitry Andric const_reference operator[](size_type i) const; 1040b57cec5SDimitry Andric reference at(size_type i); 1050b57cec5SDimitry Andric const_reference at(size_type i) const; 1060b57cec5SDimitry Andric reference front(); 1070b57cec5SDimitry Andric const_reference front() const; 1080b57cec5SDimitry Andric reference back(); 1090b57cec5SDimitry Andric const_reference back() const; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // modifiers: 1120b57cec5SDimitry Andric void push_front(const value_type& v); 1130b57cec5SDimitry Andric void push_front(value_type&& v); 114*06c3fb27SDimitry Andric template<container-compatible-range<T> R> 115*06c3fb27SDimitry Andric void prepend_range(R&& rg); // C++23 1160b57cec5SDimitry Andric void push_back(const value_type& v); 1170b57cec5SDimitry Andric void push_back(value_type&& v); 118*06c3fb27SDimitry Andric template<container-compatible-range<T> R> 119*06c3fb27SDimitry Andric void append_range(R&& rg); // C++23 1200b57cec5SDimitry Andric template <class... Args> reference emplace_front(Args&&... args); // reference in C++17 1210b57cec5SDimitry Andric template <class... Args> reference emplace_back(Args&&... args); // reference in C++17 1220b57cec5SDimitry Andric template <class... Args> iterator emplace(const_iterator p, Args&&... args); 1230b57cec5SDimitry Andric iterator insert(const_iterator p, const value_type& v); 1240b57cec5SDimitry Andric iterator insert(const_iterator p, value_type&& v); 1250b57cec5SDimitry Andric iterator insert(const_iterator p, size_type n, const value_type& v); 1260b57cec5SDimitry Andric template <class InputIterator> 1270b57cec5SDimitry Andric iterator insert(const_iterator p, InputIterator f, InputIterator l); 128*06c3fb27SDimitry Andric template<container-compatible-range<T> R> 129*06c3fb27SDimitry Andric iterator insert_range(const_iterator position, R&& rg); // C++23 1300b57cec5SDimitry Andric iterator insert(const_iterator p, initializer_list<value_type> il); 1310b57cec5SDimitry Andric void pop_front(); 1320b57cec5SDimitry Andric void pop_back(); 1330b57cec5SDimitry Andric iterator erase(const_iterator p); 1340b57cec5SDimitry Andric iterator erase(const_iterator f, const_iterator l); 1350b57cec5SDimitry Andric void swap(deque& c) 1360b57cec5SDimitry Andric noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17 1370b57cec5SDimitry Andric void clear() noexcept; 1380b57cec5SDimitry Andric}; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andrictemplate <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> 1410b57cec5SDimitry Andric deque(InputIterator, InputIterator, Allocator = Allocator()) 142349cc55cSDimitry Andric -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 1430b57cec5SDimitry Andric 144*06c3fb27SDimitry Andrictemplate<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> 145*06c3fb27SDimitry Andric deque(from_range_t, R&&, Allocator = Allocator()) 146*06c3fb27SDimitry Andric -> deque<ranges::range_value_t<R>, Allocator>; // C++23 147*06c3fb27SDimitry Andric 1480b57cec5SDimitry Andrictemplate <class T, class Allocator> 1490b57cec5SDimitry Andric bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y); 1500b57cec5SDimitry Andrictemplate <class T, class Allocator> 151*06c3fb27SDimitry Andric bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1520b57cec5SDimitry Andrictemplate <class T, class Allocator> 153*06c3fb27SDimitry Andric bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1540b57cec5SDimitry Andrictemplate <class T, class Allocator> 155*06c3fb27SDimitry Andric bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1560b57cec5SDimitry Andrictemplate <class T, class Allocator> 157*06c3fb27SDimitry Andric bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1580b57cec5SDimitry Andrictemplate <class T, class Allocator> 159*06c3fb27SDimitry Andric bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 160*06c3fb27SDimitry Andrictemplate<class T, class Allocator> 161*06c3fb27SDimitry Andric synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x, 162*06c3fb27SDimitry Andric const deque<T, Allocator>& y); // since C++20 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric// specialized algorithms: 1650b57cec5SDimitry Andrictemplate <class T, class Allocator> 1660b57cec5SDimitry Andric void swap(deque<T,Allocator>& x, deque<T,Allocator>& y) 1670b57cec5SDimitry Andric noexcept(noexcept(x.swap(y))); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andrictemplate <class T, class Allocator, class U> 1705ffd83dbSDimitry Andric typename deque<T, Allocator>::size_type 1715ffd83dbSDimitry Andric erase(deque<T, Allocator>& c, const U& value); // C++20 1720b57cec5SDimitry Andrictemplate <class T, class Allocator, class Predicate> 1735ffd83dbSDimitry Andric typename deque<T, Allocator>::size_type 1745ffd83dbSDimitry Andric erase_if(deque<T, Allocator>& c, Predicate pred); // C++20 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric} // std 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric*/ 1790b57cec5SDimitry Andric 18081ad6265SDimitry Andric#include <__algorithm/copy.h> 18181ad6265SDimitry Andric#include <__algorithm/copy_backward.h> 182*06c3fb27SDimitry Andric#include <__algorithm/copy_n.h> 18381ad6265SDimitry Andric#include <__algorithm/equal.h> 18481ad6265SDimitry Andric#include <__algorithm/fill_n.h> 18581ad6265SDimitry Andric#include <__algorithm/lexicographical_compare.h> 186*06c3fb27SDimitry Andric#include <__algorithm/lexicographical_compare_three_way.h> 18781ad6265SDimitry Andric#include <__algorithm/min.h> 18881ad6265SDimitry Andric#include <__algorithm/remove.h> 18981ad6265SDimitry Andric#include <__algorithm/remove_if.h> 19081ad6265SDimitry Andric#include <__algorithm/unwrap_iter.h> 19181ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 192*06c3fb27SDimitry Andric#include <__availability> 1930b57cec5SDimitry Andric#include <__config> 19481ad6265SDimitry Andric#include <__format/enable_insertable.h> 195*06c3fb27SDimitry Andric#include <__iterator/distance.h> 196349cc55cSDimitry Andric#include <__iterator/iterator_traits.h> 19781ad6265SDimitry Andric#include <__iterator/next.h> 19881ad6265SDimitry Andric#include <__iterator/prev.h> 19981ad6265SDimitry Andric#include <__iterator/reverse_iterator.h> 200bdd1243dSDimitry Andric#include <__iterator/segmented_iterator.h> 201*06c3fb27SDimitry Andric#include <__memory/addressof.h> 202bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h> 203bdd1243dSDimitry Andric#include <__memory/pointer_traits.h> 204bdd1243dSDimitry Andric#include <__memory/temp_value.h> 205bdd1243dSDimitry Andric#include <__memory/unique_ptr.h> 206bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h> 207*06c3fb27SDimitry Andric#include <__ranges/access.h> 208*06c3fb27SDimitry Andric#include <__ranges/concepts.h> 209*06c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h> 210*06c3fb27SDimitry Andric#include <__ranges/from_range.h> 211*06c3fb27SDimitry Andric#include <__ranges/size.h> 2120b57cec5SDimitry Andric#include <__split_buffer> 213bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h> 214*06c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 215*06c3fb27SDimitry Andric#include <__type_traits/is_same.h> 216*06c3fb27SDimitry Andric#include <__type_traits/type_identity.h> 217fe6060f1SDimitry Andric#include <__utility/forward.h> 21881ad6265SDimitry Andric#include <__utility/move.h> 219*06c3fb27SDimitry Andric#include <__utility/pair.h> 22081ad6265SDimitry Andric#include <__utility/swap.h> 221fe6060f1SDimitry Andric#include <limits> 2220b57cec5SDimitry Andric#include <stdexcept> 2230b57cec5SDimitry Andric#include <version> 2240b57cec5SDimitry Andric 22581ad6265SDimitry Andric// standard-mandated includes 22681ad6265SDimitry Andric 22781ad6265SDimitry Andric// [iterator.range] 22881ad6265SDimitry Andric#include <__iterator/access.h> 22981ad6265SDimitry Andric#include <__iterator/data.h> 23081ad6265SDimitry Andric#include <__iterator/empty.h> 23181ad6265SDimitry Andric#include <__iterator/reverse_access.h> 23281ad6265SDimitry Andric#include <__iterator/size.h> 23381ad6265SDimitry Andric 23481ad6265SDimitry Andric// [deque.syn] 23581ad6265SDimitry Andric#include <compare> 23681ad6265SDimitry Andric#include <initializer_list> 23781ad6265SDimitry Andric 2380b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2390b57cec5SDimitry Andric# pragma GCC system_header 2400b57cec5SDimitry Andric#endif 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 2430b57cec5SDimitry Andric#include <__undef_macros> 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andrictemplate <class _ValueType, class _DiffType> 2510b57cec5SDimitry Andricstruct __deque_block_size { 2520b57cec5SDimitry Andric static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16; 2530b57cec5SDimitry Andric}; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, 2560b57cec5SDimitry Andric class _DiffType, _DiffType _BS = 2570b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE 2580b57cec5SDimitry Andric// Keep template parameter to avoid changing all template declarations thoughout 2590b57cec5SDimitry Andric// this file. 2600b57cec5SDimitry Andric 0 2610b57cec5SDimitry Andric#else 2620b57cec5SDimitry Andric __deque_block_size<_ValueType, _DiffType>::value 2630b57cec5SDimitry Andric#endif 2640b57cec5SDimitry Andric > 2650b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __deque_iterator 2660b57cec5SDimitry Andric{ 2670b57cec5SDimitry Andric typedef _MapPointer __map_iterator; 2680b57cec5SDimitry Andricpublic: 2690b57cec5SDimitry Andric typedef _Pointer pointer; 2700b57cec5SDimitry Andric typedef _DiffType difference_type; 2710b57cec5SDimitry Andricprivate: 2720b57cec5SDimitry Andric __map_iterator __m_iter_; 2730b57cec5SDimitry Andric pointer __ptr_; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric static const difference_type __block_size; 2760b57cec5SDimitry Andricpublic: 2770b57cec5SDimitry Andric typedef _ValueType value_type; 2780b57cec5SDimitry Andric typedef random_access_iterator_tag iterator_category; 2790b57cec5SDimitry Andric typedef _Reference reference; 2800b57cec5SDimitry Andric 281bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT 282*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 2830b57cec5SDimitry Andric : __m_iter_(nullptr), __ptr_(nullptr) 2840b57cec5SDimitry Andric#endif 2850b57cec5SDimitry Andric {} 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric template <class _Pp, class _Rp, class _MP> 288bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 2890b57cec5SDimitry Andric __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it, 2900b57cec5SDimitry Andric typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT 2910b57cec5SDimitry Andric : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {} 2920b57cec5SDimitry Andric 293bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const {return *__ptr_;} 294bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const {return __ptr_;} 2950b57cec5SDimitry Andric 296bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++() 2970b57cec5SDimitry Andric { 2980b57cec5SDimitry Andric if (++__ptr_ - *__m_iter_ == __block_size) 2990b57cec5SDimitry Andric { 3000b57cec5SDimitry Andric ++__m_iter_; 3010b57cec5SDimitry Andric __ptr_ = *__m_iter_; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric return *this; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 306bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int) 3070b57cec5SDimitry Andric { 3080b57cec5SDimitry Andric __deque_iterator __tmp = *this; 3090b57cec5SDimitry Andric ++(*this); 3100b57cec5SDimitry Andric return __tmp; 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric 313bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--() 3140b57cec5SDimitry Andric { 3150b57cec5SDimitry Andric if (__ptr_ == *__m_iter_) 3160b57cec5SDimitry Andric { 3170b57cec5SDimitry Andric --__m_iter_; 3180b57cec5SDimitry Andric __ptr_ = *__m_iter_ + __block_size; 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric --__ptr_; 3210b57cec5SDimitry Andric return *this; 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric 324bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int) 3250b57cec5SDimitry Andric { 3260b57cec5SDimitry Andric __deque_iterator __tmp = *this; 3270b57cec5SDimitry Andric --(*this); 3280b57cec5SDimitry Andric return __tmp; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 331bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n) 3320b57cec5SDimitry Andric { 3330b57cec5SDimitry Andric if (__n != 0) 3340b57cec5SDimitry Andric { 3350b57cec5SDimitry Andric __n += __ptr_ - *__m_iter_; 3360b57cec5SDimitry Andric if (__n > 0) 3370b57cec5SDimitry Andric { 3380b57cec5SDimitry Andric __m_iter_ += __n / __block_size; 3390b57cec5SDimitry Andric __ptr_ = *__m_iter_ + __n % __block_size; 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric else // (__n < 0) 3420b57cec5SDimitry Andric { 3430b57cec5SDimitry Andric difference_type __z = __block_size - 1 - __n; 3440b57cec5SDimitry Andric __m_iter_ -= __z / __block_size; 3450b57cec5SDimitry Andric __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric return *this; 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric 351bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n) 3520b57cec5SDimitry Andric { 3530b57cec5SDimitry Andric return *this += -__n; 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric 356bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const 3570b57cec5SDimitry Andric { 3580b57cec5SDimitry Andric __deque_iterator __t(*this); 3590b57cec5SDimitry Andric __t += __n; 3600b57cec5SDimitry Andric return __t; 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 363bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const 3640b57cec5SDimitry Andric { 3650b57cec5SDimitry Andric __deque_iterator __t(*this); 3660b57cec5SDimitry Andric __t -= __n; 3670b57cec5SDimitry Andric return __t; 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric 370bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 3710b57cec5SDimitry Andric friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) 3720b57cec5SDimitry Andric {return __it + __n;} 3730b57cec5SDimitry Andric 374bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 3750b57cec5SDimitry Andric friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) 3760b57cec5SDimitry Andric { 3770b57cec5SDimitry Andric if (__x != __y) 3780b57cec5SDimitry Andric return (__x.__m_iter_ - __y.__m_iter_) * __block_size 3790b57cec5SDimitry Andric + (__x.__ptr_ - *__x.__m_iter_) 3800b57cec5SDimitry Andric - (__y.__ptr_ - *__y.__m_iter_); 3810b57cec5SDimitry Andric return 0; 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 384bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const 3850b57cec5SDimitry Andric {return *(*this + __n);} 3860b57cec5SDimitry Andric 387bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 3880b57cec5SDimitry Andric bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) 3890b57cec5SDimitry Andric {return __x.__ptr_ == __y.__ptr_;} 3900b57cec5SDimitry Andric 391bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 3920b57cec5SDimitry Andric bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) 3930b57cec5SDimitry Andric {return !(__x == __y);} 3940b57cec5SDimitry Andric 395bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 3960b57cec5SDimitry Andric bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) 3970b57cec5SDimitry Andric {return __x.__m_iter_ < __y.__m_iter_ || 3980b57cec5SDimitry Andric (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);} 3990b57cec5SDimitry Andric 400bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 4010b57cec5SDimitry Andric bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) 4020b57cec5SDimitry Andric {return __y < __x;} 4030b57cec5SDimitry Andric 404bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 4050b57cec5SDimitry Andric bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) 4060b57cec5SDimitry Andric {return !(__y < __x);} 4070b57cec5SDimitry Andric 408bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 4090b57cec5SDimitry Andric bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) 4100b57cec5SDimitry Andric {return !(__x < __y);} 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andricprivate: 413bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT 4140b57cec5SDimitry Andric : __m_iter_(__m), __ptr_(__p) {} 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque; 4170b57cec5SDimitry Andric template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp> 4180b57cec5SDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __deque_iterator; 4190b57cec5SDimitry Andric 420bdd1243dSDimitry Andric template <class> 421bdd1243dSDimitry Andric friend struct __segmented_iterator_traits; 422bdd1243dSDimitry Andric}; 4230b57cec5SDimitry Andric 424bdd1243dSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 425bdd1243dSDimitry Andricstruct __segmented_iterator_traits< 426bdd1243dSDimitry Andric __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > { 427bdd1243dSDimitry Andricprivate: 428bdd1243dSDimitry Andric using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; 4290b57cec5SDimitry Andric 430bdd1243dSDimitry Andricpublic: 431bdd1243dSDimitry Andric using __is_segmented_iterator = true_type; 432bdd1243dSDimitry Andric using __segment_iterator = _MapPointer; 433bdd1243dSDimitry Andric using __local_iterator = _Pointer; 4340b57cec5SDimitry Andric 435bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } 436bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } 437bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; } 4380b57cec5SDimitry Andric 439bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) { 440bdd1243dSDimitry Andric return *__iter + _Iterator::__block_size; 441bdd1243dSDimitry Andric } 4420b57cec5SDimitry Andric 443bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) { 444bdd1243dSDimitry Andric if (__local == __end(__segment)) { 445bdd1243dSDimitry Andric ++__segment; 446bdd1243dSDimitry Andric return _Iterator(__segment, *__segment); 447bdd1243dSDimitry Andric } 448bdd1243dSDimitry Andric return _Iterator(__segment, __local); 449bdd1243dSDimitry Andric } 4500b57cec5SDimitry Andric}; 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, 4530b57cec5SDimitry Andric class _DiffType, _DiffType _BlockSize> 4540b57cec5SDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, 4550b57cec5SDimitry Andric _DiffType, _BlockSize>::__block_size = 4560b57cec5SDimitry Andric __deque_block_size<_ValueType, _DiffType>::value; 4570b57cec5SDimitry Andric 458bdd1243dSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/> 459bdd1243dSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque 4600b57cec5SDimitry Andric{ 4610b57cec5SDimitry Andricpublic: 462bdd1243dSDimitry Andric // types: 463e40139ffSDimitry Andric 464bdd1243dSDimitry Andric using value_type = _Tp; 4650b57cec5SDimitry Andric 466bdd1243dSDimitry Andric static_assert((is_same<typename _Allocator::value_type, value_type>::value), 467bdd1243dSDimitry Andric "Allocator::value_type must be same type as value_type"); 4680b57cec5SDimitry Andric 469bdd1243dSDimitry Andric using allocator_type = _Allocator; 470bdd1243dSDimitry Andric using __alloc_traits = allocator_traits<allocator_type>; 4710b57cec5SDimitry Andric 472bdd1243dSDimitry Andric using size_type = typename __alloc_traits::size_type; 473bdd1243dSDimitry Andric using difference_type = typename __alloc_traits::difference_type; 4740b57cec5SDimitry Andric 475bdd1243dSDimitry Andric using pointer = typename __alloc_traits::pointer; 476bdd1243dSDimitry Andric using const_pointer = typename __alloc_traits::const_pointer; 477bdd1243dSDimitry Andric 478bdd1243dSDimitry Andric using __pointer_allocator = __rebind_alloc<__alloc_traits, pointer>; 479bdd1243dSDimitry Andric using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>; 480bdd1243dSDimitry Andric using __map = __split_buffer<pointer, __pointer_allocator>; 481bdd1243dSDimitry Andric using __map_alloc_traits = allocator_traits<__pointer_allocator>; 482bdd1243dSDimitry Andric using __map_pointer = typename __map_alloc_traits::pointer; 483bdd1243dSDimitry Andric using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer; 484*06c3fb27SDimitry Andric using __map_const_iterator = typename __map::const_iterator; 485bdd1243dSDimitry Andric 486bdd1243dSDimitry Andric using reference = value_type&; 487bdd1243dSDimitry Andric using const_reference = const value_type&; 488bdd1243dSDimitry Andric 489bdd1243dSDimitry Andric using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>; 490bdd1243dSDimitry Andric using const_iterator = 491bdd1243dSDimitry Andric __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>; 492bdd1243dSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 493bdd1243dSDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>; 494bdd1243dSDimitry Andric 495bdd1243dSDimitry Andric static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value, 496bdd1243dSDimitry Andric "[allocator.requirements] states that rebinding an allocator to the same type should result in the " 497bdd1243dSDimitry Andric "original allocator"); 498bdd1243dSDimitry Andric static_assert(is_nothrow_default_constructible<allocator_type>::value == 499bdd1243dSDimitry Andric is_nothrow_default_constructible<__pointer_allocator>::value, 500bdd1243dSDimitry Andric "rebinding an allocator should not change excpetion guarantees"); 501bdd1243dSDimitry Andric static_assert(is_nothrow_move_constructible<allocator_type>::value == 502bdd1243dSDimitry Andric is_nothrow_move_constructible<typename __map::allocator_type>::value, 503bdd1243dSDimitry Andric "rebinding an allocator should not change excpetion guarantees"); 504bdd1243dSDimitry Andric 505bdd1243dSDimitry Andricprivate: 506e40139ffSDimitry Andric struct __deque_block_range { 507bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI 508bdd1243dSDimitry Andric __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {} 509e40139ffSDimitry Andric const pointer __begin_; 510e40139ffSDimitry Andric const pointer __end_; 511e40139ffSDimitry Andric }; 512e40139ffSDimitry Andric 513e40139ffSDimitry Andric struct __deque_range { 514e40139ffSDimitry Andric iterator __pos_; 515e40139ffSDimitry Andric const iterator __end_; 516e40139ffSDimitry Andric 517bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT 518e40139ffSDimitry Andric : __pos_(__pos), __end_(__e) {} 519e40139ffSDimitry Andric 520bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { 521e40139ffSDimitry Andric return __pos_ != __end_; 522e40139ffSDimitry Andric } 523e40139ffSDimitry Andric 524bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { 525e40139ffSDimitry Andric return *this; 526e40139ffSDimitry Andric } 527e40139ffSDimitry Andric 528bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range end() const { 529e40139ffSDimitry Andric return __deque_range(__end_, __end_); 530e40139ffSDimitry Andric } 531bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT { 532e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 533e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, __end_.__ptr_); 534e40139ffSDimitry Andric } 535e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size); 536e40139ffSDimitry Andric } 537e40139ffSDimitry Andric 538bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT { 539e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 540e40139ffSDimitry Andric __pos_ = __end_; 541e40139ffSDimitry Andric } else { 542e40139ffSDimitry Andric ++__pos_.__m_iter_; 543e40139ffSDimitry Andric __pos_.__ptr_ = *__pos_.__m_iter_; 544e40139ffSDimitry Andric } 545e40139ffSDimitry Andric return *this; 546e40139ffSDimitry Andric } 547e40139ffSDimitry Andric 548e40139ffSDimitry Andric 549bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) { 550e40139ffSDimitry Andric return __lhs.__pos_ == __rhs.__pos_; 551e40139ffSDimitry Andric } 552bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) { 553e40139ffSDimitry Andric return !(__lhs == __rhs); 554e40139ffSDimitry Andric } 555e40139ffSDimitry Andric }; 556e40139ffSDimitry Andric 557e40139ffSDimitry Andric struct _ConstructTransaction { 558bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r) 559e40139ffSDimitry Andric : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} 560e40139ffSDimitry Andric 561e40139ffSDimitry Andric 562bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { 563bdd1243dSDimitry Andric __base_->__size() += (__pos_ - __begin_); 564e40139ffSDimitry Andric } 565e40139ffSDimitry Andric 566e40139ffSDimitry Andric pointer __pos_; 567e40139ffSDimitry Andric const pointer __end_; 568e40139ffSDimitry Andric private: 569e40139ffSDimitry Andric const pointer __begin_; 570bdd1243dSDimitry Andric deque* const __base_; 571e40139ffSDimitry Andric }; 572e40139ffSDimitry Andric 573bdd1243dSDimitry Andric static const difference_type __block_size; 574bdd1243dSDimitry Andric 5750b57cec5SDimitry Andric __map __map_; 5760b57cec5SDimitry Andric size_type __start_; 5770b57cec5SDimitry Andric __compressed_pair<size_type, allocator_type> __size_; 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andricpublic: 580bdd1243dSDimitry Andric 581bdd1243dSDimitry Andric // construct/copy/destroy: 582bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 583bdd1243dSDimitry Andric deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 584*06c3fb27SDimitry Andric : __start_(0), __size_(0, __default_init_tag()) { 585*06c3fb27SDimitry Andric __annotate_new(0); 586*06c3fb27SDimitry Andric } 587bdd1243dSDimitry Andric 588bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~deque() { 589bdd1243dSDimitry Andric clear(); 590*06c3fb27SDimitry Andric __annotate_delete(); 591bdd1243dSDimitry Andric typename __map::iterator __i = __map_.begin(); 592bdd1243dSDimitry Andric typename __map::iterator __e = __map_.end(); 593bdd1243dSDimitry Andric for (; __i != __e; ++__i) 594bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), *__i, __block_size); 595bdd1243dSDimitry Andric } 596bdd1243dSDimitry Andric 597bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) 598*06c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 599*06c3fb27SDimitry Andric __annotate_new(0); 600*06c3fb27SDimitry Andric } 601bdd1243dSDimitry Andric 602bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); 603*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 604bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); 605bdd1243dSDimitry Andric#endif 606bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); 607bdd1243dSDimitry Andric 608bdd1243dSDimitry Andric template <class = __enable_if_t<__is_allocator<_Allocator>::value> > 609bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) 610bdd1243dSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) 611bdd1243dSDimitry Andric { 612*06c3fb27SDimitry Andric __annotate_new(0); 613bdd1243dSDimitry Andric if (__n > 0) 614bdd1243dSDimitry Andric __append(__n, __v); 615bdd1243dSDimitry Andric } 616bdd1243dSDimitry Andric 617bdd1243dSDimitry Andric template <class _InputIter> 618bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, 619*06c3fb27SDimitry Andric typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0); 620bdd1243dSDimitry Andric template <class _InputIter> 621bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a, 622*06c3fb27SDimitry Andric typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0); 623*06c3fb27SDimitry Andric 624*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 625*06c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 626*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, 627*06c3fb27SDimitry Andric const allocator_type& __a = allocator_type()) 628*06c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 629*06c3fb27SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 630*06c3fb27SDimitry Andric __append_with_size(ranges::begin(__range), ranges::distance(__range)); 631*06c3fb27SDimitry Andric 632*06c3fb27SDimitry Andric } else { 633*06c3fb27SDimitry Andric for (auto&& __e : __range) { 634*06c3fb27SDimitry Andric emplace_back(std::forward<decltype(__e)>(__e)); 635*06c3fb27SDimitry Andric } 636*06c3fb27SDimitry Andric } 637*06c3fb27SDimitry Andric } 638*06c3fb27SDimitry Andric#endif 639*06c3fb27SDimitry Andric 640bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); 641bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); 642bdd1243dSDimitry Andric 643bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c); 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 646bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il); 647bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a); 648bdd1243dSDimitry Andric 649bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 650bdd1243dSDimitry Andric deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;} 651bdd1243dSDimitry Andric 652bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 653bdd1243dSDimitry Andric deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); 654bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 655bdd1243dSDimitry Andric deque(deque&& __c, const __type_identity_t<allocator_type>& __a); 656bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 657bdd1243dSDimitry Andric deque& operator=(deque&& __c) 658bdd1243dSDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && 659bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value); 660bdd1243dSDimitry Andric 661bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 662bdd1243dSDimitry Andric void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());} 6630b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 6640b57cec5SDimitry Andric 665bdd1243dSDimitry Andric template <class _InputIter> 666bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l, 667*06c3fb27SDimitry Andric typename enable_if<__has_input_iterator_category<_InputIter>::value && 668*06c3fb27SDimitry Andric !__has_random_access_iterator_category<_InputIter>::value>::type* = 0); 669bdd1243dSDimitry Andric template <class _RAIter> 670bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l, 671*06c3fb27SDimitry Andric typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type* = 0); 672*06c3fb27SDimitry Andric 673*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 674*06c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 675*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 676*06c3fb27SDimitry Andric void assign_range(_Range&& __range) { 677*06c3fb27SDimitry Andric if constexpr (ranges::random_access_range<_Range>) { 678*06c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 679*06c3fb27SDimitry Andric __assign_with_size_random_access(ranges::begin(__range), __n); 680*06c3fb27SDimitry Andric 681*06c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 682*06c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 683*06c3fb27SDimitry Andric __assign_with_size(ranges::begin(__range), __n); 684*06c3fb27SDimitry Andric 685*06c3fb27SDimitry Andric } else { 686*06c3fb27SDimitry Andric __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 687*06c3fb27SDimitry Andric } 688*06c3fb27SDimitry Andric } 689*06c3fb27SDimitry Andric#endif 690*06c3fb27SDimitry Andric 691bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); 692bdd1243dSDimitry Andric 693bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 694bdd1243dSDimitry Andric allocator_type get_allocator() const _NOEXCEPT; 695bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); } 696bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); } 697bdd1243dSDimitry Andric 698bdd1243dSDimitry Andric // iterators: 699bdd1243dSDimitry Andric 700bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { 701bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __start_ / __block_size; 702bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 703bdd1243dSDimitry Andric } 704bdd1243dSDimitry Andric 705bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { 706bdd1243dSDimitry Andric __map_const_pointer __mp = 707bdd1243dSDimitry Andric static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); 708bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 709bdd1243dSDimitry Andric } 710bdd1243dSDimitry Andric 711bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { 712bdd1243dSDimitry Andric size_type __p = size() + __start_; 713bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __p / __block_size; 714bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 715bdd1243dSDimitry Andric } 716bdd1243dSDimitry Andric 717bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { 718bdd1243dSDimitry Andric size_type __p = size() + __start_; 719bdd1243dSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); 720bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 721bdd1243dSDimitry Andric } 722bdd1243dSDimitry Andric 723bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 724bdd1243dSDimitry Andric reverse_iterator rbegin() _NOEXCEPT 725bdd1243dSDimitry Andric {return reverse_iterator(end());} 726bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 727bdd1243dSDimitry Andric const_reverse_iterator rbegin() const _NOEXCEPT 728bdd1243dSDimitry Andric {return const_reverse_iterator(end());} 729bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 730bdd1243dSDimitry Andric reverse_iterator rend() _NOEXCEPT 731bdd1243dSDimitry Andric {return reverse_iterator(begin());} 732bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 733bdd1243dSDimitry Andric const_reverse_iterator rend() const _NOEXCEPT 734bdd1243dSDimitry Andric {return const_reverse_iterator(begin());} 735bdd1243dSDimitry Andric 736bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 737bdd1243dSDimitry Andric const_iterator cbegin() const _NOEXCEPT 738bdd1243dSDimitry Andric {return begin();} 739bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 740bdd1243dSDimitry Andric const_iterator cend() const _NOEXCEPT 741bdd1243dSDimitry Andric {return end();} 742bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 743bdd1243dSDimitry Andric const_reverse_iterator crbegin() const _NOEXCEPT 744bdd1243dSDimitry Andric {return const_reverse_iterator(end());} 745bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 746bdd1243dSDimitry Andric const_reverse_iterator crend() const _NOEXCEPT 747bdd1243dSDimitry Andric {return const_reverse_iterator(begin());} 748bdd1243dSDimitry Andric 749bdd1243dSDimitry Andric // capacity: 750bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 751bdd1243dSDimitry Andric size_type size() const _NOEXCEPT {return __size();} 752bdd1243dSDimitry Andric 753bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); } 754bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); } 755bdd1243dSDimitry Andric 756bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 757bdd1243dSDimitry Andric size_type max_size() const _NOEXCEPT 758bdd1243dSDimitry Andric {return _VSTD::min<size_type>( 759bdd1243dSDimitry Andric __alloc_traits::max_size(__alloc()), 760bdd1243dSDimitry Andric numeric_limits<difference_type>::max());} 761bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); 762bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); 763bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; 764bdd1243dSDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 765bdd1243dSDimitry Andric bool empty() const _NOEXCEPT {return size() == 0;} 766bdd1243dSDimitry Andric 767bdd1243dSDimitry Andric // element access: 768bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 769bdd1243dSDimitry Andric reference operator[](size_type __i) _NOEXCEPT; 770bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 771bdd1243dSDimitry Andric const_reference operator[](size_type __i) const _NOEXCEPT; 772bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 773bdd1243dSDimitry Andric reference at(size_type __i); 774bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 775bdd1243dSDimitry Andric const_reference at(size_type __i) const; 776bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 777bdd1243dSDimitry Andric reference front() _NOEXCEPT; 778bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 779bdd1243dSDimitry Andric const_reference front() const _NOEXCEPT; 780bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 781bdd1243dSDimitry Andric reference back() _NOEXCEPT; 782bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 783bdd1243dSDimitry Andric const_reference back() const _NOEXCEPT; 784bdd1243dSDimitry Andric 785bdd1243dSDimitry Andric // 23.2.2.3 modifiers: 786bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); 787bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); 788bdd1243dSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 789*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 790bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); 791bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args); 792bdd1243dSDimitry Andric#else 793bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); 794bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI void emplace_back (_Args&&... __args); 795bdd1243dSDimitry Andric#endif 796bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); 797bdd1243dSDimitry Andric 798bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); 799bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v); 800*06c3fb27SDimitry Andric 801*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 802*06c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 803*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 804*06c3fb27SDimitry Andric void prepend_range(_Range&& __range) { 805*06c3fb27SDimitry Andric insert_range(begin(), std::forward<_Range>(__range)); 806*06c3fb27SDimitry Andric } 807*06c3fb27SDimitry Andric 808*06c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 809*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 810*06c3fb27SDimitry Andric void append_range(_Range&& __range) { 811*06c3fb27SDimitry Andric insert_range(end(), std::forward<_Range>(__range)); 812*06c3fb27SDimitry Andric } 813*06c3fb27SDimitry Andric#endif 814*06c3fb27SDimitry Andric 815bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v); 816bdd1243dSDimitry Andric 817bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 818bdd1243dSDimitry Andric iterator insert(const_iterator __p, initializer_list<value_type> __il) 819bdd1243dSDimitry Andric {return insert(__p, __il.begin(), __il.end());} 820bdd1243dSDimitry Andric#endif // _LIBCPP_CXX03_LANG 821bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v); 822bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); 823bdd1243dSDimitry Andric template <class _InputIter> 824bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l, 825*06c3fb27SDimitry Andric typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type* = 0); 826bdd1243dSDimitry Andric template <class _ForwardIterator> 827bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, 828*06c3fb27SDimitry Andric typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type* = 0); 829bdd1243dSDimitry Andric template <class _BiIter> 830bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l, 831*06c3fb27SDimitry Andric typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type* = 0); 832*06c3fb27SDimitry Andric 833*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 834*06c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 835*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 836*06c3fb27SDimitry Andric iterator insert_range(const_iterator __position, _Range&& __range) { 837*06c3fb27SDimitry Andric if constexpr (ranges::bidirectional_range<_Range>) { 838*06c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 839*06c3fb27SDimitry Andric return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n); 840*06c3fb27SDimitry Andric 841*06c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 842*06c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 843*06c3fb27SDimitry Andric return __insert_with_size(__position, ranges::begin(__range), __n); 844*06c3fb27SDimitry Andric 845*06c3fb27SDimitry Andric } else { 846*06c3fb27SDimitry Andric return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); 847*06c3fb27SDimitry Andric } 848*06c3fb27SDimitry Andric } 849*06c3fb27SDimitry Andric#endif 850bdd1243dSDimitry Andric 851bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_front(); 852bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_back(); 853bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); 854bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); 855bdd1243dSDimitry Andric 856bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 857bdd1243dSDimitry Andric void swap(deque& __c) 8580b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 8590b57cec5SDimitry Andric _NOEXCEPT; 8600b57cec5SDimitry Andric#else 8610b57cec5SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 8620b57cec5SDimitry Andric __is_nothrow_swappable<allocator_type>::value); 8630b57cec5SDimitry Andric#endif 864bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 8650b57cec5SDimitry Andric void clear() _NOEXCEPT; 8660b57cec5SDimitry Andric 867bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 868bdd1243dSDimitry Andric bool __invariants() const { 8690b57cec5SDimitry Andric if (!__map_.__invariants()) 8700b57cec5SDimitry Andric return false; 8710b57cec5SDimitry Andric if (__map_.size() >= size_type(-1) / __block_size) 8720b57cec5SDimitry Andric return false; 873*06c3fb27SDimitry Andric for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); 8740b57cec5SDimitry Andric __i != __e; ++__i) 8750b57cec5SDimitry Andric if (*__i == nullptr) 8760b57cec5SDimitry Andric return false; 8770b57cec5SDimitry Andric if (__map_.size() != 0) 8780b57cec5SDimitry Andric { 8790b57cec5SDimitry Andric if (size() >= __map_.size() * __block_size) 8800b57cec5SDimitry Andric return false; 8810b57cec5SDimitry Andric if (__start_ >= __map_.size() * __block_size - size()) 8820b57cec5SDimitry Andric return false; 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric else 8850b57cec5SDimitry Andric { 8860b57cec5SDimitry Andric if (size() != 0) 8870b57cec5SDimitry Andric return false; 8880b57cec5SDimitry Andric if (__start_ != 0) 8890b57cec5SDimitry Andric return false; 8900b57cec5SDimitry Andric } 8910b57cec5SDimitry Andric return true; 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric 894bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 895bdd1243dSDimitry Andric void __move_assign_alloc(deque& __c) 896bdd1243dSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || 897bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) 898bdd1243dSDimitry Andric {__move_assign_alloc(__c, integral_constant<bool, 899bdd1243dSDimitry Andric __alloc_traits::propagate_on_container_move_assignment::value>());} 900bdd1243dSDimitry Andric 901bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 902bdd1243dSDimitry Andric void __move_assign_alloc(deque& __c, true_type) 903bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 9040b57cec5SDimitry Andric { 905bdd1243dSDimitry Andric __alloc() = _VSTD::move(__c.__alloc()); 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric 908bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 909bdd1243dSDimitry Andric void __move_assign_alloc(deque&, false_type) _NOEXCEPT 9100b57cec5SDimitry Andric {} 9114824e7fdSDimitry Andric 912bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 913bdd1243dSDimitry Andric void __move_assign(deque& __c) 914bdd1243dSDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && 915bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) 9164824e7fdSDimitry Andric { 917bdd1243dSDimitry Andric __map_ = _VSTD::move(__c.__map_); 918bdd1243dSDimitry Andric __start_ = __c.__start_; 919bdd1243dSDimitry Andric __size() = __c.size(); 920bdd1243dSDimitry Andric __move_assign_alloc(__c); 921bdd1243dSDimitry Andric __c.__start_ = __c.__size() = 0; 9224824e7fdSDimitry Andric } 9234824e7fdSDimitry Andric 924bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 9250b57cec5SDimitry Andric static size_type __recommend_blocks(size_type __n) 9260b57cec5SDimitry Andric { 927bdd1243dSDimitry Andric return __n / __block_size + (__n % __block_size != 0); 9280b57cec5SDimitry Andric } 929bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 9300b57cec5SDimitry Andric size_type __capacity() const 9310b57cec5SDimitry Andric { 932bdd1243dSDimitry Andric return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1; 9330b57cec5SDimitry Andric } 934bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 935e40139ffSDimitry Andric size_type __block_count() const 936e40139ffSDimitry Andric { 937bdd1243dSDimitry Andric return __map_.size(); 938e40139ffSDimitry Andric } 939e40139ffSDimitry Andric 940bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 9410b57cec5SDimitry Andric size_type __front_spare() const 9420b57cec5SDimitry Andric { 943bdd1243dSDimitry Andric return __start_; 9440b57cec5SDimitry Andric } 945bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 946e40139ffSDimitry Andric size_type __front_spare_blocks() const { 947bdd1243dSDimitry Andric return __front_spare() / __block_size; 948e40139ffSDimitry Andric } 949bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 9500b57cec5SDimitry Andric size_type __back_spare() const 9510b57cec5SDimitry Andric { 952bdd1243dSDimitry Andric return __capacity() - (__start_ + size()); 9530b57cec5SDimitry Andric } 954bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 955e40139ffSDimitry Andric size_type __back_spare_blocks() const { 956bdd1243dSDimitry Andric return __back_spare() / __block_size; 957e40139ffSDimitry Andric } 958e40139ffSDimitry Andric 959e40139ffSDimitry Andric private: 960*06c3fb27SDimitry Andric enum __asan_annotation_type { 961*06c3fb27SDimitry Andric __asan_unposion, 962*06c3fb27SDimitry Andric __asan_poison 963*06c3fb27SDimitry Andric }; 964*06c3fb27SDimitry Andric 965*06c3fb27SDimitry Andric enum __asan_annotation_place { 966*06c3fb27SDimitry Andric __asan_front_moved, 967*06c3fb27SDimitry Andric __asan_back_moved, 968*06c3fb27SDimitry Andric }; 969*06c3fb27SDimitry Andric 970*06c3fb27SDimitry Andric// The following functions are no-ops outside of AddressSanitizer mode. 971*06c3fb27SDimitry Andric// We call annotations for every allocator, unless explicitly disabled. 972*06c3fb27SDimitry Andric// 973*06c3fb27SDimitry Andric// To disable annotations for a particular allocator, change value of 974*06c3fb27SDimitry Andric// __asan_annotate_container_with_allocator to false. 975*06c3fb27SDimitry Andric// For more details, see the "Using libc++" documentation page or 976*06c3fb27SDimitry Andric// the documentation for __sanitizer_annotate_contiguous_container. 977*06c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600 978*06c3fb27SDimitry Andric // TODO LLVM18: Remove the special-casing 979*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( 980*06c3fb27SDimitry Andric const void* __beg, 981*06c3fb27SDimitry Andric const void* __end, 982*06c3fb27SDimitry Andric const void* __old_con_beg, 983*06c3fb27SDimitry Andric const void* __old_con_end, 984*06c3fb27SDimitry Andric const void* __new_con_beg, 985*06c3fb27SDimitry Andric const void* __new_con_end) const { 986*06c3fb27SDimitry Andric if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value) 987*06c3fb27SDimitry Andric __sanitizer_annotate_double_ended_contiguous_container( 988*06c3fb27SDimitry Andric __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end); 989*06c3fb27SDimitry Andric } 990*06c3fb27SDimitry Andric#else 991*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( 992*06c3fb27SDimitry Andric const void*, const void*, const void*, const void*, const void*, const void*) const _NOEXCEPT {} 993*06c3fb27SDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600 994*06c3fb27SDimitry Andric 995*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 996*06c3fb27SDimitry Andric void __annotate_from_to(size_type __beg, size_type __end, __asan_annotation_type __annotation_type, __asan_annotation_place __place) const _NOEXCEPT { 997*06c3fb27SDimitry Andric // __beg - index of the first item to annotate 998*06c3fb27SDimitry Andric // __end - index behind the last item to annotate (so last item + 1) 999*06c3fb27SDimitry Andric // __annotation_type - __asan_unposion or __asan_poison 1000*06c3fb27SDimitry Andric // __place - __asan_front_moved or __asan_back_moved 1001*06c3fb27SDimitry Andric // Note: All indexes in __map_ 1002*06c3fb27SDimitry Andric if (__beg == __end) 1003*06c3fb27SDimitry Andric return; 1004*06c3fb27SDimitry Andric // __annotations_beg_map - first chunk which annotations we want to modify 1005*06c3fb27SDimitry Andric // __annotations_end_map - last chunk which annotations we want to modify 1006*06c3fb27SDimitry Andric // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist 1007*06c3fb27SDimitry Andric __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; 1008*06c3fb27SDimitry Andric __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; 1009*06c3fb27SDimitry Andric 1010*06c3fb27SDimitry Andric bool const __poisoning = __annotation_type == __asan_poison; 1011*06c3fb27SDimitry Andric // __old_c_beg_index - index of the first element in old container 1012*06c3fb27SDimitry Andric // __old_c_end_index - index of the end of old container (last + 1) 1013*06c3fb27SDimitry Andric // Note: may be outside the area we are annotating 1014*06c3fb27SDimitry Andric size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; 1015*06c3fb27SDimitry Andric size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); 1016*06c3fb27SDimitry Andric bool const __front = __place == __asan_front_moved; 1017*06c3fb27SDimitry Andric 1018*06c3fb27SDimitry Andric if (__poisoning && empty()) { 1019*06c3fb27SDimitry Andric // Special case: we shouldn't trust __start_ 1020*06c3fb27SDimitry Andric __old_c_beg_index = __beg; 1021*06c3fb27SDimitry Andric __old_c_end_index = __end; 1022*06c3fb27SDimitry Andric } 1023*06c3fb27SDimitry Andric // __old_c_beg_map - memory block (chunk) with first element 1024*06c3fb27SDimitry Andric // __old_c_end_map - memory block (chunk) with end of old container 1025*06c3fb27SDimitry Andric // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, 1026*06c3fb27SDimitry Andric // which may not exist 1027*06c3fb27SDimitry Andric __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; 1028*06c3fb27SDimitry Andric __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; 1029*06c3fb27SDimitry Andric 1030*06c3fb27SDimitry Andric // One edge (front/end) of the container was moved and one was not modified. 1031*06c3fb27SDimitry Andric // __new_edge_index - index of new edge 1032*06c3fb27SDimitry Andric // __new_edge_map - memory block (chunk) with new edge, it always equals to 1033*06c3fb27SDimitry Andric // __annotations_beg_map or __annotations_end_map 1034*06c3fb27SDimitry Andric // __old_edge_map - memory block (chunk) with old edge, it always equals to 1035*06c3fb27SDimitry Andric // __old_c_beg_map or __old_c_end_map 1036*06c3fb27SDimitry Andric size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; 1037*06c3fb27SDimitry Andric __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; 1038*06c3fb27SDimitry Andric __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; 1039*06c3fb27SDimitry Andric 1040*06c3fb27SDimitry Andric // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. 1041*06c3fb27SDimitry Andric // First and last chunk may be partially poisoned. 1042*06c3fb27SDimitry Andric // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. 1043*06c3fb27SDimitry Andric for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { 1044*06c3fb27SDimitry Andric if (__map_it == __annotations_end_map && __end % __block_size == 0) 1045*06c3fb27SDimitry Andric // Chunk may not exist, but nothing to do here anyway 1046*06c3fb27SDimitry Andric break; 1047*06c3fb27SDimitry Andric 1048*06c3fb27SDimitry Andric // The beginning and the end of the current memory block 1049*06c3fb27SDimitry Andric const void* __mem_beg = std::__to_address(*__map_it); 1050*06c3fb27SDimitry Andric const void* __mem_end = std::__to_address(*__map_it + __block_size); 1051*06c3fb27SDimitry Andric 1052*06c3fb27SDimitry Andric // The beginning of memory-in-use in the memory block before container modification 1053*06c3fb27SDimitry Andric const void* __old_beg = 1054*06c3fb27SDimitry Andric (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; 1055*06c3fb27SDimitry Andric 1056*06c3fb27SDimitry Andric // The end of memory-in-use in the memory block before container modification 1057*06c3fb27SDimitry Andric const void* __old_end; 1058*06c3fb27SDimitry Andric if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) 1059*06c3fb27SDimitry Andric __old_end = __old_beg; 1060*06c3fb27SDimitry Andric else 1061*06c3fb27SDimitry Andric __old_end = (__map_it == __old_c_end_map) ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) 1062*06c3fb27SDimitry Andric : __mem_end; 1063*06c3fb27SDimitry Andric 1064*06c3fb27SDimitry Andric // New edge of the container in current memory block 1065*06c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 1066*06c3fb27SDimitry Andric const void* __new_edge; 1067*06c3fb27SDimitry Andric if (__map_it == __new_edge_map) 1068*06c3fb27SDimitry Andric __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); 1069*06c3fb27SDimitry Andric else 1070*06c3fb27SDimitry Andric __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; 1071*06c3fb27SDimitry Andric 1072*06c3fb27SDimitry Andric // Not modified edge of the container 1073*06c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 1074*06c3fb27SDimitry Andric const void* __old_edge; 1075*06c3fb27SDimitry Andric if (__map_it == __old_edge_map) 1076*06c3fb27SDimitry Andric __old_edge = __front ? __old_end : __old_beg; 1077*06c3fb27SDimitry Andric else 1078*06c3fb27SDimitry Andric __old_edge = __front ? __mem_end : __mem_beg; 1079*06c3fb27SDimitry Andric 1080*06c3fb27SDimitry Andric // __new_beg - the beginning of memory-in-use in the memory block after container modification 1081*06c3fb27SDimitry Andric // __new_end - the end of memory-in-use in the memory block after container modification 1082*06c3fb27SDimitry Andric const void* __new_beg = __front ? __new_edge : __old_edge; 1083*06c3fb27SDimitry Andric const void* __new_end = __front ? __old_edge : __new_edge; 1084*06c3fb27SDimitry Andric 1085*06c3fb27SDimitry Andric __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); 1086*06c3fb27SDimitry Andric } 1087*06c3fb27SDimitry Andric } 1088*06c3fb27SDimitry Andric 1089*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1090*06c3fb27SDimitry Andric void __annotate_new(size_type __current_size) const _NOEXCEPT { 1091*06c3fb27SDimitry Andric if (__current_size == 0) 1092*06c3fb27SDimitry Andric __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 1093*06c3fb27SDimitry Andric else { 1094*06c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); 1095*06c3fb27SDimitry Andric __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 1096*06c3fb27SDimitry Andric } 1097*06c3fb27SDimitry Andric } 1098*06c3fb27SDimitry Andric 1099*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1100*06c3fb27SDimitry Andric void __annotate_delete() const _NOEXCEPT { 1101*06c3fb27SDimitry Andric if (empty()) { 1102*06c3fb27SDimitry Andric for(size_t __i = 0; __i < __map_.size(); ++__i) { 1103*06c3fb27SDimitry Andric __annotate_whole_block(__i, __asan_unposion); 1104*06c3fb27SDimitry Andric } 1105*06c3fb27SDimitry Andric } 1106*06c3fb27SDimitry Andric else { 1107*06c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); 1108*06c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); 1109*06c3fb27SDimitry Andric } 1110*06c3fb27SDimitry Andric } 1111*06c3fb27SDimitry Andric 1112*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1113*06c3fb27SDimitry Andric void __annotate_increase_front(size_type __n) const _NOEXCEPT { 1114*06c3fb27SDimitry Andric __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); 1115*06c3fb27SDimitry Andric } 1116*06c3fb27SDimitry Andric 1117*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1118*06c3fb27SDimitry Andric void __annotate_increase_back(size_type __n) const _NOEXCEPT { 1119*06c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); 1120*06c3fb27SDimitry Andric } 1121*06c3fb27SDimitry Andric 1122*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1123*06c3fb27SDimitry Andric void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { 1124*06c3fb27SDimitry Andric __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); 1125*06c3fb27SDimitry Andric } 1126*06c3fb27SDimitry Andric 1127*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1128*06c3fb27SDimitry Andric void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { 1129*06c3fb27SDimitry Andric __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); 1130*06c3fb27SDimitry Andric } 1131*06c3fb27SDimitry Andric 1132*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1133*06c3fb27SDimitry Andric void __annotate_poison_block(const void *__beginning, const void *__end) const _NOEXCEPT { 1134*06c3fb27SDimitry Andric __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end); 1135*06c3fb27SDimitry Andric } 1136*06c3fb27SDimitry Andric 1137*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1138*06c3fb27SDimitry Andric void __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { 1139*06c3fb27SDimitry Andric __map_const_iterator __block_it = __map_.begin() + __block_index; 1140*06c3fb27SDimitry Andric const void* __block_start = std::__to_address(*__block_it); 1141*06c3fb27SDimitry Andric const void* __block_end = std::__to_address(*__block_it + __block_size); 1142*06c3fb27SDimitry Andric 1143*06c3fb27SDimitry Andric if(__annotation_type == __asan_poison) 1144*06c3fb27SDimitry Andric __annotate_poison_block(__block_start, __block_end); 1145*06c3fb27SDimitry Andric else { 1146*06c3fb27SDimitry Andric __annotate_double_ended_contiguous_container( 1147*06c3fb27SDimitry Andric __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); 1148*06c3fb27SDimitry Andric } 1149*06c3fb27SDimitry Andric } 1150*06c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) 1151*06c3fb27SDimitry Andric 1152*06c3fb27SDimitry Andric public: 1153*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1154*06c3fb27SDimitry Andric bool __verify_asan_annotations() const _NOEXCEPT { 1155*06c3fb27SDimitry Andric // This function tests deque object annotations. 1156*06c3fb27SDimitry Andric if (empty()) { 1157*06c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 1158*06c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 1159*06c3fb27SDimitry Andric std::__to_address(*__it), 1160*06c3fb27SDimitry Andric std::__to_address(*__it), 1161*06c3fb27SDimitry Andric std::__to_address(*__it), 1162*06c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 1163*06c3fb27SDimitry Andric return false; 1164*06c3fb27SDimitry Andric } 1165*06c3fb27SDimitry Andric 1166*06c3fb27SDimitry Andric return true; 1167*06c3fb27SDimitry Andric } 1168*06c3fb27SDimitry Andric 1169*06c3fb27SDimitry Andric size_type __end = __start_ + size(); 1170*06c3fb27SDimitry Andric __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; 1171*06c3fb27SDimitry Andric __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; 1172*06c3fb27SDimitry Andric 1173*06c3fb27SDimitry Andric // Pointers to first and after last elements 1174*06c3fb27SDimitry Andric // Those can be in different deque blocks 1175*06c3fb27SDimitry Andric const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); 1176*06c3fb27SDimitry Andric const void* __p_end = 1177*06c3fb27SDimitry Andric std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); 1178*06c3fb27SDimitry Andric 1179*06c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 1180*06c3fb27SDimitry Andric // Go over all blocks, find the place we are in and verify its annotations 1181*06c3fb27SDimitry Andric // Note that __p_end points *behind* the last item. 1182*06c3fb27SDimitry Andric 1183*06c3fb27SDimitry Andric // - blocks before the first block with container elements 1184*06c3fb27SDimitry Andric // - first block with items 1185*06c3fb27SDimitry Andric // - last block with items 1186*06c3fb27SDimitry Andric // - blocks after last block with ciontainer elements 1187*06c3fb27SDimitry Andric 1188*06c3fb27SDimitry Andric // Is the block before or after deque blocks that contain elements? 1189*06c3fb27SDimitry Andric if (__it < __first_mp || __it > __last_mp) { 1190*06c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 1191*06c3fb27SDimitry Andric std::__to_address(*__it), 1192*06c3fb27SDimitry Andric std::__to_address(*__it), 1193*06c3fb27SDimitry Andric std::__to_address(*__it), 1194*06c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 1195*06c3fb27SDimitry Andric return false; 1196*06c3fb27SDimitry Andric } else { 1197*06c3fb27SDimitry Andric const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); 1198*06c3fb27SDimitry Andric const void* __containers_buffer_end = 1199*06c3fb27SDimitry Andric (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); 1200*06c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 1201*06c3fb27SDimitry Andric std::__to_address(*__it), 1202*06c3fb27SDimitry Andric __containers_buffer_beg, 1203*06c3fb27SDimitry Andric __containers_buffer_end, 1204*06c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) { 1205*06c3fb27SDimitry Andric return false; 1206*06c3fb27SDimitry Andric } 1207*06c3fb27SDimitry Andric } 1208*06c3fb27SDimitry Andric } 1209*06c3fb27SDimitry Andric return true; 1210*06c3fb27SDimitry Andric } 1211*06c3fb27SDimitry Andric 1212*06c3fb27SDimitry Andric private: 1213*06c3fb27SDimitry Andric#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS 1214bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 1215e40139ffSDimitry Andric bool __maybe_remove_front_spare(bool __keep_one = true) { 1216e40139ffSDimitry Andric if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { 1217*06c3fb27SDimitry Andric __annotate_whole_block(0, __asan_unposion); 1218bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.front(), 1219bdd1243dSDimitry Andric __block_size); 1220bdd1243dSDimitry Andric __map_.pop_front(); 1221bdd1243dSDimitry Andric __start_ -= __block_size; 1222e40139ffSDimitry Andric return true; 1223e40139ffSDimitry Andric } 1224e40139ffSDimitry Andric return false; 1225e40139ffSDimitry Andric } 1226e40139ffSDimitry Andric 1227bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 1228e40139ffSDimitry Andric bool __maybe_remove_back_spare(bool __keep_one = true) { 1229e40139ffSDimitry Andric if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { 1230*06c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_unposion); 1231bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.back(), 1232bdd1243dSDimitry Andric __block_size); 1233bdd1243dSDimitry Andric __map_.pop_back(); 1234e40139ffSDimitry Andric return true; 1235e40139ffSDimitry Andric } 1236e40139ffSDimitry Andric return false; 1237e40139ffSDimitry Andric } 12380b57cec5SDimitry Andric 1239*06c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1240*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1241*06c3fb27SDimitry Andric void __assign_with_sentinel(_Iterator __f, _Sentinel __l); 1242*06c3fb27SDimitry Andric 1243*06c3fb27SDimitry Andric template <class _RandomAccessIterator> 1244*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1245*06c3fb27SDimitry Andric void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); 1246*06c3fb27SDimitry Andric template <class _Iterator> 1247*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1248*06c3fb27SDimitry Andric void __assign_with_size(_Iterator __f, difference_type __n); 1249*06c3fb27SDimitry Andric 1250*06c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1251*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1252*06c3fb27SDimitry Andric iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); 1253*06c3fb27SDimitry Andric 1254*06c3fb27SDimitry Andric template <class _Iterator> 1255*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1256*06c3fb27SDimitry Andric iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); 1257*06c3fb27SDimitry Andric 1258*06c3fb27SDimitry Andric template <class _BiIter, class _Sentinel> 1259*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1260*06c3fb27SDimitry Andric iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); 1261*06c3fb27SDimitry Andric template <class _BiIter> 1262*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1263*06c3fb27SDimitry Andric iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); 1264*06c3fb27SDimitry Andric 12650b57cec5SDimitry Andric template <class _InpIter> 1266bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l, 1267*06c3fb27SDimitry Andric typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type* = 0); 12680b57cec5SDimitry Andric template <class _ForIter> 1269bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l, 1270*06c3fb27SDimitry Andric typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type* = 0); 1271*06c3fb27SDimitry Andric 1272*06c3fb27SDimitry Andric template <class _InputIterator> 1273*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); 1274*06c3fb27SDimitry Andric template <class _InputIterator, class _Sentinel> 1275*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); 1276*06c3fb27SDimitry Andric 1277bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); 1278bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); 1279bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); 1280bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(); 1281bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n); 1282bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(); 1283bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n); 1284bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, 12850b57cec5SDimitry Andric const_pointer& __vt); 1286bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r, 12870b57cec5SDimitry Andric const_pointer& __vt); 1288bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, 12890b57cec5SDimitry Andric iterator __r, const_pointer& __vt); 1290bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_construct_backward_and_check(iterator __f, iterator __l, 12910b57cec5SDimitry Andric iterator __r, const_pointer& __vt); 12920b57cec5SDimitry Andric 1293bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 12940b57cec5SDimitry Andric void __copy_assign_alloc(const deque& __c) 12950b57cec5SDimitry Andric {__copy_assign_alloc(__c, integral_constant<bool, 12960b57cec5SDimitry Andric __alloc_traits::propagate_on_container_copy_assignment::value>());} 12970b57cec5SDimitry Andric 1298bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 12990b57cec5SDimitry Andric void __copy_assign_alloc(const deque& __c, true_type) 13000b57cec5SDimitry Andric { 1301bdd1243dSDimitry Andric if (__alloc() != __c.__alloc()) 13020b57cec5SDimitry Andric { 13030b57cec5SDimitry Andric clear(); 13040b57cec5SDimitry Andric shrink_to_fit(); 13050b57cec5SDimitry Andric } 1306bdd1243dSDimitry Andric __alloc() = __c.__alloc(); 1307bdd1243dSDimitry Andric __map_.__alloc() = __c.__map_.__alloc(); 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric 1310bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 13110b57cec5SDimitry Andric void __copy_assign_alloc(const deque&, false_type) 13120b57cec5SDimitry Andric {} 13130b57cec5SDimitry Andric 1314bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type) 13150b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 1316bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type); 13170b57cec5SDimitry Andric}; 13180b57cec5SDimitry Andric 1319bdd1243dSDimitry Andrictemplate <class _Tp, class _Alloc> 1320bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size = 1321bdd1243dSDimitry Andric __deque_block_size<value_type, difference_type>::value; 1322bdd1243dSDimitry Andric 1323349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17 13240b57cec5SDimitry Andrictemplate<class _InputIterator, 1325fe6060f1SDimitry Andric class _Alloc = allocator<__iter_value_type<_InputIterator>>, 1326*06c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1327349cc55cSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> 13280b57cec5SDimitry Andric > 13290b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator) 1330fe6060f1SDimitry Andric -> deque<__iter_value_type<_InputIterator>, _Alloc>; 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andrictemplate<class _InputIterator, 13330b57cec5SDimitry Andric class _Alloc, 1334*06c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1335349cc55cSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> 13360b57cec5SDimitry Andric > 13370b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc) 1338fe6060f1SDimitry Andric -> deque<__iter_value_type<_InputIterator>, _Alloc>; 13390b57cec5SDimitry Andric#endif 13400b57cec5SDimitry Andric 1341*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 1342*06c3fb27SDimitry Andrictemplate <ranges::input_range _Range, 1343*06c3fb27SDimitry Andric class _Alloc = allocator<ranges::range_value_t<_Range>>, 1344*06c3fb27SDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> 1345*06c3fb27SDimitry Andric > 1346*06c3fb27SDimitry Andricdeque(from_range_t, _Range&&, _Alloc = _Alloc()) 1347*06c3fb27SDimitry Andric -> deque<ranges::range_value_t<_Range>, _Alloc>; 1348*06c3fb27SDimitry Andric#endif 1349*06c3fb27SDimitry Andric 13500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13510b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n) 1352bdd1243dSDimitry Andric : __start_(0), __size_(0, __default_init_tag()) 13530b57cec5SDimitry Andric{ 1354*06c3fb27SDimitry Andric __annotate_new(0); 13550b57cec5SDimitry Andric if (__n > 0) 13560b57cec5SDimitry Andric __append(__n); 13570b57cec5SDimitry Andric} 13580b57cec5SDimitry Andric 1359*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 13600b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13610b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) 1362bdd1243dSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) 13630b57cec5SDimitry Andric{ 1364*06c3fb27SDimitry Andric __annotate_new(0); 13650b57cec5SDimitry Andric if (__n > 0) 13660b57cec5SDimitry Andric __append(__n); 13670b57cec5SDimitry Andric} 13680b57cec5SDimitry Andric#endif 13690b57cec5SDimitry Andric 13700b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13710b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) 1372bdd1243dSDimitry Andric : __start_(0), __size_(0, __default_init_tag()) 13730b57cec5SDimitry Andric{ 1374*06c3fb27SDimitry Andric __annotate_new(0); 13750b57cec5SDimitry Andric if (__n > 0) 13760b57cec5SDimitry Andric __append(__n, __v); 13770b57cec5SDimitry Andric} 13780b57cec5SDimitry Andric 13790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13800b57cec5SDimitry Andrictemplate <class _InputIter> 13810b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, 1382*06c3fb27SDimitry Andric typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*) 1383bdd1243dSDimitry Andric : __start_(0), __size_(0, __default_init_tag()) 13840b57cec5SDimitry Andric{ 1385*06c3fb27SDimitry Andric __annotate_new(0); 13860b57cec5SDimitry Andric __append(__f, __l); 13870b57cec5SDimitry Andric} 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13900b57cec5SDimitry Andrictemplate <class _InputIter> 13910b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a, 1392*06c3fb27SDimitry Andric typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*) 1393bdd1243dSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) 13940b57cec5SDimitry Andric{ 1395*06c3fb27SDimitry Andric __annotate_new(0); 13960b57cec5SDimitry Andric __append(__f, __l); 13970b57cec5SDimitry Andric} 13980b57cec5SDimitry Andric 13990b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14000b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c) 1401bdd1243dSDimitry Andric : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))), 1402bdd1243dSDimitry Andric __start_(0), 1403bdd1243dSDimitry Andric __size_(0, __map_.__alloc()) 14040b57cec5SDimitry Andric{ 1405*06c3fb27SDimitry Andric __annotate_new(0); 14060b57cec5SDimitry Andric __append(__c.begin(), __c.end()); 14070b57cec5SDimitry Andric} 14080b57cec5SDimitry Andric 14090b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 141081ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a) 1411bdd1243dSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) 14120b57cec5SDimitry Andric{ 1413*06c3fb27SDimitry Andric __annotate_new(0); 14140b57cec5SDimitry Andric __append(__c.begin(), __c.end()); 14150b57cec5SDimitry Andric} 14160b57cec5SDimitry Andric 14170b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14180b57cec5SDimitry Andricdeque<_Tp, _Allocator>& 14190b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator=(const deque& __c) 14200b57cec5SDimitry Andric{ 1421349cc55cSDimitry Andric if (this != _VSTD::addressof(__c)) 14220b57cec5SDimitry Andric { 14230b57cec5SDimitry Andric __copy_assign_alloc(__c); 14240b57cec5SDimitry Andric assign(__c.begin(), __c.end()); 14250b57cec5SDimitry Andric } 14260b57cec5SDimitry Andric return *this; 14270b57cec5SDimitry Andric} 14280b57cec5SDimitry Andric 14290b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 14300b57cec5SDimitry Andric 14310b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14320b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il) 1433bdd1243dSDimitry Andric : __start_(0), __size_(0, __default_init_tag()) 14340b57cec5SDimitry Andric{ 1435*06c3fb27SDimitry Andric __annotate_new(0); 14360b57cec5SDimitry Andric __append(__il.begin(), __il.end()); 14370b57cec5SDimitry Andric} 14380b57cec5SDimitry Andric 14390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14400b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a) 1441bdd1243dSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) 14420b57cec5SDimitry Andric{ 1443*06c3fb27SDimitry Andric __annotate_new(0); 14440b57cec5SDimitry Andric __append(__il.begin(), __il.end()); 14450b57cec5SDimitry Andric} 14460b57cec5SDimitry Andric 14470b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14480b57cec5SDimitry Andricinline 14490b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(deque&& __c) 1450bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 1451bdd1243dSDimitry Andric : __map_(std::move(__c.__map_)), __start_(std::move(__c.__start_)), __size_(std::move(__c.__size_)) 14520b57cec5SDimitry Andric{ 1453bdd1243dSDimitry Andric __c.__start_ = 0; 1454bdd1243dSDimitry Andric __c.__size() = 0; 14550b57cec5SDimitry Andric} 14560b57cec5SDimitry Andric 14570b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14580b57cec5SDimitry Andricinline 145981ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a) 1460bdd1243dSDimitry Andric : __map_(std::move(__c.__map_), __pointer_allocator(__a)), 1461bdd1243dSDimitry Andric __start_(std::move(__c.__start_)), 1462bdd1243dSDimitry Andric __size_(std::move(__c.__size()), __a) 14630b57cec5SDimitry Andric{ 1464bdd1243dSDimitry Andric if (__a == __c.__alloc()) 14650b57cec5SDimitry Andric { 1466bdd1243dSDimitry Andric __c.__start_ = 0; 1467bdd1243dSDimitry Andric __c.__size() = 0; 1468bdd1243dSDimitry Andric } 1469bdd1243dSDimitry Andric else 1470bdd1243dSDimitry Andric { 1471bdd1243dSDimitry Andric __map_.clear(); 1472bdd1243dSDimitry Andric __start_ = 0; 1473bdd1243dSDimitry Andric __size() = 0; 14740b57cec5SDimitry Andric typedef move_iterator<iterator> _Ip; 14750b57cec5SDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end())); 14760b57cec5SDimitry Andric } 14770b57cec5SDimitry Andric} 14780b57cec5SDimitry Andric 14790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14800b57cec5SDimitry Andricinline 14810b57cec5SDimitry Andricdeque<_Tp, _Allocator>& 14820b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator=(deque&& __c) 14830b57cec5SDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && 14840b57cec5SDimitry Andric is_nothrow_move_assignable<allocator_type>::value) 14850b57cec5SDimitry Andric{ 14860b57cec5SDimitry Andric __move_assign(__c, integral_constant<bool, 14870b57cec5SDimitry Andric __alloc_traits::propagate_on_container_move_assignment::value>()); 14880b57cec5SDimitry Andric return *this; 14890b57cec5SDimitry Andric} 14900b57cec5SDimitry Andric 14910b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14920b57cec5SDimitry Andricvoid 14930b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) 14940b57cec5SDimitry Andric{ 1495bdd1243dSDimitry Andric if (__alloc() != __c.__alloc()) 14960b57cec5SDimitry Andric { 14970b57cec5SDimitry Andric typedef move_iterator<iterator> _Ip; 14980b57cec5SDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end())); 14990b57cec5SDimitry Andric } 15000b57cec5SDimitry Andric else 15010b57cec5SDimitry Andric __move_assign(__c, true_type()); 15020b57cec5SDimitry Andric} 15030b57cec5SDimitry Andric 15040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15050b57cec5SDimitry Andricvoid 15060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_assign(deque& __c, true_type) 15070b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 15080b57cec5SDimitry Andric{ 15090b57cec5SDimitry Andric clear(); 15100b57cec5SDimitry Andric shrink_to_fit(); 1511bdd1243dSDimitry Andric __move_assign(__c); 15120b57cec5SDimitry Andric} 15130b57cec5SDimitry Andric 15140b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 15150b57cec5SDimitry Andric 15160b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15170b57cec5SDimitry Andrictemplate <class _InputIter> 15180b57cec5SDimitry Andricvoid 15190b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l, 1520*06c3fb27SDimitry Andric typename enable_if<__has_input_iterator_category<_InputIter>::value && 1521*06c3fb27SDimitry Andric !__has_random_access_iterator_category<_InputIter>::value>::type*) 15220b57cec5SDimitry Andric{ 1523*06c3fb27SDimitry Andric __assign_with_sentinel(__f, __l); 1524*06c3fb27SDimitry Andric} 1525*06c3fb27SDimitry Andric 1526*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 1527*06c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 1528*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 1529*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { 1530bdd1243dSDimitry Andric iterator __i = begin(); 1531bdd1243dSDimitry Andric iterator __e = end(); 15320b57cec5SDimitry Andric for (; __f != __l && __i != __e; ++__f, (void) ++__i) 15330b57cec5SDimitry Andric *__i = *__f; 15340b57cec5SDimitry Andric if (__f != __l) 1535*06c3fb27SDimitry Andric __append_with_sentinel(std::move(__f), std::move(__l)); 15360b57cec5SDimitry Andric else 15370b57cec5SDimitry Andric __erase_to_end(__i); 15380b57cec5SDimitry Andric} 15390b57cec5SDimitry Andric 15400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15410b57cec5SDimitry Andrictemplate <class _RAIter> 15420b57cec5SDimitry Andricvoid 15430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l, 1544*06c3fb27SDimitry Andric typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type*) 15450b57cec5SDimitry Andric{ 1546*06c3fb27SDimitry Andric __assign_with_size_random_access(__f, __l - __f); 1547*06c3fb27SDimitry Andric} 1548*06c3fb27SDimitry Andric 1549*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 1550*06c3fb27SDimitry Andrictemplate <class _RandomAccessIterator> 1551*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 1552*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { 1553*06c3fb27SDimitry Andric if (static_cast<size_type>(__n) > size()) 15540b57cec5SDimitry Andric { 1555*06c3fb27SDimitry Andric auto __l = __f + size(); 1556*06c3fb27SDimitry Andric std::copy(__f, __l, begin()); 1557*06c3fb27SDimitry Andric __append_with_size(__l, __n - size()); 15580b57cec5SDimitry Andric } 15590b57cec5SDimitry Andric else 1560*06c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 1561*06c3fb27SDimitry Andric} 1562*06c3fb27SDimitry Andric 1563*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 1564*06c3fb27SDimitry Andrictemplate <class _Iterator> 1565*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 1566*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { 1567*06c3fb27SDimitry Andric if (static_cast<size_type>(__n) > size()) { 1568*06c3fb27SDimitry Andric auto __added_size = __n - size(); 1569*06c3fb27SDimitry Andric 1570*06c3fb27SDimitry Andric auto __i = begin(); 1571*06c3fb27SDimitry Andric for (auto __count = size(); __count != 0; --__count) { 1572*06c3fb27SDimitry Andric *__i++ = *__f++; 1573*06c3fb27SDimitry Andric } 1574*06c3fb27SDimitry Andric 1575*06c3fb27SDimitry Andric __append_with_size(__f, __added_size); 1576*06c3fb27SDimitry Andric 1577*06c3fb27SDimitry Andric } else { 1578*06c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 1579*06c3fb27SDimitry Andric } 15800b57cec5SDimitry Andric} 15810b57cec5SDimitry Andric 15820b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15830b57cec5SDimitry Andricvoid 15840b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) 15850b57cec5SDimitry Andric{ 1586bdd1243dSDimitry Andric if (__n > size()) 15870b57cec5SDimitry Andric { 1588bdd1243dSDimitry Andric _VSTD::fill_n(begin(), size(), __v); 1589bdd1243dSDimitry Andric __n -= size(); 15900b57cec5SDimitry Andric __append(__n, __v); 15910b57cec5SDimitry Andric } 15920b57cec5SDimitry Andric else 1593bdd1243dSDimitry Andric __erase_to_end(_VSTD::fill_n(begin(), __n, __v)); 15940b57cec5SDimitry Andric} 15950b57cec5SDimitry Andric 15960b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15970b57cec5SDimitry Andricinline 15980b57cec5SDimitry Andric_Allocator 15990b57cec5SDimitry Andricdeque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT 16000b57cec5SDimitry Andric{ 1601bdd1243dSDimitry Andric return __alloc(); 16020b57cec5SDimitry Andric} 16030b57cec5SDimitry Andric 16040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16050b57cec5SDimitry Andricvoid 16060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n) 16070b57cec5SDimitry Andric{ 1608bdd1243dSDimitry Andric if (__n > size()) 1609bdd1243dSDimitry Andric __append(__n - size()); 1610bdd1243dSDimitry Andric else if (__n < size()) 1611bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 16120b57cec5SDimitry Andric} 16130b57cec5SDimitry Andric 16140b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16150b57cec5SDimitry Andricvoid 16160b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) 16170b57cec5SDimitry Andric{ 1618bdd1243dSDimitry Andric if (__n > size()) 1619bdd1243dSDimitry Andric __append(__n - size(), __v); 1620bdd1243dSDimitry Andric else if (__n < size()) 1621bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 16220b57cec5SDimitry Andric} 16230b57cec5SDimitry Andric 16240b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16250b57cec5SDimitry Andricvoid 16260b57cec5SDimitry Andricdeque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT 16270b57cec5SDimitry Andric{ 1628bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 16290b57cec5SDimitry Andric if (empty()) 16300b57cec5SDimitry Andric { 1631*06c3fb27SDimitry Andric __annotate_delete(); 1632bdd1243dSDimitry Andric while (__map_.size() > 0) 16330b57cec5SDimitry Andric { 1634bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.back(), __block_size); 1635bdd1243dSDimitry Andric __map_.pop_back(); 16360b57cec5SDimitry Andric } 1637bdd1243dSDimitry Andric __start_ = 0; 16380b57cec5SDimitry Andric } 16390b57cec5SDimitry Andric else 16400b57cec5SDimitry Andric { 1641e40139ffSDimitry Andric __maybe_remove_front_spare(/*__keep_one=*/false); 1642e40139ffSDimitry Andric __maybe_remove_back_spare(/*__keep_one=*/false); 16430b57cec5SDimitry Andric } 1644bdd1243dSDimitry Andric __map_.shrink_to_fit(); 16450b57cec5SDimitry Andric} 16460b57cec5SDimitry Andric 16470b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16480b57cec5SDimitry Andricinline 16490b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 16500b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT 16510b57cec5SDimitry Andric{ 1652bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1653bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 16540b57cec5SDimitry Andric} 16550b57cec5SDimitry Andric 16560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16570b57cec5SDimitry Andricinline 16580b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference 16590b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT 16600b57cec5SDimitry Andric{ 1661bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1662bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 16630b57cec5SDimitry Andric} 16640b57cec5SDimitry Andric 16650b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16660b57cec5SDimitry Andricinline 16670b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 16680b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i) 16690b57cec5SDimitry Andric{ 1670bdd1243dSDimitry Andric if (__i >= size()) 1671349cc55cSDimitry Andric _VSTD::__throw_out_of_range("deque"); 1672bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1673bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 16740b57cec5SDimitry Andric} 16750b57cec5SDimitry Andric 16760b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16770b57cec5SDimitry Andricinline 16780b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference 16790b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i) const 16800b57cec5SDimitry Andric{ 1681bdd1243dSDimitry Andric if (__i >= size()) 1682349cc55cSDimitry Andric _VSTD::__throw_out_of_range("deque"); 1683bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1684bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 16850b57cec5SDimitry Andric} 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16880b57cec5SDimitry Andricinline 16890b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 16900b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() _NOEXCEPT 16910b57cec5SDimitry Andric{ 1692bdd1243dSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) 1693bdd1243dSDimitry Andric + __start_ % __block_size); 16940b57cec5SDimitry Andric} 16950b57cec5SDimitry Andric 16960b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16970b57cec5SDimitry Andricinline 16980b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference 16990b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() const _NOEXCEPT 17000b57cec5SDimitry Andric{ 1701bdd1243dSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) 1702bdd1243dSDimitry Andric + __start_ % __block_size); 17030b57cec5SDimitry Andric} 17040b57cec5SDimitry Andric 17050b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17060b57cec5SDimitry Andricinline 17070b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 17080b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() _NOEXCEPT 17090b57cec5SDimitry Andric{ 1710bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1711bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 17120b57cec5SDimitry Andric} 17130b57cec5SDimitry Andric 17140b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17150b57cec5SDimitry Andricinline 17160b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference 17170b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() const _NOEXCEPT 17180b57cec5SDimitry Andric{ 1719bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1720bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 17210b57cec5SDimitry Andric} 17220b57cec5SDimitry Andric 17230b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17240b57cec5SDimitry Andricvoid 17250b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(const value_type& __v) 17260b57cec5SDimitry Andric{ 1727bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17280b57cec5SDimitry Andric if (__back_spare() == 0) 17290b57cec5SDimitry Andric __add_back_capacity(); 17300b57cec5SDimitry Andric // __back_spare() >= 1 1731*06c3fb27SDimitry Andric __annotate_increase_back(1); 1732bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v); 1733bdd1243dSDimitry Andric ++__size(); 17340b57cec5SDimitry Andric} 17350b57cec5SDimitry Andric 17360b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17370b57cec5SDimitry Andricvoid 17380b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(const value_type& __v) 17390b57cec5SDimitry Andric{ 1740bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17410b57cec5SDimitry Andric if (__front_spare() == 0) 17420b57cec5SDimitry Andric __add_front_capacity(); 17430b57cec5SDimitry Andric // __front_spare() >= 1 1744*06c3fb27SDimitry Andric __annotate_increase_front(1); 1745bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v); 1746bdd1243dSDimitry Andric --__start_; 1747bdd1243dSDimitry Andric ++__size(); 17480b57cec5SDimitry Andric} 17490b57cec5SDimitry Andric 17500b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 17510b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17520b57cec5SDimitry Andricvoid 17530b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(value_type&& __v) 17540b57cec5SDimitry Andric{ 1755bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17560b57cec5SDimitry Andric if (__back_spare() == 0) 17570b57cec5SDimitry Andric __add_back_capacity(); 17580b57cec5SDimitry Andric // __back_spare() >= 1 1759*06c3fb27SDimitry Andric __annotate_increase_back(1); 1760bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v)); 1761bdd1243dSDimitry Andric ++__size(); 17620b57cec5SDimitry Andric} 17630b57cec5SDimitry Andric 17640b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17650b57cec5SDimitry Andrictemplate <class... _Args> 1766*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 17670b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 17680b57cec5SDimitry Andric#else 17690b57cec5SDimitry Andricvoid 17700b57cec5SDimitry Andric#endif 17710b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_back(_Args&&... __args) 17720b57cec5SDimitry Andric{ 1773bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17740b57cec5SDimitry Andric if (__back_spare() == 0) 17750b57cec5SDimitry Andric __add_back_capacity(); 17760b57cec5SDimitry Andric // __back_spare() >= 1 1777*06c3fb27SDimitry Andric __annotate_increase_back(1); 1778bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*end()), 17790b57cec5SDimitry Andric _VSTD::forward<_Args>(__args)...); 1780bdd1243dSDimitry Andric ++__size(); 1781*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 1782bdd1243dSDimitry Andric return *--end(); 17830b57cec5SDimitry Andric#endif 17840b57cec5SDimitry Andric} 17850b57cec5SDimitry Andric 17860b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17870b57cec5SDimitry Andricvoid 17880b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(value_type&& __v) 17890b57cec5SDimitry Andric{ 1790bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17910b57cec5SDimitry Andric if (__front_spare() == 0) 17920b57cec5SDimitry Andric __add_front_capacity(); 17930b57cec5SDimitry Andric // __front_spare() >= 1 1794*06c3fb27SDimitry Andric __annotate_increase_front(1); 1795bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v)); 1796bdd1243dSDimitry Andric --__start_; 1797bdd1243dSDimitry Andric ++__size(); 17980b57cec5SDimitry Andric} 17990b57cec5SDimitry Andric 18000b57cec5SDimitry Andric 18010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18020b57cec5SDimitry Andrictemplate <class... _Args> 1803*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 18040b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 18050b57cec5SDimitry Andric#else 18060b57cec5SDimitry Andricvoid 18070b57cec5SDimitry Andric#endif 18080b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_front(_Args&&... __args) 18090b57cec5SDimitry Andric{ 1810bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 18110b57cec5SDimitry Andric if (__front_spare() == 0) 18120b57cec5SDimitry Andric __add_front_capacity(); 18130b57cec5SDimitry Andric // __front_spare() >= 1 1814*06c3fb27SDimitry Andric __annotate_increase_front(1); 1815bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...); 1816bdd1243dSDimitry Andric --__start_; 1817bdd1243dSDimitry Andric ++__size(); 1818*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 1819bdd1243dSDimitry Andric return *begin(); 18200b57cec5SDimitry Andric#endif 18210b57cec5SDimitry Andric} 18220b57cec5SDimitry Andric 18230b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18240b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 18250b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) 18260b57cec5SDimitry Andric{ 1827bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1828bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1829bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 18300b57cec5SDimitry Andric if (__pos < __to_end) 18310b57cec5SDimitry Andric { // insert by shifting things backward 18320b57cec5SDimitry Andric if (__front_spare() == 0) 18330b57cec5SDimitry Andric __add_front_capacity(); 18340b57cec5SDimitry Andric // __front_spare() >= 1 1835*06c3fb27SDimitry Andric __annotate_increase_front(1); 18360b57cec5SDimitry Andric if (__pos == 0) 18370b57cec5SDimitry Andric { 1838bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v)); 1839bdd1243dSDimitry Andric --__start_; 1840bdd1243dSDimitry Andric ++__size(); 18410b57cec5SDimitry Andric } 18420b57cec5SDimitry Andric else 18430b57cec5SDimitry Andric { 1844bdd1243dSDimitry Andric iterator __b = begin(); 18450b57cec5SDimitry Andric iterator __bm1 = _VSTD::prev(__b); 18460b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); 1847bdd1243dSDimitry Andric --__start_; 1848bdd1243dSDimitry Andric ++__size(); 18490b57cec5SDimitry Andric if (__pos > 1) 18500b57cec5SDimitry Andric __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); 18510b57cec5SDimitry Andric *__b = _VSTD::move(__v); 18520b57cec5SDimitry Andric } 18530b57cec5SDimitry Andric } 18540b57cec5SDimitry Andric else 18550b57cec5SDimitry Andric { // insert by shifting things forward 18560b57cec5SDimitry Andric if (__back_spare() == 0) 18570b57cec5SDimitry Andric __add_back_capacity(); 18580b57cec5SDimitry Andric // __back_capacity >= 1 1859*06c3fb27SDimitry Andric __annotate_increase_back(1); 1860bdd1243dSDimitry Andric size_type __de = size() - __pos; 18610b57cec5SDimitry Andric if (__de == 0) 18620b57cec5SDimitry Andric { 1863bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v)); 1864bdd1243dSDimitry Andric ++__size(); 18650b57cec5SDimitry Andric } 18660b57cec5SDimitry Andric else 18670b57cec5SDimitry Andric { 1868bdd1243dSDimitry Andric iterator __e = end(); 18690b57cec5SDimitry Andric iterator __em1 = _VSTD::prev(__e); 18700b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); 1871bdd1243dSDimitry Andric ++__size(); 18720b57cec5SDimitry Andric if (__de > 1) 18730b57cec5SDimitry Andric __e = _VSTD::move_backward(__e - __de, __em1, __e); 18740b57cec5SDimitry Andric *--__e = _VSTD::move(__v); 18750b57cec5SDimitry Andric } 18760b57cec5SDimitry Andric } 1877bdd1243dSDimitry Andric return begin() + __pos; 18780b57cec5SDimitry Andric} 18790b57cec5SDimitry Andric 18800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18810b57cec5SDimitry Andrictemplate <class... _Args> 18820b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 18830b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) 18840b57cec5SDimitry Andric{ 1885bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1886bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1887bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 18880b57cec5SDimitry Andric if (__pos < __to_end) 18890b57cec5SDimitry Andric { // insert by shifting things backward 18900b57cec5SDimitry Andric if (__front_spare() == 0) 18910b57cec5SDimitry Andric __add_front_capacity(); 18920b57cec5SDimitry Andric // __front_spare() >= 1 1893*06c3fb27SDimitry Andric __annotate_increase_front(1); 18940b57cec5SDimitry Andric if (__pos == 0) 18950b57cec5SDimitry Andric { 1896bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...); 1897bdd1243dSDimitry Andric --__start_; 1898bdd1243dSDimitry Andric ++__size(); 18990b57cec5SDimitry Andric } 19000b57cec5SDimitry Andric else 19010b57cec5SDimitry Andric { 1902bdd1243dSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), _VSTD::forward<_Args>(__args)...); 1903bdd1243dSDimitry Andric iterator __b = begin(); 19040b57cec5SDimitry Andric iterator __bm1 = _VSTD::prev(__b); 19050b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); 1906bdd1243dSDimitry Andric --__start_; 1907bdd1243dSDimitry Andric ++__size(); 19080b57cec5SDimitry Andric if (__pos > 1) 19090b57cec5SDimitry Andric __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); 19100b57cec5SDimitry Andric *__b = _VSTD::move(__tmp.get()); 19110b57cec5SDimitry Andric } 19120b57cec5SDimitry Andric } 19130b57cec5SDimitry Andric else 19140b57cec5SDimitry Andric { // insert by shifting things forward 19150b57cec5SDimitry Andric if (__back_spare() == 0) 19160b57cec5SDimitry Andric __add_back_capacity(); 19170b57cec5SDimitry Andric // __back_capacity >= 1 1918*06c3fb27SDimitry Andric __annotate_increase_back(1); 1919bdd1243dSDimitry Andric size_type __de = size() - __pos; 19200b57cec5SDimitry Andric if (__de == 0) 19210b57cec5SDimitry Andric { 1922bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::forward<_Args>(__args)...); 1923bdd1243dSDimitry Andric ++__size(); 19240b57cec5SDimitry Andric } 19250b57cec5SDimitry Andric else 19260b57cec5SDimitry Andric { 1927bdd1243dSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), _VSTD::forward<_Args>(__args)...); 1928bdd1243dSDimitry Andric iterator __e = end(); 19290b57cec5SDimitry Andric iterator __em1 = _VSTD::prev(__e); 19300b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); 1931bdd1243dSDimitry Andric ++__size(); 19320b57cec5SDimitry Andric if (__de > 1) 19330b57cec5SDimitry Andric __e = _VSTD::move_backward(__e - __de, __em1, __e); 19340b57cec5SDimitry Andric *--__e = _VSTD::move(__tmp.get()); 19350b57cec5SDimitry Andric } 19360b57cec5SDimitry Andric } 1937bdd1243dSDimitry Andric return begin() + __pos; 19380b57cec5SDimitry Andric} 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 19410b57cec5SDimitry Andric 19420b57cec5SDimitry Andric 19430b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 19440b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 19450b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) 19460b57cec5SDimitry Andric{ 1947bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1948bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1949bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19500b57cec5SDimitry Andric if (__pos < __to_end) 19510b57cec5SDimitry Andric { // insert by shifting things backward 19520b57cec5SDimitry Andric if (__front_spare() == 0) 19530b57cec5SDimitry Andric __add_front_capacity(); 19540b57cec5SDimitry Andric // __front_spare() >= 1 1955*06c3fb27SDimitry Andric __annotate_increase_front(1); 19560b57cec5SDimitry Andric if (__pos == 0) 19570b57cec5SDimitry Andric { 1958bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v); 1959bdd1243dSDimitry Andric --__start_; 1960bdd1243dSDimitry Andric ++__size(); 19610b57cec5SDimitry Andric } 19620b57cec5SDimitry Andric else 19630b57cec5SDimitry Andric { 19640b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1965bdd1243dSDimitry Andric iterator __b = begin(); 19660b57cec5SDimitry Andric iterator __bm1 = _VSTD::prev(__b); 19670b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__b)) 19680b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__bm1); 19690b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); 1970bdd1243dSDimitry Andric --__start_; 1971bdd1243dSDimitry Andric ++__size(); 19720b57cec5SDimitry Andric if (__pos > 1) 19730b57cec5SDimitry Andric __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt); 19740b57cec5SDimitry Andric *__b = *__vt; 19750b57cec5SDimitry Andric } 19760b57cec5SDimitry Andric } 19770b57cec5SDimitry Andric else 19780b57cec5SDimitry Andric { // insert by shifting things forward 19790b57cec5SDimitry Andric if (__back_spare() == 0) 19800b57cec5SDimitry Andric __add_back_capacity(); 19810b57cec5SDimitry Andric // __back_capacity >= 1 1982*06c3fb27SDimitry Andric __annotate_increase_back(1); 1983bdd1243dSDimitry Andric size_type __de = size() - __pos; 19840b57cec5SDimitry Andric if (__de == 0) 19850b57cec5SDimitry Andric { 1986bdd1243dSDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v); 1987bdd1243dSDimitry Andric ++__size(); 19880b57cec5SDimitry Andric } 19890b57cec5SDimitry Andric else 19900b57cec5SDimitry Andric { 19910b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1992bdd1243dSDimitry Andric iterator __e = end(); 19930b57cec5SDimitry Andric iterator __em1 = _VSTD::prev(__e); 19940b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1)) 19950b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__e); 19960b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); 1997bdd1243dSDimitry Andric ++__size(); 19980b57cec5SDimitry Andric if (__de > 1) 19990b57cec5SDimitry Andric __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); 20000b57cec5SDimitry Andric *--__e = *__vt; 20010b57cec5SDimitry Andric } 20020b57cec5SDimitry Andric } 2003bdd1243dSDimitry Andric return begin() + __pos; 20040b57cec5SDimitry Andric} 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 20070b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 20080b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) 20090b57cec5SDimitry Andric{ 2010bdd1243dSDimitry Andric size_type __pos = __p - begin(); 2011bdd1243dSDimitry Andric size_type __to_end = __size() - __pos; 2012bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 20130b57cec5SDimitry Andric if (__pos < __to_end) 20140b57cec5SDimitry Andric { // insert by shifting things backward 20150b57cec5SDimitry Andric if (__n > __front_spare()) 20160b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 20170b57cec5SDimitry Andric // __n <= __front_spare() 2018*06c3fb27SDimitry Andric __annotate_increase_front(__n); 2019bdd1243dSDimitry Andric iterator __old_begin = begin(); 20200b57cec5SDimitry Andric iterator __i = __old_begin; 20210b57cec5SDimitry Andric if (__n > __pos) 20220b57cec5SDimitry Andric { 2023bdd1243dSDimitry Andric for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size()) 20240b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v); 20250b57cec5SDimitry Andric __n = __pos; 20260b57cec5SDimitry Andric } 20270b57cec5SDimitry Andric if (__n > 0) 20280b57cec5SDimitry Andric { 20290b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 20300b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 20310b57cec5SDimitry Andric __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); 20320b57cec5SDimitry Andric if (__n < __pos) 20330b57cec5SDimitry Andric __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); 20340b57cec5SDimitry Andric _VSTD::fill_n(__old_begin, __n, *__vt); 20350b57cec5SDimitry Andric } 20360b57cec5SDimitry Andric } 20370b57cec5SDimitry Andric else 20380b57cec5SDimitry Andric { // insert by shifting things forward 20390b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 20400b57cec5SDimitry Andric if (__n > __back_capacity) 20410b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 20420b57cec5SDimitry Andric // __n <= __back_capacity 2043*06c3fb27SDimitry Andric __annotate_increase_back(__n); 2044bdd1243dSDimitry Andric iterator __old_end = end(); 20450b57cec5SDimitry Andric iterator __i = __old_end; 2046bdd1243dSDimitry Andric size_type __de = size() - __pos; 20470b57cec5SDimitry Andric if (__n > __de) 20480b57cec5SDimitry Andric { 2049bdd1243dSDimitry Andric for (size_type __m = __n - __de; __m; --__m, (void) ++__i, ++__size()) 20500b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v); 20510b57cec5SDimitry Andric __n = __de; 20520b57cec5SDimitry Andric } 20530b57cec5SDimitry Andric if (__n > 0) 20540b57cec5SDimitry Andric { 20550b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 20560b57cec5SDimitry Andric iterator __oen = __old_end - __n; 20570b57cec5SDimitry Andric __move_construct_and_check(__oen, __old_end, __i, __vt); 20580b57cec5SDimitry Andric if (__n < __de) 20590b57cec5SDimitry Andric __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); 20600b57cec5SDimitry Andric _VSTD::fill_n(__old_end - __n, __n, *__vt); 20610b57cec5SDimitry Andric } 20620b57cec5SDimitry Andric } 2063bdd1243dSDimitry Andric return begin() + __pos; 20640b57cec5SDimitry Andric} 20650b57cec5SDimitry Andric 20660b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 20670b57cec5SDimitry Andrictemplate <class _InputIter> 20680b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 20690b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l, 2070*06c3fb27SDimitry Andric typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type*) 20710b57cec5SDimitry Andric{ 2072*06c3fb27SDimitry Andric return __insert_with_sentinel(__p, __f, __l); 2073*06c3fb27SDimitry Andric} 2074*06c3fb27SDimitry Andric 2075*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 2076*06c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 2077*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 2078*06c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2079*06c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { 2080bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__alloc()); 2081*06c3fb27SDimitry Andric __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); 20820b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; 20830b57cec5SDimitry Andric return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); 20840b57cec5SDimitry Andric} 20850b57cec5SDimitry Andric 20860b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 20870b57cec5SDimitry Andrictemplate <class _ForwardIterator> 20880b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 20890b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, 2090*06c3fb27SDimitry Andric typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type*) 20910b57cec5SDimitry Andric{ 2092*06c3fb27SDimitry Andric return __insert_with_size(__p, __f, std::distance(__f, __l)); 2093*06c3fb27SDimitry Andric} 2094*06c3fb27SDimitry Andric 2095*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 2096*06c3fb27SDimitry Andrictemplate <class _Iterator> 2097*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 2098*06c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2099*06c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) { 2100bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); 2101*06c3fb27SDimitry Andric __buf.__construct_at_end_with_size(__f, __n); 21020b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; 21030b57cec5SDimitry Andric return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); 21040b57cec5SDimitry Andric} 21050b57cec5SDimitry Andric 21060b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 21070b57cec5SDimitry Andrictemplate <class _BiIter> 21080b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 21090b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l, 2110*06c3fb27SDimitry Andric typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type*) 21110b57cec5SDimitry Andric{ 2112*06c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l)); 2113*06c3fb27SDimitry Andric} 2114*06c3fb27SDimitry Andric 2115*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 2116*06c3fb27SDimitry Andrictemplate <class _BiIter, class _Sentinel> 2117*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 2118*06c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2119*06c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) { 2120*06c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, std::next(__f, __n), __n); 2121*06c3fb27SDimitry Andric} 2122*06c3fb27SDimitry Andric 2123*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 2124*06c3fb27SDimitry Andrictemplate <class _BiIter> 2125*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 2126*06c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2127*06c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) { 2128bdd1243dSDimitry Andric size_type __pos = __p - begin(); 2129bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 2130bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 21310b57cec5SDimitry Andric if (__pos < __to_end) 21320b57cec5SDimitry Andric { // insert by shifting things backward 21330b57cec5SDimitry Andric if (__n > __front_spare()) 21340b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 21350b57cec5SDimitry Andric // __n <= __front_spare() 2136*06c3fb27SDimitry Andric __annotate_increase_front(__n); 2137bdd1243dSDimitry Andric iterator __old_begin = begin(); 21380b57cec5SDimitry Andric iterator __i = __old_begin; 21390b57cec5SDimitry Andric _BiIter __m = __f; 21400b57cec5SDimitry Andric if (__n > __pos) 21410b57cec5SDimitry Andric { 21420b57cec5SDimitry Andric __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos); 2143bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __f; --__start_, ++__size()) 21440b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j); 21450b57cec5SDimitry Andric __n = __pos; 21460b57cec5SDimitry Andric } 21470b57cec5SDimitry Andric if (__n > 0) 21480b57cec5SDimitry Andric { 21490b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 21500b57cec5SDimitry Andric for (iterator __j = __obn; __j != __old_begin;) 21510b57cec5SDimitry Andric { 21520b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j)); 2153bdd1243dSDimitry Andric --__start_; 2154bdd1243dSDimitry Andric ++__size(); 21550b57cec5SDimitry Andric } 21560b57cec5SDimitry Andric if (__n < __pos) 21570b57cec5SDimitry Andric __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin); 21580b57cec5SDimitry Andric _VSTD::copy(__m, __l, __old_begin); 21590b57cec5SDimitry Andric } 21600b57cec5SDimitry Andric } 21610b57cec5SDimitry Andric else 21620b57cec5SDimitry Andric { // insert by shifting things forward 21630b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 21640b57cec5SDimitry Andric if (__n > __back_capacity) 21650b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 21660b57cec5SDimitry Andric // __n <= __back_capacity 2167*06c3fb27SDimitry Andric __annotate_increase_back(__n); 2168bdd1243dSDimitry Andric iterator __old_end = end(); 21690b57cec5SDimitry Andric iterator __i = __old_end; 21700b57cec5SDimitry Andric _BiIter __m = __l; 2171bdd1243dSDimitry Andric size_type __de = size() - __pos; 21720b57cec5SDimitry Andric if (__n > __de) 21730b57cec5SDimitry Andric { 21740b57cec5SDimitry Andric __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de); 2175bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__size()) 21760b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j); 21770b57cec5SDimitry Andric __n = __de; 21780b57cec5SDimitry Andric } 21790b57cec5SDimitry Andric if (__n > 0) 21800b57cec5SDimitry Andric { 21810b57cec5SDimitry Andric iterator __oen = __old_end - __n; 2182bdd1243dSDimitry Andric for (iterator __j = __oen; __j != __old_end; ++__i, (void) ++__j, ++__size()) 21830b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j)); 21840b57cec5SDimitry Andric if (__n < __de) 21850b57cec5SDimitry Andric __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end); 21860b57cec5SDimitry Andric _VSTD::copy_backward(__f, __m, __old_end); 21870b57cec5SDimitry Andric } 21880b57cec5SDimitry Andric } 2189bdd1243dSDimitry Andric return begin() + __pos; 21900b57cec5SDimitry Andric} 21910b57cec5SDimitry Andric 21920b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 21930b57cec5SDimitry Andrictemplate <class _InpIter> 21940b57cec5SDimitry Andricvoid 21950b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l, 2196*06c3fb27SDimitry Andric typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type*) 21970b57cec5SDimitry Andric{ 2198*06c3fb27SDimitry Andric __append_with_sentinel(__f, __l); 2199*06c3fb27SDimitry Andric} 2200*06c3fb27SDimitry Andric 2201*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 2202*06c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 2203*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 2204*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { 22050b57cec5SDimitry Andric for (; __f != __l; ++__f) 22060b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 22070b57cec5SDimitry Andric push_back(*__f); 22080b57cec5SDimitry Andric#else 22090b57cec5SDimitry Andric emplace_back(*__f); 22100b57cec5SDimitry Andric#endif 22110b57cec5SDimitry Andric} 22120b57cec5SDimitry Andric 22130b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22140b57cec5SDimitry Andrictemplate <class _ForIter> 22150b57cec5SDimitry Andricvoid 22160b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l, 2217*06c3fb27SDimitry Andric typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type*) 22180b57cec5SDimitry Andric{ 2219*06c3fb27SDimitry Andric __append_with_size(__f, std::distance(__f, __l)); 2220*06c3fb27SDimitry Andric} 2221*06c3fb27SDimitry Andric 2222*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 2223*06c3fb27SDimitry Andrictemplate <class _InputIterator> 2224*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 2225*06c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { 2226bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 22270b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 22280b57cec5SDimitry Andric if (__n > __back_capacity) 22290b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 2230*06c3fb27SDimitry Andric 22310b57cec5SDimitry Andric // __n <= __back_capacity 2232*06c3fb27SDimitry Andric __annotate_increase_back(__n); 2233bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 2234e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 2235e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { 2236e8d8bef9SDimitry Andric __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f); 2237e40139ffSDimitry Andric } 2238e40139ffSDimitry Andric } 22390b57cec5SDimitry Andric} 22400b57cec5SDimitry Andric 22410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22420b57cec5SDimitry Andricvoid 22430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n) 22440b57cec5SDimitry Andric{ 2245bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 22460b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 22470b57cec5SDimitry Andric if (__n > __back_capacity) 22480b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 22490b57cec5SDimitry Andric // __n <= __back_capacity 2250*06c3fb27SDimitry Andric __annotate_increase_back(__n); 2251bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 2252e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 2253e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 2254e8d8bef9SDimitry Andric __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_)); 2255e40139ffSDimitry Andric } 2256e40139ffSDimitry Andric } 22570b57cec5SDimitry Andric} 22580b57cec5SDimitry Andric 22590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22600b57cec5SDimitry Andricvoid 22610b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) 22620b57cec5SDimitry Andric{ 2263bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 22640b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 22650b57cec5SDimitry Andric if (__n > __back_capacity) 22660b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 22670b57cec5SDimitry Andric // __n <= __back_capacity 2268*06c3fb27SDimitry Andric __annotate_increase_back(__n); 2269bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 2270e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 2271e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 2272e8d8bef9SDimitry Andric __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v); 2273e40139ffSDimitry Andric } 2274e40139ffSDimitry Andric } 2275e40139ffSDimitry Andric 22760b57cec5SDimitry Andric} 22770b57cec5SDimitry Andric 22780b57cec5SDimitry Andric// Create front capacity for one block of elements. 22790b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 22800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22810b57cec5SDimitry Andricvoid 22820b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity() 22830b57cec5SDimitry Andric{ 2284bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2285bdd1243dSDimitry Andric if (__back_spare() >= __block_size) 22860b57cec5SDimitry Andric { 2287bdd1243dSDimitry Andric __start_ += __block_size; 2288bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2289bdd1243dSDimitry Andric __map_.pop_back(); 2290bdd1243dSDimitry Andric __map_.push_front(__pt); 22910b57cec5SDimitry Andric } 2292bdd1243dSDimitry Andric // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer 2293bdd1243dSDimitry Andric else if (__map_.size() < __map_.capacity()) 22940b57cec5SDimitry Andric { // we can put the new buffer into the map, but don't shift things around 22950b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 22960b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2297bdd1243dSDimitry Andric if (__map_.__front_spare() > 0) 2298bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 22990b57cec5SDimitry Andric else 23000b57cec5SDimitry Andric { 2301bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 23020b57cec5SDimitry Andric // Done allocating, reorder capacity 2303bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2304bdd1243dSDimitry Andric __map_.pop_back(); 2305bdd1243dSDimitry Andric __map_.push_front(__pt); 23060b57cec5SDimitry Andric } 2307bdd1243dSDimitry Andric __start_ = __map_.size() == 1 ? 2308bdd1243dSDimitry Andric __block_size / 2 : 2309bdd1243dSDimitry Andric __start_ + __block_size; 23100b57cec5SDimitry Andric } 23110b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 23120b57cec5SDimitry Andric else 23130b57cec5SDimitry Andric { 2314bdd1243dSDimitry Andric __split_buffer<pointer, __pointer_allocator&> 2315bdd1243dSDimitry Andric __buf(std::max<size_type>(2 * __map_.capacity(), 1), 2316bdd1243dSDimitry Andric 0, __map_.__alloc()); 23170b57cec5SDimitry Andric 23180b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 23190b57cec5SDimitry Andric unique_ptr<pointer, _Dp> __hold( 2320bdd1243dSDimitry Andric __alloc_traits::allocate(__a, __block_size), 2321bdd1243dSDimitry Andric _Dp(__a, __block_size)); 23220b57cec5SDimitry Andric __buf.push_back(__hold.get()); 23230b57cec5SDimitry Andric __hold.release(); 23240b57cec5SDimitry Andric 2325bdd1243dSDimitry Andric for (__map_pointer __i = __map_.begin(); 2326bdd1243dSDimitry Andric __i != __map_.end(); ++__i) 23270b57cec5SDimitry Andric __buf.push_back(*__i); 2328bdd1243dSDimitry Andric _VSTD::swap(__map_.__first_, __buf.__first_); 2329bdd1243dSDimitry Andric _VSTD::swap(__map_.__begin_, __buf.__begin_); 2330bdd1243dSDimitry Andric _VSTD::swap(__map_.__end_, __buf.__end_); 2331bdd1243dSDimitry Andric _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); 2332bdd1243dSDimitry Andric __start_ = __map_.size() == 1 ? 2333bdd1243dSDimitry Andric __block_size / 2 : 2334bdd1243dSDimitry Andric __start_ + __block_size; 23350b57cec5SDimitry Andric } 2336*06c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 23370b57cec5SDimitry Andric} 23380b57cec5SDimitry Andric 23390b57cec5SDimitry Andric// Create front capacity for __n elements. 23400b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 23410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 23420b57cec5SDimitry Andricvoid 23430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity(size_type __n) 23440b57cec5SDimitry Andric{ 2345bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2346bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 23470b57cec5SDimitry Andric // Number of unused blocks at back: 2348bdd1243dSDimitry Andric size_type __back_capacity = __back_spare() / __block_size; 23490b57cec5SDimitry Andric __back_capacity = _VSTD::min(__back_capacity, __nb); // don't take more than you need 23500b57cec5SDimitry Andric __nb -= __back_capacity; // number of blocks need to allocate 23510b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 23520b57cec5SDimitry Andric if (__nb == 0) 23530b57cec5SDimitry Andric { 2354bdd1243dSDimitry Andric __start_ += __block_size * __back_capacity; 23550b57cec5SDimitry Andric for (; __back_capacity > 0; --__back_capacity) 23560b57cec5SDimitry Andric { 2357bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2358bdd1243dSDimitry Andric __map_.pop_back(); 2359bdd1243dSDimitry Andric __map_.push_front(__pt); 23600b57cec5SDimitry Andric } 23610b57cec5SDimitry Andric } 23620b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2363bdd1243dSDimitry Andric else if (__nb <= __map_.capacity() - __map_.size()) 23640b57cec5SDimitry Andric { // we can put the new buffers into the map, but don't shift things around 23650b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 23660b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2367bdd1243dSDimitry Andric for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) 23680b57cec5SDimitry Andric { 2369bdd1243dSDimitry Andric if (__map_.__front_spare() == 0) 23700b57cec5SDimitry Andric break; 2371bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 2372*06c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 23730b57cec5SDimitry Andric } 23740b57cec5SDimitry Andric for (; __nb > 0; --__nb, ++__back_capacity) 2375bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 23760b57cec5SDimitry Andric // Done allocating, reorder capacity 2377bdd1243dSDimitry Andric __start_ += __back_capacity * __block_size; 23780b57cec5SDimitry Andric for (; __back_capacity > 0; --__back_capacity) 23790b57cec5SDimitry Andric { 2380bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2381bdd1243dSDimitry Andric __map_.pop_back(); 2382bdd1243dSDimitry Andric __map_.push_front(__pt); 2383*06c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 23840b57cec5SDimitry Andric } 23850b57cec5SDimitry Andric } 23860b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 23870b57cec5SDimitry Andric else 23880b57cec5SDimitry Andric { 2389bdd1243dSDimitry Andric size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty(); 2390bdd1243dSDimitry Andric __split_buffer<pointer, __pointer_allocator&> 2391bdd1243dSDimitry Andric __buf(std::max<size_type>(2* __map_.capacity(), 2392bdd1243dSDimitry Andric __nb + __map_.size()), 2393bdd1243dSDimitry Andric 0, __map_.__alloc()); 2394*06c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 23950b57cec5SDimitry Andric try 23960b57cec5SDimitry Andric { 2397*06c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2398*06c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2399bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 2400*06c3fb27SDimitry Andric // ASan: this is empty container, we have to poison whole block 2401*06c3fb27SDimitry Andric __annotate_poison_block( 2402*06c3fb27SDimitry Andric std::__to_address(__buf.back()), 2403*06c3fb27SDimitry Andric std::__to_address(__buf.back() + __block_size)); 2404*06c3fb27SDimitry Andric } 2405*06c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 24060b57cec5SDimitry Andric } 24070b57cec5SDimitry Andric catch (...) 24080b57cec5SDimitry Andric { 2409*06c3fb27SDimitry Andric __annotate_delete(); 2410bdd1243dSDimitry Andric for (__map_pointer __i = __buf.begin(); 24110b57cec5SDimitry Andric __i != __buf.end(); ++__i) 2412bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 24130b57cec5SDimitry Andric throw; 24140b57cec5SDimitry Andric } 2415*06c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 24160b57cec5SDimitry Andric for (; __back_capacity > 0; --__back_capacity) 24170b57cec5SDimitry Andric { 2418bdd1243dSDimitry Andric __buf.push_back(__map_.back()); 2419bdd1243dSDimitry Andric __map_.pop_back(); 24200b57cec5SDimitry Andric } 2421bdd1243dSDimitry Andric for (__map_pointer __i = __map_.begin(); 2422bdd1243dSDimitry Andric __i != __map_.end(); ++__i) 24230b57cec5SDimitry Andric __buf.push_back(*__i); 2424bdd1243dSDimitry Andric _VSTD::swap(__map_.__first_, __buf.__first_); 2425bdd1243dSDimitry Andric _VSTD::swap(__map_.__begin_, __buf.__begin_); 2426bdd1243dSDimitry Andric _VSTD::swap(__map_.__end_, __buf.__end_); 2427bdd1243dSDimitry Andric _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); 2428bdd1243dSDimitry Andric __start_ += __ds; 24290b57cec5SDimitry Andric } 24300b57cec5SDimitry Andric} 24310b57cec5SDimitry Andric 24320b57cec5SDimitry Andric// Create back capacity for one block of elements. 24330b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 24340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 24350b57cec5SDimitry Andricvoid 24360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity() 24370b57cec5SDimitry Andric{ 2438bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2439bdd1243dSDimitry Andric if (__front_spare() >= __block_size) 24400b57cec5SDimitry Andric { 2441bdd1243dSDimitry Andric __start_ -= __block_size; 2442bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2443bdd1243dSDimitry Andric __map_.pop_front(); 2444bdd1243dSDimitry Andric __map_.push_back(__pt); 24450b57cec5SDimitry Andric } 24460b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2447bdd1243dSDimitry Andric else if (__map_.size() < __map_.capacity()) 24480b57cec5SDimitry Andric { // we can put the new buffer into the map, but don't shift things around 24490b57cec5SDimitry Andric // until it is allocated. If we throw, we don't need to fix 24500b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2451bdd1243dSDimitry Andric if (__map_.__back_spare() != 0) 2452bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 24530b57cec5SDimitry Andric else 24540b57cec5SDimitry Andric { 2455bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 24560b57cec5SDimitry Andric // Done allocating, reorder capacity 2457bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2458bdd1243dSDimitry Andric __map_.pop_front(); 2459bdd1243dSDimitry Andric __map_.push_back(__pt); 24600b57cec5SDimitry Andric } 2461*06c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 24620b57cec5SDimitry Andric } 24630b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 24640b57cec5SDimitry Andric else 24650b57cec5SDimitry Andric { 2466bdd1243dSDimitry Andric __split_buffer<pointer, __pointer_allocator&> 2467bdd1243dSDimitry Andric __buf(std::max<size_type>(2* __map_.capacity(), 1), 2468bdd1243dSDimitry Andric __map_.size(), 2469bdd1243dSDimitry Andric __map_.__alloc()); 24700b57cec5SDimitry Andric 24710b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 24720b57cec5SDimitry Andric unique_ptr<pointer, _Dp> __hold( 2473bdd1243dSDimitry Andric __alloc_traits::allocate(__a, __block_size), 2474bdd1243dSDimitry Andric _Dp(__a, __block_size)); 24750b57cec5SDimitry Andric __buf.push_back(__hold.get()); 24760b57cec5SDimitry Andric __hold.release(); 24770b57cec5SDimitry Andric 2478bdd1243dSDimitry Andric for (__map_pointer __i = __map_.end(); 2479bdd1243dSDimitry Andric __i != __map_.begin();) 24800b57cec5SDimitry Andric __buf.push_front(*--__i); 2481bdd1243dSDimitry Andric _VSTD::swap(__map_.__first_, __buf.__first_); 2482bdd1243dSDimitry Andric _VSTD::swap(__map_.__begin_, __buf.__begin_); 2483bdd1243dSDimitry Andric _VSTD::swap(__map_.__end_, __buf.__end_); 2484bdd1243dSDimitry Andric _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); 2485*06c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 24860b57cec5SDimitry Andric } 24870b57cec5SDimitry Andric} 24880b57cec5SDimitry Andric 24890b57cec5SDimitry Andric// Create back capacity for __n elements. 24900b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 24910b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 24920b57cec5SDimitry Andricvoid 24930b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity(size_type __n) 24940b57cec5SDimitry Andric{ 2495bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2496bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 24970b57cec5SDimitry Andric // Number of unused blocks at front: 2498bdd1243dSDimitry Andric size_type __front_capacity = __front_spare() / __block_size; 24990b57cec5SDimitry Andric __front_capacity = _VSTD::min(__front_capacity, __nb); // don't take more than you need 25000b57cec5SDimitry Andric __nb -= __front_capacity; // number of blocks need to allocate 25010b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 25020b57cec5SDimitry Andric if (__nb == 0) 25030b57cec5SDimitry Andric { 2504bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 25050b57cec5SDimitry Andric for (; __front_capacity > 0; --__front_capacity) 25060b57cec5SDimitry Andric { 2507bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2508bdd1243dSDimitry Andric __map_.pop_front(); 2509bdd1243dSDimitry Andric __map_.push_back(__pt); 25100b57cec5SDimitry Andric } 25110b57cec5SDimitry Andric } 25120b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2513bdd1243dSDimitry Andric else if (__nb <= __map_.capacity() - __map_.size()) 25140b57cec5SDimitry Andric { // we can put the new buffers into the map, but don't shift things around 25150b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 25160b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 25170b57cec5SDimitry Andric for (; __nb > 0; --__nb) 25180b57cec5SDimitry Andric { 2519bdd1243dSDimitry Andric if (__map_.__back_spare() == 0) 25200b57cec5SDimitry Andric break; 2521bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 2522*06c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 25230b57cec5SDimitry Andric } 2524bdd1243dSDimitry Andric for (; __nb > 0; --__nb, ++__front_capacity, __start_ += 2525*06c3fb27SDimitry Andric __block_size - (__map_.size() == 1)) { 2526bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 2527*06c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 2528*06c3fb27SDimitry Andric } 25290b57cec5SDimitry Andric // Done allocating, reorder capacity 2530bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 25310b57cec5SDimitry Andric for (; __front_capacity > 0; --__front_capacity) 25320b57cec5SDimitry Andric { 2533bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2534bdd1243dSDimitry Andric __map_.pop_front(); 2535bdd1243dSDimitry Andric __map_.push_back(__pt); 25360b57cec5SDimitry Andric } 25370b57cec5SDimitry Andric } 25380b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 25390b57cec5SDimitry Andric else 25400b57cec5SDimitry Andric { 2541bdd1243dSDimitry Andric size_type __ds = __front_capacity * __block_size; 2542bdd1243dSDimitry Andric __split_buffer<pointer, __pointer_allocator&> 2543bdd1243dSDimitry Andric __buf(std::max<size_type>(2* __map_.capacity(), 2544bdd1243dSDimitry Andric __nb + __map_.size()), 2545bdd1243dSDimitry Andric __map_.size() - __front_capacity, 2546bdd1243dSDimitry Andric __map_.__alloc()); 2547*06c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 25480b57cec5SDimitry Andric try 25490b57cec5SDimitry Andric { 2550*06c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2551*06c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2552bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 2553*06c3fb27SDimitry Andric // ASan: this is an empty container, we have to poison the whole block 2554*06c3fb27SDimitry Andric __annotate_poison_block( 2555*06c3fb27SDimitry Andric std::__to_address(__buf.back()), 2556*06c3fb27SDimitry Andric std::__to_address(__buf.back() + __block_size)); 2557*06c3fb27SDimitry Andric } 2558*06c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 25590b57cec5SDimitry Andric } 25600b57cec5SDimitry Andric catch (...) 25610b57cec5SDimitry Andric { 2562*06c3fb27SDimitry Andric __annotate_delete(); 2563bdd1243dSDimitry Andric for (__map_pointer __i = __buf.begin(); 25640b57cec5SDimitry Andric __i != __buf.end(); ++__i) 2565bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 25660b57cec5SDimitry Andric throw; 25670b57cec5SDimitry Andric } 2568*06c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 25690b57cec5SDimitry Andric for (; __front_capacity > 0; --__front_capacity) 25700b57cec5SDimitry Andric { 2571bdd1243dSDimitry Andric __buf.push_back(__map_.front()); 2572bdd1243dSDimitry Andric __map_.pop_front(); 25730b57cec5SDimitry Andric } 2574bdd1243dSDimitry Andric for (__map_pointer __i = __map_.end(); 2575bdd1243dSDimitry Andric __i != __map_.begin();) 25760b57cec5SDimitry Andric __buf.push_front(*--__i); 2577bdd1243dSDimitry Andric _VSTD::swap(__map_.__first_, __buf.__first_); 2578bdd1243dSDimitry Andric _VSTD::swap(__map_.__begin_, __buf.__begin_); 2579bdd1243dSDimitry Andric _VSTD::swap(__map_.__end_, __buf.__end_); 2580bdd1243dSDimitry Andric _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); 2581bdd1243dSDimitry Andric __start_ -= __ds; 25820b57cec5SDimitry Andric } 25830b57cec5SDimitry Andric} 25840b57cec5SDimitry Andric 25850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 25860b57cec5SDimitry Andricvoid 25870b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_front() 25880b57cec5SDimitry Andric{ 2589*06c3fb27SDimitry Andric size_type __old_sz = size(); 2590*06c3fb27SDimitry Andric size_type __old_start = __start_; 2591bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2592bdd1243dSDimitry Andric __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() + 2593bdd1243dSDimitry Andric __start_ / __block_size) + 2594bdd1243dSDimitry Andric __start_ % __block_size)); 2595bdd1243dSDimitry Andric --__size(); 2596bdd1243dSDimitry Andric ++__start_; 2597*06c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2598e40139ffSDimitry Andric __maybe_remove_front_spare(); 25990b57cec5SDimitry Andric} 26000b57cec5SDimitry Andric 26010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 26020b57cec5SDimitry Andricvoid 26030b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_back() 26040b57cec5SDimitry Andric{ 2605*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); 2606*06c3fb27SDimitry Andric size_type __old_sz = size(); 2607*06c3fb27SDimitry Andric size_type __old_start = __start_; 2608bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2609bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 2610bdd1243dSDimitry Andric __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() + 2611bdd1243dSDimitry Andric __p / __block_size) + 2612bdd1243dSDimitry Andric __p % __block_size)); 2613bdd1243dSDimitry Andric --__size(); 2614*06c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2615e40139ffSDimitry Andric __maybe_remove_back_spare(); 26160b57cec5SDimitry Andric} 26170b57cec5SDimitry Andric 26180b57cec5SDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)). 26190b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt. 26200b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 26210b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 26220b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, 26230b57cec5SDimitry Andric const_pointer& __vt) 26240b57cec5SDimitry Andric{ 26250b57cec5SDimitry Andric // as if 26260b57cec5SDimitry Andric // for (; __f != __l; ++__f, ++__r) 26270b57cec5SDimitry Andric // *__r = _VSTD::move(*__f); 26280b57cec5SDimitry Andric difference_type __n = __l - __f; 26290b57cec5SDimitry Andric while (__n > 0) 26300b57cec5SDimitry Andric { 26310b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2632bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 26330b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 26340b57cec5SDimitry Andric if (__bs > __n) 26350b57cec5SDimitry Andric { 26360b57cec5SDimitry Andric __bs = __n; 26370b57cec5SDimitry Andric __fe = __fb + __bs; 26380b57cec5SDimitry Andric } 26390b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 26400b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; 26410b57cec5SDimitry Andric __r = _VSTD::move(__fb, __fe, __r); 26420b57cec5SDimitry Andric __n -= __bs; 26430b57cec5SDimitry Andric __f += __bs; 26440b57cec5SDimitry Andric } 26450b57cec5SDimitry Andric return __r; 26460b57cec5SDimitry Andric} 26470b57cec5SDimitry Andric 26480b57cec5SDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards. 26490b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt. 26500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 26510b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 26520b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, 26530b57cec5SDimitry Andric const_pointer& __vt) 26540b57cec5SDimitry Andric{ 26550b57cec5SDimitry Andric // as if 26560b57cec5SDimitry Andric // while (__f != __l) 26570b57cec5SDimitry Andric // *--__r = _VSTD::move(*--__l); 26580b57cec5SDimitry Andric difference_type __n = __l - __f; 26590b57cec5SDimitry Andric while (__n > 0) 26600b57cec5SDimitry Andric { 26610b57cec5SDimitry Andric --__l; 26620b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 26630b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 26640b57cec5SDimitry Andric difference_type __bs = __le - __lb; 26650b57cec5SDimitry Andric if (__bs > __n) 26660b57cec5SDimitry Andric { 26670b57cec5SDimitry Andric __bs = __n; 26680b57cec5SDimitry Andric __lb = __le - __bs; 26690b57cec5SDimitry Andric } 26700b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 26710b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; 26720b57cec5SDimitry Andric __r = _VSTD::move_backward(__lb, __le, __r); 26730b57cec5SDimitry Andric __n -= __bs; 26740b57cec5SDimitry Andric __l -= __bs - 1; 26750b57cec5SDimitry Andric } 26760b57cec5SDimitry Andric return __r; 26770b57cec5SDimitry Andric} 26780b57cec5SDimitry Andric 26790b57cec5SDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)). 26800b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt. 26810b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 26820b57cec5SDimitry Andricvoid 26830b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, 26840b57cec5SDimitry Andric iterator __r, const_pointer& __vt) 26850b57cec5SDimitry Andric{ 2686bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 26870b57cec5SDimitry Andric // as if 2688bdd1243dSDimitry Andric // for (; __f != __l; ++__r, ++__f, ++__size()) 26890b57cec5SDimitry Andric // __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f)); 26900b57cec5SDimitry Andric difference_type __n = __l - __f; 26910b57cec5SDimitry Andric while (__n > 0) 26920b57cec5SDimitry Andric { 26930b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2694bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 26950b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 26960b57cec5SDimitry Andric if (__bs > __n) 26970b57cec5SDimitry Andric { 26980b57cec5SDimitry Andric __bs = __n; 26990b57cec5SDimitry Andric __fe = __fb + __bs; 27000b57cec5SDimitry Andric } 27010b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 27020b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; 2703bdd1243dSDimitry Andric for (; __fb != __fe; ++__fb, ++__r, ++__size()) 27040b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb)); 27050b57cec5SDimitry Andric __n -= __bs; 27060b57cec5SDimitry Andric __f += __bs; 27070b57cec5SDimitry Andric } 27080b57cec5SDimitry Andric} 27090b57cec5SDimitry Andric 27100b57cec5SDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards. 27110b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt. 27120b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 27130b57cec5SDimitry Andricvoid 27140b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l, 27150b57cec5SDimitry Andric iterator __r, const_pointer& __vt) 27160b57cec5SDimitry Andric{ 2717bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 27180b57cec5SDimitry Andric // as if 27190b57cec5SDimitry Andric // for (iterator __j = __l; __j != __f;) 27200b57cec5SDimitry Andric // { 27210b57cec5SDimitry Andric // __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j)); 2722bdd1243dSDimitry Andric // --__start_; 2723bdd1243dSDimitry Andric // ++__size(); 27240b57cec5SDimitry Andric // } 27250b57cec5SDimitry Andric difference_type __n = __l - __f; 27260b57cec5SDimitry Andric while (__n > 0) 27270b57cec5SDimitry Andric { 27280b57cec5SDimitry Andric --__l; 27290b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 27300b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 27310b57cec5SDimitry Andric difference_type __bs = __le - __lb; 27320b57cec5SDimitry Andric if (__bs > __n) 27330b57cec5SDimitry Andric { 27340b57cec5SDimitry Andric __bs = __n; 27350b57cec5SDimitry Andric __lb = __le - __bs; 27360b57cec5SDimitry Andric } 27370b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 27380b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; 27390b57cec5SDimitry Andric while (__le != __lb) 27400b57cec5SDimitry Andric { 27410b57cec5SDimitry Andric __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le)); 2742bdd1243dSDimitry Andric --__start_; 2743bdd1243dSDimitry Andric ++__size(); 27440b57cec5SDimitry Andric } 27450b57cec5SDimitry Andric __n -= __bs; 27460b57cec5SDimitry Andric __l -= __bs - 1; 27470b57cec5SDimitry Andric } 27480b57cec5SDimitry Andric} 27490b57cec5SDimitry Andric 27500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 27510b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 27520b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f) 27530b57cec5SDimitry Andric{ 2754*06c3fb27SDimitry Andric size_type __old_sz = size(); 2755*06c3fb27SDimitry Andric size_type __old_start = __start_; 2756bdd1243dSDimitry Andric iterator __b = begin(); 27570b57cec5SDimitry Andric difference_type __pos = __f - __b; 27580b57cec5SDimitry Andric iterator __p = __b + __pos; 2759bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2760bdd1243dSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - 1) / 2) 27610b57cec5SDimitry Andric { // erase from front 27620b57cec5SDimitry Andric _VSTD::move_backward(__b, __p, _VSTD::next(__p)); 27630b57cec5SDimitry Andric __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); 2764bdd1243dSDimitry Andric --__size(); 2765bdd1243dSDimitry Andric ++__start_; 2766*06c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2767e40139ffSDimitry Andric __maybe_remove_front_spare(); 27680b57cec5SDimitry Andric } 27690b57cec5SDimitry Andric else 27700b57cec5SDimitry Andric { // erase from back 2771bdd1243dSDimitry Andric iterator __i = _VSTD::move(_VSTD::next(__p), end(), __p); 27720b57cec5SDimitry Andric __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); 2773bdd1243dSDimitry Andric --__size(); 2774*06c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2775e40139ffSDimitry Andric __maybe_remove_back_spare(); 27760b57cec5SDimitry Andric } 2777bdd1243dSDimitry Andric return begin() + __pos; 27780b57cec5SDimitry Andric} 27790b57cec5SDimitry Andric 27800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 27810b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 27820b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) 27830b57cec5SDimitry Andric{ 2784*06c3fb27SDimitry Andric size_type __old_sz = size(); 2785*06c3fb27SDimitry Andric size_type __old_start = __start_; 27860b57cec5SDimitry Andric difference_type __n = __l - __f; 2787bdd1243dSDimitry Andric iterator __b = begin(); 27880b57cec5SDimitry Andric difference_type __pos = __f - __b; 27890b57cec5SDimitry Andric iterator __p = __b + __pos; 27900b57cec5SDimitry Andric if (__n > 0) 27910b57cec5SDimitry Andric { 2792bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2793bdd1243dSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - __n) / 2) 27940b57cec5SDimitry Andric { // erase from front 27950b57cec5SDimitry Andric iterator __i = _VSTD::move_backward(__b, __p, __p + __n); 27960b57cec5SDimitry Andric for (; __b != __i; ++__b) 27970b57cec5SDimitry Andric __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); 2798bdd1243dSDimitry Andric __size() -= __n; 2799bdd1243dSDimitry Andric __start_ += __n; 2800*06c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2801e40139ffSDimitry Andric while (__maybe_remove_front_spare()) { 28020b57cec5SDimitry Andric } 28030b57cec5SDimitry Andric } 28040b57cec5SDimitry Andric else 28050b57cec5SDimitry Andric { // erase from back 2806bdd1243dSDimitry Andric iterator __i = _VSTD::move(__p + __n, end(), __p); 2807bdd1243dSDimitry Andric for (iterator __e = end(); __i != __e; ++__i) 28080b57cec5SDimitry Andric __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); 2809bdd1243dSDimitry Andric __size() -= __n; 2810*06c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2811e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 28120b57cec5SDimitry Andric } 28130b57cec5SDimitry Andric } 28140b57cec5SDimitry Andric } 2815bdd1243dSDimitry Andric return begin() + __pos; 28160b57cec5SDimitry Andric} 28170b57cec5SDimitry Andric 28180b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 28190b57cec5SDimitry Andricvoid 28200b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) 28210b57cec5SDimitry Andric{ 2822*06c3fb27SDimitry Andric size_type __old_sz = size(); 2823*06c3fb27SDimitry Andric size_type __old_start = __start_; 2824bdd1243dSDimitry Andric iterator __e = end(); 28250b57cec5SDimitry Andric difference_type __n = __e - __f; 28260b57cec5SDimitry Andric if (__n > 0) 28270b57cec5SDimitry Andric { 2828bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2829bdd1243dSDimitry Andric iterator __b = begin(); 28300b57cec5SDimitry Andric difference_type __pos = __f - __b; 28310b57cec5SDimitry Andric for (iterator __p = __b + __pos; __p != __e; ++__p) 28320b57cec5SDimitry Andric __alloc_traits::destroy(__a, _VSTD::addressof(*__p)); 2833bdd1243dSDimitry Andric __size() -= __n; 2834*06c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2835e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 28360b57cec5SDimitry Andric } 28370b57cec5SDimitry Andric } 28380b57cec5SDimitry Andric} 28390b57cec5SDimitry Andric 28400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 28410b57cec5SDimitry Andricinline 28420b57cec5SDimitry Andricvoid 28430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::swap(deque& __c) 28440b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 28450b57cec5SDimitry Andric _NOEXCEPT 28460b57cec5SDimitry Andric#else 28470b57cec5SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 28480b57cec5SDimitry Andric __is_nothrow_swappable<allocator_type>::value) 28490b57cec5SDimitry Andric#endif 28500b57cec5SDimitry Andric{ 2851bdd1243dSDimitry Andric __map_.swap(__c.__map_); 2852bdd1243dSDimitry Andric _VSTD::swap(__start_, __c.__start_); 2853bdd1243dSDimitry Andric _VSTD::swap(__size(), __c.__size()); 2854bdd1243dSDimitry Andric _VSTD::__swap_allocator(__alloc(), __c.__alloc()); 28550b57cec5SDimitry Andric} 28560b57cec5SDimitry Andric 28570b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 28580b57cec5SDimitry Andricinline 28590b57cec5SDimitry Andricvoid 28600b57cec5SDimitry Andricdeque<_Tp, _Allocator>::clear() _NOEXCEPT 28610b57cec5SDimitry Andric{ 2862*06c3fb27SDimitry Andric __annotate_delete(); 2863bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2864bdd1243dSDimitry Andric for (iterator __i = begin(), __e = end(); __i != __e; ++__i) 2865bdd1243dSDimitry Andric __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); 2866bdd1243dSDimitry Andric __size() = 0; 2867bdd1243dSDimitry Andric while (__map_.size() > 2) 2868bdd1243dSDimitry Andric { 2869bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.front(), __block_size); 2870bdd1243dSDimitry Andric __map_.pop_front(); 2871bdd1243dSDimitry Andric } 2872bdd1243dSDimitry Andric switch (__map_.size()) 2873bdd1243dSDimitry Andric { 2874bdd1243dSDimitry Andric case 1: 2875bdd1243dSDimitry Andric __start_ = __block_size / 2; 2876bdd1243dSDimitry Andric break; 2877bdd1243dSDimitry Andric case 2: 2878bdd1243dSDimitry Andric __start_ = __block_size; 2879bdd1243dSDimitry Andric break; 2880bdd1243dSDimitry Andric } 2881*06c3fb27SDimitry Andric __annotate_new(0); 28820b57cec5SDimitry Andric} 28830b57cec5SDimitry Andric 28840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2885bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 28860b57cec5SDimitry Andricbool 28870b57cec5SDimitry Andricoperator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 28880b57cec5SDimitry Andric{ 28890b57cec5SDimitry Andric const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); 28900b57cec5SDimitry Andric return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); 28910b57cec5SDimitry Andric} 28920b57cec5SDimitry Andric 2893*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 2894*06c3fb27SDimitry Andric 28950b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2896bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 28970b57cec5SDimitry Andricbool 28980b57cec5SDimitry Andricoperator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 28990b57cec5SDimitry Andric{ 29000b57cec5SDimitry Andric return !(__x == __y); 29010b57cec5SDimitry Andric} 29020b57cec5SDimitry Andric 29030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2904bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29050b57cec5SDimitry Andricbool 29060b57cec5SDimitry Andricoperator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 29070b57cec5SDimitry Andric{ 29080b57cec5SDimitry Andric return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 29090b57cec5SDimitry Andric} 29100b57cec5SDimitry Andric 29110b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2912bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29130b57cec5SDimitry Andricbool 29140b57cec5SDimitry Andricoperator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 29150b57cec5SDimitry Andric{ 29160b57cec5SDimitry Andric return __y < __x; 29170b57cec5SDimitry Andric} 29180b57cec5SDimitry Andric 29190b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2920bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29210b57cec5SDimitry Andricbool 29220b57cec5SDimitry Andricoperator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 29230b57cec5SDimitry Andric{ 29240b57cec5SDimitry Andric return !(__x < __y); 29250b57cec5SDimitry Andric} 29260b57cec5SDimitry Andric 29270b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2928bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29290b57cec5SDimitry Andricbool 29300b57cec5SDimitry Andricoperator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 29310b57cec5SDimitry Andric{ 29320b57cec5SDimitry Andric return !(__y < __x); 29330b57cec5SDimitry Andric} 29340b57cec5SDimitry Andric 2935*06c3fb27SDimitry Andric#else // _LIBCPP_STD_VER <= 17 2936*06c3fb27SDimitry Andric 2937*06c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 2938*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> 2939*06c3fb27SDimitry Andricoperator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 2940*06c3fb27SDimitry Andric return std::lexicographical_compare_three_way( 2941*06c3fb27SDimitry Andric __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); 2942*06c3fb27SDimitry Andric} 2943*06c3fb27SDimitry Andric 2944*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER <= 17 2945*06c3fb27SDimitry Andric 29460b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2947bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29480b57cec5SDimitry Andricvoid 29490b57cec5SDimitry Andricswap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) 29500b57cec5SDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 29510b57cec5SDimitry Andric{ 29520b57cec5SDimitry Andric __x.swap(__y); 29530b57cec5SDimitry Andric} 29540b57cec5SDimitry Andric 2955*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 29560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up> 2957bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 29585ffd83dbSDimitry Andricerase(deque<_Tp, _Allocator>& __c, const _Up& __v) { 29595ffd83dbSDimitry Andric auto __old_size = __c.size(); 29605ffd83dbSDimitry Andric __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); 29615ffd83dbSDimitry Andric return __old_size - __c.size(); 29625ffd83dbSDimitry Andric} 29630b57cec5SDimitry Andric 29640b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate> 2965bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 29665ffd83dbSDimitry Andricerase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) { 29675ffd83dbSDimitry Andric auto __old_size = __c.size(); 29685ffd83dbSDimitry Andric __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); 29695ffd83dbSDimitry Andric return __old_size - __c.size(); 29705ffd83dbSDimitry Andric} 297181ad6265SDimitry Andric 297281ad6265SDimitry Andrictemplate <> 297381ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<char>> = true; 297481ad6265SDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 297581ad6265SDimitry Andrictemplate <> 297681ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true; 29770b57cec5SDimitry Andric#endif 29780b57cec5SDimitry Andric 2979*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 29800b57cec5SDimitry Andric 29810b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 29820b57cec5SDimitry Andric 2983*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 2984bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2985bdd1243dSDimitry Andricnamespace pmr { 2986bdd1243dSDimitry Andrictemplate <class _ValueT> 2987*06c3fb27SDimitry Andricusing deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>; 2988bdd1243dSDimitry Andric} // namespace pmr 2989bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD 2990bdd1243dSDimitry Andric#endif 2991bdd1243dSDimitry Andric 29920b57cec5SDimitry Andric_LIBCPP_POP_MACROS 29930b57cec5SDimitry Andric 2994bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 2995bdd1243dSDimitry Andric# include <algorithm> 2996bdd1243dSDimitry Andric# include <atomic> 2997bdd1243dSDimitry Andric# include <concepts> 2998*06c3fb27SDimitry Andric# include <cstdlib> 2999bdd1243dSDimitry Andric# include <functional> 3000bdd1243dSDimitry Andric# include <iosfwd> 3001bdd1243dSDimitry Andric# include <iterator> 3002*06c3fb27SDimitry Andric# include <type_traits> 3003bdd1243dSDimitry Andric# include <typeinfo> 3004bdd1243dSDimitry Andric#endif 3005bdd1243dSDimitry Andric 30060b57cec5SDimitry Andric#endif // _LIBCPP_DEQUE 3007