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> 1910fca6ea1SDimitry Andric#include <__assert> 1920b57cec5SDimitry Andric#include <__config> 1930fca6ea1SDimitry Andric#include <__debug_utils/sanitizers.h> 19481ad6265SDimitry Andric#include <__format/enable_insertable.h> 1950fca6ea1SDimitry 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> 2170fca6ea1SDimitry 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 379*36b606aeSDimitry Andric#if _LIBCPP_STD_VER <= 17 380cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) { 381cb14a3feSDimitry Andric return !(__x == __y); 382cb14a3feSDimitry Andric } 383*36b606aeSDimitry Andric#endif 3840b57cec5SDimitry Andric 385*36b606aeSDimitry Andric // TODO(mordante) disable these overloads in the LLVM 20 release. 386cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) { 387cb14a3feSDimitry Andric return __x.__m_iter_ < __y.__m_iter_ || (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_); 388cb14a3feSDimitry Andric } 3890b57cec5SDimitry Andric 390cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) { 391cb14a3feSDimitry Andric return __y < __x; 392cb14a3feSDimitry Andric } 3930b57cec5SDimitry Andric 394cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) { 395cb14a3feSDimitry Andric return !(__y < __x); 396cb14a3feSDimitry Andric } 3970b57cec5SDimitry Andric 398cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) { 399cb14a3feSDimitry Andric return !(__x < __y); 400cb14a3feSDimitry Andric } 4010b57cec5SDimitry Andric 402*36b606aeSDimitry Andric#if _LIBCPP_STD_VER >= 20 403*36b606aeSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend strong_ordering operator<=>(const __deque_iterator& __x, const __deque_iterator& __y) { 404*36b606aeSDimitry Andric if (__x.__m_iter_ < __y.__m_iter_) 405*36b606aeSDimitry Andric return strong_ordering::less; 406*36b606aeSDimitry Andric 407*36b606aeSDimitry Andric if (__x.__m_iter_ == __y.__m_iter_) { 408*36b606aeSDimitry Andric if constexpr (three_way_comparable<pointer, strong_ordering>) { 409*36b606aeSDimitry Andric return __x.__ptr_ <=> __y.__ptr_; 410*36b606aeSDimitry Andric } else { 411*36b606aeSDimitry Andric if (__x.__ptr_ < __y.__ptr_) 412*36b606aeSDimitry Andric return strong_ordering::less; 413*36b606aeSDimitry Andric 414*36b606aeSDimitry Andric if (__x.__ptr_ == __y.__ptr_) 415*36b606aeSDimitry Andric return strong_ordering::equal; 416*36b606aeSDimitry Andric 417*36b606aeSDimitry Andric return strong_ordering::greater; 418*36b606aeSDimitry Andric } 419*36b606aeSDimitry Andric } 420*36b606aeSDimitry Andric 421*36b606aeSDimitry Andric return strong_ordering::greater; 422*36b606aeSDimitry Andric } 423*36b606aeSDimitry Andric#endif // _LIBCPP_STD_VER >= 20 424*36b606aeSDimitry Andric 4250b57cec5SDimitry Andricprivate: 426bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT 427cb14a3feSDimitry Andric : __m_iter_(__m), 428cb14a3feSDimitry Andric __ptr_(__p) {} 4290b57cec5SDimitry Andric 430cb14a3feSDimitry Andric template <class _Tp, class _Ap> 431cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS deque; 4320b57cec5SDimitry Andric template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp> 4330b57cec5SDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __deque_iterator; 4340b57cec5SDimitry Andric 435bdd1243dSDimitry Andric template <class> 436bdd1243dSDimitry Andric friend struct __segmented_iterator_traits; 437bdd1243dSDimitry Andric}; 4380b57cec5SDimitry Andric 439bdd1243dSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 440bdd1243dSDimitry Andricstruct __segmented_iterator_traits< 441bdd1243dSDimitry Andric __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > { 442bdd1243dSDimitry Andricprivate: 443bdd1243dSDimitry Andric using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; 4440b57cec5SDimitry Andric 445bdd1243dSDimitry Andricpublic: 446bdd1243dSDimitry Andric using __is_segmented_iterator = true_type; 447bdd1243dSDimitry Andric using __segment_iterator = _MapPointer; 448bdd1243dSDimitry Andric using __local_iterator = _Pointer; 4490b57cec5SDimitry Andric 450bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } 451bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } 452bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; } 4530b57cec5SDimitry Andric 454bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) { 455bdd1243dSDimitry Andric return *__iter + _Iterator::__block_size; 456bdd1243dSDimitry Andric } 4570b57cec5SDimitry Andric 458bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) { 4595f757f3fSDimitry Andric if (__segment && __local == __end(__segment)) { 460bdd1243dSDimitry Andric ++__segment; 461bdd1243dSDimitry Andric return _Iterator(__segment, *__segment); 462bdd1243dSDimitry Andric } 463bdd1243dSDimitry Andric return _Iterator(__segment, __local); 464bdd1243dSDimitry Andric } 4650b57cec5SDimitry Andric}; 4660b57cec5SDimitry Andric 467cb14a3feSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 468cb14a3feSDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>::__block_size = 4690b57cec5SDimitry Andric __deque_block_size<_ValueType, _DiffType>::value; 4700b57cec5SDimitry Andric 471bdd1243dSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/> 472cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque { 4730b57cec5SDimitry Andricpublic: 474bdd1243dSDimitry Andric // types: 475e40139ffSDimitry Andric 476bdd1243dSDimitry Andric using value_type = _Tp; 4770b57cec5SDimitry Andric 478bdd1243dSDimitry Andric using allocator_type = _Allocator; 479bdd1243dSDimitry Andric using __alloc_traits = allocator_traits<allocator_type>; 4800fca6ea1SDimitry Andric static_assert(__check_valid_allocator<allocator_type>::value, ""); 4810fca6ea1SDimitry Andric static_assert(is_same<typename allocator_type::value_type, value_type>::value, 4820fca6ea1SDimitry Andric "Allocator::value_type must be same type as value_type"); 4830b57cec5SDimitry Andric 484bdd1243dSDimitry Andric using size_type = typename __alloc_traits::size_type; 485bdd1243dSDimitry Andric using difference_type = typename __alloc_traits::difference_type; 4860b57cec5SDimitry Andric 487bdd1243dSDimitry Andric using pointer = typename __alloc_traits::pointer; 488bdd1243dSDimitry Andric using const_pointer = typename __alloc_traits::const_pointer; 489bdd1243dSDimitry Andric 490bdd1243dSDimitry Andric using __pointer_allocator = __rebind_alloc<__alloc_traits, pointer>; 491bdd1243dSDimitry Andric using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>; 492bdd1243dSDimitry Andric using __map = __split_buffer<pointer, __pointer_allocator>; 493bdd1243dSDimitry Andric using __map_alloc_traits = allocator_traits<__pointer_allocator>; 494bdd1243dSDimitry Andric using __map_pointer = typename __map_alloc_traits::pointer; 495bdd1243dSDimitry Andric using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer; 49606c3fb27SDimitry Andric using __map_const_iterator = typename __map::const_iterator; 497bdd1243dSDimitry Andric 498bdd1243dSDimitry Andric using reference = value_type&; 499bdd1243dSDimitry Andric using const_reference = const value_type&; 500bdd1243dSDimitry Andric 501bdd1243dSDimitry Andric using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>; 502bdd1243dSDimitry Andric using const_iterator = 503bdd1243dSDimitry Andric __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>; 504bdd1243dSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 505bdd1243dSDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>; 506bdd1243dSDimitry Andric 5070fca6ea1SDimitry Andric // A deque contains the following members which may be trivially relocatable: 5080fca6ea1SDimitry Andric // - __map: is a `__split_buffer`, see `__split_buffer` for more information on when it is trivially relocatable 5090fca6ea1SDimitry Andric // - size_type: is always trivially relocatable, since it is required to be an integral type 5100fca6ea1SDimitry Andric // - allocator_type: may not be trivially relocatable, so it's checked 5110fca6ea1SDimitry Andric // None of these are referencing the `deque` itself, so if all of them are trivially relocatable, `deque` is too. 5120fca6ea1SDimitry Andric using __trivially_relocatable = __conditional_t< 5130fca6ea1SDimitry Andric __libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, 5140fca6ea1SDimitry Andric deque, 5150fca6ea1SDimitry Andric void>; 5160fca6ea1SDimitry Andric 517bdd1243dSDimitry Andric static_assert(is_nothrow_default_constructible<allocator_type>::value == 518bdd1243dSDimitry Andric is_nothrow_default_constructible<__pointer_allocator>::value, 5190fca6ea1SDimitry Andric "rebinding an allocator should not change exception guarantees"); 520bdd1243dSDimitry Andric static_assert(is_nothrow_move_constructible<allocator_type>::value == 521bdd1243dSDimitry Andric is_nothrow_move_constructible<typename __map::allocator_type>::value, 5220fca6ea1SDimitry Andric "rebinding an allocator should not change exception guarantees"); 523bdd1243dSDimitry Andric 524bdd1243dSDimitry Andricprivate: 525e40139ffSDimitry Andric struct __deque_block_range { 526cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI __deque_block_range(pointer __b, pointer __e) _NOEXCEPT 527cb14a3feSDimitry Andric : __begin_(__b), 528cb14a3feSDimitry Andric __end_(__e) {} 529e40139ffSDimitry Andric const pointer __begin_; 530e40139ffSDimitry Andric const pointer __end_; 531e40139ffSDimitry Andric }; 532e40139ffSDimitry Andric 533e40139ffSDimitry Andric struct __deque_range { 534e40139ffSDimitry Andric iterator __pos_; 535e40139ffSDimitry Andric const iterator __end_; 536e40139ffSDimitry Andric 537cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT : __pos_(__pos), __end_(__e) {} 538e40139ffSDimitry Andric 539cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { return __pos_ != __end_; } 540e40139ffSDimitry Andric 541cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { return *this; } 542e40139ffSDimitry Andric 543cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range end() const { return __deque_range(__end_, __end_); } 544bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT { 545e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 546e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, __end_.__ptr_); 547e40139ffSDimitry Andric } 548e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size); 549e40139ffSDimitry Andric } 550e40139ffSDimitry Andric 551bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT { 552e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 553e40139ffSDimitry Andric __pos_ = __end_; 554e40139ffSDimitry Andric } else { 555e40139ffSDimitry Andric ++__pos_.__m_iter_; 556e40139ffSDimitry Andric __pos_.__ptr_ = *__pos_.__m_iter_; 557e40139ffSDimitry Andric } 558e40139ffSDimitry Andric return *this; 559e40139ffSDimitry Andric } 560e40139ffSDimitry Andric 561bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) { 562e40139ffSDimitry Andric return __lhs.__pos_ == __rhs.__pos_; 563e40139ffSDimitry Andric } 564bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) { 565e40139ffSDimitry Andric return !(__lhs == __rhs); 566e40139ffSDimitry Andric } 567e40139ffSDimitry Andric }; 568e40139ffSDimitry Andric 569e40139ffSDimitry Andric struct _ConstructTransaction { 570bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r) 571e40139ffSDimitry Andric : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} 572e40139ffSDimitry Andric 573cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { __base_->__size() += (__pos_ - __begin_); } 574e40139ffSDimitry Andric 575e40139ffSDimitry Andric pointer __pos_; 576e40139ffSDimitry Andric const pointer __end_; 577cb14a3feSDimitry Andric 578e40139ffSDimitry Andric private: 579e40139ffSDimitry Andric const pointer __begin_; 580bdd1243dSDimitry Andric deque* const __base_; 581e40139ffSDimitry Andric }; 582e40139ffSDimitry Andric 583bdd1243dSDimitry Andric static const difference_type __block_size; 584bdd1243dSDimitry Andric 5850b57cec5SDimitry Andric __map __map_; 5860b57cec5SDimitry Andric size_type __start_; 5870b57cec5SDimitry Andric __compressed_pair<size_type, allocator_type> __size_; 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andricpublic: 590bdd1243dSDimitry Andric // construct/copy/destroy: 591cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 59206c3fb27SDimitry Andric : __start_(0), __size_(0, __default_init_tag()) { 59306c3fb27SDimitry Andric __annotate_new(0); 59406c3fb27SDimitry Andric } 595bdd1243dSDimitry Andric 596bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~deque() { 597bdd1243dSDimitry Andric clear(); 59806c3fb27SDimitry Andric __annotate_delete(); 599bdd1243dSDimitry Andric typename __map::iterator __i = __map_.begin(); 600bdd1243dSDimitry Andric typename __map::iterator __e = __map_.end(); 601bdd1243dSDimitry Andric for (; __i != __e; ++__i) 602bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), *__i, __block_size); 603bdd1243dSDimitry Andric } 604bdd1243dSDimitry Andric 605bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) 60606c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 60706c3fb27SDimitry Andric __annotate_new(0); 60806c3fb27SDimitry Andric } 609bdd1243dSDimitry Andric 610bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); 61106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 612bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); 613bdd1243dSDimitry Andric#endif 614bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); 615bdd1243dSDimitry Andric 6160fca6ea1SDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 617bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) 618cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 61906c3fb27SDimitry Andric __annotate_new(0); 620bdd1243dSDimitry Andric if (__n > 0) 621bdd1243dSDimitry Andric __append(__n, __v); 622bdd1243dSDimitry Andric } 623bdd1243dSDimitry Andric 6245f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 6255f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l); 6265f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 6275f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a); 62806c3fb27SDimitry Andric 62906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 63006c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 631cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) 63206c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 63306c3fb27SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 63406c3fb27SDimitry Andric __append_with_size(ranges::begin(__range), ranges::distance(__range)); 63506c3fb27SDimitry Andric 63606c3fb27SDimitry Andric } else { 63706c3fb27SDimitry Andric for (auto&& __e : __range) { 63806c3fb27SDimitry Andric emplace_back(std::forward<decltype(__e)>(__e)); 63906c3fb27SDimitry Andric } 64006c3fb27SDimitry Andric } 64106c3fb27SDimitry Andric } 64206c3fb27SDimitry Andric#endif 64306c3fb27SDimitry Andric 644bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); 645bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); 646bdd1243dSDimitry Andric 647bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c); 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 650bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il); 651bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a); 652bdd1243dSDimitry Andric 653cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(initializer_list<value_type> __il) { 654cb14a3feSDimitry Andric assign(__il); 655cb14a3feSDimitry Andric return *this; 656cb14a3feSDimitry Andric } 657bdd1243dSDimitry Andric 6580fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value); 659cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(deque&& __c, const __type_identity_t<allocator_type>& __a); 6600fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& 6610fca6ea1SDimitry Andric operator=(deque&& __c) noexcept(__alloc_traits::propagate_on_container_move_assignment::value && 662bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value); 663bdd1243dSDimitry Andric 664cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) { assign(__il.begin(), __il.end()); } 6650b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 6660b57cec5SDimitry Andric 667cb14a3feSDimitry Andric template <class _InputIter, 668cb14a3feSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIter>::value && 669cb14a3feSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, 670cb14a3feSDimitry Andric int> = 0> 6715f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l); 6725f757f3fSDimitry Andric template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> = 0> 6735f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l); 67406c3fb27SDimitry Andric 67506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 67606c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 677cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) { 67806c3fb27SDimitry Andric if constexpr (ranges::random_access_range<_Range>) { 67906c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 68006c3fb27SDimitry Andric __assign_with_size_random_access(ranges::begin(__range), __n); 68106c3fb27SDimitry Andric 68206c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 68306c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 68406c3fb27SDimitry Andric __assign_with_size(ranges::begin(__range), __n); 68506c3fb27SDimitry Andric 68606c3fb27SDimitry Andric } else { 68706c3fb27SDimitry Andric __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 68806c3fb27SDimitry Andric } 68906c3fb27SDimitry Andric } 69006c3fb27SDimitry Andric#endif 69106c3fb27SDimitry Andric 692bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); 693bdd1243dSDimitry Andric 694cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; 695bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); } 696bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); } 697bdd1243dSDimitry Andric 698bdd1243dSDimitry Andric // iterators: 699bdd1243dSDimitry Andric 700bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { 701bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __start_ / __block_size; 702bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 703bdd1243dSDimitry Andric } 704bdd1243dSDimitry Andric 705bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { 706cb14a3feSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); 707bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 708bdd1243dSDimitry Andric } 709bdd1243dSDimitry Andric 710bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { 711bdd1243dSDimitry Andric size_type __p = size() + __start_; 712bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __p / __block_size; 713bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 714bdd1243dSDimitry Andric } 715bdd1243dSDimitry Andric 716bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { 717bdd1243dSDimitry Andric size_type __p = size() + __start_; 718bdd1243dSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); 719bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 720bdd1243dSDimitry Andric } 721bdd1243dSDimitry Andric 722cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } 723cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 724cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } 725cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 726bdd1243dSDimitry Andric 727cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } 728cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } 729cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 730cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 731bdd1243dSDimitry Andric 732bdd1243dSDimitry Andric // capacity: 733cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); } 734bdd1243dSDimitry Andric 735bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); } 736bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); } 737bdd1243dSDimitry Andric 738cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { 739cb14a3feSDimitry Andric return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max()); 740cb14a3feSDimitry Andric } 741bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); 742bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); 743bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; 7440fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; } 745bdd1243dSDimitry Andric 746bdd1243dSDimitry Andric // element access: 747cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT; 748cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT; 749cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference at(size_type __i); 750cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const; 751cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT; 752cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT; 753cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT; 754cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT; 755bdd1243dSDimitry Andric 756bdd1243dSDimitry Andric // 23.2.2.3 modifiers: 757bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); 758bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); 759bdd1243dSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 76006c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 761cb14a3feSDimitry Andric template <class... _Args> 762cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); 763cb14a3feSDimitry Andric template <class... _Args> 764cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args); 765bdd1243dSDimitry Andric# else 766cb14a3feSDimitry Andric template <class... _Args> 767cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); 768cb14a3feSDimitry Andric template <class... _Args> 769cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args); 770bdd1243dSDimitry Andric# endif 771cb14a3feSDimitry Andric template <class... _Args> 772cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); 773bdd1243dSDimitry Andric 774bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); 775bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v); 77606c3fb27SDimitry Andric 77706c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 77806c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 779cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) { 78006c3fb27SDimitry Andric insert_range(begin(), std::forward<_Range>(__range)); 78106c3fb27SDimitry Andric } 78206c3fb27SDimitry Andric 78306c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 784cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void append_range(_Range&& __range) { 78506c3fb27SDimitry Andric insert_range(end(), std::forward<_Range>(__range)); 78606c3fb27SDimitry Andric } 78706c3fb27SDimitry Andric# endif 78806c3fb27SDimitry Andric 789bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v); 790bdd1243dSDimitry Andric 791cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, initializer_list<value_type> __il) { 792cb14a3feSDimitry Andric return insert(__p, __il.begin(), __il.end()); 793cb14a3feSDimitry Andric } 794bdd1243dSDimitry Andric#endif // _LIBCPP_CXX03_LANG 795bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v); 796bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); 7975f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0> 7985f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l); 799cb14a3feSDimitry Andric template <class _ForwardIterator, 800cb14a3feSDimitry Andric __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> = 0> 8015f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l); 8025f757f3fSDimitry Andric template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> = 0> 8035f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l); 80406c3fb27SDimitry Andric 80506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 80606c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 807cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert_range(const_iterator __position, _Range&& __range) { 80806c3fb27SDimitry Andric if constexpr (ranges::bidirectional_range<_Range>) { 80906c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 81006c3fb27SDimitry Andric return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n); 81106c3fb27SDimitry Andric 81206c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 81306c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 81406c3fb27SDimitry Andric return __insert_with_size(__position, ranges::begin(__range), __n); 81506c3fb27SDimitry Andric 81606c3fb27SDimitry Andric } else { 81706c3fb27SDimitry Andric return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); 81806c3fb27SDimitry Andric } 81906c3fb27SDimitry Andric } 82006c3fb27SDimitry Andric#endif 821bdd1243dSDimitry Andric 822bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_front(); 823bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_back(); 824bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); 825bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); 826bdd1243dSDimitry Andric 827cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(deque& __c) 8280b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 8290b57cec5SDimitry Andric _NOEXCEPT; 8300b57cec5SDimitry Andric#else 8310fca6ea1SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>); 8320b57cec5SDimitry Andric#endif 833cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; 8340b57cec5SDimitry Andric 835cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __invariants() const { 8360b57cec5SDimitry Andric if (!__map_.__invariants()) 8370b57cec5SDimitry Andric return false; 8380b57cec5SDimitry Andric if (__map_.size() >= size_type(-1) / __block_size) 8390b57cec5SDimitry Andric return false; 840cb14a3feSDimitry Andric for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); __i != __e; ++__i) 8410b57cec5SDimitry Andric if (*__i == nullptr) 8420b57cec5SDimitry Andric return false; 843cb14a3feSDimitry Andric if (__map_.size() != 0) { 8440b57cec5SDimitry Andric if (size() >= __map_.size() * __block_size) 8450b57cec5SDimitry Andric return false; 8460b57cec5SDimitry Andric if (__start_ >= __map_.size() * __block_size - size()) 8470b57cec5SDimitry Andric return false; 848cb14a3feSDimitry Andric } else { 8490b57cec5SDimitry Andric if (size() != 0) 8500b57cec5SDimitry Andric return false; 8510b57cec5SDimitry Andric if (__start_ != 0) 8520b57cec5SDimitry Andric return false; 8530b57cec5SDimitry Andric } 8540b57cec5SDimitry Andric return true; 8550b57cec5SDimitry Andric } 8560b57cec5SDimitry Andric 857cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c) 858bdd1243dSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || 859cb14a3feSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 860cb14a3feSDimitry Andric __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 861cb14a3feSDimitry Andric } 862bdd1243dSDimitry Andric 863cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c, true_type) 864cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 8655f757f3fSDimitry Andric __alloc() = std::move(__c.__alloc()); 8660b57cec5SDimitry Andric } 8670b57cec5SDimitry Andric 868cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque&, false_type) _NOEXCEPT {} 8694824e7fdSDimitry Andric 870cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c) 871bdd1243dSDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value&& 872cb14a3feSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 8735f757f3fSDimitry Andric __map_ = std::move(__c.__map_); 874bdd1243dSDimitry Andric __start_ = __c.__start_; 875bdd1243dSDimitry Andric __size() = __c.size(); 876bdd1243dSDimitry Andric __move_assign_alloc(__c); 877bdd1243dSDimitry Andric __c.__start_ = __c.__size() = 0; 8784824e7fdSDimitry Andric } 8794824e7fdSDimitry Andric 880cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static size_type __recommend_blocks(size_type __n) { 881bdd1243dSDimitry Andric return __n / __block_size + (__n % __block_size != 0); 8820b57cec5SDimitry Andric } 883cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __capacity() const { 884bdd1243dSDimitry Andric return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1; 8850b57cec5SDimitry Andric } 886cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __block_count() const { return __map_.size(); } 887e40139ffSDimitry Andric 888cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const { return __start_; } 889cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __front_spare_blocks() const { return __front_spare() / __block_size; } 890cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const { return __capacity() - (__start_ + size()); } 891cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __back_spare_blocks() const { return __back_spare() / __block_size; } 892e40139ffSDimitry Andric 893e40139ffSDimitry Andricprivate: 894cb14a3feSDimitry Andric enum __asan_annotation_type { __asan_unposion, __asan_poison }; 89506c3fb27SDimitry Andric 89606c3fb27SDimitry Andric enum __asan_annotation_place { 89706c3fb27SDimitry Andric __asan_front_moved, 89806c3fb27SDimitry Andric __asan_back_moved, 89906c3fb27SDimitry Andric }; 90006c3fb27SDimitry Andric 901cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_from_to( 9025f757f3fSDimitry Andric size_type __beg, 9035f757f3fSDimitry Andric size_type __end, 9045f757f3fSDimitry Andric __asan_annotation_type __annotation_type, 9055f757f3fSDimitry Andric __asan_annotation_place __place) const _NOEXCEPT { 9065f757f3fSDimitry Andric (void)__beg; 9075f757f3fSDimitry Andric (void)__end; 9085f757f3fSDimitry Andric (void)__annotation_type; 9095f757f3fSDimitry Andric (void)__place; 9105f757f3fSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 91106c3fb27SDimitry Andric // __beg - index of the first item to annotate 91206c3fb27SDimitry Andric // __end - index behind the last item to annotate (so last item + 1) 91306c3fb27SDimitry Andric // __annotation_type - __asan_unposion or __asan_poison 91406c3fb27SDimitry Andric // __place - __asan_front_moved or __asan_back_moved 91506c3fb27SDimitry Andric // Note: All indexes in __map_ 91606c3fb27SDimitry Andric if (__beg == __end) 91706c3fb27SDimitry Andric return; 91806c3fb27SDimitry Andric // __annotations_beg_map - first chunk which annotations we want to modify 91906c3fb27SDimitry Andric // __annotations_end_map - last chunk which annotations we want to modify 92006c3fb27SDimitry Andric // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist 92106c3fb27SDimitry Andric __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; 92206c3fb27SDimitry Andric __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; 92306c3fb27SDimitry Andric 92406c3fb27SDimitry Andric bool const __poisoning = __annotation_type == __asan_poison; 92506c3fb27SDimitry Andric // __old_c_beg_index - index of the first element in old container 92606c3fb27SDimitry Andric // __old_c_end_index - index of the end of old container (last + 1) 92706c3fb27SDimitry Andric // Note: may be outside the area we are annotating 92806c3fb27SDimitry Andric size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; 92906c3fb27SDimitry Andric size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); 93006c3fb27SDimitry Andric bool const __front = __place == __asan_front_moved; 93106c3fb27SDimitry Andric 93206c3fb27SDimitry Andric if (__poisoning && empty()) { 93306c3fb27SDimitry Andric // Special case: we shouldn't trust __start_ 93406c3fb27SDimitry Andric __old_c_beg_index = __beg; 93506c3fb27SDimitry Andric __old_c_end_index = __end; 93606c3fb27SDimitry Andric } 93706c3fb27SDimitry Andric // __old_c_beg_map - memory block (chunk) with first element 93806c3fb27SDimitry Andric // __old_c_end_map - memory block (chunk) with end of old container 93906c3fb27SDimitry Andric // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, 94006c3fb27SDimitry Andric // which may not exist 94106c3fb27SDimitry Andric __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; 94206c3fb27SDimitry Andric __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; 94306c3fb27SDimitry Andric 94406c3fb27SDimitry Andric // One edge (front/end) of the container was moved and one was not modified. 94506c3fb27SDimitry Andric // __new_edge_index - index of new edge 94606c3fb27SDimitry Andric // __new_edge_map - memory block (chunk) with new edge, it always equals to 94706c3fb27SDimitry Andric // __annotations_beg_map or __annotations_end_map 94806c3fb27SDimitry Andric // __old_edge_map - memory block (chunk) with old edge, it always equals to 94906c3fb27SDimitry Andric // __old_c_beg_map or __old_c_end_map 95006c3fb27SDimitry Andric size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; 95106c3fb27SDimitry Andric __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; 95206c3fb27SDimitry Andric __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; 95306c3fb27SDimitry Andric 95406c3fb27SDimitry Andric // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. 95506c3fb27SDimitry Andric // First and last chunk may be partially poisoned. 95606c3fb27SDimitry Andric // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. 95706c3fb27SDimitry Andric for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { 95806c3fb27SDimitry Andric if (__map_it == __annotations_end_map && __end % __block_size == 0) 95906c3fb27SDimitry Andric // Chunk may not exist, but nothing to do here anyway 96006c3fb27SDimitry Andric break; 96106c3fb27SDimitry Andric 96206c3fb27SDimitry Andric // The beginning and the end of the current memory block 96306c3fb27SDimitry Andric const void* __mem_beg = std::__to_address(*__map_it); 96406c3fb27SDimitry Andric const void* __mem_end = std::__to_address(*__map_it + __block_size); 96506c3fb27SDimitry Andric 96606c3fb27SDimitry Andric // The beginning of memory-in-use in the memory block before container modification 96706c3fb27SDimitry Andric const void* __old_beg = 96806c3fb27SDimitry Andric (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; 96906c3fb27SDimitry Andric 97006c3fb27SDimitry Andric // The end of memory-in-use in the memory block before container modification 97106c3fb27SDimitry Andric const void* __old_end; 97206c3fb27SDimitry Andric if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) 97306c3fb27SDimitry Andric __old_end = __old_beg; 97406c3fb27SDimitry Andric else 975cb14a3feSDimitry Andric __old_end = (__map_it == __old_c_end_map) 976cb14a3feSDimitry Andric ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) 97706c3fb27SDimitry Andric : __mem_end; 97806c3fb27SDimitry Andric 97906c3fb27SDimitry Andric // New edge of the container in current memory block 98006c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 98106c3fb27SDimitry Andric const void* __new_edge; 98206c3fb27SDimitry Andric if (__map_it == __new_edge_map) 98306c3fb27SDimitry Andric __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); 98406c3fb27SDimitry Andric else 98506c3fb27SDimitry Andric __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; 98606c3fb27SDimitry Andric 98706c3fb27SDimitry Andric // Not modified edge of the container 98806c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 98906c3fb27SDimitry Andric const void* __old_edge; 99006c3fb27SDimitry Andric if (__map_it == __old_edge_map) 99106c3fb27SDimitry Andric __old_edge = __front ? __old_end : __old_beg; 99206c3fb27SDimitry Andric else 99306c3fb27SDimitry Andric __old_edge = __front ? __mem_end : __mem_beg; 99406c3fb27SDimitry Andric 99506c3fb27SDimitry Andric // __new_beg - the beginning of memory-in-use in the memory block after container modification 99606c3fb27SDimitry Andric // __new_end - the end of memory-in-use in the memory block after container modification 99706c3fb27SDimitry Andric const void* __new_beg = __front ? __new_edge : __old_edge; 99806c3fb27SDimitry Andric const void* __new_end = __front ? __old_edge : __new_edge; 99906c3fb27SDimitry Andric 10000fca6ea1SDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>( 10010fca6ea1SDimitry Andric __mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); 100206c3fb27SDimitry Andric } 10035f757f3fSDimitry Andric#endif // !_LIBCPP_HAS_NO_ASAN 100406c3fb27SDimitry Andric } 100506c3fb27SDimitry Andric 1006cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT { 1007cb14a3feSDimitry Andric (void)__current_size; 1008cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 100906c3fb27SDimitry Andric if (__current_size == 0) 101006c3fb27SDimitry Andric __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 101106c3fb27SDimitry Andric else { 101206c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); 101306c3fb27SDimitry Andric __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 101406c3fb27SDimitry Andric } 1015cb14a3feSDimitry Andric#endif 101606c3fb27SDimitry Andric } 101706c3fb27SDimitry Andric 1018cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT { 1019cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 102006c3fb27SDimitry Andric if (empty()) { 102106c3fb27SDimitry Andric for (size_t __i = 0; __i < __map_.size(); ++__i) { 102206c3fb27SDimitry Andric __annotate_whole_block(__i, __asan_unposion); 102306c3fb27SDimitry Andric } 1024cb14a3feSDimitry Andric } else { 102506c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); 102606c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); 102706c3fb27SDimitry Andric } 1028cb14a3feSDimitry Andric#endif 102906c3fb27SDimitry Andric } 103006c3fb27SDimitry Andric 1031cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_increase_front(size_type __n) const _NOEXCEPT { 1032cb14a3feSDimitry Andric (void)__n; 1033cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 103406c3fb27SDimitry Andric __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); 1035cb14a3feSDimitry Andric#endif 103606c3fb27SDimitry Andric } 103706c3fb27SDimitry Andric 1038cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_increase_back(size_type __n) const _NOEXCEPT { 1039cb14a3feSDimitry Andric (void)__n; 1040cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 104106c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); 1042cb14a3feSDimitry Andric#endif 104306c3fb27SDimitry Andric } 104406c3fb27SDimitry Andric 1045cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { 1046cb14a3feSDimitry Andric (void)__old_size; 1047cb14a3feSDimitry Andric (void)__old_start; 1048cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 104906c3fb27SDimitry Andric __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); 1050cb14a3feSDimitry Andric#endif 105106c3fb27SDimitry Andric } 105206c3fb27SDimitry Andric 1053cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { 1054cb14a3feSDimitry Andric (void)__old_size; 1055cb14a3feSDimitry Andric (void)__old_start; 1056cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 105706c3fb27SDimitry Andric __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); 1058cb14a3feSDimitry Andric#endif 105906c3fb27SDimitry Andric } 106006c3fb27SDimitry Andric 1061cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_poison_block(const void* __beginning, const void* __end) const _NOEXCEPT { 10620fca6ea1SDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>(__beginning, __end, __beginning, __end, __end, __end); 106306c3fb27SDimitry Andric } 106406c3fb27SDimitry Andric 1065cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 1066cb14a3feSDimitry Andric __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { 1067cb14a3feSDimitry Andric (void)__block_index; 1068cb14a3feSDimitry Andric (void)__annotation_type; 1069cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 107006c3fb27SDimitry Andric __map_const_iterator __block_it = __map_.begin() + __block_index; 107106c3fb27SDimitry Andric const void* __block_start = std::__to_address(*__block_it); 107206c3fb27SDimitry Andric const void* __block_end = std::__to_address(*__block_it + __block_size); 107306c3fb27SDimitry Andric 107406c3fb27SDimitry Andric if (__annotation_type == __asan_poison) 107506c3fb27SDimitry Andric __annotate_poison_block(__block_start, __block_end); 107606c3fb27SDimitry Andric else { 10770fca6ea1SDimitry Andric std::__annotate_double_ended_contiguous_container<_Allocator>( 107806c3fb27SDimitry Andric __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); 107906c3fb27SDimitry Andric } 1080cb14a3feSDimitry Andric#endif 108106c3fb27SDimitry Andric } 108206c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) 108306c3fb27SDimitry Andric 108406c3fb27SDimitry Andricpublic: 1085cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __verify_asan_annotations() const _NOEXCEPT { 108606c3fb27SDimitry Andric // This function tests deque object annotations. 108706c3fb27SDimitry Andric if (empty()) { 108806c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 108906c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 109006c3fb27SDimitry Andric std::__to_address(*__it), 109106c3fb27SDimitry Andric std::__to_address(*__it), 109206c3fb27SDimitry Andric std::__to_address(*__it), 109306c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 109406c3fb27SDimitry Andric return false; 109506c3fb27SDimitry Andric } 109606c3fb27SDimitry Andric 109706c3fb27SDimitry Andric return true; 109806c3fb27SDimitry Andric } 109906c3fb27SDimitry Andric 110006c3fb27SDimitry Andric size_type __end = __start_ + size(); 110106c3fb27SDimitry Andric __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; 110206c3fb27SDimitry Andric __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; 110306c3fb27SDimitry Andric 110406c3fb27SDimitry Andric // Pointers to first and after last elements 110506c3fb27SDimitry Andric // Those can be in different deque blocks 110606c3fb27SDimitry Andric const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); 110706c3fb27SDimitry Andric const void* __p_end = 110806c3fb27SDimitry Andric std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); 110906c3fb27SDimitry Andric 111006c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 111106c3fb27SDimitry Andric // Go over all blocks, find the place we are in and verify its annotations 111206c3fb27SDimitry Andric // Note that __p_end points *behind* the last item. 111306c3fb27SDimitry Andric 111406c3fb27SDimitry Andric // - blocks before the first block with container elements 111506c3fb27SDimitry Andric // - first block with items 111606c3fb27SDimitry Andric // - last block with items 111706c3fb27SDimitry Andric // - blocks after last block with ciontainer elements 111806c3fb27SDimitry Andric 111906c3fb27SDimitry Andric // Is the block before or after deque blocks that contain elements? 112006c3fb27SDimitry Andric if (__it < __first_mp || __it > __last_mp) { 112106c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 112206c3fb27SDimitry Andric std::__to_address(*__it), 112306c3fb27SDimitry Andric std::__to_address(*__it), 112406c3fb27SDimitry Andric std::__to_address(*__it), 112506c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 112606c3fb27SDimitry Andric return false; 112706c3fb27SDimitry Andric } else { 112806c3fb27SDimitry Andric const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); 112906c3fb27SDimitry Andric const void* __containers_buffer_end = 113006c3fb27SDimitry Andric (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); 113106c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 113206c3fb27SDimitry Andric std::__to_address(*__it), 113306c3fb27SDimitry Andric __containers_buffer_beg, 113406c3fb27SDimitry Andric __containers_buffer_end, 113506c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) { 113606c3fb27SDimitry Andric return false; 113706c3fb27SDimitry Andric } 113806c3fb27SDimitry Andric } 113906c3fb27SDimitry Andric } 114006c3fb27SDimitry Andric return true; 114106c3fb27SDimitry Andric } 114206c3fb27SDimitry Andric 114306c3fb27SDimitry Andricprivate: 114406c3fb27SDimitry Andric#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS 1145cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_front_spare(bool __keep_one = true) { 1146e40139ffSDimitry Andric if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { 114706c3fb27SDimitry Andric __annotate_whole_block(0, __asan_unposion); 1148cb14a3feSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.front(), __block_size); 1149bdd1243dSDimitry Andric __map_.pop_front(); 1150bdd1243dSDimitry Andric __start_ -= __block_size; 1151e40139ffSDimitry Andric return true; 1152e40139ffSDimitry Andric } 1153e40139ffSDimitry Andric return false; 1154e40139ffSDimitry Andric } 1155e40139ffSDimitry Andric 1156cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_back_spare(bool __keep_one = true) { 1157e40139ffSDimitry Andric if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { 115806c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_unposion); 1159cb14a3feSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.back(), __block_size); 1160bdd1243dSDimitry Andric __map_.pop_back(); 1161e40139ffSDimitry Andric return true; 1162e40139ffSDimitry Andric } 1163e40139ffSDimitry Andric return false; 1164e40139ffSDimitry Andric } 11650b57cec5SDimitry Andric 116606c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1167cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __f, _Sentinel __l); 116806c3fb27SDimitry Andric 116906c3fb27SDimitry Andric template <class _RandomAccessIterator> 1170cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); 117106c3fb27SDimitry Andric template <class _Iterator> 1172cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_size(_Iterator __f, difference_type __n); 117306c3fb27SDimitry Andric 117406c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1175cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); 117606c3fb27SDimitry Andric 117706c3fb27SDimitry Andric template <class _Iterator> 1178cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); 117906c3fb27SDimitry Andric 118006c3fb27SDimitry Andric template <class _BiIter, class _Sentinel> 1181cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 1182cb14a3feSDimitry Andric __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); 118306c3fb27SDimitry Andric template <class _BiIter> 1184cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); 118506c3fb27SDimitry Andric 11865f757f3fSDimitry Andric template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> = 0> 11875f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l); 11885f757f3fSDimitry Andric template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> = 0> 11895f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l); 119006c3fb27SDimitry Andric 119106c3fb27SDimitry Andric template <class _InputIterator> 119206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); 119306c3fb27SDimitry Andric template <class _InputIterator, class _Sentinel> 119406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); 119506c3fb27SDimitry Andric 1196bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); 1197bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); 1198bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); 1199bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(); 1200bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n); 1201bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(); 1202bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n); 1203cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1204cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 1205cb14a3feSDimitry Andric __move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1206cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1207cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 1208cb14a3feSDimitry Andric __move_construct_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 12090b57cec5SDimitry Andric 1210cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c) { 1211cb14a3feSDimitry Andric __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); 1212cb14a3feSDimitry Andric } 12130b57cec5SDimitry Andric 1214cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c, true_type) { 1215cb14a3feSDimitry Andric if (__alloc() != __c.__alloc()) { 12160b57cec5SDimitry Andric clear(); 12170b57cec5SDimitry Andric shrink_to_fit(); 12180b57cec5SDimitry Andric } 1219bdd1243dSDimitry Andric __alloc() = __c.__alloc(); 1220bdd1243dSDimitry Andric __map_.__alloc() = __c.__map_.__alloc(); 12210b57cec5SDimitry Andric } 12220b57cec5SDimitry Andric 1223cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {} 12240b57cec5SDimitry Andric 1225bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type) 12260b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 1227bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type); 12280b57cec5SDimitry Andric}; 12290b57cec5SDimitry Andric 1230bdd1243dSDimitry Andrictemplate <class _Tp, class _Alloc> 1231bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size = 1232bdd1243dSDimitry Andric __deque_block_size<value_type, difference_type>::value; 1233bdd1243dSDimitry Andric 1234349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17 12350b57cec5SDimitry Andrictemplate <class _InputIterator, 1236fe6060f1SDimitry Andric class _Alloc = allocator<__iter_value_type<_InputIterator>>, 123706c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1238cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1239cb14a3feSDimitry Andricdeque(_InputIterator, _InputIterator) -> deque<__iter_value_type<_InputIterator>, _Alloc>; 12400b57cec5SDimitry Andric 12410b57cec5SDimitry Andrictemplate <class _InputIterator, 12420b57cec5SDimitry Andric class _Alloc, 124306c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1244cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1245cb14a3feSDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc) -> deque<__iter_value_type<_InputIterator>, _Alloc>; 12460b57cec5SDimitry Andric#endif 12470b57cec5SDimitry Andric 124806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 124906c3fb27SDimitry Andrictemplate <ranges::input_range _Range, 125006c3fb27SDimitry Andric class _Alloc = allocator<ranges::range_value_t<_Range>>, 1251cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1252cb14a3feSDimitry Andricdeque(from_range_t, _Range&&, _Alloc = _Alloc()) -> deque<ranges::range_value_t<_Range>, _Alloc>; 125306c3fb27SDimitry Andric#endif 125406c3fb27SDimitry Andric 12550b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1256cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n) : __start_(0), __size_(0, __default_init_tag()) { 125706c3fb27SDimitry Andric __annotate_new(0); 12580b57cec5SDimitry Andric if (__n > 0) 12590b57cec5SDimitry Andric __append(__n); 12600b57cec5SDimitry Andric} 12610b57cec5SDimitry Andric 126206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 12630b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12640b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) 1265cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 126606c3fb27SDimitry Andric __annotate_new(0); 12670b57cec5SDimitry Andric if (__n > 0) 12680b57cec5SDimitry Andric __append(__n); 12690b57cec5SDimitry Andric} 12700b57cec5SDimitry Andric#endif 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1273cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) : __start_(0), __size_(0, __default_init_tag()) { 127406c3fb27SDimitry Andric __annotate_new(0); 12750b57cec5SDimitry Andric if (__n > 0) 12760b57cec5SDimitry Andric __append(__n, __v); 12770b57cec5SDimitry Andric} 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12805f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 1281cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l) : __start_(0), __size_(0, __default_init_tag()) { 128206c3fb27SDimitry Andric __annotate_new(0); 12830b57cec5SDimitry Andric __append(__f, __l); 12840b57cec5SDimitry Andric} 12850b57cec5SDimitry Andric 12860b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12875f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 12885f757f3fSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a) 1289cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 129006c3fb27SDimitry Andric __annotate_new(0); 12910b57cec5SDimitry Andric __append(__f, __l); 12920b57cec5SDimitry Andric} 12930b57cec5SDimitry Andric 12940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12950b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c) 1296bdd1243dSDimitry Andric : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))), 1297bdd1243dSDimitry Andric __start_(0), 1298cb14a3feSDimitry Andric __size_(0, __map_.__alloc()) { 129906c3fb27SDimitry Andric __annotate_new(0); 13000b57cec5SDimitry Andric __append(__c.begin(), __c.end()); 13010b57cec5SDimitry Andric} 13020b57cec5SDimitry Andric 13030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 130481ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a) 1305cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 130606c3fb27SDimitry Andric __annotate_new(0); 13070b57cec5SDimitry Andric __append(__c.begin(), __c.end()); 13080b57cec5SDimitry Andric} 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1311cb14a3feSDimitry Andricdeque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(const deque& __c) { 1312cb14a3feSDimitry Andric if (this != std::addressof(__c)) { 13130b57cec5SDimitry Andric __copy_assign_alloc(__c); 13140b57cec5SDimitry Andric assign(__c.begin(), __c.end()); 13150b57cec5SDimitry Andric } 13160b57cec5SDimitry Andric return *this; 13170b57cec5SDimitry Andric} 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 13200b57cec5SDimitry Andric 13210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1322cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il) : __start_(0), __size_(0, __default_init_tag()) { 132306c3fb27SDimitry Andric __annotate_new(0); 13240b57cec5SDimitry Andric __append(__il.begin(), __il.end()); 13250b57cec5SDimitry Andric} 13260b57cec5SDimitry Andric 13270b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13280b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a) 1329cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 133006c3fb27SDimitry Andric __annotate_new(0); 13310b57cec5SDimitry Andric __append(__il.begin(), __il.end()); 13320b57cec5SDimitry Andric} 13330b57cec5SDimitry Andric 13340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13350fca6ea1SDimitry Andricinline deque<_Tp, _Allocator>::deque(deque&& __c) noexcept(is_nothrow_move_constructible<allocator_type>::value) 1336cb14a3feSDimitry Andric : __map_(std::move(__c.__map_)), __start_(std::move(__c.__start_)), __size_(std::move(__c.__size_)) { 1337bdd1243dSDimitry Andric __c.__start_ = 0; 1338bdd1243dSDimitry Andric __c.__size() = 0; 13390b57cec5SDimitry Andric} 13400b57cec5SDimitry Andric 13410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1342cb14a3feSDimitry Andricinline deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a) 1343bdd1243dSDimitry Andric : __map_(std::move(__c.__map_), __pointer_allocator(__a)), 1344bdd1243dSDimitry Andric __start_(std::move(__c.__start_)), 1345cb14a3feSDimitry Andric __size_(std::move(__c.__size()), __a) { 1346cb14a3feSDimitry Andric if (__a == __c.__alloc()) { 1347bdd1243dSDimitry Andric __c.__start_ = 0; 1348bdd1243dSDimitry Andric __c.__size() = 0; 1349cb14a3feSDimitry Andric } else { 1350bdd1243dSDimitry Andric __map_.clear(); 1351bdd1243dSDimitry Andric __start_ = 0; 1352bdd1243dSDimitry Andric __size() = 0; 13530b57cec5SDimitry Andric typedef move_iterator<iterator> _Ip; 13540b57cec5SDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end())); 13550b57cec5SDimitry Andric } 13560b57cec5SDimitry Andric} 13570b57cec5SDimitry Andric 13580b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13590fca6ea1SDimitry Andricinline deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(deque&& __c) noexcept( 13600fca6ea1SDimitry Andric __alloc_traits::propagate_on_container_move_assignment::value && 13610fca6ea1SDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 1362cb14a3feSDimitry Andric __move_assign(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 13630b57cec5SDimitry Andric return *this; 13640b57cec5SDimitry Andric} 13650b57cec5SDimitry Andric 13660b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1367cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) { 1368cb14a3feSDimitry Andric if (__alloc() != __c.__alloc()) { 13690b57cec5SDimitry Andric typedef move_iterator<iterator> _Ip; 13700b57cec5SDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end())); 1371cb14a3feSDimitry Andric } else 13720b57cec5SDimitry Andric __move_assign(__c, true_type()); 13730b57cec5SDimitry Andric} 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13760fca6ea1SDimitry Andricvoid deque<_Tp, _Allocator>::__move_assign(deque& __c, 13770fca6ea1SDimitry Andric true_type) noexcept(is_nothrow_move_assignable<allocator_type>::value) { 13780b57cec5SDimitry Andric clear(); 13790b57cec5SDimitry Andric shrink_to_fit(); 1380bdd1243dSDimitry Andric __move_assign(__c); 13810b57cec5SDimitry Andric} 13820b57cec5SDimitry Andric 13830b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1386cb14a3feSDimitry Andrictemplate <class _InputIter, 1387cb14a3feSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIter>::value && 1388cb14a3feSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, 1389cb14a3feSDimitry Andric int> > 1390cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l) { 139106c3fb27SDimitry Andric __assign_with_sentinel(__f, __l); 139206c3fb27SDimitry Andric} 139306c3fb27SDimitry Andric 139406c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 139506c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 1396cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { 1397bdd1243dSDimitry Andric iterator __i = begin(); 1398bdd1243dSDimitry Andric iterator __e = end(); 13990b57cec5SDimitry Andric for (; __f != __l && __i != __e; ++__f, (void)++__i) 14000b57cec5SDimitry Andric *__i = *__f; 14010b57cec5SDimitry Andric if (__f != __l) 140206c3fb27SDimitry Andric __append_with_sentinel(std::move(__f), std::move(__l)); 14030b57cec5SDimitry Andric else 14040b57cec5SDimitry Andric __erase_to_end(__i); 14050b57cec5SDimitry Andric} 14060b57cec5SDimitry Andric 14070b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14085f757f3fSDimitry Andrictemplate <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> > 1409cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l) { 141006c3fb27SDimitry Andric __assign_with_size_random_access(__f, __l - __f); 141106c3fb27SDimitry Andric} 141206c3fb27SDimitry Andric 141306c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 141406c3fb27SDimitry Andrictemplate <class _RandomAccessIterator> 1415cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void 1416cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { 1417cb14a3feSDimitry Andric if (static_cast<size_type>(__n) > size()) { 141806c3fb27SDimitry Andric auto __l = __f + size(); 141906c3fb27SDimitry Andric std::copy(__f, __l, begin()); 142006c3fb27SDimitry Andric __append_with_size(__l, __n - size()); 1421cb14a3feSDimitry Andric } else 142206c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 142306c3fb27SDimitry Andric} 142406c3fb27SDimitry Andric 142506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 142606c3fb27SDimitry Andrictemplate <class _Iterator> 1427cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { 142806c3fb27SDimitry Andric if (static_cast<size_type>(__n) > size()) { 142906c3fb27SDimitry Andric auto __added_size = __n - size(); 143006c3fb27SDimitry Andric 143106c3fb27SDimitry Andric auto __i = begin(); 143206c3fb27SDimitry Andric for (auto __count = size(); __count != 0; --__count) { 143306c3fb27SDimitry Andric *__i++ = *__f++; 143406c3fb27SDimitry Andric } 143506c3fb27SDimitry Andric 143606c3fb27SDimitry Andric __append_with_size(__f, __added_size); 143706c3fb27SDimitry Andric 143806c3fb27SDimitry Andric } else { 143906c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 144006c3fb27SDimitry Andric } 14410b57cec5SDimitry Andric} 14420b57cec5SDimitry Andric 14430b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1444cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) { 1445cb14a3feSDimitry Andric if (__n > size()) { 14465f757f3fSDimitry Andric std::fill_n(begin(), size(), __v); 1447bdd1243dSDimitry Andric __n -= size(); 14480b57cec5SDimitry Andric __append(__n, __v); 1449cb14a3feSDimitry Andric } else 14505f757f3fSDimitry Andric __erase_to_end(std::fill_n(begin(), __n, __v)); 14510b57cec5SDimitry Andric} 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1454cb14a3feSDimitry Andricinline _Allocator deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT { 1455bdd1243dSDimitry Andric return __alloc(); 14560b57cec5SDimitry Andric} 14570b57cec5SDimitry Andric 14580b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1459cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::resize(size_type __n) { 1460bdd1243dSDimitry Andric if (__n > size()) 1461bdd1243dSDimitry Andric __append(__n - size()); 1462bdd1243dSDimitry Andric else if (__n < size()) 1463bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 14640b57cec5SDimitry Andric} 14650b57cec5SDimitry Andric 14660b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1467cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) { 1468bdd1243dSDimitry Andric if (__n > size()) 1469bdd1243dSDimitry Andric __append(__n - size(), __v); 1470bdd1243dSDimitry Andric else if (__n < size()) 1471bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 14720b57cec5SDimitry Andric} 14730b57cec5SDimitry Andric 14740b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1475cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT { 1476bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1477cb14a3feSDimitry Andric if (empty()) { 147806c3fb27SDimitry Andric __annotate_delete(); 1479cb14a3feSDimitry Andric while (__map_.size() > 0) { 1480bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.back(), __block_size); 1481bdd1243dSDimitry Andric __map_.pop_back(); 14820b57cec5SDimitry Andric } 1483bdd1243dSDimitry Andric __start_ = 0; 1484cb14a3feSDimitry Andric } else { 1485e40139ffSDimitry Andric __maybe_remove_front_spare(/*__keep_one=*/false); 1486e40139ffSDimitry Andric __maybe_remove_back_spare(/*__keep_one=*/false); 14870b57cec5SDimitry Andric } 1488bdd1243dSDimitry Andric __map_.shrink_to_fit(); 14890b57cec5SDimitry Andric} 14900b57cec5SDimitry Andric 14910b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1492cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT { 14930fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "deque::operator[] index out of bounds"); 1494bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1495bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 14960b57cec5SDimitry Andric} 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1499cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference 1500cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT { 15010fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "deque::operator[] index out of bounds"); 1502bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1503bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15040b57cec5SDimitry Andric} 15050b57cec5SDimitry Andric 15060b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1507cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::at(size_type __i) { 1508bdd1243dSDimitry Andric if (__i >= size()) 15095f757f3fSDimitry Andric std::__throw_out_of_range("deque"); 1510bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1511bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15120b57cec5SDimitry Andric} 15130b57cec5SDimitry Andric 15140b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1515cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::at(size_type __i) const { 1516bdd1243dSDimitry Andric if (__i >= size()) 15175f757f3fSDimitry Andric std::__throw_out_of_range("deque"); 1518bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1519bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15200b57cec5SDimitry Andric} 15210b57cec5SDimitry Andric 15220b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1523cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::front() _NOEXCEPT { 15240fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::front called on an empty deque"); 1525cb14a3feSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); 15260b57cec5SDimitry Andric} 15270b57cec5SDimitry Andric 15280b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1529cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::front() const _NOEXCEPT { 15300fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::front called on an empty deque"); 1531cb14a3feSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); 15320b57cec5SDimitry Andric} 15330b57cec5SDimitry Andric 15340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1535cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::back() _NOEXCEPT { 15360fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::back called on an empty deque"); 1537bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1538bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15390b57cec5SDimitry Andric} 15400b57cec5SDimitry Andric 15410b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1542cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::back() const _NOEXCEPT { 15430fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::back called on an empty deque"); 1544bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1545bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15460b57cec5SDimitry Andric} 15470b57cec5SDimitry Andric 15480b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1549cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_back(const value_type& __v) { 1550bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15510b57cec5SDimitry Andric if (__back_spare() == 0) 15520b57cec5SDimitry Andric __add_back_capacity(); 15530b57cec5SDimitry Andric // __back_spare() >= 1 155406c3fb27SDimitry Andric __annotate_increase_back(1); 15555f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1556bdd1243dSDimitry Andric ++__size(); 15570b57cec5SDimitry Andric} 15580b57cec5SDimitry Andric 15590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1560cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_front(const value_type& __v) { 1561bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15620b57cec5SDimitry Andric if (__front_spare() == 0) 15630b57cec5SDimitry Andric __add_front_capacity(); 15640b57cec5SDimitry Andric // __front_spare() >= 1 156506c3fb27SDimitry Andric __annotate_increase_front(1); 15665f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1567bdd1243dSDimitry Andric --__start_; 1568bdd1243dSDimitry Andric ++__size(); 15690b57cec5SDimitry Andric} 15700b57cec5SDimitry Andric 15710b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 15720b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1573cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_back(value_type&& __v) { 1574bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15750b57cec5SDimitry Andric if (__back_spare() == 0) 15760b57cec5SDimitry Andric __add_back_capacity(); 15770b57cec5SDimitry Andric // __back_spare() >= 1 157806c3fb27SDimitry Andric __annotate_increase_back(1); 15795f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); 1580bdd1243dSDimitry Andric ++__size(); 15810b57cec5SDimitry Andric} 15820b57cec5SDimitry Andric 15830b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15840b57cec5SDimitry Andrictemplate <class... _Args> 158506c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 15860b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 15870b57cec5SDimitry Andric# else 15880b57cec5SDimitry Andricvoid 15890b57cec5SDimitry Andric# endif 1590cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::emplace_back(_Args&&... __args) { 1591bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15920b57cec5SDimitry Andric if (__back_spare() == 0) 15930b57cec5SDimitry Andric __add_back_capacity(); 15940b57cec5SDimitry Andric // __back_spare() >= 1 159506c3fb27SDimitry Andric __annotate_increase_back(1); 1596cb14a3feSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); 1597bdd1243dSDimitry Andric ++__size(); 159806c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 1599bdd1243dSDimitry Andric return *--end(); 16000b57cec5SDimitry Andric# endif 16010b57cec5SDimitry Andric} 16020b57cec5SDimitry Andric 16030b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1604cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_front(value_type&& __v) { 1605bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 16060b57cec5SDimitry Andric if (__front_spare() == 0) 16070b57cec5SDimitry Andric __add_front_capacity(); 16080b57cec5SDimitry Andric // __front_spare() >= 1 160906c3fb27SDimitry Andric __annotate_increase_front(1); 16105f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); 1611bdd1243dSDimitry Andric --__start_; 1612bdd1243dSDimitry Andric ++__size(); 16130b57cec5SDimitry Andric} 16140b57cec5SDimitry Andric 16150b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16160b57cec5SDimitry Andrictemplate <class... _Args> 161706c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 16180b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 16190b57cec5SDimitry Andric# else 16200b57cec5SDimitry Andricvoid 16210b57cec5SDimitry Andric# endif 1622cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::emplace_front(_Args&&... __args) { 1623bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 16240b57cec5SDimitry Andric if (__front_spare() == 0) 16250b57cec5SDimitry Andric __add_front_capacity(); 16260b57cec5SDimitry Andric // __front_spare() >= 1 162706c3fb27SDimitry Andric __annotate_increase_front(1); 16285f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); 1629bdd1243dSDimitry Andric --__start_; 1630bdd1243dSDimitry Andric ++__size(); 163106c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 1632bdd1243dSDimitry Andric return *begin(); 16330b57cec5SDimitry Andric# endif 16340b57cec5SDimitry Andric} 16350b57cec5SDimitry Andric 16360b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1637cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) { 1638bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1639bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1640bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1641cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 16420b57cec5SDimitry Andric if (__front_spare() == 0) 16430b57cec5SDimitry Andric __add_front_capacity(); 16440b57cec5SDimitry Andric // __front_spare() >= 1 164506c3fb27SDimitry Andric __annotate_increase_front(1); 1646cb14a3feSDimitry Andric if (__pos == 0) { 16475f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); 1648bdd1243dSDimitry Andric --__start_; 1649bdd1243dSDimitry Andric ++__size(); 1650cb14a3feSDimitry Andric } else { 1651bdd1243dSDimitry Andric iterator __b = begin(); 16525f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 16535f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1654bdd1243dSDimitry Andric --__start_; 1655bdd1243dSDimitry Andric ++__size(); 16560b57cec5SDimitry Andric if (__pos > 1) 16575f757f3fSDimitry Andric __b = std::move(std::next(__b), __b + __pos, __b); 16585f757f3fSDimitry Andric *__b = std::move(__v); 16590b57cec5SDimitry Andric } 1660cb14a3feSDimitry Andric } else { // insert by shifting things forward 16610b57cec5SDimitry Andric if (__back_spare() == 0) 16620b57cec5SDimitry Andric __add_back_capacity(); 16630b57cec5SDimitry Andric // __back_capacity >= 1 166406c3fb27SDimitry Andric __annotate_increase_back(1); 1665bdd1243dSDimitry Andric size_type __de = size() - __pos; 1666cb14a3feSDimitry Andric if (__de == 0) { 16675f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); 1668bdd1243dSDimitry Andric ++__size(); 1669cb14a3feSDimitry Andric } else { 1670bdd1243dSDimitry Andric iterator __e = end(); 16715f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 16725f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1673bdd1243dSDimitry Andric ++__size(); 16740b57cec5SDimitry Andric if (__de > 1) 16755f757f3fSDimitry Andric __e = std::move_backward(__e - __de, __em1, __e); 16765f757f3fSDimitry Andric *--__e = std::move(__v); 16770b57cec5SDimitry Andric } 16780b57cec5SDimitry Andric } 1679bdd1243dSDimitry Andric return begin() + __pos; 16800b57cec5SDimitry Andric} 16810b57cec5SDimitry Andric 16820b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16830b57cec5SDimitry Andrictemplate <class... _Args> 1684cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) { 1685bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1686bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1687bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1688cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 16890b57cec5SDimitry Andric if (__front_spare() == 0) 16900b57cec5SDimitry Andric __add_front_capacity(); 16910b57cec5SDimitry Andric // __front_spare() >= 1 169206c3fb27SDimitry Andric __annotate_increase_front(1); 1693cb14a3feSDimitry Andric if (__pos == 0) { 16945f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); 1695bdd1243dSDimitry Andric --__start_; 1696bdd1243dSDimitry Andric ++__size(); 1697cb14a3feSDimitry Andric } else { 16985f757f3fSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); 1699bdd1243dSDimitry Andric iterator __b = begin(); 17005f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 17015f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1702bdd1243dSDimitry Andric --__start_; 1703bdd1243dSDimitry Andric ++__size(); 17040b57cec5SDimitry Andric if (__pos > 1) 17055f757f3fSDimitry Andric __b = std::move(std::next(__b), __b + __pos, __b); 17065f757f3fSDimitry Andric *__b = std::move(__tmp.get()); 17070b57cec5SDimitry Andric } 1708cb14a3feSDimitry Andric } else { // insert by shifting things forward 17090b57cec5SDimitry Andric if (__back_spare() == 0) 17100b57cec5SDimitry Andric __add_back_capacity(); 17110b57cec5SDimitry Andric // __back_capacity >= 1 171206c3fb27SDimitry Andric __annotate_increase_back(1); 1713bdd1243dSDimitry Andric size_type __de = size() - __pos; 1714cb14a3feSDimitry Andric if (__de == 0) { 17155f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); 1716bdd1243dSDimitry Andric ++__size(); 1717cb14a3feSDimitry Andric } else { 17185f757f3fSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); 1719bdd1243dSDimitry Andric iterator __e = end(); 17205f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 17215f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1722bdd1243dSDimitry Andric ++__size(); 17230b57cec5SDimitry Andric if (__de > 1) 17245f757f3fSDimitry Andric __e = std::move_backward(__e - __de, __em1, __e); 17255f757f3fSDimitry Andric *--__e = std::move(__tmp.get()); 17260b57cec5SDimitry Andric } 17270b57cec5SDimitry Andric } 1728bdd1243dSDimitry Andric return begin() + __pos; 17290b57cec5SDimitry Andric} 17300b57cec5SDimitry Andric 17310b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 17320b57cec5SDimitry Andric 17330b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1734cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) { 1735bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1736bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1737bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1738cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 17390b57cec5SDimitry Andric if (__front_spare() == 0) 17400b57cec5SDimitry Andric __add_front_capacity(); 17410b57cec5SDimitry Andric // __front_spare() >= 1 174206c3fb27SDimitry Andric __annotate_increase_front(1); 1743cb14a3feSDimitry Andric if (__pos == 0) { 17445f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1745bdd1243dSDimitry Andric --__start_; 1746bdd1243dSDimitry Andric ++__size(); 1747cb14a3feSDimitry Andric } else { 17480b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1749bdd1243dSDimitry Andric iterator __b = begin(); 17505f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 17510b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__b)) 17520b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__bm1); 17535f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1754bdd1243dSDimitry Andric --__start_; 1755bdd1243dSDimitry Andric ++__size(); 17560b57cec5SDimitry Andric if (__pos > 1) 17575f757f3fSDimitry Andric __b = __move_and_check(std::next(__b), __b + __pos, __b, __vt); 17580b57cec5SDimitry Andric *__b = *__vt; 17590b57cec5SDimitry Andric } 1760cb14a3feSDimitry Andric } else { // insert by shifting things forward 17610b57cec5SDimitry Andric if (__back_spare() == 0) 17620b57cec5SDimitry Andric __add_back_capacity(); 17630b57cec5SDimitry Andric // __back_capacity >= 1 176406c3fb27SDimitry Andric __annotate_increase_back(1); 1765bdd1243dSDimitry Andric size_type __de = size() - __pos; 1766cb14a3feSDimitry Andric if (__de == 0) { 17675f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1768bdd1243dSDimitry Andric ++__size(); 1769cb14a3feSDimitry Andric } else { 17700b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1771bdd1243dSDimitry Andric iterator __e = end(); 17725f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 17730b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1)) 17740b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__e); 17755f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1776bdd1243dSDimitry Andric ++__size(); 17770b57cec5SDimitry Andric if (__de > 1) 17780b57cec5SDimitry Andric __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); 17790b57cec5SDimitry Andric *--__e = *__vt; 17800b57cec5SDimitry Andric } 17810b57cec5SDimitry Andric } 1782bdd1243dSDimitry Andric return begin() + __pos; 17830b57cec5SDimitry Andric} 17840b57cec5SDimitry Andric 17850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17860b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1787cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) { 1788bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1789bdd1243dSDimitry Andric size_type __to_end = __size() - __pos; 1790bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1791cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 17920b57cec5SDimitry Andric if (__n > __front_spare()) 17930b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 17940b57cec5SDimitry Andric // __n <= __front_spare() 179506c3fb27SDimitry Andric __annotate_increase_front(__n); 1796bdd1243dSDimitry Andric iterator __old_begin = begin(); 17970b57cec5SDimitry Andric iterator __i = __old_begin; 1798cb14a3feSDimitry Andric if (__n > __pos) { 1799bdd1243dSDimitry Andric for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size()) 18005f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), __v); 18010b57cec5SDimitry Andric __n = __pos; 18020b57cec5SDimitry Andric } 1803cb14a3feSDimitry Andric if (__n > 0) { 18040b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 18050b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 18060b57cec5SDimitry Andric __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); 18070b57cec5SDimitry Andric if (__n < __pos) 18080b57cec5SDimitry Andric __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); 18095f757f3fSDimitry Andric std::fill_n(__old_begin, __n, *__vt); 18100b57cec5SDimitry Andric } 1811cb14a3feSDimitry Andric } else { // insert by shifting things forward 18120b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 18130b57cec5SDimitry Andric if (__n > __back_capacity) 18140b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 18150b57cec5SDimitry Andric // __n <= __back_capacity 181606c3fb27SDimitry Andric __annotate_increase_back(__n); 1817bdd1243dSDimitry Andric iterator __old_end = end(); 18180b57cec5SDimitry Andric iterator __i = __old_end; 1819bdd1243dSDimitry Andric size_type __de = size() - __pos; 1820cb14a3feSDimitry Andric if (__n > __de) { 1821bdd1243dSDimitry Andric for (size_type __m = __n - __de; __m; --__m, (void)++__i, ++__size()) 18225f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), __v); 18230b57cec5SDimitry Andric __n = __de; 18240b57cec5SDimitry Andric } 1825cb14a3feSDimitry Andric if (__n > 0) { 18260b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 18270b57cec5SDimitry Andric iterator __oen = __old_end - __n; 18280b57cec5SDimitry Andric __move_construct_and_check(__oen, __old_end, __i, __vt); 18290b57cec5SDimitry Andric if (__n < __de) 18300b57cec5SDimitry Andric __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); 18315f757f3fSDimitry Andric std::fill_n(__old_end - __n, __n, *__vt); 18320b57cec5SDimitry Andric } 18330b57cec5SDimitry Andric } 1834bdd1243dSDimitry Andric return begin() + __pos; 18350b57cec5SDimitry Andric} 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18385f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> > 18390b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1840cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l) { 184106c3fb27SDimitry Andric return __insert_with_sentinel(__p, __f, __l); 184206c3fb27SDimitry Andric} 184306c3fb27SDimitry Andric 184406c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 184506c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 1846cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 184706c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { 1848bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__alloc()); 184906c3fb27SDimitry Andric __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); 18500b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; 18510b57cec5SDimitry Andric return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); 18520b57cec5SDimitry Andric} 18530b57cec5SDimitry Andric 18540b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18555f757f3fSDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> > 18560b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1857cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l) { 185806c3fb27SDimitry Andric return __insert_with_size(__p, __f, std::distance(__f, __l)); 185906c3fb27SDimitry Andric} 186006c3fb27SDimitry Andric 186106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 186206c3fb27SDimitry Andrictemplate <class _Iterator> 1863cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 186406c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) { 1865bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); 186606c3fb27SDimitry Andric __buf.__construct_at_end_with_size(__f, __n); 18670b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; 18680b57cec5SDimitry Andric return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); 18690b57cec5SDimitry Andric} 18700b57cec5SDimitry Andric 18710b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18725f757f3fSDimitry Andrictemplate <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> > 1873cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l) { 187406c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l)); 187506c3fb27SDimitry Andric} 187606c3fb27SDimitry Andric 187706c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 187806c3fb27SDimitry Andrictemplate <class _BiIter, class _Sentinel> 1879cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 188006c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) { 188106c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, std::next(__f, __n), __n); 188206c3fb27SDimitry Andric} 188306c3fb27SDimitry Andric 188406c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 188506c3fb27SDimitry Andrictemplate <class _BiIter> 1886cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 188706c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) { 1888bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1889bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1890bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1891cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 18920b57cec5SDimitry Andric if (__n > __front_spare()) 18930b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 18940b57cec5SDimitry Andric // __n <= __front_spare() 189506c3fb27SDimitry Andric __annotate_increase_front(__n); 1896bdd1243dSDimitry Andric iterator __old_begin = begin(); 18970b57cec5SDimitry Andric iterator __i = __old_begin; 18980b57cec5SDimitry Andric _BiIter __m = __f; 1899cb14a3feSDimitry Andric if (__n > __pos) { 19005f757f3fSDimitry Andric __m = __pos < __n / 2 ? std::prev(__l, __pos) : std::next(__f, __n - __pos); 1901bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __f; --__start_, ++__size()) 19025f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), *--__j); 19030b57cec5SDimitry Andric __n = __pos; 19040b57cec5SDimitry Andric } 1905cb14a3feSDimitry Andric if (__n > 0) { 19060b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 1907cb14a3feSDimitry Andric for (iterator __j = __obn; __j != __old_begin;) { 19085f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), std::move(*--__j)); 1909bdd1243dSDimitry Andric --__start_; 1910bdd1243dSDimitry Andric ++__size(); 19110b57cec5SDimitry Andric } 19120b57cec5SDimitry Andric if (__n < __pos) 19135f757f3fSDimitry Andric __old_begin = std::move(__obn, __old_begin + __pos, __old_begin); 19145f757f3fSDimitry Andric std::copy(__m, __l, __old_begin); 19150b57cec5SDimitry Andric } 1916cb14a3feSDimitry Andric } else { // insert by shifting things forward 19170b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19180b57cec5SDimitry Andric if (__n > __back_capacity) 19190b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 19200b57cec5SDimitry Andric // __n <= __back_capacity 192106c3fb27SDimitry Andric __annotate_increase_back(__n); 1922bdd1243dSDimitry Andric iterator __old_end = end(); 19230b57cec5SDimitry Andric iterator __i = __old_end; 19240b57cec5SDimitry Andric _BiIter __m = __l; 1925bdd1243dSDimitry Andric size_type __de = size() - __pos; 1926cb14a3feSDimitry Andric if (__n > __de) { 19275f757f3fSDimitry Andric __m = __de < __n / 2 ? std::next(__f, __de) : std::prev(__l, __n - __de); 1928bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __l; ++__i, (void)++__j, ++__size()) 19295f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), *__j); 19300b57cec5SDimitry Andric __n = __de; 19310b57cec5SDimitry Andric } 1932cb14a3feSDimitry Andric if (__n > 0) { 19330b57cec5SDimitry Andric iterator __oen = __old_end - __n; 1934bdd1243dSDimitry Andric for (iterator __j = __oen; __j != __old_end; ++__i, (void)++__j, ++__size()) 19355f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), std::move(*__j)); 19360b57cec5SDimitry Andric if (__n < __de) 19375f757f3fSDimitry Andric __old_end = std::move_backward(__old_end - __de, __oen, __old_end); 19385f757f3fSDimitry Andric std::copy_backward(__f, __m, __old_end); 19390b57cec5SDimitry Andric } 19400b57cec5SDimitry Andric } 1941bdd1243dSDimitry Andric return begin() + __pos; 19420b57cec5SDimitry Andric} 19430b57cec5SDimitry Andric 19440b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 19455f757f3fSDimitry Andrictemplate <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> > 1946cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l) { 194706c3fb27SDimitry Andric __append_with_sentinel(__f, __l); 194806c3fb27SDimitry Andric} 194906c3fb27SDimitry Andric 195006c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 195106c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 1952cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { 19530b57cec5SDimitry Andric for (; __f != __l; ++__f) 19540b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 19550b57cec5SDimitry Andric push_back(*__f); 19560b57cec5SDimitry Andric#else 19570b57cec5SDimitry Andric emplace_back(*__f); 19580b57cec5SDimitry Andric#endif 19590b57cec5SDimitry Andric} 19600b57cec5SDimitry Andric 19610b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 19625f757f3fSDimitry Andrictemplate <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> > 1963cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l) { 196406c3fb27SDimitry Andric __append_with_size(__f, std::distance(__f, __l)); 196506c3fb27SDimitry Andric} 196606c3fb27SDimitry Andric 196706c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 196806c3fb27SDimitry Andrictemplate <class _InputIterator> 1969cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { 1970bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19710b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19720b57cec5SDimitry Andric if (__n > __back_capacity) 19730b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 197406c3fb27SDimitry Andric 19750b57cec5SDimitry Andric // __n <= __back_capacity 197606c3fb27SDimitry Andric __annotate_increase_back(__n); 1977bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1978e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 1979e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { 19805f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); 1981e40139ffSDimitry Andric } 1982e40139ffSDimitry Andric } 19830b57cec5SDimitry Andric} 19840b57cec5SDimitry Andric 19850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1986cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(size_type __n) { 1987bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19880b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19890b57cec5SDimitry Andric if (__n > __back_capacity) 19900b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 19910b57cec5SDimitry Andric // __n <= __back_capacity 199206c3fb27SDimitry Andric __annotate_increase_back(__n); 1993bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1994e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 1995e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 19965f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); 1997e40139ffSDimitry Andric } 1998e40139ffSDimitry Andric } 19990b57cec5SDimitry Andric} 20000b57cec5SDimitry Andric 20010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2002cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) { 2003bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 20040b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 20050b57cec5SDimitry Andric if (__n > __back_capacity) 20060b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 20070b57cec5SDimitry Andric // __n <= __back_capacity 200806c3fb27SDimitry Andric __annotate_increase_back(__n); 2009bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 2010e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 2011e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 20125f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); 2013e40139ffSDimitry Andric } 2014e40139ffSDimitry Andric } 20150b57cec5SDimitry Andric} 20160b57cec5SDimitry Andric 20170b57cec5SDimitry Andric// Create front capacity for one block of elements. 20180b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 20190b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2020cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_front_capacity() { 2021bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2022cb14a3feSDimitry Andric if (__back_spare() >= __block_size) { 2023bdd1243dSDimitry Andric __start_ += __block_size; 2024bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2025bdd1243dSDimitry Andric __map_.pop_back(); 2026bdd1243dSDimitry Andric __map_.push_front(__pt); 20270b57cec5SDimitry Andric } 2028bdd1243dSDimitry Andric // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer 2029cb14a3feSDimitry Andric else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around 20300b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 20310b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2032bdd1243dSDimitry Andric if (__map_.__front_spare() > 0) 2033bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 2034cb14a3feSDimitry Andric else { 2035bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 20360b57cec5SDimitry Andric // Done allocating, reorder capacity 2037bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2038bdd1243dSDimitry Andric __map_.pop_back(); 2039bdd1243dSDimitry Andric __map_.push_front(__pt); 20400b57cec5SDimitry Andric } 2041cb14a3feSDimitry Andric __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; 20420b57cec5SDimitry Andric } 20430b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 2044cb14a3feSDimitry Andric else { 2045cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2046cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__alloc()); 20470b57cec5SDimitry Andric 20480b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 2049cb14a3feSDimitry Andric unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); 20500b57cec5SDimitry Andric __buf.push_back(__hold.get()); 20510b57cec5SDimitry Andric __hold.release(); 20520b57cec5SDimitry Andric 2053cb14a3feSDimitry Andric for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) 20540b57cec5SDimitry Andric __buf.push_back(*__i); 20555f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 20565f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 20575f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 20585f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2059cb14a3feSDimitry Andric __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; 20600b57cec5SDimitry Andric } 206106c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 20620b57cec5SDimitry Andric} 20630b57cec5SDimitry Andric 20640b57cec5SDimitry Andric// Create front capacity for __n elements. 20650b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 20660b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2067cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) { 2068bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2069bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 20700b57cec5SDimitry Andric // Number of unused blocks at back: 2071bdd1243dSDimitry Andric size_type __back_capacity = __back_spare() / __block_size; 20725f757f3fSDimitry Andric __back_capacity = std::min(__back_capacity, __nb); // don't take more than you need 20730b57cec5SDimitry Andric __nb -= __back_capacity; // number of blocks need to allocate 20740b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 2075cb14a3feSDimitry Andric if (__nb == 0) { 2076bdd1243dSDimitry Andric __start_ += __block_size * __back_capacity; 2077cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2078bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2079bdd1243dSDimitry Andric __map_.pop_back(); 2080bdd1243dSDimitry Andric __map_.push_front(__pt); 20810b57cec5SDimitry Andric } 20820b57cec5SDimitry Andric } 20830b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2084cb14a3feSDimitry Andric else if (__nb <= __map_.capacity() - 2085cb14a3feSDimitry Andric __map_.size()) { // we can put the new buffers into the map, but don't shift things around 20860b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 20870b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2088cb14a3feSDimitry Andric for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) { 2089bdd1243dSDimitry Andric if (__map_.__front_spare() == 0) 20900b57cec5SDimitry Andric break; 2091bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 209206c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 20930b57cec5SDimitry Andric } 20940b57cec5SDimitry Andric for (; __nb > 0; --__nb, ++__back_capacity) 2095bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 20960b57cec5SDimitry Andric // Done allocating, reorder capacity 2097bdd1243dSDimitry Andric __start_ += __back_capacity * __block_size; 2098cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2099bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2100bdd1243dSDimitry Andric __map_.pop_back(); 2101bdd1243dSDimitry Andric __map_.push_front(__pt); 210206c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 21030b57cec5SDimitry Andric } 21040b57cec5SDimitry Andric } 21050b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 2106cb14a3feSDimitry Andric else { 2107bdd1243dSDimitry Andric size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty(); 2108cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2109cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__alloc()); 211006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2111cb14a3feSDimitry Andric try { 211206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 211306c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2114bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 211506c3fb27SDimitry Andric // ASan: this is empty container, we have to poison whole block 2116cb14a3feSDimitry Andric __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); 211706c3fb27SDimitry Andric } 211806c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2119cb14a3feSDimitry Andric } catch (...) { 212006c3fb27SDimitry Andric __annotate_delete(); 2121cb14a3feSDimitry Andric for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) 2122bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 21230b57cec5SDimitry Andric throw; 21240b57cec5SDimitry Andric } 212506c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2126cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2127bdd1243dSDimitry Andric __buf.push_back(__map_.back()); 2128bdd1243dSDimitry Andric __map_.pop_back(); 21290b57cec5SDimitry Andric } 2130cb14a3feSDimitry Andric for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) 21310b57cec5SDimitry Andric __buf.push_back(*__i); 21325f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 21335f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 21345f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 21355f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2136bdd1243dSDimitry Andric __start_ += __ds; 21370b57cec5SDimitry Andric } 21380b57cec5SDimitry Andric} 21390b57cec5SDimitry Andric 21400b57cec5SDimitry Andric// Create back capacity for one block of elements. 21410b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 21420b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2143cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_back_capacity() { 2144bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2145cb14a3feSDimitry Andric if (__front_spare() >= __block_size) { 2146bdd1243dSDimitry Andric __start_ -= __block_size; 2147bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2148bdd1243dSDimitry Andric __map_.pop_front(); 2149bdd1243dSDimitry Andric __map_.push_back(__pt); 21500b57cec5SDimitry Andric } 21510b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2152cb14a3feSDimitry Andric else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around 21530b57cec5SDimitry Andric // until it is allocated. If we throw, we don't need to fix 21540b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2155bdd1243dSDimitry Andric if (__map_.__back_spare() != 0) 2156bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 2157cb14a3feSDimitry Andric else { 2158bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 21590b57cec5SDimitry Andric // Done allocating, reorder capacity 2160bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2161bdd1243dSDimitry Andric __map_.pop_front(); 2162bdd1243dSDimitry Andric __map_.push_back(__pt); 21630b57cec5SDimitry Andric } 216406c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 21650b57cec5SDimitry Andric } 21660b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 2167cb14a3feSDimitry Andric else { 2168cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2169cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__alloc()); 21700b57cec5SDimitry Andric 21710b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 2172cb14a3feSDimitry Andric unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); 21730b57cec5SDimitry Andric __buf.push_back(__hold.get()); 21740b57cec5SDimitry Andric __hold.release(); 21750b57cec5SDimitry Andric 2176cb14a3feSDimitry Andric for (__map_pointer __i = __map_.end(); __i != __map_.begin();) 21770b57cec5SDimitry Andric __buf.push_front(*--__i); 21785f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 21795f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 21805f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 21815f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 218206c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 21830b57cec5SDimitry Andric } 21840b57cec5SDimitry Andric} 21850b57cec5SDimitry Andric 21860b57cec5SDimitry Andric// Create back capacity for __n elements. 21870b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 21880b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2189cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) { 2190bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2191bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 21920b57cec5SDimitry Andric // Number of unused blocks at front: 2193bdd1243dSDimitry Andric size_type __front_capacity = __front_spare() / __block_size; 21945f757f3fSDimitry Andric __front_capacity = std::min(__front_capacity, __nb); // don't take more than you need 21950b57cec5SDimitry Andric __nb -= __front_capacity; // number of blocks need to allocate 21960b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 2197cb14a3feSDimitry Andric if (__nb == 0) { 2198bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 2199cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2200bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2201bdd1243dSDimitry Andric __map_.pop_front(); 2202bdd1243dSDimitry Andric __map_.push_back(__pt); 22030b57cec5SDimitry Andric } 22040b57cec5SDimitry Andric } 22050b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2206cb14a3feSDimitry Andric else if (__nb <= __map_.capacity() - 2207cb14a3feSDimitry Andric __map_.size()) { // we can put the new buffers into the map, but don't shift things around 22080b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 22090b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2210cb14a3feSDimitry Andric for (; __nb > 0; --__nb) { 2211bdd1243dSDimitry Andric if (__map_.__back_spare() == 0) 22120b57cec5SDimitry Andric break; 2213bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 221406c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 22150b57cec5SDimitry Andric } 2216cb14a3feSDimitry Andric for (; __nb > 0; --__nb, ++__front_capacity, __start_ += __block_size - (__map_.size() == 1)) { 2217bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 221806c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 221906c3fb27SDimitry Andric } 22200b57cec5SDimitry Andric // Done allocating, reorder capacity 2221bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 2222cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2223bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2224bdd1243dSDimitry Andric __map_.pop_front(); 2225bdd1243dSDimitry Andric __map_.push_back(__pt); 22260b57cec5SDimitry Andric } 22270b57cec5SDimitry Andric } 22280b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 2229cb14a3feSDimitry Andric else { 2230bdd1243dSDimitry Andric size_type __ds = __front_capacity * __block_size; 2231cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2232cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 2233bdd1243dSDimitry Andric __map_.size() - __front_capacity, 2234bdd1243dSDimitry Andric __map_.__alloc()); 223506c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2236cb14a3feSDimitry Andric try { 223706c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 223806c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2239bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 224006c3fb27SDimitry Andric // ASan: this is an empty container, we have to poison the whole block 2241cb14a3feSDimitry Andric __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); 224206c3fb27SDimitry Andric } 224306c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2244cb14a3feSDimitry Andric } catch (...) { 224506c3fb27SDimitry Andric __annotate_delete(); 2246cb14a3feSDimitry Andric for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) 2247bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 22480b57cec5SDimitry Andric throw; 22490b57cec5SDimitry Andric } 225006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2251cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2252bdd1243dSDimitry Andric __buf.push_back(__map_.front()); 2253bdd1243dSDimitry Andric __map_.pop_front(); 22540b57cec5SDimitry Andric } 2255cb14a3feSDimitry Andric for (__map_pointer __i = __map_.end(); __i != __map_.begin();) 22560b57cec5SDimitry Andric __buf.push_front(*--__i); 22575f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 22585f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 22595f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 22605f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2261bdd1243dSDimitry Andric __start_ -= __ds; 22620b57cec5SDimitry Andric } 22630b57cec5SDimitry Andric} 22640b57cec5SDimitry Andric 22650b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2266cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::pop_front() { 22670fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_front called on an empty deque"); 226806c3fb27SDimitry Andric size_type __old_sz = size(); 226906c3fb27SDimitry Andric size_type __old_start = __start_; 2270bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2271cb14a3feSDimitry Andric __alloc_traits::destroy( 2272cb14a3feSDimitry Andric __a, std::__to_address(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size)); 2273bdd1243dSDimitry Andric --__size(); 2274bdd1243dSDimitry Andric ++__start_; 227506c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2276e40139ffSDimitry Andric __maybe_remove_front_spare(); 22770b57cec5SDimitry Andric} 22780b57cec5SDimitry Andric 22790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2280cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::pop_back() { 228106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); 228206c3fb27SDimitry Andric size_type __old_sz = size(); 228306c3fb27SDimitry Andric size_type __old_start = __start_; 2284bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2285bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 2286cb14a3feSDimitry Andric __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() + __p / __block_size) + __p % __block_size)); 2287bdd1243dSDimitry Andric --__size(); 228806c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2289e40139ffSDimitry Andric __maybe_remove_back_spare(); 22900b57cec5SDimitry Andric} 22910b57cec5SDimitry Andric 22920b57cec5SDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)). 22930b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt. 22940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22950b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2296cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 22970b57cec5SDimitry Andric // as if 22980b57cec5SDimitry Andric // for (; __f != __l; ++__f, ++__r) 22995f757f3fSDimitry Andric // *__r = std::move(*__f); 23000b57cec5SDimitry Andric difference_type __n = __l - __f; 2301cb14a3feSDimitry Andric while (__n > 0) { 23020b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2303bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 23040b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 2305cb14a3feSDimitry Andric if (__bs > __n) { 23060b57cec5SDimitry Andric __bs = __n; 23070b57cec5SDimitry Andric __fe = __fb + __bs; 23080b57cec5SDimitry Andric } 23090b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 23100b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; 23115f757f3fSDimitry Andric __r = std::move(__fb, __fe, __r); 23120b57cec5SDimitry Andric __n -= __bs; 23130b57cec5SDimitry Andric __f += __bs; 23140b57cec5SDimitry Andric } 23150b57cec5SDimitry Andric return __r; 23160b57cec5SDimitry Andric} 23170b57cec5SDimitry Andric 23180b57cec5SDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards. 23190b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt. 23200b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 23210b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2322cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 23230b57cec5SDimitry Andric // as if 23240b57cec5SDimitry Andric // while (__f != __l) 23255f757f3fSDimitry Andric // *--__r = std::move(*--__l); 23260b57cec5SDimitry Andric difference_type __n = __l - __f; 2327cb14a3feSDimitry Andric while (__n > 0) { 23280b57cec5SDimitry Andric --__l; 23290b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 23300b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 23310b57cec5SDimitry Andric difference_type __bs = __le - __lb; 2332cb14a3feSDimitry Andric if (__bs > __n) { 23330b57cec5SDimitry Andric __bs = __n; 23340b57cec5SDimitry Andric __lb = __le - __bs; 23350b57cec5SDimitry Andric } 23360b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 23370b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; 23385f757f3fSDimitry Andric __r = std::move_backward(__lb, __le, __r); 23390b57cec5SDimitry Andric __n -= __bs; 23400b57cec5SDimitry Andric __l -= __bs - 1; 23410b57cec5SDimitry Andric } 23420b57cec5SDimitry Andric return __r; 23430b57cec5SDimitry Andric} 23440b57cec5SDimitry Andric 23450b57cec5SDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)). 23460b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt. 23470b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2348cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 2349bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 23500b57cec5SDimitry Andric // as if 2351bdd1243dSDimitry Andric // for (; __f != __l; ++__r, ++__f, ++__size()) 23525f757f3fSDimitry Andric // __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__f)); 23530b57cec5SDimitry Andric difference_type __n = __l - __f; 2354cb14a3feSDimitry Andric while (__n > 0) { 23550b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2356bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 23570b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 2358cb14a3feSDimitry Andric if (__bs > __n) { 23590b57cec5SDimitry Andric __bs = __n; 23600b57cec5SDimitry Andric __fe = __fb + __bs; 23610b57cec5SDimitry Andric } 23620b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 23630b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; 2364bdd1243dSDimitry Andric for (; __fb != __fe; ++__fb, ++__r, ++__size()) 23655f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__fb)); 23660b57cec5SDimitry Andric __n -= __bs; 23670b57cec5SDimitry Andric __f += __bs; 23680b57cec5SDimitry Andric } 23690b57cec5SDimitry Andric} 23700b57cec5SDimitry Andric 23710b57cec5SDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards. 23720b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt. 23730b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2374cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_construct_backward_and_check( 2375cb14a3feSDimitry Andric iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 2376bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 23770b57cec5SDimitry Andric // as if 23780b57cec5SDimitry Andric // for (iterator __j = __l; __j != __f;) 23790b57cec5SDimitry Andric // { 23805f757f3fSDimitry Andric // __alloc_traitsconstruct(__a, std::addressof(*--__r), std::move(*--__j)); 2381bdd1243dSDimitry Andric // --__start_; 2382bdd1243dSDimitry Andric // ++__size(); 23830b57cec5SDimitry Andric // } 23840b57cec5SDimitry Andric difference_type __n = __l - __f; 2385cb14a3feSDimitry Andric while (__n > 0) { 23860b57cec5SDimitry Andric --__l; 23870b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 23880b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 23890b57cec5SDimitry Andric difference_type __bs = __le - __lb; 2390cb14a3feSDimitry Andric if (__bs > __n) { 23910b57cec5SDimitry Andric __bs = __n; 23920b57cec5SDimitry Andric __lb = __le - __bs; 23930b57cec5SDimitry Andric } 23940b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 23950b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; 2396cb14a3feSDimitry Andric while (__le != __lb) { 23975f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__r), std::move(*--__le)); 2398bdd1243dSDimitry Andric --__start_; 2399bdd1243dSDimitry Andric ++__size(); 24000b57cec5SDimitry Andric } 24010b57cec5SDimitry Andric __n -= __bs; 24020b57cec5SDimitry Andric __l -= __bs - 1; 24030b57cec5SDimitry Andric } 24040b57cec5SDimitry Andric} 24050b57cec5SDimitry Andric 24060b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2407cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f) { 24080fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 24090fca6ea1SDimitry Andric __f != end(), "deque::erase(iterator) called with a non-dereferenceable iterator"); 241006c3fb27SDimitry Andric size_type __old_sz = size(); 241106c3fb27SDimitry Andric size_type __old_start = __start_; 2412bdd1243dSDimitry Andric iterator __b = begin(); 24130b57cec5SDimitry Andric difference_type __pos = __f - __b; 24140b57cec5SDimitry Andric iterator __p = __b + __pos; 2415bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2416cb14a3feSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - 1) / 2) { // erase from front 24175f757f3fSDimitry Andric std::move_backward(__b, __p, std::next(__p)); 24185f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2419bdd1243dSDimitry Andric --__size(); 2420bdd1243dSDimitry Andric ++__start_; 242106c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2422e40139ffSDimitry Andric __maybe_remove_front_spare(); 2423cb14a3feSDimitry Andric } else { // erase from back 24245f757f3fSDimitry Andric iterator __i = std::move(std::next(__p), end(), __p); 24255f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2426bdd1243dSDimitry Andric --__size(); 242706c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2428e40139ffSDimitry Andric __maybe_remove_back_spare(); 24290b57cec5SDimitry Andric } 2430bdd1243dSDimitry Andric return begin() + __pos; 24310b57cec5SDimitry Andric} 24320b57cec5SDimitry Andric 24330b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2434cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) { 24350fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__f <= __l, "deque::erase(first, last) called with an invalid range"); 243606c3fb27SDimitry Andric size_type __old_sz = size(); 243706c3fb27SDimitry Andric size_type __old_start = __start_; 24380b57cec5SDimitry Andric difference_type __n = __l - __f; 2439bdd1243dSDimitry Andric iterator __b = begin(); 24400b57cec5SDimitry Andric difference_type __pos = __f - __b; 24410b57cec5SDimitry Andric iterator __p = __b + __pos; 2442cb14a3feSDimitry Andric if (__n > 0) { 2443bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2444cb14a3feSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - __n) / 2) { // erase from front 24455f757f3fSDimitry Andric iterator __i = std::move_backward(__b, __p, __p + __n); 24460b57cec5SDimitry Andric for (; __b != __i; ++__b) 24475f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2448bdd1243dSDimitry Andric __size() -= __n; 2449bdd1243dSDimitry Andric __start_ += __n; 245006c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2451e40139ffSDimitry Andric while (__maybe_remove_front_spare()) { 24520b57cec5SDimitry Andric } 2453cb14a3feSDimitry Andric } else { // erase from back 24545f757f3fSDimitry Andric iterator __i = std::move(__p + __n, end(), __p); 2455bdd1243dSDimitry Andric for (iterator __e = end(); __i != __e; ++__i) 24565f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2457bdd1243dSDimitry Andric __size() -= __n; 245806c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2459e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 24600b57cec5SDimitry Andric } 24610b57cec5SDimitry Andric } 24620b57cec5SDimitry Andric } 2463bdd1243dSDimitry Andric return begin() + __pos; 24640b57cec5SDimitry Andric} 24650b57cec5SDimitry Andric 24660b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2467cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) { 246806c3fb27SDimitry Andric size_type __old_sz = size(); 246906c3fb27SDimitry Andric size_type __old_start = __start_; 2470bdd1243dSDimitry Andric iterator __e = end(); 24710b57cec5SDimitry Andric difference_type __n = __e - __f; 2472cb14a3feSDimitry Andric if (__n > 0) { 2473bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2474bdd1243dSDimitry Andric iterator __b = begin(); 24750b57cec5SDimitry Andric difference_type __pos = __f - __b; 24760b57cec5SDimitry Andric for (iterator __p = __b + __pos; __p != __e; ++__p) 24775f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__p)); 2478bdd1243dSDimitry Andric __size() -= __n; 247906c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2480e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 24810b57cec5SDimitry Andric } 24820b57cec5SDimitry Andric } 24830b57cec5SDimitry Andric} 24840b57cec5SDimitry Andric 24850b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2486cb14a3feSDimitry Andricinline void deque<_Tp, _Allocator>::swap(deque& __c) 24870b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 24880b57cec5SDimitry Andric _NOEXCEPT 24890b57cec5SDimitry Andric#else 24900fca6ea1SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) 24910b57cec5SDimitry Andric#endif 24920b57cec5SDimitry Andric{ 2493bdd1243dSDimitry Andric __map_.swap(__c.__map_); 24945f757f3fSDimitry Andric std::swap(__start_, __c.__start_); 24955f757f3fSDimitry Andric std::swap(__size(), __c.__size()); 24965f757f3fSDimitry Andric std::__swap_allocator(__alloc(), __c.__alloc()); 24970b57cec5SDimitry Andric} 24980b57cec5SDimitry Andric 24990b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2500cb14a3feSDimitry Andricinline void deque<_Tp, _Allocator>::clear() _NOEXCEPT { 250106c3fb27SDimitry Andric __annotate_delete(); 2502bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2503bdd1243dSDimitry Andric for (iterator __i = begin(), __e = end(); __i != __e; ++__i) 25045f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2505bdd1243dSDimitry Andric __size() = 0; 2506cb14a3feSDimitry Andric while (__map_.size() > 2) { 2507bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.front(), __block_size); 2508bdd1243dSDimitry Andric __map_.pop_front(); 2509bdd1243dSDimitry Andric } 2510cb14a3feSDimitry Andric switch (__map_.size()) { 2511bdd1243dSDimitry Andric case 1: 2512bdd1243dSDimitry Andric __start_ = __block_size / 2; 2513bdd1243dSDimitry Andric break; 2514bdd1243dSDimitry Andric case 2: 2515bdd1243dSDimitry Andric __start_ = __block_size; 2516bdd1243dSDimitry Andric break; 2517bdd1243dSDimitry Andric } 251806c3fb27SDimitry Andric __annotate_new(0); 25190b57cec5SDimitry Andric} 25200b57cec5SDimitry Andric 25210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2522cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25230b57cec5SDimitry Andric const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); 25245f757f3fSDimitry Andric return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); 25250b57cec5SDimitry Andric} 25260b57cec5SDimitry Andric 252706c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 252806c3fb27SDimitry Andric 25290b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2530cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25310b57cec5SDimitry Andric return !(__x == __y); 25320b57cec5SDimitry Andric} 25330b57cec5SDimitry Andric 25340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2535cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25365f757f3fSDimitry Andric return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 25370b57cec5SDimitry Andric} 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2540cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25410b57cec5SDimitry Andric return __y < __x; 25420b57cec5SDimitry Andric} 25430b57cec5SDimitry Andric 25440b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2545cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25460b57cec5SDimitry Andric return !(__x < __y); 25470b57cec5SDimitry Andric} 25480b57cec5SDimitry Andric 25490b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2550cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25510b57cec5SDimitry Andric return !(__y < __x); 25520b57cec5SDimitry Andric} 25530b57cec5SDimitry Andric 255406c3fb27SDimitry Andric#else // _LIBCPP_STD_VER <= 17 255506c3fb27SDimitry Andric 255606c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 255706c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> 255806c3fb27SDimitry Andricoperator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 2559*36b606aeSDimitry Andric return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); 256006c3fb27SDimitry Andric} 256106c3fb27SDimitry Andric 256206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER <= 17 256306c3fb27SDimitry Andric 25640b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2565cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) 2566cb14a3feSDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { 25670b57cec5SDimitry Andric __x.swap(__y); 25680b57cec5SDimitry Andric} 25690b57cec5SDimitry Andric 257006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 25710b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up> 2572bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 25735ffd83dbSDimitry Andricerase(deque<_Tp, _Allocator>& __c, const _Up& __v) { 25745ffd83dbSDimitry Andric auto __old_size = __c.size(); 25755f757f3fSDimitry Andric __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end()); 25765ffd83dbSDimitry Andric return __old_size - __c.size(); 25775ffd83dbSDimitry Andric} 25780b57cec5SDimitry Andric 25790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate> 2580bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 25815ffd83dbSDimitry Andricerase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) { 25825ffd83dbSDimitry Andric auto __old_size = __c.size(); 25835f757f3fSDimitry Andric __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end()); 25845ffd83dbSDimitry Andric return __old_size - __c.size(); 25855ffd83dbSDimitry Andric} 258681ad6265SDimitry Andric 258781ad6265SDimitry Andrictemplate <> 258881ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<char>> = true; 258981ad6265SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 259081ad6265SDimitry Andrictemplate <> 259181ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true; 25920b57cec5SDimitry Andric# endif 25930b57cec5SDimitry Andric 259406c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 25950b57cec5SDimitry Andric 25960b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 25970b57cec5SDimitry Andric 259806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 2599bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2600bdd1243dSDimitry Andricnamespace pmr { 2601bdd1243dSDimitry Andrictemplate <class _ValueT> 260206c3fb27SDimitry Andricusing deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>; 2603bdd1243dSDimitry Andric} // namespace pmr 2604bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD 2605bdd1243dSDimitry Andric#endif 2606bdd1243dSDimitry Andric 26070b57cec5SDimitry Andric_LIBCPP_POP_MACROS 26080b57cec5SDimitry Andric 2609bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 2610bdd1243dSDimitry Andric# include <algorithm> 2611bdd1243dSDimitry Andric# include <atomic> 2612bdd1243dSDimitry Andric# include <concepts> 261306c3fb27SDimitry Andric# include <cstdlib> 2614bdd1243dSDimitry Andric# include <functional> 2615bdd1243dSDimitry Andric# include <iosfwd> 2616bdd1243dSDimitry Andric# include <iterator> 261706c3fb27SDimitry Andric# include <type_traits> 2618bdd1243dSDimitry Andric# include <typeinfo> 2619bdd1243dSDimitry Andric#endif 2620bdd1243dSDimitry Andric 26210b57cec5SDimitry Andric#endif // _LIBCPP_DEQUE 2622