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> 191*0fca6ea1SDimitry Andric#include <__assert> 1920b57cec5SDimitry Andric#include <__config> 193*0fca6ea1SDimitry Andric#include <__debug_utils/sanitizers.h> 19481ad6265SDimitry Andric#include <__format/enable_insertable.h> 195*0fca6ea1SDimitry Andric#include <__fwd/deque.h> 19606c3fb27SDimitry Andric#include <__iterator/distance.h> 197349cc55cSDimitry Andric#include <__iterator/iterator_traits.h> 19881ad6265SDimitry Andric#include <__iterator/next.h> 19981ad6265SDimitry Andric#include <__iterator/prev.h> 20081ad6265SDimitry Andric#include <__iterator/reverse_iterator.h> 201bdd1243dSDimitry Andric#include <__iterator/segmented_iterator.h> 20206c3fb27SDimitry Andric#include <__memory/addressof.h> 203bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h> 204bdd1243dSDimitry Andric#include <__memory/pointer_traits.h> 205bdd1243dSDimitry Andric#include <__memory/temp_value.h> 206bdd1243dSDimitry Andric#include <__memory/unique_ptr.h> 207bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h> 20806c3fb27SDimitry Andric#include <__ranges/access.h> 20906c3fb27SDimitry Andric#include <__ranges/concepts.h> 21006c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h> 21106c3fb27SDimitry Andric#include <__ranges/from_range.h> 21206c3fb27SDimitry Andric#include <__ranges/size.h> 2130b57cec5SDimitry Andric#include <__split_buffer> 214bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h> 21506c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 21606c3fb27SDimitry Andric#include <__type_traits/is_same.h> 217*0fca6ea1SDimitry Andric#include <__type_traits/is_swappable.h> 21806c3fb27SDimitry Andric#include <__type_traits/type_identity.h> 219fe6060f1SDimitry Andric#include <__utility/forward.h> 22081ad6265SDimitry Andric#include <__utility/move.h> 22106c3fb27SDimitry Andric#include <__utility/pair.h> 22281ad6265SDimitry Andric#include <__utility/swap.h> 223fe6060f1SDimitry Andric#include <limits> 2240b57cec5SDimitry Andric#include <stdexcept> 2250b57cec5SDimitry Andric#include <version> 2260b57cec5SDimitry Andric 22781ad6265SDimitry Andric// standard-mandated includes 22881ad6265SDimitry Andric 22981ad6265SDimitry Andric// [iterator.range] 23081ad6265SDimitry Andric#include <__iterator/access.h> 23181ad6265SDimitry Andric#include <__iterator/data.h> 23281ad6265SDimitry Andric#include <__iterator/empty.h> 23381ad6265SDimitry Andric#include <__iterator/reverse_access.h> 23481ad6265SDimitry Andric#include <__iterator/size.h> 23581ad6265SDimitry Andric 23681ad6265SDimitry Andric// [deque.syn] 23781ad6265SDimitry Andric#include <compare> 23881ad6265SDimitry Andric#include <initializer_list> 23981ad6265SDimitry Andric 2400b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2410b57cec5SDimitry Andric# pragma GCC system_header 2420b57cec5SDimitry Andric#endif 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 2450b57cec5SDimitry Andric#include <__undef_macros> 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andrictemplate <class _ValueType, class _DiffType> 2500b57cec5SDimitry Andricstruct __deque_block_size { 2510b57cec5SDimitry Andric static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16; 2520b57cec5SDimitry Andric}; 2530b57cec5SDimitry Andric 254cb14a3feSDimitry Andrictemplate <class _ValueType, 255cb14a3feSDimitry Andric class _Pointer, 256cb14a3feSDimitry Andric class _Reference, 257cb14a3feSDimitry Andric class _MapPointer, 258cb14a3feSDimitry Andric class _DiffType, 259cb14a3feSDimitry Andric _DiffType _BS = 2600b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE 2610b57cec5SDimitry Andric // Keep template parameter to avoid changing all template declarations thoughout 2620b57cec5SDimitry Andric // this file. 2630b57cec5SDimitry Andric 0 2640b57cec5SDimitry Andric#else 2650b57cec5SDimitry Andric __deque_block_size<_ValueType, _DiffType>::value 2660b57cec5SDimitry Andric#endif 2670b57cec5SDimitry Andric > 268cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __deque_iterator { 2690b57cec5SDimitry Andric typedef _MapPointer __map_iterator; 270cb14a3feSDimitry Andric 2710b57cec5SDimitry Andricpublic: 2720b57cec5SDimitry Andric typedef _Pointer pointer; 2730b57cec5SDimitry Andric typedef _DiffType difference_type; 274cb14a3feSDimitry Andric 2750b57cec5SDimitry Andricprivate: 2760b57cec5SDimitry Andric __map_iterator __m_iter_; 2770b57cec5SDimitry Andric pointer __ptr_; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric static const difference_type __block_size; 280cb14a3feSDimitry Andric 2810b57cec5SDimitry Andricpublic: 2820b57cec5SDimitry Andric typedef _ValueType value_type; 2830b57cec5SDimitry Andric typedef random_access_iterator_tag iterator_category; 2840b57cec5SDimitry Andric typedef _Reference reference; 2850b57cec5SDimitry Andric 286bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT 28706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 288cb14a3feSDimitry Andric : __m_iter_(nullptr), 289cb14a3feSDimitry Andric __ptr_(nullptr) 2900b57cec5SDimitry Andric#endif 291cb14a3feSDimitry Andric { 292cb14a3feSDimitry Andric } 2930b57cec5SDimitry Andric 2945f757f3fSDimitry Andric template <class _Pp, class _Rp, class _MP, __enable_if_t<is_convertible<_Pp, pointer>::value, int> = 0> 295bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 2965f757f3fSDimitry Andric __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it) _NOEXCEPT 297cb14a3feSDimitry Andric : __m_iter_(__it.__m_iter_), 298cb14a3feSDimitry Andric __ptr_(__it.__ptr_) {} 2990b57cec5SDimitry Andric 300bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__ptr_; } 301bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return __ptr_; } 3020b57cec5SDimitry Andric 303cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++() { 304cb14a3feSDimitry Andric if (++__ptr_ - *__m_iter_ == __block_size) { 3050b57cec5SDimitry Andric ++__m_iter_; 3060b57cec5SDimitry Andric __ptr_ = *__m_iter_; 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric return *this; 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 311cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int) { 3120b57cec5SDimitry Andric __deque_iterator __tmp = *this; 3130b57cec5SDimitry Andric ++(*this); 3140b57cec5SDimitry Andric return __tmp; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 317cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--() { 318cb14a3feSDimitry Andric if (__ptr_ == *__m_iter_) { 3190b57cec5SDimitry Andric --__m_iter_; 3200b57cec5SDimitry Andric __ptr_ = *__m_iter_ + __block_size; 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric --__ptr_; 3230b57cec5SDimitry Andric return *this; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 326cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int) { 3270b57cec5SDimitry Andric __deque_iterator __tmp = *this; 3280b57cec5SDimitry Andric --(*this); 3290b57cec5SDimitry Andric return __tmp; 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 332cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n) { 333cb14a3feSDimitry Andric if (__n != 0) { 3340b57cec5SDimitry Andric __n += __ptr_ - *__m_iter_; 335cb14a3feSDimitry Andric if (__n > 0) { 3360b57cec5SDimitry Andric __m_iter_ += __n / __block_size; 3370b57cec5SDimitry Andric __ptr_ = *__m_iter_ + __n % __block_size; 338cb14a3feSDimitry Andric } else // (__n < 0) 3390b57cec5SDimitry Andric { 3400b57cec5SDimitry Andric difference_type __z = __block_size - 1 - __n; 3410b57cec5SDimitry Andric __m_iter_ -= __z / __block_size; 3420b57cec5SDimitry Andric __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size); 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric return *this; 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 348cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n) { return *this += -__n; } 3490b57cec5SDimitry Andric 350cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const { 3510b57cec5SDimitry Andric __deque_iterator __t(*this); 3520b57cec5SDimitry Andric __t += __n; 3530b57cec5SDimitry Andric return __t; 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric 356cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const { 3570b57cec5SDimitry Andric __deque_iterator __t(*this); 3580b57cec5SDimitry Andric __t -= __n; 3590b57cec5SDimitry Andric return __t; 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 362cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) { 363cb14a3feSDimitry Andric return __it + __n; 364cb14a3feSDimitry Andric } 3650b57cec5SDimitry Andric 366cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) { 3670b57cec5SDimitry Andric if (__x != __y) 368cb14a3feSDimitry Andric return (__x.__m_iter_ - __y.__m_iter_) * __block_size + (__x.__ptr_ - *__x.__m_iter_) - 369cb14a3feSDimitry Andric (__y.__ptr_ - *__y.__m_iter_); 3700b57cec5SDimitry Andric return 0; 3710b57cec5SDimitry Andric } 3720b57cec5SDimitry Andric 373cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const { return *(*this + __n); } 3740b57cec5SDimitry Andric 375cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) { 376cb14a3feSDimitry Andric return __x.__ptr_ == __y.__ptr_; 377cb14a3feSDimitry Andric } 3780b57cec5SDimitry Andric 379cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) { 380cb14a3feSDimitry Andric return !(__x == __y); 381cb14a3feSDimitry Andric } 3820b57cec5SDimitry Andric 383cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) { 384cb14a3feSDimitry Andric return __x.__m_iter_ < __y.__m_iter_ || (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_); 385cb14a3feSDimitry Andric } 3860b57cec5SDimitry Andric 387cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) { 388cb14a3feSDimitry Andric return __y < __x; 389cb14a3feSDimitry Andric } 3900b57cec5SDimitry Andric 391cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) { 392cb14a3feSDimitry Andric return !(__y < __x); 393cb14a3feSDimitry Andric } 3940b57cec5SDimitry Andric 395cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) { 396cb14a3feSDimitry Andric return !(__x < __y); 397cb14a3feSDimitry Andric } 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andricprivate: 400bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT 401cb14a3feSDimitry Andric : __m_iter_(__m), 402cb14a3feSDimitry Andric __ptr_(__p) {} 4030b57cec5SDimitry Andric 404cb14a3feSDimitry Andric template <class _Tp, class _Ap> 405cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS deque; 4060b57cec5SDimitry Andric template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp> 4070b57cec5SDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __deque_iterator; 4080b57cec5SDimitry Andric 409bdd1243dSDimitry Andric template <class> 410bdd1243dSDimitry Andric friend struct __segmented_iterator_traits; 411bdd1243dSDimitry Andric}; 4120b57cec5SDimitry Andric 413bdd1243dSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 414bdd1243dSDimitry Andricstruct __segmented_iterator_traits< 415bdd1243dSDimitry Andric __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > { 416bdd1243dSDimitry Andricprivate: 417bdd1243dSDimitry Andric using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; 4180b57cec5SDimitry Andric 419bdd1243dSDimitry Andricpublic: 420bdd1243dSDimitry Andric using __is_segmented_iterator = true_type; 421bdd1243dSDimitry Andric using __segment_iterator = _MapPointer; 422bdd1243dSDimitry Andric using __local_iterator = _Pointer; 4230b57cec5SDimitry Andric 424bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } 425bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } 426bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; } 4270b57cec5SDimitry Andric 428bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) { 429bdd1243dSDimitry Andric return *__iter + _Iterator::__block_size; 430bdd1243dSDimitry Andric } 4310b57cec5SDimitry Andric 432bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) { 4335f757f3fSDimitry Andric if (__segment && __local == __end(__segment)) { 434bdd1243dSDimitry Andric ++__segment; 435bdd1243dSDimitry Andric return _Iterator(__segment, *__segment); 436bdd1243dSDimitry Andric } 437bdd1243dSDimitry Andric return _Iterator(__segment, __local); 438bdd1243dSDimitry Andric } 4390b57cec5SDimitry Andric}; 4400b57cec5SDimitry Andric 441cb14a3feSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 442cb14a3feSDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>::__block_size = 4430b57cec5SDimitry Andric __deque_block_size<_ValueType, _DiffType>::value; 4440b57cec5SDimitry Andric 445bdd1243dSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/> 446cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque { 4470b57cec5SDimitry Andricpublic: 448bdd1243dSDimitry Andric // types: 449e40139ffSDimitry Andric 450bdd1243dSDimitry Andric using value_type = _Tp; 4510b57cec5SDimitry Andric 452bdd1243dSDimitry Andric using allocator_type = _Allocator; 453bdd1243dSDimitry Andric using __alloc_traits = allocator_traits<allocator_type>; 454*0fca6ea1SDimitry Andric static_assert(__check_valid_allocator<allocator_type>::value, ""); 455*0fca6ea1SDimitry Andric static_assert(is_same<typename allocator_type::value_type, value_type>::value, 456*0fca6ea1SDimitry Andric "Allocator::value_type must be same type as value_type"); 4570b57cec5SDimitry Andric 458bdd1243dSDimitry Andric using size_type = typename __alloc_traits::size_type; 459bdd1243dSDimitry Andric using difference_type = typename __alloc_traits::difference_type; 4600b57cec5SDimitry Andric 461bdd1243dSDimitry Andric using pointer = typename __alloc_traits::pointer; 462bdd1243dSDimitry Andric using const_pointer = typename __alloc_traits::const_pointer; 463bdd1243dSDimitry Andric 464bdd1243dSDimitry Andric using __pointer_allocator = __rebind_alloc<__alloc_traits, pointer>; 465bdd1243dSDimitry Andric using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>; 466bdd1243dSDimitry Andric using __map = __split_buffer<pointer, __pointer_allocator>; 467bdd1243dSDimitry Andric using __map_alloc_traits = allocator_traits<__pointer_allocator>; 468bdd1243dSDimitry Andric using __map_pointer = typename __map_alloc_traits::pointer; 469bdd1243dSDimitry Andric using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer; 47006c3fb27SDimitry Andric using __map_const_iterator = typename __map::const_iterator; 471bdd1243dSDimitry Andric 472bdd1243dSDimitry Andric using reference = value_type&; 473bdd1243dSDimitry Andric using const_reference = const value_type&; 474bdd1243dSDimitry Andric 475bdd1243dSDimitry Andric using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>; 476bdd1243dSDimitry Andric using const_iterator = 477bdd1243dSDimitry Andric __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>; 478bdd1243dSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 479bdd1243dSDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>; 480bdd1243dSDimitry Andric 481*0fca6ea1SDimitry Andric // A deque contains the following members which may be trivially relocatable: 482*0fca6ea1SDimitry Andric // - __map: is a `__split_buffer`, see `__split_buffer` for more information on when it is trivially relocatable 483*0fca6ea1SDimitry Andric // - size_type: is always trivially relocatable, since it is required to be an integral type 484*0fca6ea1SDimitry Andric // - allocator_type: may not be trivially relocatable, so it's checked 485*0fca6ea1SDimitry Andric // None of these are referencing the `deque` itself, so if all of them are trivially relocatable, `deque` is too. 486*0fca6ea1SDimitry Andric using __trivially_relocatable = __conditional_t< 487*0fca6ea1SDimitry Andric __libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, 488*0fca6ea1SDimitry Andric deque, 489*0fca6ea1SDimitry Andric void>; 490*0fca6ea1SDimitry Andric 491bdd1243dSDimitry Andric static_assert(is_nothrow_default_constructible<allocator_type>::value == 492bdd1243dSDimitry Andric is_nothrow_default_constructible<__pointer_allocator>::value, 493*0fca6ea1SDimitry Andric "rebinding an allocator should not change exception guarantees"); 494bdd1243dSDimitry Andric static_assert(is_nothrow_move_constructible<allocator_type>::value == 495bdd1243dSDimitry Andric is_nothrow_move_constructible<typename __map::allocator_type>::value, 496*0fca6ea1SDimitry Andric "rebinding an allocator should not change exception guarantees"); 497bdd1243dSDimitry Andric 498bdd1243dSDimitry Andricprivate: 499e40139ffSDimitry Andric struct __deque_block_range { 500cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI __deque_block_range(pointer __b, pointer __e) _NOEXCEPT 501cb14a3feSDimitry Andric : __begin_(__b), 502cb14a3feSDimitry Andric __end_(__e) {} 503e40139ffSDimitry Andric const pointer __begin_; 504e40139ffSDimitry Andric const pointer __end_; 505e40139ffSDimitry Andric }; 506e40139ffSDimitry Andric 507e40139ffSDimitry Andric struct __deque_range { 508e40139ffSDimitry Andric iterator __pos_; 509e40139ffSDimitry Andric const iterator __end_; 510e40139ffSDimitry Andric 511cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT : __pos_(__pos), __end_(__e) {} 512e40139ffSDimitry Andric 513cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { return __pos_ != __end_; } 514e40139ffSDimitry Andric 515cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { return *this; } 516e40139ffSDimitry Andric 517cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range end() const { return __deque_range(__end_, __end_); } 518bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT { 519e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 520e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, __end_.__ptr_); 521e40139ffSDimitry Andric } 522e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size); 523e40139ffSDimitry Andric } 524e40139ffSDimitry Andric 525bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT { 526e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 527e40139ffSDimitry Andric __pos_ = __end_; 528e40139ffSDimitry Andric } else { 529e40139ffSDimitry Andric ++__pos_.__m_iter_; 530e40139ffSDimitry Andric __pos_.__ptr_ = *__pos_.__m_iter_; 531e40139ffSDimitry Andric } 532e40139ffSDimitry Andric return *this; 533e40139ffSDimitry Andric } 534e40139ffSDimitry Andric 535bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) { 536e40139ffSDimitry Andric return __lhs.__pos_ == __rhs.__pos_; 537e40139ffSDimitry Andric } 538bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) { 539e40139ffSDimitry Andric return !(__lhs == __rhs); 540e40139ffSDimitry Andric } 541e40139ffSDimitry Andric }; 542e40139ffSDimitry Andric 543e40139ffSDimitry Andric struct _ConstructTransaction { 544bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r) 545e40139ffSDimitry Andric : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} 546e40139ffSDimitry Andric 547cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { __base_->__size() += (__pos_ - __begin_); } 548e40139ffSDimitry Andric 549e40139ffSDimitry Andric pointer __pos_; 550e40139ffSDimitry Andric const pointer __end_; 551cb14a3feSDimitry Andric 552e40139ffSDimitry Andric private: 553e40139ffSDimitry Andric const pointer __begin_; 554bdd1243dSDimitry Andric deque* const __base_; 555e40139ffSDimitry Andric }; 556e40139ffSDimitry Andric 557bdd1243dSDimitry Andric static const difference_type __block_size; 558bdd1243dSDimitry Andric 5590b57cec5SDimitry Andric __map __map_; 5600b57cec5SDimitry Andric size_type __start_; 5610b57cec5SDimitry Andric __compressed_pair<size_type, allocator_type> __size_; 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andricpublic: 564bdd1243dSDimitry Andric // construct/copy/destroy: 565cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 56606c3fb27SDimitry Andric : __start_(0), __size_(0, __default_init_tag()) { 56706c3fb27SDimitry Andric __annotate_new(0); 56806c3fb27SDimitry Andric } 569bdd1243dSDimitry Andric 570bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~deque() { 571bdd1243dSDimitry Andric clear(); 57206c3fb27SDimitry Andric __annotate_delete(); 573bdd1243dSDimitry Andric typename __map::iterator __i = __map_.begin(); 574bdd1243dSDimitry Andric typename __map::iterator __e = __map_.end(); 575bdd1243dSDimitry Andric for (; __i != __e; ++__i) 576bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), *__i, __block_size); 577bdd1243dSDimitry Andric } 578bdd1243dSDimitry Andric 579bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) 58006c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 58106c3fb27SDimitry Andric __annotate_new(0); 58206c3fb27SDimitry Andric } 583bdd1243dSDimitry Andric 584bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); 58506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 586bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); 587bdd1243dSDimitry Andric#endif 588bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); 589bdd1243dSDimitry Andric 590*0fca6ea1SDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 591bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) 592cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 59306c3fb27SDimitry Andric __annotate_new(0); 594bdd1243dSDimitry Andric if (__n > 0) 595bdd1243dSDimitry Andric __append(__n, __v); 596bdd1243dSDimitry Andric } 597bdd1243dSDimitry Andric 5985f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 5995f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l); 6005f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 6015f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a); 60206c3fb27SDimitry Andric 60306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 60406c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 605cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) 60606c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 60706c3fb27SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 60806c3fb27SDimitry Andric __append_with_size(ranges::begin(__range), ranges::distance(__range)); 60906c3fb27SDimitry Andric 61006c3fb27SDimitry Andric } else { 61106c3fb27SDimitry Andric for (auto&& __e : __range) { 61206c3fb27SDimitry Andric emplace_back(std::forward<decltype(__e)>(__e)); 61306c3fb27SDimitry Andric } 61406c3fb27SDimitry Andric } 61506c3fb27SDimitry Andric } 61606c3fb27SDimitry Andric#endif 61706c3fb27SDimitry Andric 618bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); 619bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); 620bdd1243dSDimitry Andric 621bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c); 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 624bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il); 625bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a); 626bdd1243dSDimitry Andric 627cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(initializer_list<value_type> __il) { 628cb14a3feSDimitry Andric assign(__il); 629cb14a3feSDimitry Andric return *this; 630cb14a3feSDimitry Andric } 631bdd1243dSDimitry Andric 632*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value); 633cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(deque&& __c, const __type_identity_t<allocator_type>& __a); 634*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& 635*0fca6ea1SDimitry Andric operator=(deque&& __c) noexcept(__alloc_traits::propagate_on_container_move_assignment::value && 636bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value); 637bdd1243dSDimitry Andric 638cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) { assign(__il.begin(), __il.end()); } 6390b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 6400b57cec5SDimitry Andric 641cb14a3feSDimitry Andric template <class _InputIter, 642cb14a3feSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIter>::value && 643cb14a3feSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, 644cb14a3feSDimitry Andric int> = 0> 6455f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l); 6465f757f3fSDimitry Andric template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> = 0> 6475f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l); 64806c3fb27SDimitry Andric 64906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 65006c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 651cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) { 65206c3fb27SDimitry Andric if constexpr (ranges::random_access_range<_Range>) { 65306c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 65406c3fb27SDimitry Andric __assign_with_size_random_access(ranges::begin(__range), __n); 65506c3fb27SDimitry Andric 65606c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 65706c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 65806c3fb27SDimitry Andric __assign_with_size(ranges::begin(__range), __n); 65906c3fb27SDimitry Andric 66006c3fb27SDimitry Andric } else { 66106c3fb27SDimitry Andric __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 66206c3fb27SDimitry Andric } 66306c3fb27SDimitry Andric } 66406c3fb27SDimitry Andric#endif 66506c3fb27SDimitry Andric 666bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); 667bdd1243dSDimitry Andric 668cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; 669bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); } 670bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); } 671bdd1243dSDimitry Andric 672bdd1243dSDimitry Andric // iterators: 673bdd1243dSDimitry Andric 674bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { 675bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __start_ / __block_size; 676bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 677bdd1243dSDimitry Andric } 678bdd1243dSDimitry Andric 679bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { 680cb14a3feSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); 681bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 682bdd1243dSDimitry Andric } 683bdd1243dSDimitry Andric 684bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { 685bdd1243dSDimitry Andric size_type __p = size() + __start_; 686bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __p / __block_size; 687bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 688bdd1243dSDimitry Andric } 689bdd1243dSDimitry Andric 690bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { 691bdd1243dSDimitry Andric size_type __p = size() + __start_; 692bdd1243dSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); 693bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 694bdd1243dSDimitry Andric } 695bdd1243dSDimitry Andric 696cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } 697cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 698cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } 699cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 700bdd1243dSDimitry Andric 701cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } 702cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } 703cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 704cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 705bdd1243dSDimitry Andric 706bdd1243dSDimitry Andric // capacity: 707cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); } 708bdd1243dSDimitry Andric 709bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); } 710bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); } 711bdd1243dSDimitry Andric 712cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { 713cb14a3feSDimitry Andric return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max()); 714cb14a3feSDimitry Andric } 715bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); 716bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); 717bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; 718*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; } 719bdd1243dSDimitry Andric 720bdd1243dSDimitry Andric // element access: 721cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT; 722cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT; 723cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference at(size_type __i); 724cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const; 725cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT; 726cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT; 727cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT; 728cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT; 729bdd1243dSDimitry Andric 730bdd1243dSDimitry Andric // 23.2.2.3 modifiers: 731bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); 732bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); 733bdd1243dSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 73406c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 735cb14a3feSDimitry Andric template <class... _Args> 736cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); 737cb14a3feSDimitry Andric template <class... _Args> 738cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args); 739bdd1243dSDimitry Andric# else 740cb14a3feSDimitry Andric template <class... _Args> 741cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); 742cb14a3feSDimitry Andric template <class... _Args> 743cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args); 744bdd1243dSDimitry Andric# endif 745cb14a3feSDimitry Andric template <class... _Args> 746cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); 747bdd1243dSDimitry Andric 748bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); 749bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v); 75006c3fb27SDimitry Andric 75106c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 75206c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 753cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) { 75406c3fb27SDimitry Andric insert_range(begin(), std::forward<_Range>(__range)); 75506c3fb27SDimitry Andric } 75606c3fb27SDimitry Andric 75706c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 758cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void append_range(_Range&& __range) { 75906c3fb27SDimitry Andric insert_range(end(), std::forward<_Range>(__range)); 76006c3fb27SDimitry Andric } 76106c3fb27SDimitry Andric# endif 76206c3fb27SDimitry Andric 763bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v); 764bdd1243dSDimitry Andric 765cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, initializer_list<value_type> __il) { 766cb14a3feSDimitry Andric return insert(__p, __il.begin(), __il.end()); 767cb14a3feSDimitry Andric } 768bdd1243dSDimitry Andric#endif // _LIBCPP_CXX03_LANG 769bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v); 770bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); 7715f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0> 7725f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l); 773cb14a3feSDimitry Andric template <class _ForwardIterator, 774cb14a3feSDimitry Andric __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> = 0> 7755f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l); 7765f757f3fSDimitry Andric template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> = 0> 7775f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l); 77806c3fb27SDimitry Andric 77906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 78006c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 781cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert_range(const_iterator __position, _Range&& __range) { 78206c3fb27SDimitry Andric if constexpr (ranges::bidirectional_range<_Range>) { 78306c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 78406c3fb27SDimitry Andric return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n); 78506c3fb27SDimitry Andric 78606c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 78706c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 78806c3fb27SDimitry Andric return __insert_with_size(__position, ranges::begin(__range), __n); 78906c3fb27SDimitry Andric 79006c3fb27SDimitry Andric } else { 79106c3fb27SDimitry Andric return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); 79206c3fb27SDimitry Andric } 79306c3fb27SDimitry Andric } 79406c3fb27SDimitry Andric#endif 795bdd1243dSDimitry Andric 796bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_front(); 797bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_back(); 798bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); 799bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); 800bdd1243dSDimitry Andric 801cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(deque& __c) 8020b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 8030b57cec5SDimitry Andric _NOEXCEPT; 8040b57cec5SDimitry Andric#else 805*0fca6ea1SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>); 8060b57cec5SDimitry Andric#endif 807cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; 8080b57cec5SDimitry Andric 809cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __invariants() const { 8100b57cec5SDimitry Andric if (!__map_.__invariants()) 8110b57cec5SDimitry Andric return false; 8120b57cec5SDimitry Andric if (__map_.size() >= size_type(-1) / __block_size) 8130b57cec5SDimitry Andric return false; 814cb14a3feSDimitry Andric for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); __i != __e; ++__i) 8150b57cec5SDimitry Andric if (*__i == nullptr) 8160b57cec5SDimitry Andric return false; 817cb14a3feSDimitry Andric if (__map_.size() != 0) { 8180b57cec5SDimitry Andric if (size() >= __map_.size() * __block_size) 8190b57cec5SDimitry Andric return false; 8200b57cec5SDimitry Andric if (__start_ >= __map_.size() * __block_size - size()) 8210b57cec5SDimitry Andric return false; 822cb14a3feSDimitry Andric } else { 8230b57cec5SDimitry Andric if (size() != 0) 8240b57cec5SDimitry Andric return false; 8250b57cec5SDimitry Andric if (__start_ != 0) 8260b57cec5SDimitry Andric return false; 8270b57cec5SDimitry Andric } 8280b57cec5SDimitry Andric return true; 8290b57cec5SDimitry Andric } 8300b57cec5SDimitry Andric 831cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c) 832bdd1243dSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || 833cb14a3feSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 834cb14a3feSDimitry Andric __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 835cb14a3feSDimitry Andric } 836bdd1243dSDimitry Andric 837cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c, true_type) 838cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 8395f757f3fSDimitry Andric __alloc() = std::move(__c.__alloc()); 8400b57cec5SDimitry Andric } 8410b57cec5SDimitry Andric 842cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque&, false_type) _NOEXCEPT {} 8434824e7fdSDimitry Andric 844cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c) 845bdd1243dSDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value&& 846cb14a3feSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 8475f757f3fSDimitry Andric __map_ = std::move(__c.__map_); 848bdd1243dSDimitry Andric __start_ = __c.__start_; 849bdd1243dSDimitry Andric __size() = __c.size(); 850bdd1243dSDimitry Andric __move_assign_alloc(__c); 851bdd1243dSDimitry Andric __c.__start_ = __c.__size() = 0; 8524824e7fdSDimitry Andric } 8534824e7fdSDimitry Andric 854cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static size_type __recommend_blocks(size_type __n) { 855bdd1243dSDimitry Andric return __n / __block_size + (__n % __block_size != 0); 8560b57cec5SDimitry Andric } 857cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __capacity() const { 858bdd1243dSDimitry Andric return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1; 8590b57cec5SDimitry Andric } 860cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __block_count() const { return __map_.size(); } 861e40139ffSDimitry Andric 862cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const { return __start_; } 863cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __front_spare_blocks() const { return __front_spare() / __block_size; } 864cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const { return __capacity() - (__start_ + size()); } 865cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __back_spare_blocks() const { return __back_spare() / __block_size; } 866e40139ffSDimitry Andric 867e40139ffSDimitry Andricprivate: 868cb14a3feSDimitry Andric enum __asan_annotation_type { __asan_unposion, __asan_poison }; 86906c3fb27SDimitry Andric 87006c3fb27SDimitry Andric enum __asan_annotation_place { 87106c3fb27SDimitry Andric __asan_front_moved, 87206c3fb27SDimitry Andric __asan_back_moved, 87306c3fb27SDimitry Andric }; 87406c3fb27SDimitry Andric 875cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_from_to( 8765f757f3fSDimitry Andric size_type __beg, 8775f757f3fSDimitry Andric size_type __end, 8785f757f3fSDimitry Andric __asan_annotation_type __annotation_type, 8795f757f3fSDimitry Andric __asan_annotation_place __place) const _NOEXCEPT { 8805f757f3fSDimitry Andric (void)__beg; 8815f757f3fSDimitry Andric (void)__end; 8825f757f3fSDimitry Andric (void)__annotation_type; 8835f757f3fSDimitry Andric (void)__place; 8845f757f3fSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 88506c3fb27SDimitry Andric // __beg - index of the first item to annotate 88606c3fb27SDimitry Andric // __end - index behind the last item to annotate (so last item + 1) 88706c3fb27SDimitry Andric // __annotation_type - __asan_unposion or __asan_poison 88806c3fb27SDimitry Andric // __place - __asan_front_moved or __asan_back_moved 88906c3fb27SDimitry Andric // Note: All indexes in __map_ 89006c3fb27SDimitry Andric if (__beg == __end) 89106c3fb27SDimitry Andric return; 89206c3fb27SDimitry Andric // __annotations_beg_map - first chunk which annotations we want to modify 89306c3fb27SDimitry Andric // __annotations_end_map - last chunk which annotations we want to modify 89406c3fb27SDimitry Andric // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist 89506c3fb27SDimitry Andric __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; 89606c3fb27SDimitry Andric __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; 89706c3fb27SDimitry Andric 89806c3fb27SDimitry Andric bool const __poisoning = __annotation_type == __asan_poison; 89906c3fb27SDimitry Andric // __old_c_beg_index - index of the first element in old container 90006c3fb27SDimitry Andric // __old_c_end_index - index of the end of old container (last + 1) 90106c3fb27SDimitry Andric // Note: may be outside the area we are annotating 90206c3fb27SDimitry Andric size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; 90306c3fb27SDimitry Andric size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); 90406c3fb27SDimitry Andric bool const __front = __place == __asan_front_moved; 90506c3fb27SDimitry Andric 90606c3fb27SDimitry Andric if (__poisoning && empty()) { 90706c3fb27SDimitry Andric // Special case: we shouldn't trust __start_ 90806c3fb27SDimitry Andric __old_c_beg_index = __beg; 90906c3fb27SDimitry Andric __old_c_end_index = __end; 91006c3fb27SDimitry Andric } 91106c3fb27SDimitry Andric // __old_c_beg_map - memory block (chunk) with first element 91206c3fb27SDimitry Andric // __old_c_end_map - memory block (chunk) with end of old container 91306c3fb27SDimitry Andric // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, 91406c3fb27SDimitry Andric // which may not exist 91506c3fb27SDimitry Andric __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; 91606c3fb27SDimitry Andric __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; 91706c3fb27SDimitry Andric 91806c3fb27SDimitry Andric // One edge (front/end) of the container was moved and one was not modified. 91906c3fb27SDimitry Andric // __new_edge_index - index of new edge 92006c3fb27SDimitry Andric // __new_edge_map - memory block (chunk) with new edge, it always equals to 92106c3fb27SDimitry Andric // __annotations_beg_map or __annotations_end_map 92206c3fb27SDimitry Andric // __old_edge_map - memory block (chunk) with old edge, it always equals to 92306c3fb27SDimitry Andric // __old_c_beg_map or __old_c_end_map 92406c3fb27SDimitry Andric size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; 92506c3fb27SDimitry Andric __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; 92606c3fb27SDimitry Andric __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; 92706c3fb27SDimitry Andric 92806c3fb27SDimitry Andric // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. 92906c3fb27SDimitry Andric // First and last chunk may be partially poisoned. 93006c3fb27SDimitry Andric // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. 93106c3fb27SDimitry Andric for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { 93206c3fb27SDimitry Andric if (__map_it == __annotations_end_map && __end % __block_size == 0) 93306c3fb27SDimitry Andric // Chunk may not exist, but nothing to do here anyway 93406c3fb27SDimitry Andric break; 93506c3fb27SDimitry Andric 93606c3fb27SDimitry Andric // The beginning and the end of the current memory block 93706c3fb27SDimitry Andric const void* __mem_beg = std::__to_address(*__map_it); 93806c3fb27SDimitry Andric const void* __mem_end = std::__to_address(*__map_it + __block_size); 93906c3fb27SDimitry Andric 94006c3fb27SDimitry Andric // The beginning of memory-in-use in the memory block before container modification 94106c3fb27SDimitry Andric const void* __old_beg = 94206c3fb27SDimitry Andric (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; 94306c3fb27SDimitry Andric 94406c3fb27SDimitry Andric // The end of memory-in-use in the memory block before container modification 94506c3fb27SDimitry Andric const void* __old_end; 94606c3fb27SDimitry Andric if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) 94706c3fb27SDimitry Andric __old_end = __old_beg; 94806c3fb27SDimitry Andric else 949cb14a3feSDimitry Andric __old_end = (__map_it == __old_c_end_map) 950cb14a3feSDimitry Andric ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) 95106c3fb27SDimitry Andric : __mem_end; 95206c3fb27SDimitry Andric 95306c3fb27SDimitry Andric // New edge of the container in current memory block 95406c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 95506c3fb27SDimitry Andric const void* __new_edge; 95606c3fb27SDimitry Andric if (__map_it == __new_edge_map) 95706c3fb27SDimitry Andric __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); 95806c3fb27SDimitry Andric else 95906c3fb27SDimitry Andric __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; 96006c3fb27SDimitry Andric 96106c3fb27SDimitry Andric // Not modified edge of the container 96206c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 96306c3fb27SDimitry Andric const void* __old_edge; 96406c3fb27SDimitry Andric if (__map_it == __old_edge_map) 96506c3fb27SDimitry Andric __old_edge = __front ? __old_end : __old_beg; 96606c3fb27SDimitry Andric else 96706c3fb27SDimitry Andric __old_edge = __front ? __mem_end : __mem_beg; 96806c3fb27SDimitry Andric 96906c3fb27SDimitry Andric // __new_beg - the beginning of memory-in-use in the memory block after container modification 97006c3fb27SDimitry Andric // __new_end - the end of memory-in-use in the memory block after container modification 97106c3fb27SDimitry Andric const void* __new_beg = __front ? __new_edge : __old_edge; 97206c3fb27SDimitry Andric const void* __new_end = __front ? __old_edge : __new_edge; 97306c3fb27SDimitry Andric 974*0fca6ea1SDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>( 975*0fca6ea1SDimitry Andric __mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); 97606c3fb27SDimitry Andric } 9775f757f3fSDimitry Andric#endif // !_LIBCPP_HAS_NO_ASAN 97806c3fb27SDimitry Andric } 97906c3fb27SDimitry Andric 980cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT { 981cb14a3feSDimitry Andric (void)__current_size; 982cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 98306c3fb27SDimitry Andric if (__current_size == 0) 98406c3fb27SDimitry Andric __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 98506c3fb27SDimitry Andric else { 98606c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); 98706c3fb27SDimitry Andric __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 98806c3fb27SDimitry Andric } 989cb14a3feSDimitry Andric#endif 99006c3fb27SDimitry Andric } 99106c3fb27SDimitry Andric 992cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT { 993cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 99406c3fb27SDimitry Andric if (empty()) { 99506c3fb27SDimitry Andric for (size_t __i = 0; __i < __map_.size(); ++__i) { 99606c3fb27SDimitry Andric __annotate_whole_block(__i, __asan_unposion); 99706c3fb27SDimitry Andric } 998cb14a3feSDimitry Andric } else { 99906c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); 100006c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); 100106c3fb27SDimitry Andric } 1002cb14a3feSDimitry Andric#endif 100306c3fb27SDimitry Andric } 100406c3fb27SDimitry Andric 1005cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_increase_front(size_type __n) const _NOEXCEPT { 1006cb14a3feSDimitry Andric (void)__n; 1007cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 100806c3fb27SDimitry Andric __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); 1009cb14a3feSDimitry Andric#endif 101006c3fb27SDimitry Andric } 101106c3fb27SDimitry Andric 1012cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_increase_back(size_type __n) const _NOEXCEPT { 1013cb14a3feSDimitry Andric (void)__n; 1014cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 101506c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); 1016cb14a3feSDimitry Andric#endif 101706c3fb27SDimitry Andric } 101806c3fb27SDimitry Andric 1019cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { 1020cb14a3feSDimitry Andric (void)__old_size; 1021cb14a3feSDimitry Andric (void)__old_start; 1022cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 102306c3fb27SDimitry Andric __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); 1024cb14a3feSDimitry Andric#endif 102506c3fb27SDimitry Andric } 102606c3fb27SDimitry Andric 1027cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { 1028cb14a3feSDimitry Andric (void)__old_size; 1029cb14a3feSDimitry Andric (void)__old_start; 1030cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 103106c3fb27SDimitry Andric __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); 1032cb14a3feSDimitry Andric#endif 103306c3fb27SDimitry Andric } 103406c3fb27SDimitry Andric 1035cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_poison_block(const void* __beginning, const void* __end) const _NOEXCEPT { 1036*0fca6ea1SDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>(__beginning, __end, __beginning, __end, __end, __end); 103706c3fb27SDimitry Andric } 103806c3fb27SDimitry Andric 1039cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 1040cb14a3feSDimitry Andric __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { 1041cb14a3feSDimitry Andric (void)__block_index; 1042cb14a3feSDimitry Andric (void)__annotation_type; 1043cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 104406c3fb27SDimitry Andric __map_const_iterator __block_it = __map_.begin() + __block_index; 104506c3fb27SDimitry Andric const void* __block_start = std::__to_address(*__block_it); 104606c3fb27SDimitry Andric const void* __block_end = std::__to_address(*__block_it + __block_size); 104706c3fb27SDimitry Andric 104806c3fb27SDimitry Andric if (__annotation_type == __asan_poison) 104906c3fb27SDimitry Andric __annotate_poison_block(__block_start, __block_end); 105006c3fb27SDimitry Andric else { 1051*0fca6ea1SDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>( 105206c3fb27SDimitry Andric __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); 105306c3fb27SDimitry Andric } 1054cb14a3feSDimitry Andric#endif 105506c3fb27SDimitry Andric } 105606c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) 105706c3fb27SDimitry Andric 105806c3fb27SDimitry Andricpublic: 1059cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __verify_asan_annotations() const _NOEXCEPT { 106006c3fb27SDimitry Andric // This function tests deque object annotations. 106106c3fb27SDimitry Andric if (empty()) { 106206c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 106306c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 106406c3fb27SDimitry Andric std::__to_address(*__it), 106506c3fb27SDimitry Andric std::__to_address(*__it), 106606c3fb27SDimitry Andric std::__to_address(*__it), 106706c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 106806c3fb27SDimitry Andric return false; 106906c3fb27SDimitry Andric } 107006c3fb27SDimitry Andric 107106c3fb27SDimitry Andric return true; 107206c3fb27SDimitry Andric } 107306c3fb27SDimitry Andric 107406c3fb27SDimitry Andric size_type __end = __start_ + size(); 107506c3fb27SDimitry Andric __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; 107606c3fb27SDimitry Andric __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; 107706c3fb27SDimitry Andric 107806c3fb27SDimitry Andric // Pointers to first and after last elements 107906c3fb27SDimitry Andric // Those can be in different deque blocks 108006c3fb27SDimitry Andric const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); 108106c3fb27SDimitry Andric const void* __p_end = 108206c3fb27SDimitry Andric std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); 108306c3fb27SDimitry Andric 108406c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 108506c3fb27SDimitry Andric // Go over all blocks, find the place we are in and verify its annotations 108606c3fb27SDimitry Andric // Note that __p_end points *behind* the last item. 108706c3fb27SDimitry Andric 108806c3fb27SDimitry Andric // - blocks before the first block with container elements 108906c3fb27SDimitry Andric // - first block with items 109006c3fb27SDimitry Andric // - last block with items 109106c3fb27SDimitry Andric // - blocks after last block with ciontainer elements 109206c3fb27SDimitry Andric 109306c3fb27SDimitry Andric // Is the block before or after deque blocks that contain elements? 109406c3fb27SDimitry Andric if (__it < __first_mp || __it > __last_mp) { 109506c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 109606c3fb27SDimitry Andric std::__to_address(*__it), 109706c3fb27SDimitry Andric std::__to_address(*__it), 109806c3fb27SDimitry Andric std::__to_address(*__it), 109906c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 110006c3fb27SDimitry Andric return false; 110106c3fb27SDimitry Andric } else { 110206c3fb27SDimitry Andric const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); 110306c3fb27SDimitry Andric const void* __containers_buffer_end = 110406c3fb27SDimitry Andric (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); 110506c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 110606c3fb27SDimitry Andric std::__to_address(*__it), 110706c3fb27SDimitry Andric __containers_buffer_beg, 110806c3fb27SDimitry Andric __containers_buffer_end, 110906c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) { 111006c3fb27SDimitry Andric return false; 111106c3fb27SDimitry Andric } 111206c3fb27SDimitry Andric } 111306c3fb27SDimitry Andric } 111406c3fb27SDimitry Andric return true; 111506c3fb27SDimitry Andric } 111606c3fb27SDimitry Andric 111706c3fb27SDimitry Andricprivate: 111806c3fb27SDimitry Andric#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS 1119cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_front_spare(bool __keep_one = true) { 1120e40139ffSDimitry Andric if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { 112106c3fb27SDimitry Andric __annotate_whole_block(0, __asan_unposion); 1122cb14a3feSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.front(), __block_size); 1123bdd1243dSDimitry Andric __map_.pop_front(); 1124bdd1243dSDimitry Andric __start_ -= __block_size; 1125e40139ffSDimitry Andric return true; 1126e40139ffSDimitry Andric } 1127e40139ffSDimitry Andric return false; 1128e40139ffSDimitry Andric } 1129e40139ffSDimitry Andric 1130cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_back_spare(bool __keep_one = true) { 1131e40139ffSDimitry Andric if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { 113206c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_unposion); 1133cb14a3feSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.back(), __block_size); 1134bdd1243dSDimitry Andric __map_.pop_back(); 1135e40139ffSDimitry Andric return true; 1136e40139ffSDimitry Andric } 1137e40139ffSDimitry Andric return false; 1138e40139ffSDimitry Andric } 11390b57cec5SDimitry Andric 114006c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1141cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __f, _Sentinel __l); 114206c3fb27SDimitry Andric 114306c3fb27SDimitry Andric template <class _RandomAccessIterator> 1144cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); 114506c3fb27SDimitry Andric template <class _Iterator> 1146cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_size(_Iterator __f, difference_type __n); 114706c3fb27SDimitry Andric 114806c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1149cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); 115006c3fb27SDimitry Andric 115106c3fb27SDimitry Andric template <class _Iterator> 1152cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); 115306c3fb27SDimitry Andric 115406c3fb27SDimitry Andric template <class _BiIter, class _Sentinel> 1155cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 1156cb14a3feSDimitry Andric __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); 115706c3fb27SDimitry Andric template <class _BiIter> 1158cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); 115906c3fb27SDimitry Andric 11605f757f3fSDimitry Andric template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> = 0> 11615f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l); 11625f757f3fSDimitry Andric template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> = 0> 11635f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l); 116406c3fb27SDimitry Andric 116506c3fb27SDimitry Andric template <class _InputIterator> 116606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); 116706c3fb27SDimitry Andric template <class _InputIterator, class _Sentinel> 116806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); 116906c3fb27SDimitry Andric 1170bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); 1171bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); 1172bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); 1173bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(); 1174bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n); 1175bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(); 1176bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n); 1177cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1178cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 1179cb14a3feSDimitry Andric __move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1180cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1181cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 1182cb14a3feSDimitry Andric __move_construct_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 11830b57cec5SDimitry Andric 1184cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c) { 1185cb14a3feSDimitry Andric __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); 1186cb14a3feSDimitry Andric } 11870b57cec5SDimitry Andric 1188cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c, true_type) { 1189cb14a3feSDimitry Andric if (__alloc() != __c.__alloc()) { 11900b57cec5SDimitry Andric clear(); 11910b57cec5SDimitry Andric shrink_to_fit(); 11920b57cec5SDimitry Andric } 1193bdd1243dSDimitry Andric __alloc() = __c.__alloc(); 1194bdd1243dSDimitry Andric __map_.__alloc() = __c.__map_.__alloc(); 11950b57cec5SDimitry Andric } 11960b57cec5SDimitry Andric 1197cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {} 11980b57cec5SDimitry Andric 1199bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type) 12000b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 1201bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type); 12020b57cec5SDimitry Andric}; 12030b57cec5SDimitry Andric 1204bdd1243dSDimitry Andrictemplate <class _Tp, class _Alloc> 1205bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size = 1206bdd1243dSDimitry Andric __deque_block_size<value_type, difference_type>::value; 1207bdd1243dSDimitry Andric 1208349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17 12090b57cec5SDimitry Andrictemplate <class _InputIterator, 1210fe6060f1SDimitry Andric class _Alloc = allocator<__iter_value_type<_InputIterator>>, 121106c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1212cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1213cb14a3feSDimitry Andricdeque(_InputIterator, _InputIterator) -> deque<__iter_value_type<_InputIterator>, _Alloc>; 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andrictemplate <class _InputIterator, 12160b57cec5SDimitry Andric class _Alloc, 121706c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1218cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1219cb14a3feSDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc) -> deque<__iter_value_type<_InputIterator>, _Alloc>; 12200b57cec5SDimitry Andric#endif 12210b57cec5SDimitry Andric 122206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 122306c3fb27SDimitry Andrictemplate <ranges::input_range _Range, 122406c3fb27SDimitry Andric class _Alloc = allocator<ranges::range_value_t<_Range>>, 1225cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1226cb14a3feSDimitry Andricdeque(from_range_t, _Range&&, _Alloc = _Alloc()) -> deque<ranges::range_value_t<_Range>, _Alloc>; 122706c3fb27SDimitry Andric#endif 122806c3fb27SDimitry Andric 12290b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1230cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n) : __start_(0), __size_(0, __default_init_tag()) { 123106c3fb27SDimitry Andric __annotate_new(0); 12320b57cec5SDimitry Andric if (__n > 0) 12330b57cec5SDimitry Andric __append(__n); 12340b57cec5SDimitry Andric} 12350b57cec5SDimitry Andric 123606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 12370b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12380b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) 1239cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 124006c3fb27SDimitry Andric __annotate_new(0); 12410b57cec5SDimitry Andric if (__n > 0) 12420b57cec5SDimitry Andric __append(__n); 12430b57cec5SDimitry Andric} 12440b57cec5SDimitry Andric#endif 12450b57cec5SDimitry Andric 12460b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1247cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) : __start_(0), __size_(0, __default_init_tag()) { 124806c3fb27SDimitry Andric __annotate_new(0); 12490b57cec5SDimitry Andric if (__n > 0) 12500b57cec5SDimitry Andric __append(__n, __v); 12510b57cec5SDimitry Andric} 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12545f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 1255cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l) : __start_(0), __size_(0, __default_init_tag()) { 125606c3fb27SDimitry Andric __annotate_new(0); 12570b57cec5SDimitry Andric __append(__f, __l); 12580b57cec5SDimitry Andric} 12590b57cec5SDimitry Andric 12600b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12615f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 12625f757f3fSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a) 1263cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 126406c3fb27SDimitry Andric __annotate_new(0); 12650b57cec5SDimitry Andric __append(__f, __l); 12660b57cec5SDimitry Andric} 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12690b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c) 1270bdd1243dSDimitry Andric : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))), 1271bdd1243dSDimitry Andric __start_(0), 1272cb14a3feSDimitry Andric __size_(0, __map_.__alloc()) { 127306c3fb27SDimitry Andric __annotate_new(0); 12740b57cec5SDimitry Andric __append(__c.begin(), __c.end()); 12750b57cec5SDimitry Andric} 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 127881ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a) 1279cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 128006c3fb27SDimitry Andric __annotate_new(0); 12810b57cec5SDimitry Andric __append(__c.begin(), __c.end()); 12820b57cec5SDimitry Andric} 12830b57cec5SDimitry Andric 12840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1285cb14a3feSDimitry Andricdeque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(const deque& __c) { 1286cb14a3feSDimitry Andric if (this != std::addressof(__c)) { 12870b57cec5SDimitry Andric __copy_assign_alloc(__c); 12880b57cec5SDimitry Andric assign(__c.begin(), __c.end()); 12890b57cec5SDimitry Andric } 12900b57cec5SDimitry Andric return *this; 12910b57cec5SDimitry Andric} 12920b57cec5SDimitry Andric 12930b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 12940b57cec5SDimitry Andric 12950b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1296cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il) : __start_(0), __size_(0, __default_init_tag()) { 129706c3fb27SDimitry Andric __annotate_new(0); 12980b57cec5SDimitry Andric __append(__il.begin(), __il.end()); 12990b57cec5SDimitry Andric} 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13020b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a) 1303cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 130406c3fb27SDimitry Andric __annotate_new(0); 13050b57cec5SDimitry Andric __append(__il.begin(), __il.end()); 13060b57cec5SDimitry Andric} 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1309*0fca6ea1SDimitry Andricinline deque<_Tp, _Allocator>::deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value) 1310cb14a3feSDimitry Andric : __map_(std::move(__c.__map_)), __start_(std::move(__c.__start_)), __size_(std::move(__c.__size_)) { 1311bdd1243dSDimitry Andric __c.__start_ = 0; 1312bdd1243dSDimitry Andric __c.__size() = 0; 13130b57cec5SDimitry Andric} 13140b57cec5SDimitry Andric 13150b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1316cb14a3feSDimitry Andricinline deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a) 1317bdd1243dSDimitry Andric : __map_(std::move(__c.__map_), __pointer_allocator(__a)), 1318bdd1243dSDimitry Andric __start_(std::move(__c.__start_)), 1319cb14a3feSDimitry Andric __size_(std::move(__c.__size()), __a) { 1320cb14a3feSDimitry Andric if (__a == __c.__alloc()) { 1321bdd1243dSDimitry Andric __c.__start_ = 0; 1322bdd1243dSDimitry Andric __c.__size() = 0; 1323cb14a3feSDimitry Andric } else { 1324bdd1243dSDimitry Andric __map_.clear(); 1325bdd1243dSDimitry Andric __start_ = 0; 1326bdd1243dSDimitry Andric __size() = 0; 13270b57cec5SDimitry Andric typedef move_iterator<iterator> _Ip; 13280b57cec5SDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end())); 13290b57cec5SDimitry Andric } 13300b57cec5SDimitry Andric} 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1333*0fca6ea1SDimitry Andricinline deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(deque&& __c) noexcept( 1334*0fca6ea1SDimitry Andric __alloc_traits::propagate_on_container_move_assignment::value && 1335*0fca6ea1SDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 1336cb14a3feSDimitry Andric __move_assign(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 13370b57cec5SDimitry Andric return *this; 13380b57cec5SDimitry Andric} 13390b57cec5SDimitry Andric 13400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1341cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) { 1342cb14a3feSDimitry Andric if (__alloc() != __c.__alloc()) { 13430b57cec5SDimitry Andric typedef move_iterator<iterator> _Ip; 13440b57cec5SDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end())); 1345cb14a3feSDimitry Andric } else 13460b57cec5SDimitry Andric __move_assign(__c, true_type()); 13470b57cec5SDimitry Andric} 13480b57cec5SDimitry Andric 13490b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1350*0fca6ea1SDimitry Andricvoid deque<_Tp, _Allocator>::__move_assign(deque& __c, 1351*0fca6ea1SDimitry Andric true_type) noexcept(is_nothrow_move_assignable<allocator_type>::value) { 13520b57cec5SDimitry Andric clear(); 13530b57cec5SDimitry Andric shrink_to_fit(); 1354bdd1243dSDimitry Andric __move_assign(__c); 13550b57cec5SDimitry Andric} 13560b57cec5SDimitry Andric 13570b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1360cb14a3feSDimitry Andrictemplate <class _InputIter, 1361cb14a3feSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIter>::value && 1362cb14a3feSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, 1363cb14a3feSDimitry Andric int> > 1364cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l) { 136506c3fb27SDimitry Andric __assign_with_sentinel(__f, __l); 136606c3fb27SDimitry Andric} 136706c3fb27SDimitry Andric 136806c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 136906c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 1370cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { 1371bdd1243dSDimitry Andric iterator __i = begin(); 1372bdd1243dSDimitry Andric iterator __e = end(); 13730b57cec5SDimitry Andric for (; __f != __l && __i != __e; ++__f, (void)++__i) 13740b57cec5SDimitry Andric *__i = *__f; 13750b57cec5SDimitry Andric if (__f != __l) 137606c3fb27SDimitry Andric __append_with_sentinel(std::move(__f), std::move(__l)); 13770b57cec5SDimitry Andric else 13780b57cec5SDimitry Andric __erase_to_end(__i); 13790b57cec5SDimitry Andric} 13800b57cec5SDimitry Andric 13810b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13825f757f3fSDimitry Andrictemplate <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> > 1383cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l) { 138406c3fb27SDimitry Andric __assign_with_size_random_access(__f, __l - __f); 138506c3fb27SDimitry Andric} 138606c3fb27SDimitry Andric 138706c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 138806c3fb27SDimitry Andrictemplate <class _RandomAccessIterator> 1389cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void 1390cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { 1391cb14a3feSDimitry Andric if (static_cast<size_type>(__n) > size()) { 139206c3fb27SDimitry Andric auto __l = __f + size(); 139306c3fb27SDimitry Andric std::copy(__f, __l, begin()); 139406c3fb27SDimitry Andric __append_with_size(__l, __n - size()); 1395cb14a3feSDimitry Andric } else 139606c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 139706c3fb27SDimitry Andric} 139806c3fb27SDimitry Andric 139906c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 140006c3fb27SDimitry Andrictemplate <class _Iterator> 1401cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { 140206c3fb27SDimitry Andric if (static_cast<size_type>(__n) > size()) { 140306c3fb27SDimitry Andric auto __added_size = __n - size(); 140406c3fb27SDimitry Andric 140506c3fb27SDimitry Andric auto __i = begin(); 140606c3fb27SDimitry Andric for (auto __count = size(); __count != 0; --__count) { 140706c3fb27SDimitry Andric *__i++ = *__f++; 140806c3fb27SDimitry Andric } 140906c3fb27SDimitry Andric 141006c3fb27SDimitry Andric __append_with_size(__f, __added_size); 141106c3fb27SDimitry Andric 141206c3fb27SDimitry Andric } else { 141306c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 141406c3fb27SDimitry Andric } 14150b57cec5SDimitry Andric} 14160b57cec5SDimitry Andric 14170b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1418cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) { 1419cb14a3feSDimitry Andric if (__n > size()) { 14205f757f3fSDimitry Andric std::fill_n(begin(), size(), __v); 1421bdd1243dSDimitry Andric __n -= size(); 14220b57cec5SDimitry Andric __append(__n, __v); 1423cb14a3feSDimitry Andric } else 14245f757f3fSDimitry Andric __erase_to_end(std::fill_n(begin(), __n, __v)); 14250b57cec5SDimitry Andric} 14260b57cec5SDimitry Andric 14270b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1428cb14a3feSDimitry Andricinline _Allocator deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT { 1429bdd1243dSDimitry Andric return __alloc(); 14300b57cec5SDimitry Andric} 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1433cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::resize(size_type __n) { 1434bdd1243dSDimitry Andric if (__n > size()) 1435bdd1243dSDimitry Andric __append(__n - size()); 1436bdd1243dSDimitry Andric else if (__n < size()) 1437bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 14380b57cec5SDimitry Andric} 14390b57cec5SDimitry Andric 14400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1441cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) { 1442bdd1243dSDimitry Andric if (__n > size()) 1443bdd1243dSDimitry Andric __append(__n - size(), __v); 1444bdd1243dSDimitry Andric else if (__n < size()) 1445bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 14460b57cec5SDimitry Andric} 14470b57cec5SDimitry Andric 14480b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1449cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT { 1450bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1451cb14a3feSDimitry Andric if (empty()) { 145206c3fb27SDimitry Andric __annotate_delete(); 1453cb14a3feSDimitry Andric while (__map_.size() > 0) { 1454bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.back(), __block_size); 1455bdd1243dSDimitry Andric __map_.pop_back(); 14560b57cec5SDimitry Andric } 1457bdd1243dSDimitry Andric __start_ = 0; 1458cb14a3feSDimitry Andric } else { 1459e40139ffSDimitry Andric __maybe_remove_front_spare(/*__keep_one=*/false); 1460e40139ffSDimitry Andric __maybe_remove_back_spare(/*__keep_one=*/false); 14610b57cec5SDimitry Andric } 1462bdd1243dSDimitry Andric __map_.shrink_to_fit(); 14630b57cec5SDimitry Andric} 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1466cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT { 1467*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "deque::operator[] index out of bounds"); 1468bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1469bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 14700b57cec5SDimitry Andric} 14710b57cec5SDimitry Andric 14720b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1473cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference 1474cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT { 1475*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "deque::operator[] index out of bounds"); 1476bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1477bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 14780b57cec5SDimitry Andric} 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1481cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::at(size_type __i) { 1482bdd1243dSDimitry Andric if (__i >= size()) 14835f757f3fSDimitry Andric std::__throw_out_of_range("deque"); 1484bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1485bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 14860b57cec5SDimitry Andric} 14870b57cec5SDimitry Andric 14880b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1489cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::at(size_type __i) const { 1490bdd1243dSDimitry Andric if (__i >= size()) 14915f757f3fSDimitry Andric std::__throw_out_of_range("deque"); 1492bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1493bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 14940b57cec5SDimitry Andric} 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1497cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::front() _NOEXCEPT { 1498*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::front called on an empty deque"); 1499cb14a3feSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); 15000b57cec5SDimitry Andric} 15010b57cec5SDimitry Andric 15020b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1503cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::front() const _NOEXCEPT { 1504*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::front called on an empty deque"); 1505cb14a3feSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); 15060b57cec5SDimitry Andric} 15070b57cec5SDimitry Andric 15080b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1509cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::back() _NOEXCEPT { 1510*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::back called on an empty deque"); 1511bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1512bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15130b57cec5SDimitry Andric} 15140b57cec5SDimitry Andric 15150b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1516cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::back() const _NOEXCEPT { 1517*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::back called on an empty deque"); 1518bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1519bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15200b57cec5SDimitry Andric} 15210b57cec5SDimitry Andric 15220b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1523cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_back(const value_type& __v) { 1524bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15250b57cec5SDimitry Andric if (__back_spare() == 0) 15260b57cec5SDimitry Andric __add_back_capacity(); 15270b57cec5SDimitry Andric // __back_spare() >= 1 152806c3fb27SDimitry Andric __annotate_increase_back(1); 15295f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1530bdd1243dSDimitry Andric ++__size(); 15310b57cec5SDimitry Andric} 15320b57cec5SDimitry Andric 15330b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1534cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_front(const value_type& __v) { 1535bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15360b57cec5SDimitry Andric if (__front_spare() == 0) 15370b57cec5SDimitry Andric __add_front_capacity(); 15380b57cec5SDimitry Andric // __front_spare() >= 1 153906c3fb27SDimitry Andric __annotate_increase_front(1); 15405f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1541bdd1243dSDimitry Andric --__start_; 1542bdd1243dSDimitry Andric ++__size(); 15430b57cec5SDimitry Andric} 15440b57cec5SDimitry Andric 15450b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 15460b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1547cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_back(value_type&& __v) { 1548bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15490b57cec5SDimitry Andric if (__back_spare() == 0) 15500b57cec5SDimitry Andric __add_back_capacity(); 15510b57cec5SDimitry Andric // __back_spare() >= 1 155206c3fb27SDimitry Andric __annotate_increase_back(1); 15535f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); 1554bdd1243dSDimitry Andric ++__size(); 15550b57cec5SDimitry Andric} 15560b57cec5SDimitry Andric 15570b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15580b57cec5SDimitry Andrictemplate <class... _Args> 155906c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 15600b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 15610b57cec5SDimitry Andric# else 15620b57cec5SDimitry Andricvoid 15630b57cec5SDimitry Andric# endif 1564cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::emplace_back(_Args&&... __args) { 1565bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15660b57cec5SDimitry Andric if (__back_spare() == 0) 15670b57cec5SDimitry Andric __add_back_capacity(); 15680b57cec5SDimitry Andric // __back_spare() >= 1 156906c3fb27SDimitry Andric __annotate_increase_back(1); 1570cb14a3feSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); 1571bdd1243dSDimitry Andric ++__size(); 157206c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 1573bdd1243dSDimitry Andric return *--end(); 15740b57cec5SDimitry Andric# endif 15750b57cec5SDimitry Andric} 15760b57cec5SDimitry Andric 15770b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1578cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_front(value_type&& __v) { 1579bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15800b57cec5SDimitry Andric if (__front_spare() == 0) 15810b57cec5SDimitry Andric __add_front_capacity(); 15820b57cec5SDimitry Andric // __front_spare() >= 1 158306c3fb27SDimitry Andric __annotate_increase_front(1); 15845f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); 1585bdd1243dSDimitry Andric --__start_; 1586bdd1243dSDimitry Andric ++__size(); 15870b57cec5SDimitry Andric} 15880b57cec5SDimitry Andric 15890b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15900b57cec5SDimitry Andrictemplate <class... _Args> 159106c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 15920b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 15930b57cec5SDimitry Andric# else 15940b57cec5SDimitry Andricvoid 15950b57cec5SDimitry Andric# endif 1596cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::emplace_front(_Args&&... __args) { 1597bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15980b57cec5SDimitry Andric if (__front_spare() == 0) 15990b57cec5SDimitry Andric __add_front_capacity(); 16000b57cec5SDimitry Andric // __front_spare() >= 1 160106c3fb27SDimitry Andric __annotate_increase_front(1); 16025f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); 1603bdd1243dSDimitry Andric --__start_; 1604bdd1243dSDimitry Andric ++__size(); 160506c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 1606bdd1243dSDimitry Andric return *begin(); 16070b57cec5SDimitry Andric# endif 16080b57cec5SDimitry Andric} 16090b57cec5SDimitry Andric 16100b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1611cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) { 1612bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1613bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1614bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1615cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 16160b57cec5SDimitry Andric if (__front_spare() == 0) 16170b57cec5SDimitry Andric __add_front_capacity(); 16180b57cec5SDimitry Andric // __front_spare() >= 1 161906c3fb27SDimitry Andric __annotate_increase_front(1); 1620cb14a3feSDimitry Andric if (__pos == 0) { 16215f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); 1622bdd1243dSDimitry Andric --__start_; 1623bdd1243dSDimitry Andric ++__size(); 1624cb14a3feSDimitry Andric } else { 1625bdd1243dSDimitry Andric iterator __b = begin(); 16265f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 16275f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1628bdd1243dSDimitry Andric --__start_; 1629bdd1243dSDimitry Andric ++__size(); 16300b57cec5SDimitry Andric if (__pos > 1) 16315f757f3fSDimitry Andric __b = std::move(std::next(__b), __b + __pos, __b); 16325f757f3fSDimitry Andric *__b = std::move(__v); 16330b57cec5SDimitry Andric } 1634cb14a3feSDimitry Andric } else { // insert by shifting things forward 16350b57cec5SDimitry Andric if (__back_spare() == 0) 16360b57cec5SDimitry Andric __add_back_capacity(); 16370b57cec5SDimitry Andric // __back_capacity >= 1 163806c3fb27SDimitry Andric __annotate_increase_back(1); 1639bdd1243dSDimitry Andric size_type __de = size() - __pos; 1640cb14a3feSDimitry Andric if (__de == 0) { 16415f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); 1642bdd1243dSDimitry Andric ++__size(); 1643cb14a3feSDimitry Andric } else { 1644bdd1243dSDimitry Andric iterator __e = end(); 16455f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 16465f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1647bdd1243dSDimitry Andric ++__size(); 16480b57cec5SDimitry Andric if (__de > 1) 16495f757f3fSDimitry Andric __e = std::move_backward(__e - __de, __em1, __e); 16505f757f3fSDimitry Andric *--__e = std::move(__v); 16510b57cec5SDimitry Andric } 16520b57cec5SDimitry Andric } 1653bdd1243dSDimitry Andric return begin() + __pos; 16540b57cec5SDimitry Andric} 16550b57cec5SDimitry Andric 16560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16570b57cec5SDimitry Andrictemplate <class... _Args> 1658cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) { 1659bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1660bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1661bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1662cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 16630b57cec5SDimitry Andric if (__front_spare() == 0) 16640b57cec5SDimitry Andric __add_front_capacity(); 16650b57cec5SDimitry Andric // __front_spare() >= 1 166606c3fb27SDimitry Andric __annotate_increase_front(1); 1667cb14a3feSDimitry Andric if (__pos == 0) { 16685f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); 1669bdd1243dSDimitry Andric --__start_; 1670bdd1243dSDimitry Andric ++__size(); 1671cb14a3feSDimitry Andric } else { 16725f757f3fSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); 1673bdd1243dSDimitry Andric iterator __b = begin(); 16745f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 16755f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1676bdd1243dSDimitry Andric --__start_; 1677bdd1243dSDimitry Andric ++__size(); 16780b57cec5SDimitry Andric if (__pos > 1) 16795f757f3fSDimitry Andric __b = std::move(std::next(__b), __b + __pos, __b); 16805f757f3fSDimitry Andric *__b = std::move(__tmp.get()); 16810b57cec5SDimitry Andric } 1682cb14a3feSDimitry Andric } else { // insert by shifting things forward 16830b57cec5SDimitry Andric if (__back_spare() == 0) 16840b57cec5SDimitry Andric __add_back_capacity(); 16850b57cec5SDimitry Andric // __back_capacity >= 1 168606c3fb27SDimitry Andric __annotate_increase_back(1); 1687bdd1243dSDimitry Andric size_type __de = size() - __pos; 1688cb14a3feSDimitry Andric if (__de == 0) { 16895f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); 1690bdd1243dSDimitry Andric ++__size(); 1691cb14a3feSDimitry Andric } else { 16925f757f3fSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); 1693bdd1243dSDimitry Andric iterator __e = end(); 16945f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 16955f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1696bdd1243dSDimitry Andric ++__size(); 16970b57cec5SDimitry Andric if (__de > 1) 16985f757f3fSDimitry Andric __e = std::move_backward(__e - __de, __em1, __e); 16995f757f3fSDimitry Andric *--__e = std::move(__tmp.get()); 17000b57cec5SDimitry Andric } 17010b57cec5SDimitry Andric } 1702bdd1243dSDimitry Andric return begin() + __pos; 17030b57cec5SDimitry Andric} 17040b57cec5SDimitry Andric 17050b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 17060b57cec5SDimitry Andric 17070b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1708cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) { 1709bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1710bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1711bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1712cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 17130b57cec5SDimitry Andric if (__front_spare() == 0) 17140b57cec5SDimitry Andric __add_front_capacity(); 17150b57cec5SDimitry Andric // __front_spare() >= 1 171606c3fb27SDimitry Andric __annotate_increase_front(1); 1717cb14a3feSDimitry Andric if (__pos == 0) { 17185f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1719bdd1243dSDimitry Andric --__start_; 1720bdd1243dSDimitry Andric ++__size(); 1721cb14a3feSDimitry Andric } else { 17220b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1723bdd1243dSDimitry Andric iterator __b = begin(); 17245f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 17250b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__b)) 17260b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__bm1); 17275f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1728bdd1243dSDimitry Andric --__start_; 1729bdd1243dSDimitry Andric ++__size(); 17300b57cec5SDimitry Andric if (__pos > 1) 17315f757f3fSDimitry Andric __b = __move_and_check(std::next(__b), __b + __pos, __b, __vt); 17320b57cec5SDimitry Andric *__b = *__vt; 17330b57cec5SDimitry Andric } 1734cb14a3feSDimitry Andric } else { // insert by shifting things forward 17350b57cec5SDimitry Andric if (__back_spare() == 0) 17360b57cec5SDimitry Andric __add_back_capacity(); 17370b57cec5SDimitry Andric // __back_capacity >= 1 173806c3fb27SDimitry Andric __annotate_increase_back(1); 1739bdd1243dSDimitry Andric size_type __de = size() - __pos; 1740cb14a3feSDimitry Andric if (__de == 0) { 17415f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1742bdd1243dSDimitry Andric ++__size(); 1743cb14a3feSDimitry Andric } else { 17440b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1745bdd1243dSDimitry Andric iterator __e = end(); 17465f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 17470b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1)) 17480b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__e); 17495f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1750bdd1243dSDimitry Andric ++__size(); 17510b57cec5SDimitry Andric if (__de > 1) 17520b57cec5SDimitry Andric __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); 17530b57cec5SDimitry Andric *--__e = *__vt; 17540b57cec5SDimitry Andric } 17550b57cec5SDimitry Andric } 1756bdd1243dSDimitry Andric return begin() + __pos; 17570b57cec5SDimitry Andric} 17580b57cec5SDimitry Andric 17590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17600b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1761cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) { 1762bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1763bdd1243dSDimitry Andric size_type __to_end = __size() - __pos; 1764bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1765cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 17660b57cec5SDimitry Andric if (__n > __front_spare()) 17670b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 17680b57cec5SDimitry Andric // __n <= __front_spare() 176906c3fb27SDimitry Andric __annotate_increase_front(__n); 1770bdd1243dSDimitry Andric iterator __old_begin = begin(); 17710b57cec5SDimitry Andric iterator __i = __old_begin; 1772cb14a3feSDimitry Andric if (__n > __pos) { 1773bdd1243dSDimitry Andric for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size()) 17745f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), __v); 17750b57cec5SDimitry Andric __n = __pos; 17760b57cec5SDimitry Andric } 1777cb14a3feSDimitry Andric if (__n > 0) { 17780b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 17790b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 17800b57cec5SDimitry Andric __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); 17810b57cec5SDimitry Andric if (__n < __pos) 17820b57cec5SDimitry Andric __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); 17835f757f3fSDimitry Andric std::fill_n(__old_begin, __n, *__vt); 17840b57cec5SDimitry Andric } 1785cb14a3feSDimitry Andric } else { // insert by shifting things forward 17860b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 17870b57cec5SDimitry Andric if (__n > __back_capacity) 17880b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 17890b57cec5SDimitry Andric // __n <= __back_capacity 179006c3fb27SDimitry Andric __annotate_increase_back(__n); 1791bdd1243dSDimitry Andric iterator __old_end = end(); 17920b57cec5SDimitry Andric iterator __i = __old_end; 1793bdd1243dSDimitry Andric size_type __de = size() - __pos; 1794cb14a3feSDimitry Andric if (__n > __de) { 1795bdd1243dSDimitry Andric for (size_type __m = __n - __de; __m; --__m, (void)++__i, ++__size()) 17965f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), __v); 17970b57cec5SDimitry Andric __n = __de; 17980b57cec5SDimitry Andric } 1799cb14a3feSDimitry Andric if (__n > 0) { 18000b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 18010b57cec5SDimitry Andric iterator __oen = __old_end - __n; 18020b57cec5SDimitry Andric __move_construct_and_check(__oen, __old_end, __i, __vt); 18030b57cec5SDimitry Andric if (__n < __de) 18040b57cec5SDimitry Andric __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); 18055f757f3fSDimitry Andric std::fill_n(__old_end - __n, __n, *__vt); 18060b57cec5SDimitry Andric } 18070b57cec5SDimitry Andric } 1808bdd1243dSDimitry Andric return begin() + __pos; 18090b57cec5SDimitry Andric} 18100b57cec5SDimitry Andric 18110b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18125f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> > 18130b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1814cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l) { 181506c3fb27SDimitry Andric return __insert_with_sentinel(__p, __f, __l); 181606c3fb27SDimitry Andric} 181706c3fb27SDimitry Andric 181806c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 181906c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 1820cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 182106c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { 1822bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__alloc()); 182306c3fb27SDimitry Andric __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); 18240b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; 18250b57cec5SDimitry Andric return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); 18260b57cec5SDimitry Andric} 18270b57cec5SDimitry Andric 18280b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18295f757f3fSDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> > 18300b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1831cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l) { 183206c3fb27SDimitry Andric return __insert_with_size(__p, __f, std::distance(__f, __l)); 183306c3fb27SDimitry Andric} 183406c3fb27SDimitry Andric 183506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 183606c3fb27SDimitry Andrictemplate <class _Iterator> 1837cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 183806c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) { 1839bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); 184006c3fb27SDimitry Andric __buf.__construct_at_end_with_size(__f, __n); 18410b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; 18420b57cec5SDimitry Andric return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); 18430b57cec5SDimitry Andric} 18440b57cec5SDimitry Andric 18450b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18465f757f3fSDimitry Andrictemplate <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> > 1847cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l) { 184806c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l)); 184906c3fb27SDimitry Andric} 185006c3fb27SDimitry Andric 185106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 185206c3fb27SDimitry Andrictemplate <class _BiIter, class _Sentinel> 1853cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 185406c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) { 185506c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, std::next(__f, __n), __n); 185606c3fb27SDimitry Andric} 185706c3fb27SDimitry Andric 185806c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 185906c3fb27SDimitry Andrictemplate <class _BiIter> 1860cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 186106c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) { 1862bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1863bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1864bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1865cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 18660b57cec5SDimitry Andric if (__n > __front_spare()) 18670b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 18680b57cec5SDimitry Andric // __n <= __front_spare() 186906c3fb27SDimitry Andric __annotate_increase_front(__n); 1870bdd1243dSDimitry Andric iterator __old_begin = begin(); 18710b57cec5SDimitry Andric iterator __i = __old_begin; 18720b57cec5SDimitry Andric _BiIter __m = __f; 1873cb14a3feSDimitry Andric if (__n > __pos) { 18745f757f3fSDimitry Andric __m = __pos < __n / 2 ? std::prev(__l, __pos) : std::next(__f, __n - __pos); 1875bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __f; --__start_, ++__size()) 18765f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), *--__j); 18770b57cec5SDimitry Andric __n = __pos; 18780b57cec5SDimitry Andric } 1879cb14a3feSDimitry Andric if (__n > 0) { 18800b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 1881cb14a3feSDimitry Andric for (iterator __j = __obn; __j != __old_begin;) { 18825f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), std::move(*--__j)); 1883bdd1243dSDimitry Andric --__start_; 1884bdd1243dSDimitry Andric ++__size(); 18850b57cec5SDimitry Andric } 18860b57cec5SDimitry Andric if (__n < __pos) 18875f757f3fSDimitry Andric __old_begin = std::move(__obn, __old_begin + __pos, __old_begin); 18885f757f3fSDimitry Andric std::copy(__m, __l, __old_begin); 18890b57cec5SDimitry Andric } 1890cb14a3feSDimitry Andric } else { // insert by shifting things forward 18910b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 18920b57cec5SDimitry Andric if (__n > __back_capacity) 18930b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 18940b57cec5SDimitry Andric // __n <= __back_capacity 189506c3fb27SDimitry Andric __annotate_increase_back(__n); 1896bdd1243dSDimitry Andric iterator __old_end = end(); 18970b57cec5SDimitry Andric iterator __i = __old_end; 18980b57cec5SDimitry Andric _BiIter __m = __l; 1899bdd1243dSDimitry Andric size_type __de = size() - __pos; 1900cb14a3feSDimitry Andric if (__n > __de) { 19015f757f3fSDimitry Andric __m = __de < __n / 2 ? std::next(__f, __de) : std::prev(__l, __n - __de); 1902bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __l; ++__i, (void)++__j, ++__size()) 19035f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), *__j); 19040b57cec5SDimitry Andric __n = __de; 19050b57cec5SDimitry Andric } 1906cb14a3feSDimitry Andric if (__n > 0) { 19070b57cec5SDimitry Andric iterator __oen = __old_end - __n; 1908bdd1243dSDimitry Andric for (iterator __j = __oen; __j != __old_end; ++__i, (void)++__j, ++__size()) 19095f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), std::move(*__j)); 19100b57cec5SDimitry Andric if (__n < __de) 19115f757f3fSDimitry Andric __old_end = std::move_backward(__old_end - __de, __oen, __old_end); 19125f757f3fSDimitry Andric std::copy_backward(__f, __m, __old_end); 19130b57cec5SDimitry Andric } 19140b57cec5SDimitry Andric } 1915bdd1243dSDimitry Andric return begin() + __pos; 19160b57cec5SDimitry Andric} 19170b57cec5SDimitry Andric 19180b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 19195f757f3fSDimitry Andrictemplate <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> > 1920cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l) { 192106c3fb27SDimitry Andric __append_with_sentinel(__f, __l); 192206c3fb27SDimitry Andric} 192306c3fb27SDimitry Andric 192406c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 192506c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 1926cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { 19270b57cec5SDimitry Andric for (; __f != __l; ++__f) 19280b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 19290b57cec5SDimitry Andric push_back(*__f); 19300b57cec5SDimitry Andric#else 19310b57cec5SDimitry Andric emplace_back(*__f); 19320b57cec5SDimitry Andric#endif 19330b57cec5SDimitry Andric} 19340b57cec5SDimitry Andric 19350b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 19365f757f3fSDimitry Andrictemplate <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> > 1937cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l) { 193806c3fb27SDimitry Andric __append_with_size(__f, std::distance(__f, __l)); 193906c3fb27SDimitry Andric} 194006c3fb27SDimitry Andric 194106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 194206c3fb27SDimitry Andrictemplate <class _InputIterator> 1943cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { 1944bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19450b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19460b57cec5SDimitry Andric if (__n > __back_capacity) 19470b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 194806c3fb27SDimitry Andric 19490b57cec5SDimitry Andric // __n <= __back_capacity 195006c3fb27SDimitry Andric __annotate_increase_back(__n); 1951bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1952e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 1953e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { 19545f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); 1955e40139ffSDimitry Andric } 1956e40139ffSDimitry Andric } 19570b57cec5SDimitry Andric} 19580b57cec5SDimitry Andric 19590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1960cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(size_type __n) { 1961bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19620b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19630b57cec5SDimitry Andric if (__n > __back_capacity) 19640b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 19650b57cec5SDimitry Andric // __n <= __back_capacity 196606c3fb27SDimitry Andric __annotate_increase_back(__n); 1967bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1968e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 1969e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 19705f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); 1971e40139ffSDimitry Andric } 1972e40139ffSDimitry Andric } 19730b57cec5SDimitry Andric} 19740b57cec5SDimitry Andric 19750b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1976cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) { 1977bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19780b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19790b57cec5SDimitry Andric if (__n > __back_capacity) 19800b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 19810b57cec5SDimitry Andric // __n <= __back_capacity 198206c3fb27SDimitry Andric __annotate_increase_back(__n); 1983bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1984e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 1985e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 19865f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); 1987e40139ffSDimitry Andric } 1988e40139ffSDimitry Andric } 19890b57cec5SDimitry Andric} 19900b57cec5SDimitry Andric 19910b57cec5SDimitry Andric// Create front capacity for one block of elements. 19920b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 19930b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1994cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_front_capacity() { 1995bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1996cb14a3feSDimitry Andric if (__back_spare() >= __block_size) { 1997bdd1243dSDimitry Andric __start_ += __block_size; 1998bdd1243dSDimitry Andric pointer __pt = __map_.back(); 1999bdd1243dSDimitry Andric __map_.pop_back(); 2000bdd1243dSDimitry Andric __map_.push_front(__pt); 20010b57cec5SDimitry Andric } 2002bdd1243dSDimitry Andric // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer 2003cb14a3feSDimitry Andric else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around 20040b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 20050b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2006bdd1243dSDimitry Andric if (__map_.__front_spare() > 0) 2007bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 2008cb14a3feSDimitry Andric else { 2009bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 20100b57cec5SDimitry Andric // Done allocating, reorder capacity 2011bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2012bdd1243dSDimitry Andric __map_.pop_back(); 2013bdd1243dSDimitry Andric __map_.push_front(__pt); 20140b57cec5SDimitry Andric } 2015cb14a3feSDimitry Andric __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; 20160b57cec5SDimitry Andric } 20170b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 2018cb14a3feSDimitry Andric else { 2019cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2020cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__alloc()); 20210b57cec5SDimitry Andric 20220b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 2023cb14a3feSDimitry Andric unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); 20240b57cec5SDimitry Andric __buf.push_back(__hold.get()); 20250b57cec5SDimitry Andric __hold.release(); 20260b57cec5SDimitry Andric 2027cb14a3feSDimitry Andric for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) 20280b57cec5SDimitry Andric __buf.push_back(*__i); 20295f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 20305f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 20315f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 20325f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2033cb14a3feSDimitry Andric __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; 20340b57cec5SDimitry Andric } 203506c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 20360b57cec5SDimitry Andric} 20370b57cec5SDimitry Andric 20380b57cec5SDimitry Andric// Create front capacity for __n elements. 20390b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 20400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2041cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) { 2042bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2043bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 20440b57cec5SDimitry Andric // Number of unused blocks at back: 2045bdd1243dSDimitry Andric size_type __back_capacity = __back_spare() / __block_size; 20465f757f3fSDimitry Andric __back_capacity = std::min(__back_capacity, __nb); // don't take more than you need 20470b57cec5SDimitry Andric __nb -= __back_capacity; // number of blocks need to allocate 20480b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 2049cb14a3feSDimitry Andric if (__nb == 0) { 2050bdd1243dSDimitry Andric __start_ += __block_size * __back_capacity; 2051cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2052bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2053bdd1243dSDimitry Andric __map_.pop_back(); 2054bdd1243dSDimitry Andric __map_.push_front(__pt); 20550b57cec5SDimitry Andric } 20560b57cec5SDimitry Andric } 20570b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2058cb14a3feSDimitry Andric else if (__nb <= __map_.capacity() - 2059cb14a3feSDimitry Andric __map_.size()) { // we can put the new buffers into the map, but don't shift things around 20600b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 20610b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2062cb14a3feSDimitry Andric for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) { 2063bdd1243dSDimitry Andric if (__map_.__front_spare() == 0) 20640b57cec5SDimitry Andric break; 2065bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 206606c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 20670b57cec5SDimitry Andric } 20680b57cec5SDimitry Andric for (; __nb > 0; --__nb, ++__back_capacity) 2069bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 20700b57cec5SDimitry Andric // Done allocating, reorder capacity 2071bdd1243dSDimitry Andric __start_ += __back_capacity * __block_size; 2072cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2073bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2074bdd1243dSDimitry Andric __map_.pop_back(); 2075bdd1243dSDimitry Andric __map_.push_front(__pt); 207606c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 20770b57cec5SDimitry Andric } 20780b57cec5SDimitry Andric } 20790b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 2080cb14a3feSDimitry Andric else { 2081bdd1243dSDimitry Andric size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty(); 2082cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2083cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__alloc()); 208406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2085cb14a3feSDimitry Andric try { 208606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 208706c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2088bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 208906c3fb27SDimitry Andric // ASan: this is empty container, we have to poison whole block 2090cb14a3feSDimitry Andric __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); 209106c3fb27SDimitry Andric } 209206c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2093cb14a3feSDimitry Andric } catch (...) { 209406c3fb27SDimitry Andric __annotate_delete(); 2095cb14a3feSDimitry Andric for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) 2096bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 20970b57cec5SDimitry Andric throw; 20980b57cec5SDimitry Andric } 209906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2100cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2101bdd1243dSDimitry Andric __buf.push_back(__map_.back()); 2102bdd1243dSDimitry Andric __map_.pop_back(); 21030b57cec5SDimitry Andric } 2104cb14a3feSDimitry Andric for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) 21050b57cec5SDimitry Andric __buf.push_back(*__i); 21065f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 21075f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 21085f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 21095f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2110bdd1243dSDimitry Andric __start_ += __ds; 21110b57cec5SDimitry Andric } 21120b57cec5SDimitry Andric} 21130b57cec5SDimitry Andric 21140b57cec5SDimitry Andric// Create back capacity for one block of elements. 21150b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 21160b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2117cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_back_capacity() { 2118bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2119cb14a3feSDimitry Andric if (__front_spare() >= __block_size) { 2120bdd1243dSDimitry Andric __start_ -= __block_size; 2121bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2122bdd1243dSDimitry Andric __map_.pop_front(); 2123bdd1243dSDimitry Andric __map_.push_back(__pt); 21240b57cec5SDimitry Andric } 21250b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2126cb14a3feSDimitry Andric else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around 21270b57cec5SDimitry Andric // until it is allocated. If we throw, we don't need to fix 21280b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2129bdd1243dSDimitry Andric if (__map_.__back_spare() != 0) 2130bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 2131cb14a3feSDimitry Andric else { 2132bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 21330b57cec5SDimitry Andric // Done allocating, reorder capacity 2134bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2135bdd1243dSDimitry Andric __map_.pop_front(); 2136bdd1243dSDimitry Andric __map_.push_back(__pt); 21370b57cec5SDimitry Andric } 213806c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 21390b57cec5SDimitry Andric } 21400b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 2141cb14a3feSDimitry Andric else { 2142cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2143cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__alloc()); 21440b57cec5SDimitry Andric 21450b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 2146cb14a3feSDimitry Andric unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); 21470b57cec5SDimitry Andric __buf.push_back(__hold.get()); 21480b57cec5SDimitry Andric __hold.release(); 21490b57cec5SDimitry Andric 2150cb14a3feSDimitry Andric for (__map_pointer __i = __map_.end(); __i != __map_.begin();) 21510b57cec5SDimitry Andric __buf.push_front(*--__i); 21525f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 21535f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 21545f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 21555f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 215606c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 21570b57cec5SDimitry Andric } 21580b57cec5SDimitry Andric} 21590b57cec5SDimitry Andric 21600b57cec5SDimitry Andric// Create back capacity for __n elements. 21610b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 21620b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2163cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) { 2164bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2165bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 21660b57cec5SDimitry Andric // Number of unused blocks at front: 2167bdd1243dSDimitry Andric size_type __front_capacity = __front_spare() / __block_size; 21685f757f3fSDimitry Andric __front_capacity = std::min(__front_capacity, __nb); // don't take more than you need 21690b57cec5SDimitry Andric __nb -= __front_capacity; // number of blocks need to allocate 21700b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 2171cb14a3feSDimitry Andric if (__nb == 0) { 2172bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 2173cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2174bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2175bdd1243dSDimitry Andric __map_.pop_front(); 2176bdd1243dSDimitry Andric __map_.push_back(__pt); 21770b57cec5SDimitry Andric } 21780b57cec5SDimitry Andric } 21790b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2180cb14a3feSDimitry Andric else if (__nb <= __map_.capacity() - 2181cb14a3feSDimitry Andric __map_.size()) { // we can put the new buffers into the map, but don't shift things around 21820b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 21830b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2184cb14a3feSDimitry Andric for (; __nb > 0; --__nb) { 2185bdd1243dSDimitry Andric if (__map_.__back_spare() == 0) 21860b57cec5SDimitry Andric break; 2187bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 218806c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 21890b57cec5SDimitry Andric } 2190cb14a3feSDimitry Andric for (; __nb > 0; --__nb, ++__front_capacity, __start_ += __block_size - (__map_.size() == 1)) { 2191bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 219206c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 219306c3fb27SDimitry Andric } 21940b57cec5SDimitry Andric // Done allocating, reorder capacity 2195bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 2196cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2197bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2198bdd1243dSDimitry Andric __map_.pop_front(); 2199bdd1243dSDimitry Andric __map_.push_back(__pt); 22000b57cec5SDimitry Andric } 22010b57cec5SDimitry Andric } 22020b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 2203cb14a3feSDimitry Andric else { 2204bdd1243dSDimitry Andric size_type __ds = __front_capacity * __block_size; 2205cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2206cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 2207bdd1243dSDimitry Andric __map_.size() - __front_capacity, 2208bdd1243dSDimitry Andric __map_.__alloc()); 220906c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2210cb14a3feSDimitry Andric try { 221106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 221206c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2213bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 221406c3fb27SDimitry Andric // ASan: this is an empty container, we have to poison the whole block 2215cb14a3feSDimitry Andric __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); 221606c3fb27SDimitry Andric } 221706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2218cb14a3feSDimitry Andric } catch (...) { 221906c3fb27SDimitry Andric __annotate_delete(); 2220cb14a3feSDimitry Andric for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) 2221bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 22220b57cec5SDimitry Andric throw; 22230b57cec5SDimitry Andric } 222406c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2225cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2226bdd1243dSDimitry Andric __buf.push_back(__map_.front()); 2227bdd1243dSDimitry Andric __map_.pop_front(); 22280b57cec5SDimitry Andric } 2229cb14a3feSDimitry Andric for (__map_pointer __i = __map_.end(); __i != __map_.begin();) 22300b57cec5SDimitry Andric __buf.push_front(*--__i); 22315f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 22325f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 22335f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 22345f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2235bdd1243dSDimitry Andric __start_ -= __ds; 22360b57cec5SDimitry Andric } 22370b57cec5SDimitry Andric} 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2240cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::pop_front() { 2241*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_front called on an empty deque"); 224206c3fb27SDimitry Andric size_type __old_sz = size(); 224306c3fb27SDimitry Andric size_type __old_start = __start_; 2244bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2245cb14a3feSDimitry Andric __alloc_traits::destroy( 2246cb14a3feSDimitry Andric __a, std::__to_address(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size)); 2247bdd1243dSDimitry Andric --__size(); 2248bdd1243dSDimitry Andric ++__start_; 224906c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2250e40139ffSDimitry Andric __maybe_remove_front_spare(); 22510b57cec5SDimitry Andric} 22520b57cec5SDimitry Andric 22530b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2254cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::pop_back() { 225506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); 225606c3fb27SDimitry Andric size_type __old_sz = size(); 225706c3fb27SDimitry Andric size_type __old_start = __start_; 2258bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2259bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 2260cb14a3feSDimitry Andric __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() + __p / __block_size) + __p % __block_size)); 2261bdd1243dSDimitry Andric --__size(); 226206c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2263e40139ffSDimitry Andric __maybe_remove_back_spare(); 22640b57cec5SDimitry Andric} 22650b57cec5SDimitry Andric 22660b57cec5SDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)). 22670b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt. 22680b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22690b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2270cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 22710b57cec5SDimitry Andric // as if 22720b57cec5SDimitry Andric // for (; __f != __l; ++__f, ++__r) 22735f757f3fSDimitry Andric // *__r = std::move(*__f); 22740b57cec5SDimitry Andric difference_type __n = __l - __f; 2275cb14a3feSDimitry Andric while (__n > 0) { 22760b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2277bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 22780b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 2279cb14a3feSDimitry Andric if (__bs > __n) { 22800b57cec5SDimitry Andric __bs = __n; 22810b57cec5SDimitry Andric __fe = __fb + __bs; 22820b57cec5SDimitry Andric } 22830b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 22840b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; 22855f757f3fSDimitry Andric __r = std::move(__fb, __fe, __r); 22860b57cec5SDimitry Andric __n -= __bs; 22870b57cec5SDimitry Andric __f += __bs; 22880b57cec5SDimitry Andric } 22890b57cec5SDimitry Andric return __r; 22900b57cec5SDimitry Andric} 22910b57cec5SDimitry Andric 22920b57cec5SDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards. 22930b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt. 22940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22950b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2296cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 22970b57cec5SDimitry Andric // as if 22980b57cec5SDimitry Andric // while (__f != __l) 22995f757f3fSDimitry Andric // *--__r = std::move(*--__l); 23000b57cec5SDimitry Andric difference_type __n = __l - __f; 2301cb14a3feSDimitry Andric while (__n > 0) { 23020b57cec5SDimitry Andric --__l; 23030b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 23040b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 23050b57cec5SDimitry Andric difference_type __bs = __le - __lb; 2306cb14a3feSDimitry Andric if (__bs > __n) { 23070b57cec5SDimitry Andric __bs = __n; 23080b57cec5SDimitry Andric __lb = __le - __bs; 23090b57cec5SDimitry Andric } 23100b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 23110b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; 23125f757f3fSDimitry Andric __r = std::move_backward(__lb, __le, __r); 23130b57cec5SDimitry Andric __n -= __bs; 23140b57cec5SDimitry Andric __l -= __bs - 1; 23150b57cec5SDimitry Andric } 23160b57cec5SDimitry Andric return __r; 23170b57cec5SDimitry Andric} 23180b57cec5SDimitry Andric 23190b57cec5SDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)). 23200b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt. 23210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2322cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 2323bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 23240b57cec5SDimitry Andric // as if 2325bdd1243dSDimitry Andric // for (; __f != __l; ++__r, ++__f, ++__size()) 23265f757f3fSDimitry Andric // __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__f)); 23270b57cec5SDimitry Andric difference_type __n = __l - __f; 2328cb14a3feSDimitry Andric while (__n > 0) { 23290b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2330bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 23310b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 2332cb14a3feSDimitry Andric if (__bs > __n) { 23330b57cec5SDimitry Andric __bs = __n; 23340b57cec5SDimitry Andric __fe = __fb + __bs; 23350b57cec5SDimitry Andric } 23360b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 23370b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; 2338bdd1243dSDimitry Andric for (; __fb != __fe; ++__fb, ++__r, ++__size()) 23395f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__fb)); 23400b57cec5SDimitry Andric __n -= __bs; 23410b57cec5SDimitry Andric __f += __bs; 23420b57cec5SDimitry Andric } 23430b57cec5SDimitry Andric} 23440b57cec5SDimitry Andric 23450b57cec5SDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards. 23460b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt. 23470b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2348cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_construct_backward_and_check( 2349cb14a3feSDimitry Andric iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 2350bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 23510b57cec5SDimitry Andric // as if 23520b57cec5SDimitry Andric // for (iterator __j = __l; __j != __f;) 23530b57cec5SDimitry Andric // { 23545f757f3fSDimitry Andric // __alloc_traitsconstruct(__a, std::addressof(*--__r), std::move(*--__j)); 2355bdd1243dSDimitry Andric // --__start_; 2356bdd1243dSDimitry Andric // ++__size(); 23570b57cec5SDimitry Andric // } 23580b57cec5SDimitry Andric difference_type __n = __l - __f; 2359cb14a3feSDimitry Andric while (__n > 0) { 23600b57cec5SDimitry Andric --__l; 23610b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 23620b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 23630b57cec5SDimitry Andric difference_type __bs = __le - __lb; 2364cb14a3feSDimitry Andric if (__bs > __n) { 23650b57cec5SDimitry Andric __bs = __n; 23660b57cec5SDimitry Andric __lb = __le - __bs; 23670b57cec5SDimitry Andric } 23680b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 23690b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; 2370cb14a3feSDimitry Andric while (__le != __lb) { 23715f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__r), std::move(*--__le)); 2372bdd1243dSDimitry Andric --__start_; 2373bdd1243dSDimitry Andric ++__size(); 23740b57cec5SDimitry Andric } 23750b57cec5SDimitry Andric __n -= __bs; 23760b57cec5SDimitry Andric __l -= __bs - 1; 23770b57cec5SDimitry Andric } 23780b57cec5SDimitry Andric} 23790b57cec5SDimitry Andric 23800b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2381cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f) { 2382*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 2383*0fca6ea1SDimitry Andric __f != end(), "deque::erase(iterator) called with a non-dereferenceable iterator"); 238406c3fb27SDimitry Andric size_type __old_sz = size(); 238506c3fb27SDimitry Andric size_type __old_start = __start_; 2386bdd1243dSDimitry Andric iterator __b = begin(); 23870b57cec5SDimitry Andric difference_type __pos = __f - __b; 23880b57cec5SDimitry Andric iterator __p = __b + __pos; 2389bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2390cb14a3feSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - 1) / 2) { // erase from front 23915f757f3fSDimitry Andric std::move_backward(__b, __p, std::next(__p)); 23925f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2393bdd1243dSDimitry Andric --__size(); 2394bdd1243dSDimitry Andric ++__start_; 239506c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2396e40139ffSDimitry Andric __maybe_remove_front_spare(); 2397cb14a3feSDimitry Andric } else { // erase from back 23985f757f3fSDimitry Andric iterator __i = std::move(std::next(__p), end(), __p); 23995f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2400bdd1243dSDimitry Andric --__size(); 240106c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2402e40139ffSDimitry Andric __maybe_remove_back_spare(); 24030b57cec5SDimitry Andric } 2404bdd1243dSDimitry Andric return begin() + __pos; 24050b57cec5SDimitry Andric} 24060b57cec5SDimitry Andric 24070b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2408cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) { 2409*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__f <= __l, "deque::erase(first, last) called with an invalid range"); 241006c3fb27SDimitry Andric size_type __old_sz = size(); 241106c3fb27SDimitry Andric size_type __old_start = __start_; 24120b57cec5SDimitry Andric difference_type __n = __l - __f; 2413bdd1243dSDimitry Andric iterator __b = begin(); 24140b57cec5SDimitry Andric difference_type __pos = __f - __b; 24150b57cec5SDimitry Andric iterator __p = __b + __pos; 2416cb14a3feSDimitry Andric if (__n > 0) { 2417bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2418cb14a3feSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - __n) / 2) { // erase from front 24195f757f3fSDimitry Andric iterator __i = std::move_backward(__b, __p, __p + __n); 24200b57cec5SDimitry Andric for (; __b != __i; ++__b) 24215f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2422bdd1243dSDimitry Andric __size() -= __n; 2423bdd1243dSDimitry Andric __start_ += __n; 242406c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2425e40139ffSDimitry Andric while (__maybe_remove_front_spare()) { 24260b57cec5SDimitry Andric } 2427cb14a3feSDimitry Andric } else { // erase from back 24285f757f3fSDimitry Andric iterator __i = std::move(__p + __n, end(), __p); 2429bdd1243dSDimitry Andric for (iterator __e = end(); __i != __e; ++__i) 24305f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2431bdd1243dSDimitry Andric __size() -= __n; 243206c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2433e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 24340b57cec5SDimitry Andric } 24350b57cec5SDimitry Andric } 24360b57cec5SDimitry Andric } 2437bdd1243dSDimitry Andric return begin() + __pos; 24380b57cec5SDimitry Andric} 24390b57cec5SDimitry Andric 24400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2441cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) { 244206c3fb27SDimitry Andric size_type __old_sz = size(); 244306c3fb27SDimitry Andric size_type __old_start = __start_; 2444bdd1243dSDimitry Andric iterator __e = end(); 24450b57cec5SDimitry Andric difference_type __n = __e - __f; 2446cb14a3feSDimitry Andric if (__n > 0) { 2447bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2448bdd1243dSDimitry Andric iterator __b = begin(); 24490b57cec5SDimitry Andric difference_type __pos = __f - __b; 24500b57cec5SDimitry Andric for (iterator __p = __b + __pos; __p != __e; ++__p) 24515f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__p)); 2452bdd1243dSDimitry Andric __size() -= __n; 245306c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2454e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 24550b57cec5SDimitry Andric } 24560b57cec5SDimitry Andric } 24570b57cec5SDimitry Andric} 24580b57cec5SDimitry Andric 24590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2460cb14a3feSDimitry Andricinline void deque<_Tp, _Allocator>::swap(deque& __c) 24610b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 24620b57cec5SDimitry Andric _NOEXCEPT 24630b57cec5SDimitry Andric#else 2464*0fca6ea1SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) 24650b57cec5SDimitry Andric#endif 24660b57cec5SDimitry Andric{ 2467bdd1243dSDimitry Andric __map_.swap(__c.__map_); 24685f757f3fSDimitry Andric std::swap(__start_, __c.__start_); 24695f757f3fSDimitry Andric std::swap(__size(), __c.__size()); 24705f757f3fSDimitry Andric std::__swap_allocator(__alloc(), __c.__alloc()); 24710b57cec5SDimitry Andric} 24720b57cec5SDimitry Andric 24730b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2474cb14a3feSDimitry Andricinline void deque<_Tp, _Allocator>::clear() _NOEXCEPT { 247506c3fb27SDimitry Andric __annotate_delete(); 2476bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2477bdd1243dSDimitry Andric for (iterator __i = begin(), __e = end(); __i != __e; ++__i) 24785f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2479bdd1243dSDimitry Andric __size() = 0; 2480cb14a3feSDimitry Andric while (__map_.size() > 2) { 2481bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.front(), __block_size); 2482bdd1243dSDimitry Andric __map_.pop_front(); 2483bdd1243dSDimitry Andric } 2484cb14a3feSDimitry Andric switch (__map_.size()) { 2485bdd1243dSDimitry Andric case 1: 2486bdd1243dSDimitry Andric __start_ = __block_size / 2; 2487bdd1243dSDimitry Andric break; 2488bdd1243dSDimitry Andric case 2: 2489bdd1243dSDimitry Andric __start_ = __block_size; 2490bdd1243dSDimitry Andric break; 2491bdd1243dSDimitry Andric } 249206c3fb27SDimitry Andric __annotate_new(0); 24930b57cec5SDimitry Andric} 24940b57cec5SDimitry Andric 24950b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2496cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 24970b57cec5SDimitry Andric const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); 24985f757f3fSDimitry Andric return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); 24990b57cec5SDimitry Andric} 25000b57cec5SDimitry Andric 250106c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 250206c3fb27SDimitry Andric 25030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2504cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25050b57cec5SDimitry Andric return !(__x == __y); 25060b57cec5SDimitry Andric} 25070b57cec5SDimitry Andric 25080b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2509cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25105f757f3fSDimitry Andric return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 25110b57cec5SDimitry Andric} 25120b57cec5SDimitry Andric 25130b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2514cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25150b57cec5SDimitry Andric return __y < __x; 25160b57cec5SDimitry Andric} 25170b57cec5SDimitry Andric 25180b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2519cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25200b57cec5SDimitry Andric return !(__x < __y); 25210b57cec5SDimitry Andric} 25220b57cec5SDimitry Andric 25230b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2524cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25250b57cec5SDimitry Andric return !(__y < __x); 25260b57cec5SDimitry Andric} 25270b57cec5SDimitry Andric 252806c3fb27SDimitry Andric#else // _LIBCPP_STD_VER <= 17 252906c3fb27SDimitry Andric 253006c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 253106c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> 253206c3fb27SDimitry Andricoperator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 253306c3fb27SDimitry Andric return std::lexicographical_compare_three_way( 2534*0fca6ea1SDimitry Andric __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); 253506c3fb27SDimitry Andric} 253606c3fb27SDimitry Andric 253706c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER <= 17 253806c3fb27SDimitry Andric 25390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2540cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) 2541cb14a3feSDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { 25420b57cec5SDimitry Andric __x.swap(__y); 25430b57cec5SDimitry Andric} 25440b57cec5SDimitry Andric 254506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 25460b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up> 2547bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 25485ffd83dbSDimitry Andricerase(deque<_Tp, _Allocator>& __c, const _Up& __v) { 25495ffd83dbSDimitry Andric auto __old_size = __c.size(); 25505f757f3fSDimitry Andric __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end()); 25515ffd83dbSDimitry Andric return __old_size - __c.size(); 25525ffd83dbSDimitry Andric} 25530b57cec5SDimitry Andric 25540b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate> 2555bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 25565ffd83dbSDimitry Andricerase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) { 25575ffd83dbSDimitry Andric auto __old_size = __c.size(); 25585f757f3fSDimitry Andric __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end()); 25595ffd83dbSDimitry Andric return __old_size - __c.size(); 25605ffd83dbSDimitry Andric} 256181ad6265SDimitry Andric 256281ad6265SDimitry Andrictemplate <> 256381ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<char>> = true; 256481ad6265SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 256581ad6265SDimitry Andrictemplate <> 256681ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true; 25670b57cec5SDimitry Andric# endif 25680b57cec5SDimitry Andric 256906c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 25700b57cec5SDimitry Andric 25710b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 25720b57cec5SDimitry Andric 257306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 2574bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2575bdd1243dSDimitry Andricnamespace pmr { 2576bdd1243dSDimitry Andrictemplate <class _ValueT> 257706c3fb27SDimitry Andricusing deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>; 2578bdd1243dSDimitry Andric} // namespace pmr 2579bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD 2580bdd1243dSDimitry Andric#endif 2581bdd1243dSDimitry Andric 25820b57cec5SDimitry Andric_LIBCPP_POP_MACROS 25830b57cec5SDimitry Andric 2584bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 2585bdd1243dSDimitry Andric# include <algorithm> 2586bdd1243dSDimitry Andric# include <atomic> 2587bdd1243dSDimitry Andric# include <concepts> 258806c3fb27SDimitry Andric# include <cstdlib> 2589bdd1243dSDimitry Andric# include <functional> 2590bdd1243dSDimitry Andric# include <iosfwd> 2591bdd1243dSDimitry Andric# include <iterator> 259206c3fb27SDimitry Andric# include <type_traits> 2593bdd1243dSDimitry Andric# include <typeinfo> 2594bdd1243dSDimitry Andric#endif 2595bdd1243dSDimitry Andric 25960b57cec5SDimitry Andric#endif // _LIBCPP_DEQUE 2597