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); 5006c3fb27SDimitry Andric template<container-compatible-range<T> R> 5106c3fb27SDimitry 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); 6906c3fb27SDimitry Andric template<container-compatible-range<T> R> 7006c3fb27SDimitry 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); 11406c3fb27SDimitry Andric template<container-compatible-range<T> R> 11506c3fb27SDimitry 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); 11806c3fb27SDimitry Andric template<container-compatible-range<T> R> 11906c3fb27SDimitry 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); 12806c3fb27SDimitry Andric template<container-compatible-range<T> R> 12906c3fb27SDimitry 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 14406c3fb27SDimitry Andrictemplate<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> 14506c3fb27SDimitry Andric deque(from_range_t, R&&, Allocator = Allocator()) 14606c3fb27SDimitry Andric -> deque<ranges::range_value_t<R>, Allocator>; // C++23 14706c3fb27SDimitry 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> 15106c3fb27SDimitry Andric bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1520b57cec5SDimitry Andrictemplate <class T, class Allocator> 15306c3fb27SDimitry Andric bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1540b57cec5SDimitry Andrictemplate <class T, class Allocator> 15506c3fb27SDimitry Andric bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1560b57cec5SDimitry Andrictemplate <class T, class Allocator> 15706c3fb27SDimitry Andric bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1580b57cec5SDimitry Andrictemplate <class T, class Allocator> 15906c3fb27SDimitry Andric bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 16006c3fb27SDimitry Andrictemplate<class T, class Allocator> 16106c3fb27SDimitry Andric synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x, 16206c3fb27SDimitry 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> 18206c3fb27SDimitry 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> 18606c3fb27SDimitry 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 19206c3fb27SDimitry Andric#include <__availability> 1930b57cec5SDimitry Andric#include <__config> 19481ad6265SDimitry Andric#include <__format/enable_insertable.h> 19506c3fb27SDimitry 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> 20106c3fb27SDimitry 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> 20706c3fb27SDimitry Andric#include <__ranges/access.h> 20806c3fb27SDimitry Andric#include <__ranges/concepts.h> 20906c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h> 21006c3fb27SDimitry Andric#include <__ranges/from_range.h> 21106c3fb27SDimitry Andric#include <__ranges/size.h> 2120b57cec5SDimitry Andric#include <__split_buffer> 213bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h> 21406c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 21506c3fb27SDimitry Andric#include <__type_traits/is_same.h> 21606c3fb27SDimitry Andric#include <__type_traits/type_identity.h> 217fe6060f1SDimitry Andric#include <__utility/forward.h> 21881ad6265SDimitry Andric#include <__utility/move.h> 21906c3fb27SDimitry 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 28206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 2830b57cec5SDimitry Andric : __m_iter_(nullptr), __ptr_(nullptr) 2840b57cec5SDimitry Andric#endif 2850b57cec5SDimitry Andric {} 2860b57cec5SDimitry Andric 287*5f757f3fSDimitry Andric template <class _Pp, class _Rp, class _MP, __enable_if_t<is_convertible<_Pp, pointer>::value, int> = 0> 288bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 289*5f757f3fSDimitry Andric __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it) _NOEXCEPT 2900b57cec5SDimitry Andric : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {} 2910b57cec5SDimitry Andric 292bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const {return *__ptr_;} 293bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const {return __ptr_;} 2940b57cec5SDimitry Andric 295bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++() 2960b57cec5SDimitry Andric { 2970b57cec5SDimitry Andric if (++__ptr_ - *__m_iter_ == __block_size) 2980b57cec5SDimitry Andric { 2990b57cec5SDimitry Andric ++__m_iter_; 3000b57cec5SDimitry Andric __ptr_ = *__m_iter_; 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric return *this; 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric 305bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int) 3060b57cec5SDimitry Andric { 3070b57cec5SDimitry Andric __deque_iterator __tmp = *this; 3080b57cec5SDimitry Andric ++(*this); 3090b57cec5SDimitry Andric return __tmp; 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 312bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--() 3130b57cec5SDimitry Andric { 3140b57cec5SDimitry Andric if (__ptr_ == *__m_iter_) 3150b57cec5SDimitry Andric { 3160b57cec5SDimitry Andric --__m_iter_; 3170b57cec5SDimitry Andric __ptr_ = *__m_iter_ + __block_size; 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric --__ptr_; 3200b57cec5SDimitry Andric return *this; 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 323bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int) 3240b57cec5SDimitry Andric { 3250b57cec5SDimitry Andric __deque_iterator __tmp = *this; 3260b57cec5SDimitry Andric --(*this); 3270b57cec5SDimitry Andric return __tmp; 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 330bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n) 3310b57cec5SDimitry Andric { 3320b57cec5SDimitry Andric if (__n != 0) 3330b57cec5SDimitry Andric { 3340b57cec5SDimitry Andric __n += __ptr_ - *__m_iter_; 3350b57cec5SDimitry Andric if (__n > 0) 3360b57cec5SDimitry Andric { 3370b57cec5SDimitry Andric __m_iter_ += __n / __block_size; 3380b57cec5SDimitry Andric __ptr_ = *__m_iter_ + __n % __block_size; 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric else // (__n < 0) 3410b57cec5SDimitry Andric { 3420b57cec5SDimitry Andric difference_type __z = __block_size - 1 - __n; 3430b57cec5SDimitry Andric __m_iter_ -= __z / __block_size; 3440b57cec5SDimitry Andric __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size); 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric return *this; 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric 350bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n) 3510b57cec5SDimitry Andric { 3520b57cec5SDimitry Andric return *this += -__n; 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 355bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const 3560b57cec5SDimitry Andric { 3570b57cec5SDimitry Andric __deque_iterator __t(*this); 3580b57cec5SDimitry Andric __t += __n; 3590b57cec5SDimitry Andric return __t; 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 362bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const 3630b57cec5SDimitry Andric { 3640b57cec5SDimitry Andric __deque_iterator __t(*this); 3650b57cec5SDimitry Andric __t -= __n; 3660b57cec5SDimitry Andric return __t; 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 369bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 3700b57cec5SDimitry Andric friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) 3710b57cec5SDimitry Andric {return __it + __n;} 3720b57cec5SDimitry Andric 373bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 3740b57cec5SDimitry Andric friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) 3750b57cec5SDimitry Andric { 3760b57cec5SDimitry Andric if (__x != __y) 3770b57cec5SDimitry Andric return (__x.__m_iter_ - __y.__m_iter_) * __block_size 3780b57cec5SDimitry Andric + (__x.__ptr_ - *__x.__m_iter_) 3790b57cec5SDimitry Andric - (__y.__ptr_ - *__y.__m_iter_); 3800b57cec5SDimitry Andric return 0; 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 383bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const 3840b57cec5SDimitry Andric {return *(*this + __n);} 3850b57cec5SDimitry Andric 386bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 3870b57cec5SDimitry Andric bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) 3880b57cec5SDimitry Andric {return __x.__ptr_ == __y.__ptr_;} 3890b57cec5SDimitry Andric 390bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 3910b57cec5SDimitry Andric bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) 3920b57cec5SDimitry Andric {return !(__x == __y);} 3930b57cec5SDimitry Andric 394bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 3950b57cec5SDimitry Andric bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) 3960b57cec5SDimitry Andric {return __x.__m_iter_ < __y.__m_iter_ || 3970b57cec5SDimitry Andric (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);} 3980b57cec5SDimitry Andric 399bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 4000b57cec5SDimitry Andric bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) 4010b57cec5SDimitry Andric {return __y < __x;} 4020b57cec5SDimitry Andric 403bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 4040b57cec5SDimitry Andric bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) 4050b57cec5SDimitry Andric {return !(__y < __x);} 4060b57cec5SDimitry Andric 407bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 4080b57cec5SDimitry Andric bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) 4090b57cec5SDimitry Andric {return !(__x < __y);} 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andricprivate: 412bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT 4130b57cec5SDimitry Andric : __m_iter_(__m), __ptr_(__p) {} 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque; 4160b57cec5SDimitry Andric template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp> 4170b57cec5SDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __deque_iterator; 4180b57cec5SDimitry Andric 419bdd1243dSDimitry Andric template <class> 420bdd1243dSDimitry Andric friend struct __segmented_iterator_traits; 421bdd1243dSDimitry Andric}; 4220b57cec5SDimitry Andric 423bdd1243dSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 424bdd1243dSDimitry Andricstruct __segmented_iterator_traits< 425bdd1243dSDimitry Andric __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > { 426bdd1243dSDimitry Andricprivate: 427bdd1243dSDimitry Andric using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; 4280b57cec5SDimitry Andric 429bdd1243dSDimitry Andricpublic: 430bdd1243dSDimitry Andric using __is_segmented_iterator = true_type; 431bdd1243dSDimitry Andric using __segment_iterator = _MapPointer; 432bdd1243dSDimitry Andric using __local_iterator = _Pointer; 4330b57cec5SDimitry Andric 434bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } 435bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } 436bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; } 4370b57cec5SDimitry Andric 438bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) { 439bdd1243dSDimitry Andric return *__iter + _Iterator::__block_size; 440bdd1243dSDimitry Andric } 4410b57cec5SDimitry Andric 442bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) { 443*5f757f3fSDimitry Andric if (__segment && __local == __end(__segment)) { 444bdd1243dSDimitry Andric ++__segment; 445bdd1243dSDimitry Andric return _Iterator(__segment, *__segment); 446bdd1243dSDimitry Andric } 447bdd1243dSDimitry Andric return _Iterator(__segment, __local); 448bdd1243dSDimitry Andric } 4490b57cec5SDimitry Andric}; 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, 4520b57cec5SDimitry Andric class _DiffType, _DiffType _BlockSize> 4530b57cec5SDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, 4540b57cec5SDimitry Andric _DiffType, _BlockSize>::__block_size = 4550b57cec5SDimitry Andric __deque_block_size<_ValueType, _DiffType>::value; 4560b57cec5SDimitry Andric 457bdd1243dSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/> 458bdd1243dSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque 4590b57cec5SDimitry Andric{ 4600b57cec5SDimitry Andricpublic: 461bdd1243dSDimitry Andric // types: 462e40139ffSDimitry Andric 463bdd1243dSDimitry Andric using value_type = _Tp; 4640b57cec5SDimitry Andric 465bdd1243dSDimitry Andric static_assert((is_same<typename _Allocator::value_type, value_type>::value), 466bdd1243dSDimitry Andric "Allocator::value_type must be same type as value_type"); 4670b57cec5SDimitry Andric 468bdd1243dSDimitry Andric using allocator_type = _Allocator; 469bdd1243dSDimitry Andric using __alloc_traits = allocator_traits<allocator_type>; 4700b57cec5SDimitry Andric 471bdd1243dSDimitry Andric using size_type = typename __alloc_traits::size_type; 472bdd1243dSDimitry Andric using difference_type = typename __alloc_traits::difference_type; 4730b57cec5SDimitry Andric 474bdd1243dSDimitry Andric using pointer = typename __alloc_traits::pointer; 475bdd1243dSDimitry Andric using const_pointer = typename __alloc_traits::const_pointer; 476bdd1243dSDimitry Andric 477bdd1243dSDimitry Andric using __pointer_allocator = __rebind_alloc<__alloc_traits, pointer>; 478bdd1243dSDimitry Andric using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>; 479bdd1243dSDimitry Andric using __map = __split_buffer<pointer, __pointer_allocator>; 480bdd1243dSDimitry Andric using __map_alloc_traits = allocator_traits<__pointer_allocator>; 481bdd1243dSDimitry Andric using __map_pointer = typename __map_alloc_traits::pointer; 482bdd1243dSDimitry Andric using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer; 48306c3fb27SDimitry Andric using __map_const_iterator = typename __map::const_iterator; 484bdd1243dSDimitry Andric 485bdd1243dSDimitry Andric using reference = value_type&; 486bdd1243dSDimitry Andric using const_reference = const value_type&; 487bdd1243dSDimitry Andric 488bdd1243dSDimitry Andric using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>; 489bdd1243dSDimitry Andric using const_iterator = 490bdd1243dSDimitry Andric __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>; 491bdd1243dSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 492bdd1243dSDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>; 493bdd1243dSDimitry Andric 494bdd1243dSDimitry Andric static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value, 495bdd1243dSDimitry Andric "[allocator.requirements] states that rebinding an allocator to the same type should result in the " 496bdd1243dSDimitry Andric "original allocator"); 497bdd1243dSDimitry Andric static_assert(is_nothrow_default_constructible<allocator_type>::value == 498bdd1243dSDimitry Andric is_nothrow_default_constructible<__pointer_allocator>::value, 499bdd1243dSDimitry Andric "rebinding an allocator should not change excpetion guarantees"); 500bdd1243dSDimitry Andric static_assert(is_nothrow_move_constructible<allocator_type>::value == 501bdd1243dSDimitry Andric is_nothrow_move_constructible<typename __map::allocator_type>::value, 502bdd1243dSDimitry Andric "rebinding an allocator should not change excpetion guarantees"); 503bdd1243dSDimitry Andric 504bdd1243dSDimitry Andricprivate: 505e40139ffSDimitry Andric struct __deque_block_range { 506bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI 507bdd1243dSDimitry Andric __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {} 508e40139ffSDimitry Andric const pointer __begin_; 509e40139ffSDimitry Andric const pointer __end_; 510e40139ffSDimitry Andric }; 511e40139ffSDimitry Andric 512e40139ffSDimitry Andric struct __deque_range { 513e40139ffSDimitry Andric iterator __pos_; 514e40139ffSDimitry Andric const iterator __end_; 515e40139ffSDimitry Andric 516bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT 517e40139ffSDimitry Andric : __pos_(__pos), __end_(__e) {} 518e40139ffSDimitry Andric 519bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { 520e40139ffSDimitry Andric return __pos_ != __end_; 521e40139ffSDimitry Andric } 522e40139ffSDimitry Andric 523bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { 524e40139ffSDimitry Andric return *this; 525e40139ffSDimitry Andric } 526e40139ffSDimitry Andric 527bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range end() const { 528e40139ffSDimitry Andric return __deque_range(__end_, __end_); 529e40139ffSDimitry Andric } 530bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT { 531e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 532e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, __end_.__ptr_); 533e40139ffSDimitry Andric } 534e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size); 535e40139ffSDimitry Andric } 536e40139ffSDimitry Andric 537bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT { 538e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 539e40139ffSDimitry Andric __pos_ = __end_; 540e40139ffSDimitry Andric } else { 541e40139ffSDimitry Andric ++__pos_.__m_iter_; 542e40139ffSDimitry Andric __pos_.__ptr_ = *__pos_.__m_iter_; 543e40139ffSDimitry Andric } 544e40139ffSDimitry Andric return *this; 545e40139ffSDimitry Andric } 546e40139ffSDimitry Andric 547e40139ffSDimitry Andric 548bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) { 549e40139ffSDimitry Andric return __lhs.__pos_ == __rhs.__pos_; 550e40139ffSDimitry Andric } 551bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) { 552e40139ffSDimitry Andric return !(__lhs == __rhs); 553e40139ffSDimitry Andric } 554e40139ffSDimitry Andric }; 555e40139ffSDimitry Andric 556e40139ffSDimitry Andric struct _ConstructTransaction { 557bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r) 558e40139ffSDimitry Andric : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} 559e40139ffSDimitry Andric 560e40139ffSDimitry Andric 561bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { 562bdd1243dSDimitry Andric __base_->__size() += (__pos_ - __begin_); 563e40139ffSDimitry Andric } 564e40139ffSDimitry Andric 565e40139ffSDimitry Andric pointer __pos_; 566e40139ffSDimitry Andric const pointer __end_; 567e40139ffSDimitry Andric private: 568e40139ffSDimitry Andric const pointer __begin_; 569bdd1243dSDimitry Andric deque* const __base_; 570e40139ffSDimitry Andric }; 571e40139ffSDimitry Andric 572bdd1243dSDimitry Andric static const difference_type __block_size; 573bdd1243dSDimitry Andric 5740b57cec5SDimitry Andric __map __map_; 5750b57cec5SDimitry Andric size_type __start_; 5760b57cec5SDimitry Andric __compressed_pair<size_type, allocator_type> __size_; 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andricpublic: 579bdd1243dSDimitry Andric 580bdd1243dSDimitry Andric // construct/copy/destroy: 581bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 582bdd1243dSDimitry Andric deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 58306c3fb27SDimitry Andric : __start_(0), __size_(0, __default_init_tag()) { 58406c3fb27SDimitry Andric __annotate_new(0); 58506c3fb27SDimitry Andric } 586bdd1243dSDimitry Andric 587bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~deque() { 588bdd1243dSDimitry Andric clear(); 58906c3fb27SDimitry Andric __annotate_delete(); 590bdd1243dSDimitry Andric typename __map::iterator __i = __map_.begin(); 591bdd1243dSDimitry Andric typename __map::iterator __e = __map_.end(); 592bdd1243dSDimitry Andric for (; __i != __e; ++__i) 593bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), *__i, __block_size); 594bdd1243dSDimitry Andric } 595bdd1243dSDimitry Andric 596bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) 59706c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 59806c3fb27SDimitry Andric __annotate_new(0); 59906c3fb27SDimitry Andric } 600bdd1243dSDimitry Andric 601bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); 60206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 603bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); 604bdd1243dSDimitry Andric#endif 605bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); 606bdd1243dSDimitry Andric 607bdd1243dSDimitry Andric template <class = __enable_if_t<__is_allocator<_Allocator>::value> > 608bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) 609bdd1243dSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) 610bdd1243dSDimitry Andric { 61106c3fb27SDimitry Andric __annotate_new(0); 612bdd1243dSDimitry Andric if (__n > 0) 613bdd1243dSDimitry Andric __append(__n, __v); 614bdd1243dSDimitry Andric } 615bdd1243dSDimitry Andric 616*5f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 617*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l); 618*5f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 619*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a); 62006c3fb27SDimitry Andric 62106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 62206c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 62306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, 62406c3fb27SDimitry Andric const allocator_type& __a = allocator_type()) 62506c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 62606c3fb27SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 62706c3fb27SDimitry Andric __append_with_size(ranges::begin(__range), ranges::distance(__range)); 62806c3fb27SDimitry Andric 62906c3fb27SDimitry Andric } else { 63006c3fb27SDimitry Andric for (auto&& __e : __range) { 63106c3fb27SDimitry Andric emplace_back(std::forward<decltype(__e)>(__e)); 63206c3fb27SDimitry Andric } 63306c3fb27SDimitry Andric } 63406c3fb27SDimitry Andric } 63506c3fb27SDimitry Andric#endif 63606c3fb27SDimitry Andric 637bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); 638bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); 639bdd1243dSDimitry Andric 640bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c); 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 643bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il); 644bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a); 645bdd1243dSDimitry Andric 646bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 647bdd1243dSDimitry Andric deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;} 648bdd1243dSDimitry Andric 649bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 650bdd1243dSDimitry Andric deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); 651bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 652bdd1243dSDimitry Andric deque(deque&& __c, const __type_identity_t<allocator_type>& __a); 653bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 654bdd1243dSDimitry Andric deque& operator=(deque&& __c) 655bdd1243dSDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && 656bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value); 657bdd1243dSDimitry Andric 658bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 659bdd1243dSDimitry Andric void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());} 6600b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 6610b57cec5SDimitry Andric 662*5f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value && 663*5f757f3fSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, int> = 0> 664*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l); 665*5f757f3fSDimitry Andric template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> = 0> 666*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l); 66706c3fb27SDimitry Andric 66806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 66906c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 67006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 67106c3fb27SDimitry Andric void assign_range(_Range&& __range) { 67206c3fb27SDimitry Andric if constexpr (ranges::random_access_range<_Range>) { 67306c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 67406c3fb27SDimitry Andric __assign_with_size_random_access(ranges::begin(__range), __n); 67506c3fb27SDimitry Andric 67606c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 67706c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 67806c3fb27SDimitry Andric __assign_with_size(ranges::begin(__range), __n); 67906c3fb27SDimitry Andric 68006c3fb27SDimitry Andric } else { 68106c3fb27SDimitry Andric __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 68206c3fb27SDimitry Andric } 68306c3fb27SDimitry Andric } 68406c3fb27SDimitry Andric#endif 68506c3fb27SDimitry Andric 686bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); 687bdd1243dSDimitry Andric 688bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 689bdd1243dSDimitry Andric allocator_type get_allocator() const _NOEXCEPT; 690bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); } 691bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); } 692bdd1243dSDimitry Andric 693bdd1243dSDimitry Andric // iterators: 694bdd1243dSDimitry Andric 695bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { 696bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __start_ / __block_size; 697bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 698bdd1243dSDimitry Andric } 699bdd1243dSDimitry Andric 700bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { 701bdd1243dSDimitry Andric __map_const_pointer __mp = 702bdd1243dSDimitry Andric static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); 703bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 704bdd1243dSDimitry Andric } 705bdd1243dSDimitry Andric 706bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { 707bdd1243dSDimitry Andric size_type __p = size() + __start_; 708bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __p / __block_size; 709bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 710bdd1243dSDimitry Andric } 711bdd1243dSDimitry Andric 712bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { 713bdd1243dSDimitry Andric size_type __p = size() + __start_; 714bdd1243dSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); 715bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 716bdd1243dSDimitry Andric } 717bdd1243dSDimitry Andric 718bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 719bdd1243dSDimitry Andric reverse_iterator rbegin() _NOEXCEPT 720bdd1243dSDimitry Andric {return reverse_iterator(end());} 721bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 722bdd1243dSDimitry Andric const_reverse_iterator rbegin() const _NOEXCEPT 723bdd1243dSDimitry Andric {return const_reverse_iterator(end());} 724bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 725bdd1243dSDimitry Andric reverse_iterator rend() _NOEXCEPT 726bdd1243dSDimitry Andric {return reverse_iterator(begin());} 727bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 728bdd1243dSDimitry Andric const_reverse_iterator rend() const _NOEXCEPT 729bdd1243dSDimitry Andric {return const_reverse_iterator(begin());} 730bdd1243dSDimitry Andric 731bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 732bdd1243dSDimitry Andric const_iterator cbegin() const _NOEXCEPT 733bdd1243dSDimitry Andric {return begin();} 734bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 735bdd1243dSDimitry Andric const_iterator cend() const _NOEXCEPT 736bdd1243dSDimitry Andric {return end();} 737bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 738bdd1243dSDimitry Andric const_reverse_iterator crbegin() const _NOEXCEPT 739bdd1243dSDimitry Andric {return const_reverse_iterator(end());} 740bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 741bdd1243dSDimitry Andric const_reverse_iterator crend() const _NOEXCEPT 742bdd1243dSDimitry Andric {return const_reverse_iterator(begin());} 743bdd1243dSDimitry Andric 744bdd1243dSDimitry Andric // capacity: 745bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 746bdd1243dSDimitry Andric size_type size() const _NOEXCEPT {return __size();} 747bdd1243dSDimitry Andric 748bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); } 749bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); } 750bdd1243dSDimitry Andric 751bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 752bdd1243dSDimitry Andric size_type max_size() const _NOEXCEPT 753*5f757f3fSDimitry Andric {return std::min<size_type>( 754bdd1243dSDimitry Andric __alloc_traits::max_size(__alloc()), 755bdd1243dSDimitry Andric numeric_limits<difference_type>::max());} 756bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); 757bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); 758bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; 759bdd1243dSDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 760bdd1243dSDimitry Andric bool empty() const _NOEXCEPT {return size() == 0;} 761bdd1243dSDimitry Andric 762bdd1243dSDimitry Andric // element access: 763bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 764bdd1243dSDimitry Andric reference operator[](size_type __i) _NOEXCEPT; 765bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 766bdd1243dSDimitry Andric const_reference operator[](size_type __i) const _NOEXCEPT; 767bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 768bdd1243dSDimitry Andric reference at(size_type __i); 769bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 770bdd1243dSDimitry Andric const_reference at(size_type __i) const; 771bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 772bdd1243dSDimitry Andric reference front() _NOEXCEPT; 773bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 774bdd1243dSDimitry Andric const_reference front() const _NOEXCEPT; 775bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 776bdd1243dSDimitry Andric reference back() _NOEXCEPT; 777bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 778bdd1243dSDimitry Andric const_reference back() const _NOEXCEPT; 779bdd1243dSDimitry Andric 780bdd1243dSDimitry Andric // 23.2.2.3 modifiers: 781bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); 782bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); 783bdd1243dSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 78406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 785bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); 786bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args); 787bdd1243dSDimitry Andric#else 788bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); 789bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI void emplace_back (_Args&&... __args); 790bdd1243dSDimitry Andric#endif 791bdd1243dSDimitry Andric template <class... _Args> _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); 792bdd1243dSDimitry Andric 793bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); 794bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v); 79506c3fb27SDimitry Andric 79606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 79706c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 79806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 79906c3fb27SDimitry Andric void prepend_range(_Range&& __range) { 80006c3fb27SDimitry Andric insert_range(begin(), std::forward<_Range>(__range)); 80106c3fb27SDimitry Andric } 80206c3fb27SDimitry Andric 80306c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 80406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 80506c3fb27SDimitry Andric void append_range(_Range&& __range) { 80606c3fb27SDimitry Andric insert_range(end(), std::forward<_Range>(__range)); 80706c3fb27SDimitry Andric } 80806c3fb27SDimitry Andric#endif 80906c3fb27SDimitry Andric 810bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v); 811bdd1243dSDimitry Andric 812bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 813bdd1243dSDimitry Andric iterator insert(const_iterator __p, initializer_list<value_type> __il) 814bdd1243dSDimitry Andric {return insert(__p, __il.begin(), __il.end());} 815bdd1243dSDimitry Andric#endif // _LIBCPP_CXX03_LANG 816bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v); 817bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); 818*5f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0> 819*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l); 820*5f757f3fSDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> = 0> 821*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l); 822*5f757f3fSDimitry Andric template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> = 0> 823*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l); 82406c3fb27SDimitry Andric 82506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 82606c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 82706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 82806c3fb27SDimitry Andric iterator insert_range(const_iterator __position, _Range&& __range) { 82906c3fb27SDimitry Andric if constexpr (ranges::bidirectional_range<_Range>) { 83006c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 83106c3fb27SDimitry Andric return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n); 83206c3fb27SDimitry Andric 83306c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 83406c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 83506c3fb27SDimitry Andric return __insert_with_size(__position, ranges::begin(__range), __n); 83606c3fb27SDimitry Andric 83706c3fb27SDimitry Andric } else { 83806c3fb27SDimitry Andric return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); 83906c3fb27SDimitry Andric } 84006c3fb27SDimitry Andric } 84106c3fb27SDimitry Andric#endif 842bdd1243dSDimitry Andric 843bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_front(); 844bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_back(); 845bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); 846bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); 847bdd1243dSDimitry Andric 848bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 849bdd1243dSDimitry Andric void swap(deque& __c) 8500b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 8510b57cec5SDimitry Andric _NOEXCEPT; 8520b57cec5SDimitry Andric#else 8530b57cec5SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 8540b57cec5SDimitry Andric __is_nothrow_swappable<allocator_type>::value); 8550b57cec5SDimitry Andric#endif 856bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 8570b57cec5SDimitry Andric void clear() _NOEXCEPT; 8580b57cec5SDimitry Andric 859bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 860bdd1243dSDimitry Andric bool __invariants() const { 8610b57cec5SDimitry Andric if (!__map_.__invariants()) 8620b57cec5SDimitry Andric return false; 8630b57cec5SDimitry Andric if (__map_.size() >= size_type(-1) / __block_size) 8640b57cec5SDimitry Andric return false; 86506c3fb27SDimitry Andric for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); 8660b57cec5SDimitry Andric __i != __e; ++__i) 8670b57cec5SDimitry Andric if (*__i == nullptr) 8680b57cec5SDimitry Andric return false; 8690b57cec5SDimitry Andric if (__map_.size() != 0) 8700b57cec5SDimitry Andric { 8710b57cec5SDimitry Andric if (size() >= __map_.size() * __block_size) 8720b57cec5SDimitry Andric return false; 8730b57cec5SDimitry Andric if (__start_ >= __map_.size() * __block_size - size()) 8740b57cec5SDimitry Andric return false; 8750b57cec5SDimitry Andric } 8760b57cec5SDimitry Andric else 8770b57cec5SDimitry Andric { 8780b57cec5SDimitry Andric if (size() != 0) 8790b57cec5SDimitry Andric return false; 8800b57cec5SDimitry Andric if (__start_ != 0) 8810b57cec5SDimitry Andric return false; 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric return true; 8840b57cec5SDimitry Andric } 8850b57cec5SDimitry Andric 886bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 887bdd1243dSDimitry Andric void __move_assign_alloc(deque& __c) 888bdd1243dSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || 889bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) 890bdd1243dSDimitry Andric {__move_assign_alloc(__c, integral_constant<bool, 891bdd1243dSDimitry Andric __alloc_traits::propagate_on_container_move_assignment::value>());} 892bdd1243dSDimitry Andric 893bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 894bdd1243dSDimitry Andric void __move_assign_alloc(deque& __c, true_type) 895bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 8960b57cec5SDimitry Andric { 897*5f757f3fSDimitry Andric __alloc() = std::move(__c.__alloc()); 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric 900bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 901bdd1243dSDimitry Andric void __move_assign_alloc(deque&, false_type) _NOEXCEPT 9020b57cec5SDimitry Andric {} 9034824e7fdSDimitry Andric 904bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 905bdd1243dSDimitry Andric void __move_assign(deque& __c) 906bdd1243dSDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && 907bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) 9084824e7fdSDimitry Andric { 909*5f757f3fSDimitry Andric __map_ = std::move(__c.__map_); 910bdd1243dSDimitry Andric __start_ = __c.__start_; 911bdd1243dSDimitry Andric __size() = __c.size(); 912bdd1243dSDimitry Andric __move_assign_alloc(__c); 913bdd1243dSDimitry Andric __c.__start_ = __c.__size() = 0; 9144824e7fdSDimitry Andric } 9154824e7fdSDimitry Andric 916bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 9170b57cec5SDimitry Andric static size_type __recommend_blocks(size_type __n) 9180b57cec5SDimitry Andric { 919bdd1243dSDimitry Andric return __n / __block_size + (__n % __block_size != 0); 9200b57cec5SDimitry Andric } 921bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 9220b57cec5SDimitry Andric size_type __capacity() const 9230b57cec5SDimitry Andric { 924bdd1243dSDimitry Andric return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1; 9250b57cec5SDimitry Andric } 926bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 927e40139ffSDimitry Andric size_type __block_count() const 928e40139ffSDimitry Andric { 929bdd1243dSDimitry Andric return __map_.size(); 930e40139ffSDimitry Andric } 931e40139ffSDimitry Andric 932bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 9330b57cec5SDimitry Andric size_type __front_spare() const 9340b57cec5SDimitry Andric { 935bdd1243dSDimitry Andric return __start_; 9360b57cec5SDimitry Andric } 937bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 938e40139ffSDimitry Andric size_type __front_spare_blocks() const { 939bdd1243dSDimitry Andric return __front_spare() / __block_size; 940e40139ffSDimitry Andric } 941bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 9420b57cec5SDimitry Andric size_type __back_spare() const 9430b57cec5SDimitry Andric { 944bdd1243dSDimitry Andric return __capacity() - (__start_ + size()); 9450b57cec5SDimitry Andric } 946bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 947e40139ffSDimitry Andric size_type __back_spare_blocks() const { 948bdd1243dSDimitry Andric return __back_spare() / __block_size; 949e40139ffSDimitry Andric } 950e40139ffSDimitry Andric 951e40139ffSDimitry Andric private: 95206c3fb27SDimitry Andric enum __asan_annotation_type { 95306c3fb27SDimitry Andric __asan_unposion, 95406c3fb27SDimitry Andric __asan_poison 95506c3fb27SDimitry Andric }; 95606c3fb27SDimitry Andric 95706c3fb27SDimitry Andric enum __asan_annotation_place { 95806c3fb27SDimitry Andric __asan_front_moved, 95906c3fb27SDimitry Andric __asan_back_moved, 96006c3fb27SDimitry Andric }; 96106c3fb27SDimitry Andric 96206c3fb27SDimitry Andric// The following functions are no-ops outside of AddressSanitizer mode. 96306c3fb27SDimitry Andric// We call annotations for every allocator, unless explicitly disabled. 96406c3fb27SDimitry Andric// 96506c3fb27SDimitry Andric// To disable annotations for a particular allocator, change value of 96606c3fb27SDimitry Andric// __asan_annotate_container_with_allocator to false. 96706c3fb27SDimitry Andric// For more details, see the "Using libc++" documentation page or 96806c3fb27SDimitry Andric// the documentation for __sanitizer_annotate_contiguous_container. 96906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( 97006c3fb27SDimitry Andric const void* __beg, 97106c3fb27SDimitry Andric const void* __end, 97206c3fb27SDimitry Andric const void* __old_con_beg, 97306c3fb27SDimitry Andric const void* __old_con_end, 97406c3fb27SDimitry Andric const void* __new_con_beg, 97506c3fb27SDimitry Andric const void* __new_con_end) const { 976*5f757f3fSDimitry Andric (void)__beg; 977*5f757f3fSDimitry Andric (void)__end; 978*5f757f3fSDimitry Andric (void)__old_con_beg; 979*5f757f3fSDimitry Andric (void)__old_con_end; 980*5f757f3fSDimitry Andric (void)__new_con_beg; 981*5f757f3fSDimitry Andric (void)__new_con_end; 982*5f757f3fSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 98306c3fb27SDimitry Andric if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value) 98406c3fb27SDimitry Andric __sanitizer_annotate_double_ended_contiguous_container( 98506c3fb27SDimitry Andric __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end); 986*5f757f3fSDimitry Andric#endif 98706c3fb27SDimitry Andric } 98806c3fb27SDimitry Andric 98906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 990*5f757f3fSDimitry Andric void __annotate_from_to( 991*5f757f3fSDimitry Andric size_type __beg, 992*5f757f3fSDimitry Andric size_type __end, 993*5f757f3fSDimitry Andric __asan_annotation_type __annotation_type, 994*5f757f3fSDimitry Andric __asan_annotation_place __place) const _NOEXCEPT { 995*5f757f3fSDimitry Andric (void)__beg; 996*5f757f3fSDimitry Andric (void)__end; 997*5f757f3fSDimitry Andric (void)__annotation_type; 998*5f757f3fSDimitry Andric (void)__place; 999*5f757f3fSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 100006c3fb27SDimitry Andric // __beg - index of the first item to annotate 100106c3fb27SDimitry Andric // __end - index behind the last item to annotate (so last item + 1) 100206c3fb27SDimitry Andric // __annotation_type - __asan_unposion or __asan_poison 100306c3fb27SDimitry Andric // __place - __asan_front_moved or __asan_back_moved 100406c3fb27SDimitry Andric // Note: All indexes in __map_ 100506c3fb27SDimitry Andric if (__beg == __end) 100606c3fb27SDimitry Andric return; 100706c3fb27SDimitry Andric // __annotations_beg_map - first chunk which annotations we want to modify 100806c3fb27SDimitry Andric // __annotations_end_map - last chunk which annotations we want to modify 100906c3fb27SDimitry Andric // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist 101006c3fb27SDimitry Andric __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; 101106c3fb27SDimitry Andric __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; 101206c3fb27SDimitry Andric 101306c3fb27SDimitry Andric bool const __poisoning = __annotation_type == __asan_poison; 101406c3fb27SDimitry Andric // __old_c_beg_index - index of the first element in old container 101506c3fb27SDimitry Andric // __old_c_end_index - index of the end of old container (last + 1) 101606c3fb27SDimitry Andric // Note: may be outside the area we are annotating 101706c3fb27SDimitry Andric size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; 101806c3fb27SDimitry Andric size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); 101906c3fb27SDimitry Andric bool const __front = __place == __asan_front_moved; 102006c3fb27SDimitry Andric 102106c3fb27SDimitry Andric if (__poisoning && empty()) { 102206c3fb27SDimitry Andric // Special case: we shouldn't trust __start_ 102306c3fb27SDimitry Andric __old_c_beg_index = __beg; 102406c3fb27SDimitry Andric __old_c_end_index = __end; 102506c3fb27SDimitry Andric } 102606c3fb27SDimitry Andric // __old_c_beg_map - memory block (chunk) with first element 102706c3fb27SDimitry Andric // __old_c_end_map - memory block (chunk) with end of old container 102806c3fb27SDimitry Andric // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, 102906c3fb27SDimitry Andric // which may not exist 103006c3fb27SDimitry Andric __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; 103106c3fb27SDimitry Andric __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; 103206c3fb27SDimitry Andric 103306c3fb27SDimitry Andric // One edge (front/end) of the container was moved and one was not modified. 103406c3fb27SDimitry Andric // __new_edge_index - index of new edge 103506c3fb27SDimitry Andric // __new_edge_map - memory block (chunk) with new edge, it always equals to 103606c3fb27SDimitry Andric // __annotations_beg_map or __annotations_end_map 103706c3fb27SDimitry Andric // __old_edge_map - memory block (chunk) with old edge, it always equals to 103806c3fb27SDimitry Andric // __old_c_beg_map or __old_c_end_map 103906c3fb27SDimitry Andric size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; 104006c3fb27SDimitry Andric __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; 104106c3fb27SDimitry Andric __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; 104206c3fb27SDimitry Andric 104306c3fb27SDimitry Andric // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. 104406c3fb27SDimitry Andric // First and last chunk may be partially poisoned. 104506c3fb27SDimitry Andric // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. 104606c3fb27SDimitry Andric for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { 104706c3fb27SDimitry Andric if (__map_it == __annotations_end_map && __end % __block_size == 0) 104806c3fb27SDimitry Andric // Chunk may not exist, but nothing to do here anyway 104906c3fb27SDimitry Andric break; 105006c3fb27SDimitry Andric 105106c3fb27SDimitry Andric // The beginning and the end of the current memory block 105206c3fb27SDimitry Andric const void* __mem_beg = std::__to_address(*__map_it); 105306c3fb27SDimitry Andric const void* __mem_end = std::__to_address(*__map_it + __block_size); 105406c3fb27SDimitry Andric 105506c3fb27SDimitry Andric // The beginning of memory-in-use in the memory block before container modification 105606c3fb27SDimitry Andric const void* __old_beg = 105706c3fb27SDimitry Andric (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; 105806c3fb27SDimitry Andric 105906c3fb27SDimitry Andric // The end of memory-in-use in the memory block before container modification 106006c3fb27SDimitry Andric const void* __old_end; 106106c3fb27SDimitry Andric if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) 106206c3fb27SDimitry Andric __old_end = __old_beg; 106306c3fb27SDimitry Andric else 106406c3fb27SDimitry Andric __old_end = (__map_it == __old_c_end_map) ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) 106506c3fb27SDimitry Andric : __mem_end; 106606c3fb27SDimitry Andric 106706c3fb27SDimitry Andric // New edge of the container in current memory block 106806c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 106906c3fb27SDimitry Andric const void* __new_edge; 107006c3fb27SDimitry Andric if (__map_it == __new_edge_map) 107106c3fb27SDimitry Andric __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); 107206c3fb27SDimitry Andric else 107306c3fb27SDimitry Andric __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; 107406c3fb27SDimitry Andric 107506c3fb27SDimitry Andric // Not modified edge of the container 107606c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 107706c3fb27SDimitry Andric const void* __old_edge; 107806c3fb27SDimitry Andric if (__map_it == __old_edge_map) 107906c3fb27SDimitry Andric __old_edge = __front ? __old_end : __old_beg; 108006c3fb27SDimitry Andric else 108106c3fb27SDimitry Andric __old_edge = __front ? __mem_end : __mem_beg; 108206c3fb27SDimitry Andric 108306c3fb27SDimitry Andric // __new_beg - the beginning of memory-in-use in the memory block after container modification 108406c3fb27SDimitry Andric // __new_end - the end of memory-in-use in the memory block after container modification 108506c3fb27SDimitry Andric const void* __new_beg = __front ? __new_edge : __old_edge; 108606c3fb27SDimitry Andric const void* __new_end = __front ? __old_edge : __new_edge; 108706c3fb27SDimitry Andric 108806c3fb27SDimitry Andric __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); 108906c3fb27SDimitry Andric } 1090*5f757f3fSDimitry Andric#endif // !_LIBCPP_HAS_NO_ASAN 109106c3fb27SDimitry Andric } 109206c3fb27SDimitry Andric 109306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 109406c3fb27SDimitry Andric void __annotate_new(size_type __current_size) const _NOEXCEPT { 109506c3fb27SDimitry Andric if (__current_size == 0) 109606c3fb27SDimitry Andric __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 109706c3fb27SDimitry Andric else { 109806c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); 109906c3fb27SDimitry Andric __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 110006c3fb27SDimitry Andric } 110106c3fb27SDimitry Andric } 110206c3fb27SDimitry Andric 110306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 110406c3fb27SDimitry Andric void __annotate_delete() const _NOEXCEPT { 110506c3fb27SDimitry Andric if (empty()) { 110606c3fb27SDimitry Andric for(size_t __i = 0; __i < __map_.size(); ++__i) { 110706c3fb27SDimitry Andric __annotate_whole_block(__i, __asan_unposion); 110806c3fb27SDimitry Andric } 110906c3fb27SDimitry Andric } 111006c3fb27SDimitry Andric else { 111106c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); 111206c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); 111306c3fb27SDimitry Andric } 111406c3fb27SDimitry Andric } 111506c3fb27SDimitry Andric 111606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 111706c3fb27SDimitry Andric void __annotate_increase_front(size_type __n) const _NOEXCEPT { 111806c3fb27SDimitry Andric __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); 111906c3fb27SDimitry Andric } 112006c3fb27SDimitry Andric 112106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 112206c3fb27SDimitry Andric void __annotate_increase_back(size_type __n) const _NOEXCEPT { 112306c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); 112406c3fb27SDimitry Andric } 112506c3fb27SDimitry Andric 112606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 112706c3fb27SDimitry Andric void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { 112806c3fb27SDimitry Andric __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); 112906c3fb27SDimitry Andric } 113006c3fb27SDimitry Andric 113106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 113206c3fb27SDimitry Andric void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { 113306c3fb27SDimitry Andric __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); 113406c3fb27SDimitry Andric } 113506c3fb27SDimitry Andric 113606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 113706c3fb27SDimitry Andric void __annotate_poison_block(const void *__beginning, const void *__end) const _NOEXCEPT { 113806c3fb27SDimitry Andric __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end); 113906c3fb27SDimitry Andric } 114006c3fb27SDimitry Andric 114106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 114206c3fb27SDimitry Andric void __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { 114306c3fb27SDimitry Andric __map_const_iterator __block_it = __map_.begin() + __block_index; 114406c3fb27SDimitry Andric const void* __block_start = std::__to_address(*__block_it); 114506c3fb27SDimitry Andric const void* __block_end = std::__to_address(*__block_it + __block_size); 114606c3fb27SDimitry Andric 114706c3fb27SDimitry Andric if(__annotation_type == __asan_poison) 114806c3fb27SDimitry Andric __annotate_poison_block(__block_start, __block_end); 114906c3fb27SDimitry Andric else { 115006c3fb27SDimitry Andric __annotate_double_ended_contiguous_container( 115106c3fb27SDimitry Andric __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); 115206c3fb27SDimitry Andric } 115306c3fb27SDimitry Andric } 115406c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) 115506c3fb27SDimitry Andric 115606c3fb27SDimitry Andric public: 115706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 115806c3fb27SDimitry Andric bool __verify_asan_annotations() const _NOEXCEPT { 115906c3fb27SDimitry Andric // This function tests deque object annotations. 116006c3fb27SDimitry Andric if (empty()) { 116106c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 116206c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 116306c3fb27SDimitry Andric std::__to_address(*__it), 116406c3fb27SDimitry Andric std::__to_address(*__it), 116506c3fb27SDimitry Andric std::__to_address(*__it), 116606c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 116706c3fb27SDimitry Andric return false; 116806c3fb27SDimitry Andric } 116906c3fb27SDimitry Andric 117006c3fb27SDimitry Andric return true; 117106c3fb27SDimitry Andric } 117206c3fb27SDimitry Andric 117306c3fb27SDimitry Andric size_type __end = __start_ + size(); 117406c3fb27SDimitry Andric __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; 117506c3fb27SDimitry Andric __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; 117606c3fb27SDimitry Andric 117706c3fb27SDimitry Andric // Pointers to first and after last elements 117806c3fb27SDimitry Andric // Those can be in different deque blocks 117906c3fb27SDimitry Andric const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); 118006c3fb27SDimitry Andric const void* __p_end = 118106c3fb27SDimitry Andric std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); 118206c3fb27SDimitry Andric 118306c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 118406c3fb27SDimitry Andric // Go over all blocks, find the place we are in and verify its annotations 118506c3fb27SDimitry Andric // Note that __p_end points *behind* the last item. 118606c3fb27SDimitry Andric 118706c3fb27SDimitry Andric // - blocks before the first block with container elements 118806c3fb27SDimitry Andric // - first block with items 118906c3fb27SDimitry Andric // - last block with items 119006c3fb27SDimitry Andric // - blocks after last block with ciontainer elements 119106c3fb27SDimitry Andric 119206c3fb27SDimitry Andric // Is the block before or after deque blocks that contain elements? 119306c3fb27SDimitry Andric if (__it < __first_mp || __it > __last_mp) { 119406c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 119506c3fb27SDimitry Andric std::__to_address(*__it), 119606c3fb27SDimitry Andric std::__to_address(*__it), 119706c3fb27SDimitry Andric std::__to_address(*__it), 119806c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 119906c3fb27SDimitry Andric return false; 120006c3fb27SDimitry Andric } else { 120106c3fb27SDimitry Andric const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); 120206c3fb27SDimitry Andric const void* __containers_buffer_end = 120306c3fb27SDimitry Andric (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); 120406c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 120506c3fb27SDimitry Andric std::__to_address(*__it), 120606c3fb27SDimitry Andric __containers_buffer_beg, 120706c3fb27SDimitry Andric __containers_buffer_end, 120806c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) { 120906c3fb27SDimitry Andric return false; 121006c3fb27SDimitry Andric } 121106c3fb27SDimitry Andric } 121206c3fb27SDimitry Andric } 121306c3fb27SDimitry Andric return true; 121406c3fb27SDimitry Andric } 121506c3fb27SDimitry Andric 121606c3fb27SDimitry Andric private: 121706c3fb27SDimitry Andric#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS 1218bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 1219e40139ffSDimitry Andric bool __maybe_remove_front_spare(bool __keep_one = true) { 1220e40139ffSDimitry Andric if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { 122106c3fb27SDimitry Andric __annotate_whole_block(0, __asan_unposion); 1222bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.front(), 1223bdd1243dSDimitry Andric __block_size); 1224bdd1243dSDimitry Andric __map_.pop_front(); 1225bdd1243dSDimitry Andric __start_ -= __block_size; 1226e40139ffSDimitry Andric return true; 1227e40139ffSDimitry Andric } 1228e40139ffSDimitry Andric return false; 1229e40139ffSDimitry Andric } 1230e40139ffSDimitry Andric 1231bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 1232e40139ffSDimitry Andric bool __maybe_remove_back_spare(bool __keep_one = true) { 1233e40139ffSDimitry Andric if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { 123406c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_unposion); 1235bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.back(), 1236bdd1243dSDimitry Andric __block_size); 1237bdd1243dSDimitry Andric __map_.pop_back(); 1238e40139ffSDimitry Andric return true; 1239e40139ffSDimitry Andric } 1240e40139ffSDimitry Andric return false; 1241e40139ffSDimitry Andric } 12420b57cec5SDimitry Andric 124306c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 124406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 124506c3fb27SDimitry Andric void __assign_with_sentinel(_Iterator __f, _Sentinel __l); 124606c3fb27SDimitry Andric 124706c3fb27SDimitry Andric template <class _RandomAccessIterator> 124806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 124906c3fb27SDimitry Andric void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); 125006c3fb27SDimitry Andric template <class _Iterator> 125106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 125206c3fb27SDimitry Andric void __assign_with_size(_Iterator __f, difference_type __n); 125306c3fb27SDimitry Andric 125406c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 125506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 125606c3fb27SDimitry Andric iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); 125706c3fb27SDimitry Andric 125806c3fb27SDimitry Andric template <class _Iterator> 125906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 126006c3fb27SDimitry Andric iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); 126106c3fb27SDimitry Andric 126206c3fb27SDimitry Andric template <class _BiIter, class _Sentinel> 126306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 126406c3fb27SDimitry Andric iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); 126506c3fb27SDimitry Andric template <class _BiIter> 126606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 126706c3fb27SDimitry Andric iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); 126806c3fb27SDimitry Andric 1269*5f757f3fSDimitry Andric template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> = 0> 1270*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l); 1271*5f757f3fSDimitry Andric template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> = 0> 1272*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l); 127306c3fb27SDimitry Andric 127406c3fb27SDimitry Andric template <class _InputIterator> 127506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); 127606c3fb27SDimitry Andric template <class _InputIterator, class _Sentinel> 127706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); 127806c3fb27SDimitry Andric 1279bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); 1280bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); 1281bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); 1282bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(); 1283bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n); 1284bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(); 1285bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n); 1286bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, 12870b57cec5SDimitry Andric const_pointer& __vt); 1288bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r, 12890b57cec5SDimitry Andric const_pointer& __vt); 1290bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, 12910b57cec5SDimitry Andric iterator __r, const_pointer& __vt); 1292bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_construct_backward_and_check(iterator __f, iterator __l, 12930b57cec5SDimitry Andric iterator __r, const_pointer& __vt); 12940b57cec5SDimitry Andric 1295bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 12960b57cec5SDimitry Andric void __copy_assign_alloc(const deque& __c) 12970b57cec5SDimitry Andric {__copy_assign_alloc(__c, integral_constant<bool, 12980b57cec5SDimitry Andric __alloc_traits::propagate_on_container_copy_assignment::value>());} 12990b57cec5SDimitry Andric 1300bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 13010b57cec5SDimitry Andric void __copy_assign_alloc(const deque& __c, true_type) 13020b57cec5SDimitry Andric { 1303bdd1243dSDimitry Andric if (__alloc() != __c.__alloc()) 13040b57cec5SDimitry Andric { 13050b57cec5SDimitry Andric clear(); 13060b57cec5SDimitry Andric shrink_to_fit(); 13070b57cec5SDimitry Andric } 1308bdd1243dSDimitry Andric __alloc() = __c.__alloc(); 1309bdd1243dSDimitry Andric __map_.__alloc() = __c.__map_.__alloc(); 13100b57cec5SDimitry Andric } 13110b57cec5SDimitry Andric 1312bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 13130b57cec5SDimitry Andric void __copy_assign_alloc(const deque&, false_type) 13140b57cec5SDimitry Andric {} 13150b57cec5SDimitry Andric 1316bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type) 13170b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 1318bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type); 13190b57cec5SDimitry Andric}; 13200b57cec5SDimitry Andric 1321bdd1243dSDimitry Andrictemplate <class _Tp, class _Alloc> 1322bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size = 1323bdd1243dSDimitry Andric __deque_block_size<value_type, difference_type>::value; 1324bdd1243dSDimitry Andric 1325349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17 13260b57cec5SDimitry Andrictemplate<class _InputIterator, 1327fe6060f1SDimitry Andric class _Alloc = allocator<__iter_value_type<_InputIterator>>, 132806c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1329349cc55cSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> 13300b57cec5SDimitry Andric > 13310b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator) 1332fe6060f1SDimitry Andric -> deque<__iter_value_type<_InputIterator>, _Alloc>; 13330b57cec5SDimitry Andric 13340b57cec5SDimitry Andrictemplate<class _InputIterator, 13350b57cec5SDimitry Andric class _Alloc, 133606c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1337349cc55cSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> 13380b57cec5SDimitry Andric > 13390b57cec5SDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc) 1340fe6060f1SDimitry Andric -> deque<__iter_value_type<_InputIterator>, _Alloc>; 13410b57cec5SDimitry Andric#endif 13420b57cec5SDimitry Andric 134306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 134406c3fb27SDimitry Andrictemplate <ranges::input_range _Range, 134506c3fb27SDimitry Andric class _Alloc = allocator<ranges::range_value_t<_Range>>, 134606c3fb27SDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> 134706c3fb27SDimitry Andric > 134806c3fb27SDimitry Andricdeque(from_range_t, _Range&&, _Alloc = _Alloc()) 134906c3fb27SDimitry Andric -> deque<ranges::range_value_t<_Range>, _Alloc>; 135006c3fb27SDimitry Andric#endif 135106c3fb27SDimitry Andric 13520b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13530b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n) 1354bdd1243dSDimitry Andric : __start_(0), __size_(0, __default_init_tag()) 13550b57cec5SDimitry Andric{ 135606c3fb27SDimitry Andric __annotate_new(0); 13570b57cec5SDimitry Andric if (__n > 0) 13580b57cec5SDimitry Andric __append(__n); 13590b57cec5SDimitry Andric} 13600b57cec5SDimitry Andric 136106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 13620b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13630b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) 1364bdd1243dSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) 13650b57cec5SDimitry Andric{ 136606c3fb27SDimitry Andric __annotate_new(0); 13670b57cec5SDimitry Andric if (__n > 0) 13680b57cec5SDimitry Andric __append(__n); 13690b57cec5SDimitry Andric} 13700b57cec5SDimitry Andric#endif 13710b57cec5SDimitry Andric 13720b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13730b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) 1374bdd1243dSDimitry Andric : __start_(0), __size_(0, __default_init_tag()) 13750b57cec5SDimitry Andric{ 137606c3fb27SDimitry Andric __annotate_new(0); 13770b57cec5SDimitry Andric if (__n > 0) 13780b57cec5SDimitry Andric __append(__n, __v); 13790b57cec5SDimitry Andric} 13800b57cec5SDimitry Andric 13810b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1382*5f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 1383*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l) 1384bdd1243dSDimitry Andric : __start_(0), __size_(0, __default_init_tag()) 13850b57cec5SDimitry Andric{ 138606c3fb27SDimitry Andric __annotate_new(0); 13870b57cec5SDimitry Andric __append(__f, __l); 13880b57cec5SDimitry Andric} 13890b57cec5SDimitry Andric 13900b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1391*5f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 1392*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a) 1393bdd1243dSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) 13940b57cec5SDimitry Andric{ 139506c3fb27SDimitry 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{ 140506c3fb27SDimitry 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{ 141306c3fb27SDimitry 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{ 1421*5f757f3fSDimitry Andric if (this != std::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{ 143506c3fb27SDimitry 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{ 144306c3fb27SDimitry 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> 1517*5f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value && 1518*5f757f3fSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, int> > 15190b57cec5SDimitry Andricvoid 1520*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l) 15210b57cec5SDimitry Andric{ 152206c3fb27SDimitry Andric __assign_with_sentinel(__f, __l); 152306c3fb27SDimitry Andric} 152406c3fb27SDimitry Andric 152506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 152606c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 152706c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 152806c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { 1529bdd1243dSDimitry Andric iterator __i = begin(); 1530bdd1243dSDimitry Andric iterator __e = end(); 15310b57cec5SDimitry Andric for (; __f != __l && __i != __e; ++__f, (void) ++__i) 15320b57cec5SDimitry Andric *__i = *__f; 15330b57cec5SDimitry Andric if (__f != __l) 153406c3fb27SDimitry Andric __append_with_sentinel(std::move(__f), std::move(__l)); 15350b57cec5SDimitry Andric else 15360b57cec5SDimitry Andric __erase_to_end(__i); 15370b57cec5SDimitry Andric} 15380b57cec5SDimitry Andric 15390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1540*5f757f3fSDimitry Andrictemplate <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> > 15410b57cec5SDimitry Andricvoid 1542*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l) 15430b57cec5SDimitry Andric{ 154406c3fb27SDimitry Andric __assign_with_size_random_access(__f, __l - __f); 154506c3fb27SDimitry Andric} 154606c3fb27SDimitry Andric 154706c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 154806c3fb27SDimitry Andrictemplate <class _RandomAccessIterator> 154906c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 155006c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { 155106c3fb27SDimitry Andric if (static_cast<size_type>(__n) > size()) 15520b57cec5SDimitry Andric { 155306c3fb27SDimitry Andric auto __l = __f + size(); 155406c3fb27SDimitry Andric std::copy(__f, __l, begin()); 155506c3fb27SDimitry Andric __append_with_size(__l, __n - size()); 15560b57cec5SDimitry Andric } 15570b57cec5SDimitry Andric else 155806c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 155906c3fb27SDimitry Andric} 156006c3fb27SDimitry Andric 156106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 156206c3fb27SDimitry Andrictemplate <class _Iterator> 156306c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 156406c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { 156506c3fb27SDimitry Andric if (static_cast<size_type>(__n) > size()) { 156606c3fb27SDimitry Andric auto __added_size = __n - size(); 156706c3fb27SDimitry Andric 156806c3fb27SDimitry Andric auto __i = begin(); 156906c3fb27SDimitry Andric for (auto __count = size(); __count != 0; --__count) { 157006c3fb27SDimitry Andric *__i++ = *__f++; 157106c3fb27SDimitry Andric } 157206c3fb27SDimitry Andric 157306c3fb27SDimitry Andric __append_with_size(__f, __added_size); 157406c3fb27SDimitry Andric 157506c3fb27SDimitry Andric } else { 157606c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 157706c3fb27SDimitry Andric } 15780b57cec5SDimitry Andric} 15790b57cec5SDimitry Andric 15800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15810b57cec5SDimitry Andricvoid 15820b57cec5SDimitry Andricdeque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) 15830b57cec5SDimitry Andric{ 1584bdd1243dSDimitry Andric if (__n > size()) 15850b57cec5SDimitry Andric { 1586*5f757f3fSDimitry Andric std::fill_n(begin(), size(), __v); 1587bdd1243dSDimitry Andric __n -= size(); 15880b57cec5SDimitry Andric __append(__n, __v); 15890b57cec5SDimitry Andric } 15900b57cec5SDimitry Andric else 1591*5f757f3fSDimitry Andric __erase_to_end(std::fill_n(begin(), __n, __v)); 15920b57cec5SDimitry Andric} 15930b57cec5SDimitry Andric 15940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15950b57cec5SDimitry Andricinline 15960b57cec5SDimitry Andric_Allocator 15970b57cec5SDimitry Andricdeque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT 15980b57cec5SDimitry Andric{ 1599bdd1243dSDimitry Andric return __alloc(); 16000b57cec5SDimitry Andric} 16010b57cec5SDimitry Andric 16020b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16030b57cec5SDimitry Andricvoid 16040b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n) 16050b57cec5SDimitry Andric{ 1606bdd1243dSDimitry Andric if (__n > size()) 1607bdd1243dSDimitry Andric __append(__n - size()); 1608bdd1243dSDimitry Andric else if (__n < size()) 1609bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 16100b57cec5SDimitry Andric} 16110b57cec5SDimitry Andric 16120b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16130b57cec5SDimitry Andricvoid 16140b57cec5SDimitry Andricdeque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) 16150b57cec5SDimitry Andric{ 1616bdd1243dSDimitry Andric if (__n > size()) 1617bdd1243dSDimitry Andric __append(__n - size(), __v); 1618bdd1243dSDimitry Andric else if (__n < size()) 1619bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 16200b57cec5SDimitry Andric} 16210b57cec5SDimitry Andric 16220b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16230b57cec5SDimitry Andricvoid 16240b57cec5SDimitry Andricdeque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT 16250b57cec5SDimitry Andric{ 1626bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 16270b57cec5SDimitry Andric if (empty()) 16280b57cec5SDimitry Andric { 162906c3fb27SDimitry Andric __annotate_delete(); 1630bdd1243dSDimitry Andric while (__map_.size() > 0) 16310b57cec5SDimitry Andric { 1632bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.back(), __block_size); 1633bdd1243dSDimitry Andric __map_.pop_back(); 16340b57cec5SDimitry Andric } 1635bdd1243dSDimitry Andric __start_ = 0; 16360b57cec5SDimitry Andric } 16370b57cec5SDimitry Andric else 16380b57cec5SDimitry Andric { 1639e40139ffSDimitry Andric __maybe_remove_front_spare(/*__keep_one=*/false); 1640e40139ffSDimitry Andric __maybe_remove_back_spare(/*__keep_one=*/false); 16410b57cec5SDimitry Andric } 1642bdd1243dSDimitry Andric __map_.shrink_to_fit(); 16430b57cec5SDimitry Andric} 16440b57cec5SDimitry Andric 16450b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16460b57cec5SDimitry Andricinline 16470b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 16480b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT 16490b57cec5SDimitry Andric{ 1650bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1651bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 16520b57cec5SDimitry Andric} 16530b57cec5SDimitry Andric 16540b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16550b57cec5SDimitry Andricinline 16560b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference 16570b57cec5SDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT 16580b57cec5SDimitry Andric{ 1659bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1660bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 16610b57cec5SDimitry Andric} 16620b57cec5SDimitry Andric 16630b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16640b57cec5SDimitry Andricinline 16650b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 16660b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i) 16670b57cec5SDimitry Andric{ 1668bdd1243dSDimitry Andric if (__i >= size()) 1669*5f757f3fSDimitry Andric std::__throw_out_of_range("deque"); 1670bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1671bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 16720b57cec5SDimitry Andric} 16730b57cec5SDimitry Andric 16740b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16750b57cec5SDimitry Andricinline 16760b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference 16770b57cec5SDimitry Andricdeque<_Tp, _Allocator>::at(size_type __i) const 16780b57cec5SDimitry Andric{ 1679bdd1243dSDimitry Andric if (__i >= size()) 1680*5f757f3fSDimitry Andric std::__throw_out_of_range("deque"); 1681bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1682bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 16830b57cec5SDimitry Andric} 16840b57cec5SDimitry Andric 16850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16860b57cec5SDimitry Andricinline 16870b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 16880b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() _NOEXCEPT 16890b57cec5SDimitry Andric{ 1690bdd1243dSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) 1691bdd1243dSDimitry Andric + __start_ % __block_size); 16920b57cec5SDimitry Andric} 16930b57cec5SDimitry Andric 16940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16950b57cec5SDimitry Andricinline 16960b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference 16970b57cec5SDimitry Andricdeque<_Tp, _Allocator>::front() const _NOEXCEPT 16980b57cec5SDimitry Andric{ 1699bdd1243dSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) 1700bdd1243dSDimitry Andric + __start_ % __block_size); 17010b57cec5SDimitry Andric} 17020b57cec5SDimitry Andric 17030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17040b57cec5SDimitry Andricinline 17050b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 17060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() _NOEXCEPT 17070b57cec5SDimitry Andric{ 1708bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1709bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 17100b57cec5SDimitry Andric} 17110b57cec5SDimitry Andric 17120b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17130b57cec5SDimitry Andricinline 17140b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::const_reference 17150b57cec5SDimitry Andricdeque<_Tp, _Allocator>::back() const _NOEXCEPT 17160b57cec5SDimitry Andric{ 1717bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1718bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 17190b57cec5SDimitry Andric} 17200b57cec5SDimitry Andric 17210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17220b57cec5SDimitry Andricvoid 17230b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(const value_type& __v) 17240b57cec5SDimitry Andric{ 1725bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17260b57cec5SDimitry Andric if (__back_spare() == 0) 17270b57cec5SDimitry Andric __add_back_capacity(); 17280b57cec5SDimitry Andric // __back_spare() >= 1 172906c3fb27SDimitry Andric __annotate_increase_back(1); 1730*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1731bdd1243dSDimitry Andric ++__size(); 17320b57cec5SDimitry Andric} 17330b57cec5SDimitry Andric 17340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17350b57cec5SDimitry Andricvoid 17360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(const value_type& __v) 17370b57cec5SDimitry Andric{ 1738bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17390b57cec5SDimitry Andric if (__front_spare() == 0) 17400b57cec5SDimitry Andric __add_front_capacity(); 17410b57cec5SDimitry Andric // __front_spare() >= 1 174206c3fb27SDimitry Andric __annotate_increase_front(1); 1743*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1744bdd1243dSDimitry Andric --__start_; 1745bdd1243dSDimitry Andric ++__size(); 17460b57cec5SDimitry Andric} 17470b57cec5SDimitry Andric 17480b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 17490b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17500b57cec5SDimitry Andricvoid 17510b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_back(value_type&& __v) 17520b57cec5SDimitry Andric{ 1753bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17540b57cec5SDimitry Andric if (__back_spare() == 0) 17550b57cec5SDimitry Andric __add_back_capacity(); 17560b57cec5SDimitry Andric // __back_spare() >= 1 175706c3fb27SDimitry Andric __annotate_increase_back(1); 1758*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); 1759bdd1243dSDimitry Andric ++__size(); 17600b57cec5SDimitry Andric} 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17630b57cec5SDimitry Andrictemplate <class... _Args> 176406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 17650b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 17660b57cec5SDimitry Andric#else 17670b57cec5SDimitry Andricvoid 17680b57cec5SDimitry Andric#endif 17690b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_back(_Args&&... __args) 17700b57cec5SDimitry Andric{ 1771bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17720b57cec5SDimitry Andric if (__back_spare() == 0) 17730b57cec5SDimitry Andric __add_back_capacity(); 17740b57cec5SDimitry Andric // __back_spare() >= 1 177506c3fb27SDimitry Andric __annotate_increase_back(1); 1776*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), 1777*5f757f3fSDimitry Andric std::forward<_Args>(__args)...); 1778bdd1243dSDimitry Andric ++__size(); 177906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 1780bdd1243dSDimitry Andric return *--end(); 17810b57cec5SDimitry Andric#endif 17820b57cec5SDimitry Andric} 17830b57cec5SDimitry Andric 17840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17850b57cec5SDimitry Andricvoid 17860b57cec5SDimitry Andricdeque<_Tp, _Allocator>::push_front(value_type&& __v) 17870b57cec5SDimitry Andric{ 1788bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 17890b57cec5SDimitry Andric if (__front_spare() == 0) 17900b57cec5SDimitry Andric __add_front_capacity(); 17910b57cec5SDimitry Andric // __front_spare() >= 1 179206c3fb27SDimitry Andric __annotate_increase_front(1); 1793*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); 1794bdd1243dSDimitry Andric --__start_; 1795bdd1243dSDimitry Andric ++__size(); 17960b57cec5SDimitry Andric} 17970b57cec5SDimitry Andric 17980b57cec5SDimitry Andric 17990b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18000b57cec5SDimitry Andrictemplate <class... _Args> 180106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 18020b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 18030b57cec5SDimitry Andric#else 18040b57cec5SDimitry Andricvoid 18050b57cec5SDimitry Andric#endif 18060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace_front(_Args&&... __args) 18070b57cec5SDimitry Andric{ 1808bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 18090b57cec5SDimitry Andric if (__front_spare() == 0) 18100b57cec5SDimitry Andric __add_front_capacity(); 18110b57cec5SDimitry Andric // __front_spare() >= 1 181206c3fb27SDimitry Andric __annotate_increase_front(1); 1813*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); 1814bdd1243dSDimitry Andric --__start_; 1815bdd1243dSDimitry Andric ++__size(); 181606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 1817bdd1243dSDimitry Andric return *begin(); 18180b57cec5SDimitry Andric#endif 18190b57cec5SDimitry Andric} 18200b57cec5SDimitry Andric 18210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18220b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 18230b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) 18240b57cec5SDimitry Andric{ 1825bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1826bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1827bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 18280b57cec5SDimitry Andric if (__pos < __to_end) 18290b57cec5SDimitry Andric { // insert by shifting things backward 18300b57cec5SDimitry Andric if (__front_spare() == 0) 18310b57cec5SDimitry Andric __add_front_capacity(); 18320b57cec5SDimitry Andric // __front_spare() >= 1 183306c3fb27SDimitry Andric __annotate_increase_front(1); 18340b57cec5SDimitry Andric if (__pos == 0) 18350b57cec5SDimitry Andric { 1836*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); 1837bdd1243dSDimitry Andric --__start_; 1838bdd1243dSDimitry Andric ++__size(); 18390b57cec5SDimitry Andric } 18400b57cec5SDimitry Andric else 18410b57cec5SDimitry Andric { 1842bdd1243dSDimitry Andric iterator __b = begin(); 1843*5f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 1844*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1845bdd1243dSDimitry Andric --__start_; 1846bdd1243dSDimitry Andric ++__size(); 18470b57cec5SDimitry Andric if (__pos > 1) 1848*5f757f3fSDimitry Andric __b = std::move(std::next(__b), __b + __pos, __b); 1849*5f757f3fSDimitry Andric *__b = std::move(__v); 18500b57cec5SDimitry Andric } 18510b57cec5SDimitry Andric } 18520b57cec5SDimitry Andric else 18530b57cec5SDimitry Andric { // insert by shifting things forward 18540b57cec5SDimitry Andric if (__back_spare() == 0) 18550b57cec5SDimitry Andric __add_back_capacity(); 18560b57cec5SDimitry Andric // __back_capacity >= 1 185706c3fb27SDimitry Andric __annotate_increase_back(1); 1858bdd1243dSDimitry Andric size_type __de = size() - __pos; 18590b57cec5SDimitry Andric if (__de == 0) 18600b57cec5SDimitry Andric { 1861*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); 1862bdd1243dSDimitry Andric ++__size(); 18630b57cec5SDimitry Andric } 18640b57cec5SDimitry Andric else 18650b57cec5SDimitry Andric { 1866bdd1243dSDimitry Andric iterator __e = end(); 1867*5f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 1868*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1869bdd1243dSDimitry Andric ++__size(); 18700b57cec5SDimitry Andric if (__de > 1) 1871*5f757f3fSDimitry Andric __e = std::move_backward(__e - __de, __em1, __e); 1872*5f757f3fSDimitry Andric *--__e = std::move(__v); 18730b57cec5SDimitry Andric } 18740b57cec5SDimitry Andric } 1875bdd1243dSDimitry Andric return begin() + __pos; 18760b57cec5SDimitry Andric} 18770b57cec5SDimitry Andric 18780b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18790b57cec5SDimitry Andrictemplate <class... _Args> 18800b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 18810b57cec5SDimitry Andricdeque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) 18820b57cec5SDimitry Andric{ 1883bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1884bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1885bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 18860b57cec5SDimitry Andric if (__pos < __to_end) 18870b57cec5SDimitry Andric { // insert by shifting things backward 18880b57cec5SDimitry Andric if (__front_spare() == 0) 18890b57cec5SDimitry Andric __add_front_capacity(); 18900b57cec5SDimitry Andric // __front_spare() >= 1 189106c3fb27SDimitry Andric __annotate_increase_front(1); 18920b57cec5SDimitry Andric if (__pos == 0) 18930b57cec5SDimitry Andric { 1894*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); 1895bdd1243dSDimitry Andric --__start_; 1896bdd1243dSDimitry Andric ++__size(); 18970b57cec5SDimitry Andric } 18980b57cec5SDimitry Andric else 18990b57cec5SDimitry Andric { 1900*5f757f3fSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); 1901bdd1243dSDimitry Andric iterator __b = begin(); 1902*5f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 1903*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1904bdd1243dSDimitry Andric --__start_; 1905bdd1243dSDimitry Andric ++__size(); 19060b57cec5SDimitry Andric if (__pos > 1) 1907*5f757f3fSDimitry Andric __b = std::move(std::next(__b), __b + __pos, __b); 1908*5f757f3fSDimitry Andric *__b = std::move(__tmp.get()); 19090b57cec5SDimitry Andric } 19100b57cec5SDimitry Andric } 19110b57cec5SDimitry Andric else 19120b57cec5SDimitry Andric { // insert by shifting things forward 19130b57cec5SDimitry Andric if (__back_spare() == 0) 19140b57cec5SDimitry Andric __add_back_capacity(); 19150b57cec5SDimitry Andric // __back_capacity >= 1 191606c3fb27SDimitry Andric __annotate_increase_back(1); 1917bdd1243dSDimitry Andric size_type __de = size() - __pos; 19180b57cec5SDimitry Andric if (__de == 0) 19190b57cec5SDimitry Andric { 1920*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); 1921bdd1243dSDimitry Andric ++__size(); 19220b57cec5SDimitry Andric } 19230b57cec5SDimitry Andric else 19240b57cec5SDimitry Andric { 1925*5f757f3fSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); 1926bdd1243dSDimitry Andric iterator __e = end(); 1927*5f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 1928*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1929bdd1243dSDimitry Andric ++__size(); 19300b57cec5SDimitry Andric if (__de > 1) 1931*5f757f3fSDimitry Andric __e = std::move_backward(__e - __de, __em1, __e); 1932*5f757f3fSDimitry Andric *--__e = std::move(__tmp.get()); 19330b57cec5SDimitry Andric } 19340b57cec5SDimitry Andric } 1935bdd1243dSDimitry Andric return begin() + __pos; 19360b57cec5SDimitry Andric} 19370b57cec5SDimitry Andric 19380b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric 19410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 19420b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 19430b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) 19440b57cec5SDimitry Andric{ 1945bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1946bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1947bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19480b57cec5SDimitry Andric if (__pos < __to_end) 19490b57cec5SDimitry Andric { // insert by shifting things backward 19500b57cec5SDimitry Andric if (__front_spare() == 0) 19510b57cec5SDimitry Andric __add_front_capacity(); 19520b57cec5SDimitry Andric // __front_spare() >= 1 195306c3fb27SDimitry Andric __annotate_increase_front(1); 19540b57cec5SDimitry Andric if (__pos == 0) 19550b57cec5SDimitry Andric { 1956*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1957bdd1243dSDimitry Andric --__start_; 1958bdd1243dSDimitry Andric ++__size(); 19590b57cec5SDimitry Andric } 19600b57cec5SDimitry Andric else 19610b57cec5SDimitry Andric { 19620b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1963bdd1243dSDimitry Andric iterator __b = begin(); 1964*5f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 19650b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__b)) 19660b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__bm1); 1967*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1968bdd1243dSDimitry Andric --__start_; 1969bdd1243dSDimitry Andric ++__size(); 19700b57cec5SDimitry Andric if (__pos > 1) 1971*5f757f3fSDimitry Andric __b = __move_and_check(std::next(__b), __b + __pos, __b, __vt); 19720b57cec5SDimitry Andric *__b = *__vt; 19730b57cec5SDimitry Andric } 19740b57cec5SDimitry Andric } 19750b57cec5SDimitry Andric else 19760b57cec5SDimitry Andric { // insert by shifting things forward 19770b57cec5SDimitry Andric if (__back_spare() == 0) 19780b57cec5SDimitry Andric __add_back_capacity(); 19790b57cec5SDimitry Andric // __back_capacity >= 1 198006c3fb27SDimitry Andric __annotate_increase_back(1); 1981bdd1243dSDimitry Andric size_type __de = size() - __pos; 19820b57cec5SDimitry Andric if (__de == 0) 19830b57cec5SDimitry Andric { 1984*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1985bdd1243dSDimitry Andric ++__size(); 19860b57cec5SDimitry Andric } 19870b57cec5SDimitry Andric else 19880b57cec5SDimitry Andric { 19890b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1990bdd1243dSDimitry Andric iterator __e = end(); 1991*5f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 19920b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1)) 19930b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__e); 1994*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1995bdd1243dSDimitry Andric ++__size(); 19960b57cec5SDimitry Andric if (__de > 1) 19970b57cec5SDimitry Andric __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); 19980b57cec5SDimitry Andric *--__e = *__vt; 19990b57cec5SDimitry Andric } 20000b57cec5SDimitry Andric } 2001bdd1243dSDimitry Andric return begin() + __pos; 20020b57cec5SDimitry Andric} 20030b57cec5SDimitry Andric 20040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 20050b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 20060b57cec5SDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) 20070b57cec5SDimitry Andric{ 2008bdd1243dSDimitry Andric size_type __pos = __p - begin(); 2009bdd1243dSDimitry Andric size_type __to_end = __size() - __pos; 2010bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 20110b57cec5SDimitry Andric if (__pos < __to_end) 20120b57cec5SDimitry Andric { // insert by shifting things backward 20130b57cec5SDimitry Andric if (__n > __front_spare()) 20140b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 20150b57cec5SDimitry Andric // __n <= __front_spare() 201606c3fb27SDimitry Andric __annotate_increase_front(__n); 2017bdd1243dSDimitry Andric iterator __old_begin = begin(); 20180b57cec5SDimitry Andric iterator __i = __old_begin; 20190b57cec5SDimitry Andric if (__n > __pos) 20200b57cec5SDimitry Andric { 2021bdd1243dSDimitry Andric for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size()) 2022*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), __v); 20230b57cec5SDimitry Andric __n = __pos; 20240b57cec5SDimitry Andric } 20250b57cec5SDimitry Andric if (__n > 0) 20260b57cec5SDimitry Andric { 20270b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 20280b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 20290b57cec5SDimitry Andric __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); 20300b57cec5SDimitry Andric if (__n < __pos) 20310b57cec5SDimitry Andric __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); 2032*5f757f3fSDimitry Andric std::fill_n(__old_begin, __n, *__vt); 20330b57cec5SDimitry Andric } 20340b57cec5SDimitry Andric } 20350b57cec5SDimitry Andric else 20360b57cec5SDimitry Andric { // insert by shifting things forward 20370b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 20380b57cec5SDimitry Andric if (__n > __back_capacity) 20390b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 20400b57cec5SDimitry Andric // __n <= __back_capacity 204106c3fb27SDimitry Andric __annotate_increase_back(__n); 2042bdd1243dSDimitry Andric iterator __old_end = end(); 20430b57cec5SDimitry Andric iterator __i = __old_end; 2044bdd1243dSDimitry Andric size_type __de = size() - __pos; 20450b57cec5SDimitry Andric if (__n > __de) 20460b57cec5SDimitry Andric { 2047bdd1243dSDimitry Andric for (size_type __m = __n - __de; __m; --__m, (void) ++__i, ++__size()) 2048*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), __v); 20490b57cec5SDimitry Andric __n = __de; 20500b57cec5SDimitry Andric } 20510b57cec5SDimitry Andric if (__n > 0) 20520b57cec5SDimitry Andric { 20530b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 20540b57cec5SDimitry Andric iterator __oen = __old_end - __n; 20550b57cec5SDimitry Andric __move_construct_and_check(__oen, __old_end, __i, __vt); 20560b57cec5SDimitry Andric if (__n < __de) 20570b57cec5SDimitry Andric __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); 2058*5f757f3fSDimitry Andric std::fill_n(__old_end - __n, __n, *__vt); 20590b57cec5SDimitry Andric } 20600b57cec5SDimitry Andric } 2061bdd1243dSDimitry Andric return begin() + __pos; 20620b57cec5SDimitry Andric} 20630b57cec5SDimitry Andric 20640b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2065*5f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> > 20660b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2067*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l) 20680b57cec5SDimitry Andric{ 206906c3fb27SDimitry Andric return __insert_with_sentinel(__p, __f, __l); 207006c3fb27SDimitry Andric} 207106c3fb27SDimitry Andric 207206c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 207306c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 207406c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 207506c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 207606c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { 2077bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__alloc()); 207806c3fb27SDimitry Andric __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); 20790b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; 20800b57cec5SDimitry Andric return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); 20810b57cec5SDimitry Andric} 20820b57cec5SDimitry Andric 20830b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2084*5f757f3fSDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> > 20850b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2086*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l) 20870b57cec5SDimitry Andric{ 208806c3fb27SDimitry Andric return __insert_with_size(__p, __f, std::distance(__f, __l)); 208906c3fb27SDimitry Andric} 209006c3fb27SDimitry Andric 209106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 209206c3fb27SDimitry Andrictemplate <class _Iterator> 209306c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 209406c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 209506c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) { 2096bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); 209706c3fb27SDimitry Andric __buf.__construct_at_end_with_size(__f, __n); 20980b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; 20990b57cec5SDimitry Andric return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); 21000b57cec5SDimitry Andric} 21010b57cec5SDimitry Andric 21020b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2103*5f757f3fSDimitry Andrictemplate <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> > 21040b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2105*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l) 21060b57cec5SDimitry Andric{ 210706c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l)); 210806c3fb27SDimitry Andric} 210906c3fb27SDimitry Andric 211006c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 211106c3fb27SDimitry Andrictemplate <class _BiIter, class _Sentinel> 211206c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 211306c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 211406c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) { 211506c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, std::next(__f, __n), __n); 211606c3fb27SDimitry Andric} 211706c3fb27SDimitry Andric 211806c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 211906c3fb27SDimitry Andrictemplate <class _BiIter> 212006c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 212106c3fb27SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 212206c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) { 2123bdd1243dSDimitry Andric size_type __pos = __p - begin(); 2124bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 2125bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 21260b57cec5SDimitry Andric if (__pos < __to_end) 21270b57cec5SDimitry Andric { // insert by shifting things backward 21280b57cec5SDimitry Andric if (__n > __front_spare()) 21290b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 21300b57cec5SDimitry Andric // __n <= __front_spare() 213106c3fb27SDimitry Andric __annotate_increase_front(__n); 2132bdd1243dSDimitry Andric iterator __old_begin = begin(); 21330b57cec5SDimitry Andric iterator __i = __old_begin; 21340b57cec5SDimitry Andric _BiIter __m = __f; 21350b57cec5SDimitry Andric if (__n > __pos) 21360b57cec5SDimitry Andric { 2137*5f757f3fSDimitry Andric __m = __pos < __n / 2 ? std::prev(__l, __pos) : std::next(__f, __n - __pos); 2138bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __f; --__start_, ++__size()) 2139*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), *--__j); 21400b57cec5SDimitry Andric __n = __pos; 21410b57cec5SDimitry Andric } 21420b57cec5SDimitry Andric if (__n > 0) 21430b57cec5SDimitry Andric { 21440b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 21450b57cec5SDimitry Andric for (iterator __j = __obn; __j != __old_begin;) 21460b57cec5SDimitry Andric { 2147*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), std::move(*--__j)); 2148bdd1243dSDimitry Andric --__start_; 2149bdd1243dSDimitry Andric ++__size(); 21500b57cec5SDimitry Andric } 21510b57cec5SDimitry Andric if (__n < __pos) 2152*5f757f3fSDimitry Andric __old_begin = std::move(__obn, __old_begin + __pos, __old_begin); 2153*5f757f3fSDimitry Andric std::copy(__m, __l, __old_begin); 21540b57cec5SDimitry Andric } 21550b57cec5SDimitry Andric } 21560b57cec5SDimitry Andric else 21570b57cec5SDimitry Andric { // insert by shifting things forward 21580b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 21590b57cec5SDimitry Andric if (__n > __back_capacity) 21600b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 21610b57cec5SDimitry Andric // __n <= __back_capacity 216206c3fb27SDimitry Andric __annotate_increase_back(__n); 2163bdd1243dSDimitry Andric iterator __old_end = end(); 21640b57cec5SDimitry Andric iterator __i = __old_end; 21650b57cec5SDimitry Andric _BiIter __m = __l; 2166bdd1243dSDimitry Andric size_type __de = size() - __pos; 21670b57cec5SDimitry Andric if (__n > __de) 21680b57cec5SDimitry Andric { 2169*5f757f3fSDimitry Andric __m = __de < __n / 2 ? std::next(__f, __de) : std::prev(__l, __n - __de); 2170bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__size()) 2171*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), *__j); 21720b57cec5SDimitry Andric __n = __de; 21730b57cec5SDimitry Andric } 21740b57cec5SDimitry Andric if (__n > 0) 21750b57cec5SDimitry Andric { 21760b57cec5SDimitry Andric iterator __oen = __old_end - __n; 2177bdd1243dSDimitry Andric for (iterator __j = __oen; __j != __old_end; ++__i, (void) ++__j, ++__size()) 2178*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), std::move(*__j)); 21790b57cec5SDimitry Andric if (__n < __de) 2180*5f757f3fSDimitry Andric __old_end = std::move_backward(__old_end - __de, __oen, __old_end); 2181*5f757f3fSDimitry Andric std::copy_backward(__f, __m, __old_end); 21820b57cec5SDimitry Andric } 21830b57cec5SDimitry Andric } 2184bdd1243dSDimitry Andric return begin() + __pos; 21850b57cec5SDimitry Andric} 21860b57cec5SDimitry Andric 21870b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2188*5f757f3fSDimitry Andrictemplate <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> > 21890b57cec5SDimitry Andricvoid 2190*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l) 21910b57cec5SDimitry Andric{ 219206c3fb27SDimitry Andric __append_with_sentinel(__f, __l); 219306c3fb27SDimitry Andric} 219406c3fb27SDimitry Andric 219506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 219606c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 219706c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 219806c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { 21990b57cec5SDimitry Andric for (; __f != __l; ++__f) 22000b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 22010b57cec5SDimitry Andric push_back(*__f); 22020b57cec5SDimitry Andric#else 22030b57cec5SDimitry Andric emplace_back(*__f); 22040b57cec5SDimitry Andric#endif 22050b57cec5SDimitry Andric} 22060b57cec5SDimitry Andric 22070b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2208*5f757f3fSDimitry Andrictemplate <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> > 22090b57cec5SDimitry Andricvoid 2210*5f757f3fSDimitry Andricdeque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l) 22110b57cec5SDimitry Andric{ 221206c3fb27SDimitry Andric __append_with_size(__f, std::distance(__f, __l)); 221306c3fb27SDimitry Andric} 221406c3fb27SDimitry Andric 221506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 221606c3fb27SDimitry Andrictemplate <class _InputIterator> 221706c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 221806c3fb27SDimitry Andricvoid deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { 2219bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 22200b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 22210b57cec5SDimitry Andric if (__n > __back_capacity) 22220b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 222306c3fb27SDimitry Andric 22240b57cec5SDimitry Andric // __n <= __back_capacity 222506c3fb27SDimitry Andric __annotate_increase_back(__n); 2226bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 2227e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 2228e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { 2229*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); 2230e40139ffSDimitry Andric } 2231e40139ffSDimitry Andric } 22320b57cec5SDimitry Andric} 22330b57cec5SDimitry Andric 22340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22350b57cec5SDimitry Andricvoid 22360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n) 22370b57cec5SDimitry Andric{ 2238bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 22390b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 22400b57cec5SDimitry Andric if (__n > __back_capacity) 22410b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 22420b57cec5SDimitry Andric // __n <= __back_capacity 224306c3fb27SDimitry Andric __annotate_increase_back(__n); 2244bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 2245e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 2246e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 2247*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); 2248e40139ffSDimitry Andric } 2249e40139ffSDimitry Andric } 22500b57cec5SDimitry Andric} 22510b57cec5SDimitry Andric 22520b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22530b57cec5SDimitry Andricvoid 22540b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) 22550b57cec5SDimitry Andric{ 2256bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 22570b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 22580b57cec5SDimitry Andric if (__n > __back_capacity) 22590b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 22600b57cec5SDimitry Andric // __n <= __back_capacity 226106c3fb27SDimitry Andric __annotate_increase_back(__n); 2262bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 2263e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 2264e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 2265*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); 2266e40139ffSDimitry Andric } 2267e40139ffSDimitry Andric } 2268e40139ffSDimitry Andric 22690b57cec5SDimitry Andric} 22700b57cec5SDimitry Andric 22710b57cec5SDimitry Andric// Create front capacity for one block of elements. 22720b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 22730b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22740b57cec5SDimitry Andricvoid 22750b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity() 22760b57cec5SDimitry Andric{ 2277bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2278bdd1243dSDimitry Andric if (__back_spare() >= __block_size) 22790b57cec5SDimitry Andric { 2280bdd1243dSDimitry Andric __start_ += __block_size; 2281bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2282bdd1243dSDimitry Andric __map_.pop_back(); 2283bdd1243dSDimitry Andric __map_.push_front(__pt); 22840b57cec5SDimitry Andric } 2285bdd1243dSDimitry Andric // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer 2286bdd1243dSDimitry Andric else if (__map_.size() < __map_.capacity()) 22870b57cec5SDimitry Andric { // we can put the new buffer into the map, but don't shift things around 22880b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 22890b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2290bdd1243dSDimitry Andric if (__map_.__front_spare() > 0) 2291bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 22920b57cec5SDimitry Andric else 22930b57cec5SDimitry Andric { 2294bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 22950b57cec5SDimitry Andric // Done allocating, reorder capacity 2296bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2297bdd1243dSDimitry Andric __map_.pop_back(); 2298bdd1243dSDimitry Andric __map_.push_front(__pt); 22990b57cec5SDimitry Andric } 2300bdd1243dSDimitry Andric __start_ = __map_.size() == 1 ? 2301bdd1243dSDimitry Andric __block_size / 2 : 2302bdd1243dSDimitry Andric __start_ + __block_size; 23030b57cec5SDimitry Andric } 23040b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 23050b57cec5SDimitry Andric else 23060b57cec5SDimitry Andric { 2307bdd1243dSDimitry Andric __split_buffer<pointer, __pointer_allocator&> 2308bdd1243dSDimitry Andric __buf(std::max<size_type>(2 * __map_.capacity(), 1), 2309bdd1243dSDimitry Andric 0, __map_.__alloc()); 23100b57cec5SDimitry Andric 23110b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 23120b57cec5SDimitry Andric unique_ptr<pointer, _Dp> __hold( 2313bdd1243dSDimitry Andric __alloc_traits::allocate(__a, __block_size), 2314bdd1243dSDimitry Andric _Dp(__a, __block_size)); 23150b57cec5SDimitry Andric __buf.push_back(__hold.get()); 23160b57cec5SDimitry Andric __hold.release(); 23170b57cec5SDimitry Andric 2318bdd1243dSDimitry Andric for (__map_pointer __i = __map_.begin(); 2319bdd1243dSDimitry Andric __i != __map_.end(); ++__i) 23200b57cec5SDimitry Andric __buf.push_back(*__i); 2321*5f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 2322*5f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 2323*5f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 2324*5f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2325bdd1243dSDimitry Andric __start_ = __map_.size() == 1 ? 2326bdd1243dSDimitry Andric __block_size / 2 : 2327bdd1243dSDimitry Andric __start_ + __block_size; 23280b57cec5SDimitry Andric } 232906c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 23300b57cec5SDimitry Andric} 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andric// Create front capacity for __n elements. 23330b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 23340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 23350b57cec5SDimitry Andricvoid 23360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_front_capacity(size_type __n) 23370b57cec5SDimitry Andric{ 2338bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2339bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 23400b57cec5SDimitry Andric // Number of unused blocks at back: 2341bdd1243dSDimitry Andric size_type __back_capacity = __back_spare() / __block_size; 2342*5f757f3fSDimitry Andric __back_capacity = std::min(__back_capacity, __nb); // don't take more than you need 23430b57cec5SDimitry Andric __nb -= __back_capacity; // number of blocks need to allocate 23440b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 23450b57cec5SDimitry Andric if (__nb == 0) 23460b57cec5SDimitry Andric { 2347bdd1243dSDimitry Andric __start_ += __block_size * __back_capacity; 23480b57cec5SDimitry Andric for (; __back_capacity > 0; --__back_capacity) 23490b57cec5SDimitry Andric { 2350bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2351bdd1243dSDimitry Andric __map_.pop_back(); 2352bdd1243dSDimitry Andric __map_.push_front(__pt); 23530b57cec5SDimitry Andric } 23540b57cec5SDimitry Andric } 23550b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2356bdd1243dSDimitry Andric else if (__nb <= __map_.capacity() - __map_.size()) 23570b57cec5SDimitry Andric { // we can put the new buffers into the map, but don't shift things around 23580b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 23590b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2360bdd1243dSDimitry Andric for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) 23610b57cec5SDimitry Andric { 2362bdd1243dSDimitry Andric if (__map_.__front_spare() == 0) 23630b57cec5SDimitry Andric break; 2364bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 236506c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 23660b57cec5SDimitry Andric } 23670b57cec5SDimitry Andric for (; __nb > 0; --__nb, ++__back_capacity) 2368bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 23690b57cec5SDimitry Andric // Done allocating, reorder capacity 2370bdd1243dSDimitry Andric __start_ += __back_capacity * __block_size; 23710b57cec5SDimitry Andric for (; __back_capacity > 0; --__back_capacity) 23720b57cec5SDimitry Andric { 2373bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2374bdd1243dSDimitry Andric __map_.pop_back(); 2375bdd1243dSDimitry Andric __map_.push_front(__pt); 237606c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 23770b57cec5SDimitry Andric } 23780b57cec5SDimitry Andric } 23790b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 23800b57cec5SDimitry Andric else 23810b57cec5SDimitry Andric { 2382bdd1243dSDimitry Andric size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty(); 2383bdd1243dSDimitry Andric __split_buffer<pointer, __pointer_allocator&> 2384bdd1243dSDimitry Andric __buf(std::max<size_type>(2* __map_.capacity(), 2385bdd1243dSDimitry Andric __nb + __map_.size()), 2386bdd1243dSDimitry Andric 0, __map_.__alloc()); 238706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 23880b57cec5SDimitry Andric try 23890b57cec5SDimitry Andric { 239006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 239106c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2392bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 239306c3fb27SDimitry Andric // ASan: this is empty container, we have to poison whole block 239406c3fb27SDimitry Andric __annotate_poison_block( 239506c3fb27SDimitry Andric std::__to_address(__buf.back()), 239606c3fb27SDimitry Andric std::__to_address(__buf.back() + __block_size)); 239706c3fb27SDimitry Andric } 239806c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 23990b57cec5SDimitry Andric } 24000b57cec5SDimitry Andric catch (...) 24010b57cec5SDimitry Andric { 240206c3fb27SDimitry Andric __annotate_delete(); 2403bdd1243dSDimitry Andric for (__map_pointer __i = __buf.begin(); 24040b57cec5SDimitry Andric __i != __buf.end(); ++__i) 2405bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 24060b57cec5SDimitry Andric throw; 24070b57cec5SDimitry Andric } 240806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 24090b57cec5SDimitry Andric for (; __back_capacity > 0; --__back_capacity) 24100b57cec5SDimitry Andric { 2411bdd1243dSDimitry Andric __buf.push_back(__map_.back()); 2412bdd1243dSDimitry Andric __map_.pop_back(); 24130b57cec5SDimitry Andric } 2414bdd1243dSDimitry Andric for (__map_pointer __i = __map_.begin(); 2415bdd1243dSDimitry Andric __i != __map_.end(); ++__i) 24160b57cec5SDimitry Andric __buf.push_back(*__i); 2417*5f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 2418*5f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 2419*5f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 2420*5f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2421bdd1243dSDimitry Andric __start_ += __ds; 24220b57cec5SDimitry Andric } 24230b57cec5SDimitry Andric} 24240b57cec5SDimitry Andric 24250b57cec5SDimitry Andric// Create back capacity for one block of elements. 24260b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 24270b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 24280b57cec5SDimitry Andricvoid 24290b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity() 24300b57cec5SDimitry Andric{ 2431bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2432bdd1243dSDimitry Andric if (__front_spare() >= __block_size) 24330b57cec5SDimitry Andric { 2434bdd1243dSDimitry Andric __start_ -= __block_size; 2435bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2436bdd1243dSDimitry Andric __map_.pop_front(); 2437bdd1243dSDimitry Andric __map_.push_back(__pt); 24380b57cec5SDimitry Andric } 24390b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2440bdd1243dSDimitry Andric else if (__map_.size() < __map_.capacity()) 24410b57cec5SDimitry Andric { // we can put the new buffer into the map, but don't shift things around 24420b57cec5SDimitry Andric // until it is allocated. If we throw, we don't need to fix 24430b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2444bdd1243dSDimitry Andric if (__map_.__back_spare() != 0) 2445bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 24460b57cec5SDimitry Andric else 24470b57cec5SDimitry Andric { 2448bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 24490b57cec5SDimitry Andric // Done allocating, reorder capacity 2450bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2451bdd1243dSDimitry Andric __map_.pop_front(); 2452bdd1243dSDimitry Andric __map_.push_back(__pt); 24530b57cec5SDimitry Andric } 245406c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 24550b57cec5SDimitry Andric } 24560b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 24570b57cec5SDimitry Andric else 24580b57cec5SDimitry Andric { 2459bdd1243dSDimitry Andric __split_buffer<pointer, __pointer_allocator&> 2460bdd1243dSDimitry Andric __buf(std::max<size_type>(2* __map_.capacity(), 1), 2461bdd1243dSDimitry Andric __map_.size(), 2462bdd1243dSDimitry Andric __map_.__alloc()); 24630b57cec5SDimitry Andric 24640b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 24650b57cec5SDimitry Andric unique_ptr<pointer, _Dp> __hold( 2466bdd1243dSDimitry Andric __alloc_traits::allocate(__a, __block_size), 2467bdd1243dSDimitry Andric _Dp(__a, __block_size)); 24680b57cec5SDimitry Andric __buf.push_back(__hold.get()); 24690b57cec5SDimitry Andric __hold.release(); 24700b57cec5SDimitry Andric 2471bdd1243dSDimitry Andric for (__map_pointer __i = __map_.end(); 2472bdd1243dSDimitry Andric __i != __map_.begin();) 24730b57cec5SDimitry Andric __buf.push_front(*--__i); 2474*5f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 2475*5f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 2476*5f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 2477*5f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 247806c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 24790b57cec5SDimitry Andric } 24800b57cec5SDimitry Andric} 24810b57cec5SDimitry Andric 24820b57cec5SDimitry Andric// Create back capacity for __n elements. 24830b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 24840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 24850b57cec5SDimitry Andricvoid 24860b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__add_back_capacity(size_type __n) 24870b57cec5SDimitry Andric{ 2488bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2489bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 24900b57cec5SDimitry Andric // Number of unused blocks at front: 2491bdd1243dSDimitry Andric size_type __front_capacity = __front_spare() / __block_size; 2492*5f757f3fSDimitry Andric __front_capacity = std::min(__front_capacity, __nb); // don't take more than you need 24930b57cec5SDimitry Andric __nb -= __front_capacity; // number of blocks need to allocate 24940b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 24950b57cec5SDimitry Andric if (__nb == 0) 24960b57cec5SDimitry Andric { 2497bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 24980b57cec5SDimitry Andric for (; __front_capacity > 0; --__front_capacity) 24990b57cec5SDimitry Andric { 2500bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2501bdd1243dSDimitry Andric __map_.pop_front(); 2502bdd1243dSDimitry Andric __map_.push_back(__pt); 25030b57cec5SDimitry Andric } 25040b57cec5SDimitry Andric } 25050b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2506bdd1243dSDimitry Andric else if (__nb <= __map_.capacity() - __map_.size()) 25070b57cec5SDimitry Andric { // we can put the new buffers into the map, but don't shift things around 25080b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 25090b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 25100b57cec5SDimitry Andric for (; __nb > 0; --__nb) 25110b57cec5SDimitry Andric { 2512bdd1243dSDimitry Andric if (__map_.__back_spare() == 0) 25130b57cec5SDimitry Andric break; 2514bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 251506c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 25160b57cec5SDimitry Andric } 2517bdd1243dSDimitry Andric for (; __nb > 0; --__nb, ++__front_capacity, __start_ += 251806c3fb27SDimitry Andric __block_size - (__map_.size() == 1)) { 2519bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 252006c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 252106c3fb27SDimitry Andric } 25220b57cec5SDimitry Andric // Done allocating, reorder capacity 2523bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 25240b57cec5SDimitry Andric for (; __front_capacity > 0; --__front_capacity) 25250b57cec5SDimitry Andric { 2526bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2527bdd1243dSDimitry Andric __map_.pop_front(); 2528bdd1243dSDimitry Andric __map_.push_back(__pt); 25290b57cec5SDimitry Andric } 25300b57cec5SDimitry Andric } 25310b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 25320b57cec5SDimitry Andric else 25330b57cec5SDimitry Andric { 2534bdd1243dSDimitry Andric size_type __ds = __front_capacity * __block_size; 2535bdd1243dSDimitry Andric __split_buffer<pointer, __pointer_allocator&> 2536bdd1243dSDimitry Andric __buf(std::max<size_type>(2* __map_.capacity(), 2537bdd1243dSDimitry Andric __nb + __map_.size()), 2538bdd1243dSDimitry Andric __map_.size() - __front_capacity, 2539bdd1243dSDimitry Andric __map_.__alloc()); 254006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 25410b57cec5SDimitry Andric try 25420b57cec5SDimitry Andric { 254306c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 254406c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2545bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 254606c3fb27SDimitry Andric // ASan: this is an empty container, we have to poison the whole block 254706c3fb27SDimitry Andric __annotate_poison_block( 254806c3fb27SDimitry Andric std::__to_address(__buf.back()), 254906c3fb27SDimitry Andric std::__to_address(__buf.back() + __block_size)); 255006c3fb27SDimitry Andric } 255106c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 25520b57cec5SDimitry Andric } 25530b57cec5SDimitry Andric catch (...) 25540b57cec5SDimitry Andric { 255506c3fb27SDimitry Andric __annotate_delete(); 2556bdd1243dSDimitry Andric for (__map_pointer __i = __buf.begin(); 25570b57cec5SDimitry Andric __i != __buf.end(); ++__i) 2558bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 25590b57cec5SDimitry Andric throw; 25600b57cec5SDimitry Andric } 256106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 25620b57cec5SDimitry Andric for (; __front_capacity > 0; --__front_capacity) 25630b57cec5SDimitry Andric { 2564bdd1243dSDimitry Andric __buf.push_back(__map_.front()); 2565bdd1243dSDimitry Andric __map_.pop_front(); 25660b57cec5SDimitry Andric } 2567bdd1243dSDimitry Andric for (__map_pointer __i = __map_.end(); 2568bdd1243dSDimitry Andric __i != __map_.begin();) 25690b57cec5SDimitry Andric __buf.push_front(*--__i); 2570*5f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 2571*5f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 2572*5f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 2573*5f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2574bdd1243dSDimitry Andric __start_ -= __ds; 25750b57cec5SDimitry Andric } 25760b57cec5SDimitry Andric} 25770b57cec5SDimitry Andric 25780b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 25790b57cec5SDimitry Andricvoid 25800b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_front() 25810b57cec5SDimitry Andric{ 258206c3fb27SDimitry Andric size_type __old_sz = size(); 258306c3fb27SDimitry Andric size_type __old_start = __start_; 2584bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2585*5f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() + 2586bdd1243dSDimitry Andric __start_ / __block_size) + 2587bdd1243dSDimitry Andric __start_ % __block_size)); 2588bdd1243dSDimitry Andric --__size(); 2589bdd1243dSDimitry Andric ++__start_; 259006c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2591e40139ffSDimitry Andric __maybe_remove_front_spare(); 25920b57cec5SDimitry Andric} 25930b57cec5SDimitry Andric 25940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 25950b57cec5SDimitry Andricvoid 25960b57cec5SDimitry Andricdeque<_Tp, _Allocator>::pop_back() 25970b57cec5SDimitry Andric{ 259806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); 259906c3fb27SDimitry Andric size_type __old_sz = size(); 260006c3fb27SDimitry Andric size_type __old_start = __start_; 2601bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2602bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 2603*5f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() + 2604bdd1243dSDimitry Andric __p / __block_size) + 2605bdd1243dSDimitry Andric __p % __block_size)); 2606bdd1243dSDimitry Andric --__size(); 260706c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2608e40139ffSDimitry Andric __maybe_remove_back_spare(); 26090b57cec5SDimitry Andric} 26100b57cec5SDimitry Andric 26110b57cec5SDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)). 26120b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt. 26130b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 26140b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 26150b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, 26160b57cec5SDimitry Andric const_pointer& __vt) 26170b57cec5SDimitry Andric{ 26180b57cec5SDimitry Andric // as if 26190b57cec5SDimitry Andric // for (; __f != __l; ++__f, ++__r) 2620*5f757f3fSDimitry Andric // *__r = std::move(*__f); 26210b57cec5SDimitry Andric difference_type __n = __l - __f; 26220b57cec5SDimitry Andric while (__n > 0) 26230b57cec5SDimitry Andric { 26240b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2625bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 26260b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 26270b57cec5SDimitry Andric if (__bs > __n) 26280b57cec5SDimitry Andric { 26290b57cec5SDimitry Andric __bs = __n; 26300b57cec5SDimitry Andric __fe = __fb + __bs; 26310b57cec5SDimitry Andric } 26320b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 26330b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; 2634*5f757f3fSDimitry Andric __r = std::move(__fb, __fe, __r); 26350b57cec5SDimitry Andric __n -= __bs; 26360b57cec5SDimitry Andric __f += __bs; 26370b57cec5SDimitry Andric } 26380b57cec5SDimitry Andric return __r; 26390b57cec5SDimitry Andric} 26400b57cec5SDimitry Andric 26410b57cec5SDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards. 26420b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt. 26430b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 26440b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 26450b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, 26460b57cec5SDimitry Andric const_pointer& __vt) 26470b57cec5SDimitry Andric{ 26480b57cec5SDimitry Andric // as if 26490b57cec5SDimitry Andric // while (__f != __l) 2650*5f757f3fSDimitry Andric // *--__r = std::move(*--__l); 26510b57cec5SDimitry Andric difference_type __n = __l - __f; 26520b57cec5SDimitry Andric while (__n > 0) 26530b57cec5SDimitry Andric { 26540b57cec5SDimitry Andric --__l; 26550b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 26560b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 26570b57cec5SDimitry Andric difference_type __bs = __le - __lb; 26580b57cec5SDimitry Andric if (__bs > __n) 26590b57cec5SDimitry Andric { 26600b57cec5SDimitry Andric __bs = __n; 26610b57cec5SDimitry Andric __lb = __le - __bs; 26620b57cec5SDimitry Andric } 26630b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 26640b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; 2665*5f757f3fSDimitry Andric __r = std::move_backward(__lb, __le, __r); 26660b57cec5SDimitry Andric __n -= __bs; 26670b57cec5SDimitry Andric __l -= __bs - 1; 26680b57cec5SDimitry Andric } 26690b57cec5SDimitry Andric return __r; 26700b57cec5SDimitry Andric} 26710b57cec5SDimitry Andric 26720b57cec5SDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)). 26730b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt. 26740b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 26750b57cec5SDimitry Andricvoid 26760b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, 26770b57cec5SDimitry Andric iterator __r, const_pointer& __vt) 26780b57cec5SDimitry Andric{ 2679bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 26800b57cec5SDimitry Andric // as if 2681bdd1243dSDimitry Andric // for (; __f != __l; ++__r, ++__f, ++__size()) 2682*5f757f3fSDimitry Andric // __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__f)); 26830b57cec5SDimitry Andric difference_type __n = __l - __f; 26840b57cec5SDimitry Andric while (__n > 0) 26850b57cec5SDimitry Andric { 26860b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2687bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 26880b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 26890b57cec5SDimitry Andric if (__bs > __n) 26900b57cec5SDimitry Andric { 26910b57cec5SDimitry Andric __bs = __n; 26920b57cec5SDimitry Andric __fe = __fb + __bs; 26930b57cec5SDimitry Andric } 26940b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 26950b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; 2696bdd1243dSDimitry Andric for (; __fb != __fe; ++__fb, ++__r, ++__size()) 2697*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__fb)); 26980b57cec5SDimitry Andric __n -= __bs; 26990b57cec5SDimitry Andric __f += __bs; 27000b57cec5SDimitry Andric } 27010b57cec5SDimitry Andric} 27020b57cec5SDimitry Andric 27030b57cec5SDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards. 27040b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt. 27050b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 27060b57cec5SDimitry Andricvoid 27070b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l, 27080b57cec5SDimitry Andric iterator __r, const_pointer& __vt) 27090b57cec5SDimitry Andric{ 2710bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 27110b57cec5SDimitry Andric // as if 27120b57cec5SDimitry Andric // for (iterator __j = __l; __j != __f;) 27130b57cec5SDimitry Andric // { 2714*5f757f3fSDimitry Andric // __alloc_traitsconstruct(__a, std::addressof(*--__r), std::move(*--__j)); 2715bdd1243dSDimitry Andric // --__start_; 2716bdd1243dSDimitry Andric // ++__size(); 27170b57cec5SDimitry Andric // } 27180b57cec5SDimitry Andric difference_type __n = __l - __f; 27190b57cec5SDimitry Andric while (__n > 0) 27200b57cec5SDimitry Andric { 27210b57cec5SDimitry Andric --__l; 27220b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 27230b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 27240b57cec5SDimitry Andric difference_type __bs = __le - __lb; 27250b57cec5SDimitry Andric if (__bs > __n) 27260b57cec5SDimitry Andric { 27270b57cec5SDimitry Andric __bs = __n; 27280b57cec5SDimitry Andric __lb = __le - __bs; 27290b57cec5SDimitry Andric } 27300b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 27310b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; 27320b57cec5SDimitry Andric while (__le != __lb) 27330b57cec5SDimitry Andric { 2734*5f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__r), std::move(*--__le)); 2735bdd1243dSDimitry Andric --__start_; 2736bdd1243dSDimitry Andric ++__size(); 27370b57cec5SDimitry Andric } 27380b57cec5SDimitry Andric __n -= __bs; 27390b57cec5SDimitry Andric __l -= __bs - 1; 27400b57cec5SDimitry Andric } 27410b57cec5SDimitry Andric} 27420b57cec5SDimitry Andric 27430b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 27440b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 27450b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f) 27460b57cec5SDimitry Andric{ 274706c3fb27SDimitry Andric size_type __old_sz = size(); 274806c3fb27SDimitry Andric size_type __old_start = __start_; 2749bdd1243dSDimitry Andric iterator __b = begin(); 27500b57cec5SDimitry Andric difference_type __pos = __f - __b; 27510b57cec5SDimitry Andric iterator __p = __b + __pos; 2752bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2753bdd1243dSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - 1) / 2) 27540b57cec5SDimitry Andric { // erase from front 2755*5f757f3fSDimitry Andric std::move_backward(__b, __p, std::next(__p)); 2756*5f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2757bdd1243dSDimitry Andric --__size(); 2758bdd1243dSDimitry Andric ++__start_; 275906c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2760e40139ffSDimitry Andric __maybe_remove_front_spare(); 27610b57cec5SDimitry Andric } 27620b57cec5SDimitry Andric else 27630b57cec5SDimitry Andric { // erase from back 2764*5f757f3fSDimitry Andric iterator __i = std::move(std::next(__p), end(), __p); 2765*5f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2766bdd1243dSDimitry Andric --__size(); 276706c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2768e40139ffSDimitry Andric __maybe_remove_back_spare(); 27690b57cec5SDimitry Andric } 2770bdd1243dSDimitry Andric return begin() + __pos; 27710b57cec5SDimitry Andric} 27720b57cec5SDimitry Andric 27730b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 27740b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 27750b57cec5SDimitry Andricdeque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) 27760b57cec5SDimitry Andric{ 277706c3fb27SDimitry Andric size_type __old_sz = size(); 277806c3fb27SDimitry Andric size_type __old_start = __start_; 27790b57cec5SDimitry Andric difference_type __n = __l - __f; 2780bdd1243dSDimitry Andric iterator __b = begin(); 27810b57cec5SDimitry Andric difference_type __pos = __f - __b; 27820b57cec5SDimitry Andric iterator __p = __b + __pos; 27830b57cec5SDimitry Andric if (__n > 0) 27840b57cec5SDimitry Andric { 2785bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2786bdd1243dSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - __n) / 2) 27870b57cec5SDimitry Andric { // erase from front 2788*5f757f3fSDimitry Andric iterator __i = std::move_backward(__b, __p, __p + __n); 27890b57cec5SDimitry Andric for (; __b != __i; ++__b) 2790*5f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2791bdd1243dSDimitry Andric __size() -= __n; 2792bdd1243dSDimitry Andric __start_ += __n; 279306c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2794e40139ffSDimitry Andric while (__maybe_remove_front_spare()) { 27950b57cec5SDimitry Andric } 27960b57cec5SDimitry Andric } 27970b57cec5SDimitry Andric else 27980b57cec5SDimitry Andric { // erase from back 2799*5f757f3fSDimitry Andric iterator __i = std::move(__p + __n, end(), __p); 2800bdd1243dSDimitry Andric for (iterator __e = end(); __i != __e; ++__i) 2801*5f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2802bdd1243dSDimitry Andric __size() -= __n; 280306c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2804e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 28050b57cec5SDimitry Andric } 28060b57cec5SDimitry Andric } 28070b57cec5SDimitry Andric } 2808bdd1243dSDimitry Andric return begin() + __pos; 28090b57cec5SDimitry Andric} 28100b57cec5SDimitry Andric 28110b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 28120b57cec5SDimitry Andricvoid 28130b57cec5SDimitry Andricdeque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) 28140b57cec5SDimitry Andric{ 281506c3fb27SDimitry Andric size_type __old_sz = size(); 281606c3fb27SDimitry Andric size_type __old_start = __start_; 2817bdd1243dSDimitry Andric iterator __e = end(); 28180b57cec5SDimitry Andric difference_type __n = __e - __f; 28190b57cec5SDimitry Andric if (__n > 0) 28200b57cec5SDimitry Andric { 2821bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2822bdd1243dSDimitry Andric iterator __b = begin(); 28230b57cec5SDimitry Andric difference_type __pos = __f - __b; 28240b57cec5SDimitry Andric for (iterator __p = __b + __pos; __p != __e; ++__p) 2825*5f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__p)); 2826bdd1243dSDimitry Andric __size() -= __n; 282706c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2828e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 28290b57cec5SDimitry Andric } 28300b57cec5SDimitry Andric } 28310b57cec5SDimitry Andric} 28320b57cec5SDimitry Andric 28330b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 28340b57cec5SDimitry Andricinline 28350b57cec5SDimitry Andricvoid 28360b57cec5SDimitry Andricdeque<_Tp, _Allocator>::swap(deque& __c) 28370b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 28380b57cec5SDimitry Andric _NOEXCEPT 28390b57cec5SDimitry Andric#else 28400b57cec5SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 28410b57cec5SDimitry Andric __is_nothrow_swappable<allocator_type>::value) 28420b57cec5SDimitry Andric#endif 28430b57cec5SDimitry Andric{ 2844bdd1243dSDimitry Andric __map_.swap(__c.__map_); 2845*5f757f3fSDimitry Andric std::swap(__start_, __c.__start_); 2846*5f757f3fSDimitry Andric std::swap(__size(), __c.__size()); 2847*5f757f3fSDimitry Andric std::__swap_allocator(__alloc(), __c.__alloc()); 28480b57cec5SDimitry Andric} 28490b57cec5SDimitry Andric 28500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 28510b57cec5SDimitry Andricinline 28520b57cec5SDimitry Andricvoid 28530b57cec5SDimitry Andricdeque<_Tp, _Allocator>::clear() _NOEXCEPT 28540b57cec5SDimitry Andric{ 285506c3fb27SDimitry Andric __annotate_delete(); 2856bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2857bdd1243dSDimitry Andric for (iterator __i = begin(), __e = end(); __i != __e; ++__i) 2858*5f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2859bdd1243dSDimitry Andric __size() = 0; 2860bdd1243dSDimitry Andric while (__map_.size() > 2) 2861bdd1243dSDimitry Andric { 2862bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.front(), __block_size); 2863bdd1243dSDimitry Andric __map_.pop_front(); 2864bdd1243dSDimitry Andric } 2865bdd1243dSDimitry Andric switch (__map_.size()) 2866bdd1243dSDimitry Andric { 2867bdd1243dSDimitry Andric case 1: 2868bdd1243dSDimitry Andric __start_ = __block_size / 2; 2869bdd1243dSDimitry Andric break; 2870bdd1243dSDimitry Andric case 2: 2871bdd1243dSDimitry Andric __start_ = __block_size; 2872bdd1243dSDimitry Andric break; 2873bdd1243dSDimitry Andric } 287406c3fb27SDimitry Andric __annotate_new(0); 28750b57cec5SDimitry Andric} 28760b57cec5SDimitry Andric 28770b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2878bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 28790b57cec5SDimitry Andricbool 28800b57cec5SDimitry Andricoperator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 28810b57cec5SDimitry Andric{ 28820b57cec5SDimitry Andric const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); 2883*5f757f3fSDimitry Andric return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); 28840b57cec5SDimitry Andric} 28850b57cec5SDimitry Andric 288606c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 288706c3fb27SDimitry Andric 28880b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2889bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 28900b57cec5SDimitry Andricbool 28910b57cec5SDimitry Andricoperator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 28920b57cec5SDimitry Andric{ 28930b57cec5SDimitry Andric return !(__x == __y); 28940b57cec5SDimitry Andric} 28950b57cec5SDimitry Andric 28960b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2897bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 28980b57cec5SDimitry Andricbool 28990b57cec5SDimitry Andricoperator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 29000b57cec5SDimitry Andric{ 2901*5f757f3fSDimitry Andric return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 29020b57cec5SDimitry Andric} 29030b57cec5SDimitry Andric 29040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2905bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29060b57cec5SDimitry Andricbool 29070b57cec5SDimitry Andricoperator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 29080b57cec5SDimitry Andric{ 29090b57cec5SDimitry Andric return __y < __x; 29100b57cec5SDimitry Andric} 29110b57cec5SDimitry Andric 29120b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2913bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29140b57cec5SDimitry Andricbool 29150b57cec5SDimitry Andricoperator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 29160b57cec5SDimitry Andric{ 29170b57cec5SDimitry Andric return !(__x < __y); 29180b57cec5SDimitry Andric} 29190b57cec5SDimitry Andric 29200b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2921bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29220b57cec5SDimitry Andricbool 29230b57cec5SDimitry Andricoperator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) 29240b57cec5SDimitry Andric{ 29250b57cec5SDimitry Andric return !(__y < __x); 29260b57cec5SDimitry Andric} 29270b57cec5SDimitry Andric 292806c3fb27SDimitry Andric#else // _LIBCPP_STD_VER <= 17 292906c3fb27SDimitry Andric 293006c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 293106c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> 293206c3fb27SDimitry Andricoperator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 293306c3fb27SDimitry Andric return std::lexicographical_compare_three_way( 293406c3fb27SDimitry Andric __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); 293506c3fb27SDimitry Andric} 293606c3fb27SDimitry Andric 293706c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER <= 17 293806c3fb27SDimitry Andric 29390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2940bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 29410b57cec5SDimitry Andricvoid 29420b57cec5SDimitry Andricswap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) 29430b57cec5SDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 29440b57cec5SDimitry Andric{ 29450b57cec5SDimitry Andric __x.swap(__y); 29460b57cec5SDimitry Andric} 29470b57cec5SDimitry Andric 294806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 29490b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up> 2950bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 29515ffd83dbSDimitry Andricerase(deque<_Tp, _Allocator>& __c, const _Up& __v) { 29525ffd83dbSDimitry Andric auto __old_size = __c.size(); 2953*5f757f3fSDimitry Andric __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end()); 29545ffd83dbSDimitry Andric return __old_size - __c.size(); 29555ffd83dbSDimitry Andric} 29560b57cec5SDimitry Andric 29570b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate> 2958bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 29595ffd83dbSDimitry Andricerase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) { 29605ffd83dbSDimitry Andric auto __old_size = __c.size(); 2961*5f757f3fSDimitry Andric __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end()); 29625ffd83dbSDimitry Andric return __old_size - __c.size(); 29635ffd83dbSDimitry Andric} 296481ad6265SDimitry Andric 296581ad6265SDimitry Andrictemplate <> 296681ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<char>> = true; 296781ad6265SDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 296881ad6265SDimitry Andrictemplate <> 296981ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true; 29700b57cec5SDimitry Andric#endif 29710b57cec5SDimitry Andric 297206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 29730b57cec5SDimitry Andric 29740b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 29750b57cec5SDimitry Andric 297606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 2977bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2978bdd1243dSDimitry Andricnamespace pmr { 2979bdd1243dSDimitry Andrictemplate <class _ValueT> 298006c3fb27SDimitry Andricusing deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>; 2981bdd1243dSDimitry Andric} // namespace pmr 2982bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD 2983bdd1243dSDimitry Andric#endif 2984bdd1243dSDimitry Andric 29850b57cec5SDimitry Andric_LIBCPP_POP_MACROS 29860b57cec5SDimitry Andric 2987bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 2988bdd1243dSDimitry Andric# include <algorithm> 2989bdd1243dSDimitry Andric# include <atomic> 2990bdd1243dSDimitry Andric# include <concepts> 299106c3fb27SDimitry Andric# include <cstdlib> 2992bdd1243dSDimitry Andric# include <functional> 2993bdd1243dSDimitry Andric# include <iosfwd> 2994bdd1243dSDimitry Andric# include <iterator> 299506c3fb27SDimitry Andric# include <type_traits> 2996bdd1243dSDimitry Andric# include <typeinfo> 2997bdd1243dSDimitry Andric#endif 2998bdd1243dSDimitry Andric 29990b57cec5SDimitry Andric#endif // _LIBCPP_DEQUE 3000