10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_DEQUE 110b57cec5SDimitry Andric#define _LIBCPP_DEQUE 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric deque synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std 170b57cec5SDimitry Andric{ 180b57cec5SDimitry Andric 190b57cec5SDimitry Andrictemplate <class T, class Allocator = allocator<T> > 200b57cec5SDimitry Andricclass deque 210b57cec5SDimitry Andric{ 220b57cec5SDimitry Andricpublic: 230b57cec5SDimitry Andric // types: 240b57cec5SDimitry Andric typedef T value_type; 250b57cec5SDimitry Andric typedef Allocator allocator_type; 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric typedef typename allocator_type::reference reference; 280b57cec5SDimitry Andric typedef typename allocator_type::const_reference const_reference; 290b57cec5SDimitry Andric typedef implementation-defined iterator; 300b57cec5SDimitry Andric typedef implementation-defined const_iterator; 310b57cec5SDimitry Andric typedef typename allocator_type::size_type size_type; 320b57cec5SDimitry Andric typedef typename allocator_type::difference_type difference_type; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric typedef typename allocator_type::pointer pointer; 350b57cec5SDimitry Andric typedef typename allocator_type::const_pointer const_pointer; 360b57cec5SDimitry Andric typedef std::reverse_iterator<iterator> reverse_iterator; 370b57cec5SDimitry Andric typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric // construct/copy/destroy: 400b57cec5SDimitry Andric deque() noexcept(is_nothrow_default_constructible<allocator_type>::value); 410b57cec5SDimitry Andric explicit deque(const allocator_type& a); 420b57cec5SDimitry Andric explicit deque(size_type n); 430b57cec5SDimitry Andric explicit deque(size_type n, const allocator_type& a); // C++14 440b57cec5SDimitry Andric deque(size_type n, const value_type& v); 450b57cec5SDimitry Andric deque(size_type n, const value_type& v, const allocator_type& a); 460b57cec5SDimitry Andric template <class InputIterator> 470b57cec5SDimitry Andric deque(InputIterator f, InputIterator l); 480b57cec5SDimitry Andric template <class InputIterator> 490b57cec5SDimitry Andric deque(InputIterator f, InputIterator l, const allocator_type& a); 5006c3fb27SDimitry Andric template<container-compatible-range<T> R> 5106c3fb27SDimitry Andric deque(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 520b57cec5SDimitry Andric deque(const deque& c); 530b57cec5SDimitry Andric deque(deque&& c) 540b57cec5SDimitry Andric noexcept(is_nothrow_move_constructible<allocator_type>::value); 550b57cec5SDimitry Andric deque(initializer_list<value_type> il, const Allocator& a = allocator_type()); 560b57cec5SDimitry Andric deque(const deque& c, const allocator_type& a); 570b57cec5SDimitry Andric deque(deque&& c, const allocator_type& a); 580b57cec5SDimitry Andric ~deque(); 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric deque& operator=(const deque& c); 610b57cec5SDimitry Andric deque& operator=(deque&& c) 620b57cec5SDimitry Andric noexcept( 630b57cec5SDimitry Andric allocator_type::propagate_on_container_move_assignment::value && 640b57cec5SDimitry Andric is_nothrow_move_assignable<allocator_type>::value); 650b57cec5SDimitry Andric deque& operator=(initializer_list<value_type> il); 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric template <class InputIterator> 680b57cec5SDimitry Andric void assign(InputIterator f, InputIterator l); 6906c3fb27SDimitry Andric template<container-compatible-range<T> R> 7006c3fb27SDimitry Andric void assign_range(R&& rg); // C++23 710b57cec5SDimitry Andric void assign(size_type n, const value_type& v); 720b57cec5SDimitry Andric void assign(initializer_list<value_type> il); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric allocator_type get_allocator() const noexcept; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric // iterators: 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric iterator begin() noexcept; 790b57cec5SDimitry Andric const_iterator begin() const noexcept; 800b57cec5SDimitry Andric iterator end() noexcept; 810b57cec5SDimitry Andric const_iterator end() const noexcept; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric reverse_iterator rbegin() noexcept; 840b57cec5SDimitry Andric const_reverse_iterator rbegin() const noexcept; 850b57cec5SDimitry Andric reverse_iterator rend() noexcept; 860b57cec5SDimitry Andric const_reverse_iterator rend() const noexcept; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric const_iterator cbegin() const noexcept; 890b57cec5SDimitry Andric const_iterator cend() const noexcept; 900b57cec5SDimitry Andric const_reverse_iterator crbegin() const noexcept; 910b57cec5SDimitry Andric const_reverse_iterator crend() const noexcept; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric // capacity: 940b57cec5SDimitry Andric size_type size() const noexcept; 950b57cec5SDimitry Andric size_type max_size() const noexcept; 960b57cec5SDimitry Andric void resize(size_type n); 970b57cec5SDimitry Andric void resize(size_type n, const value_type& v); 980b57cec5SDimitry Andric void shrink_to_fit(); 990b57cec5SDimitry Andric bool empty() const noexcept; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric // element access: 1020b57cec5SDimitry Andric reference operator[](size_type i); 1030b57cec5SDimitry Andric const_reference operator[](size_type i) const; 1040b57cec5SDimitry Andric reference at(size_type i); 1050b57cec5SDimitry Andric const_reference at(size_type i) const; 1060b57cec5SDimitry Andric reference front(); 1070b57cec5SDimitry Andric const_reference front() const; 1080b57cec5SDimitry Andric reference back(); 1090b57cec5SDimitry Andric const_reference back() const; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // modifiers: 1120b57cec5SDimitry Andric void push_front(const value_type& v); 1130b57cec5SDimitry Andric void push_front(value_type&& v); 11406c3fb27SDimitry Andric template<container-compatible-range<T> R> 11506c3fb27SDimitry Andric void prepend_range(R&& rg); // C++23 1160b57cec5SDimitry Andric void push_back(const value_type& v); 1170b57cec5SDimitry Andric void push_back(value_type&& v); 11806c3fb27SDimitry Andric template<container-compatible-range<T> R> 11906c3fb27SDimitry Andric void append_range(R&& rg); // C++23 1200b57cec5SDimitry Andric template <class... Args> reference emplace_front(Args&&... args); // reference in C++17 1210b57cec5SDimitry Andric template <class... Args> reference emplace_back(Args&&... args); // reference in C++17 1220b57cec5SDimitry Andric template <class... Args> iterator emplace(const_iterator p, Args&&... args); 1230b57cec5SDimitry Andric iterator insert(const_iterator p, const value_type& v); 1240b57cec5SDimitry Andric iterator insert(const_iterator p, value_type&& v); 1250b57cec5SDimitry Andric iterator insert(const_iterator p, size_type n, const value_type& v); 1260b57cec5SDimitry Andric template <class InputIterator> 1270b57cec5SDimitry Andric iterator insert(const_iterator p, InputIterator f, InputIterator l); 12806c3fb27SDimitry Andric template<container-compatible-range<T> R> 12906c3fb27SDimitry Andric iterator insert_range(const_iterator position, R&& rg); // C++23 1300b57cec5SDimitry Andric iterator insert(const_iterator p, initializer_list<value_type> il); 1310b57cec5SDimitry Andric void pop_front(); 1320b57cec5SDimitry Andric void pop_back(); 1330b57cec5SDimitry Andric iterator erase(const_iterator p); 1340b57cec5SDimitry Andric iterator erase(const_iterator f, const_iterator l); 1350b57cec5SDimitry Andric void swap(deque& c) 1360b57cec5SDimitry Andric noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17 1370b57cec5SDimitry Andric void clear() noexcept; 1380b57cec5SDimitry Andric}; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andrictemplate <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> 1410b57cec5SDimitry Andric deque(InputIterator, InputIterator, Allocator = Allocator()) 142349cc55cSDimitry Andric -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 1430b57cec5SDimitry Andric 14406c3fb27SDimitry Andrictemplate<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> 14506c3fb27SDimitry Andric deque(from_range_t, R&&, Allocator = Allocator()) 14606c3fb27SDimitry Andric -> deque<ranges::range_value_t<R>, Allocator>; // C++23 14706c3fb27SDimitry Andric 1480b57cec5SDimitry Andrictemplate <class T, class Allocator> 1490b57cec5SDimitry Andric bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y); 1500b57cec5SDimitry Andrictemplate <class T, class Allocator> 15106c3fb27SDimitry Andric bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1520b57cec5SDimitry Andrictemplate <class T, class Allocator> 15306c3fb27SDimitry Andric bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1540b57cec5SDimitry Andrictemplate <class T, class Allocator> 15506c3fb27SDimitry Andric bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1560b57cec5SDimitry Andrictemplate <class T, class Allocator> 15706c3fb27SDimitry Andric bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 1580b57cec5SDimitry Andrictemplate <class T, class Allocator> 15906c3fb27SDimitry Andric bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 16006c3fb27SDimitry Andrictemplate<class T, class Allocator> 16106c3fb27SDimitry Andric synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x, 16206c3fb27SDimitry Andric const deque<T, Allocator>& y); // since C++20 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric// specialized algorithms: 1650b57cec5SDimitry Andrictemplate <class T, class Allocator> 1660b57cec5SDimitry Andric void swap(deque<T,Allocator>& x, deque<T,Allocator>& y) 1670b57cec5SDimitry Andric noexcept(noexcept(x.swap(y))); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andrictemplate <class T, class Allocator, class U> 1705ffd83dbSDimitry Andric typename deque<T, Allocator>::size_type 1715ffd83dbSDimitry Andric erase(deque<T, Allocator>& c, const U& value); // C++20 1720b57cec5SDimitry Andrictemplate <class T, class Allocator, class Predicate> 1735ffd83dbSDimitry Andric typename deque<T, Allocator>::size_type 1745ffd83dbSDimitry Andric erase_if(deque<T, Allocator>& c, Predicate pred); // C++20 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric} // std 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric*/ 1790b57cec5SDimitry Andric 18081ad6265SDimitry Andric#include <__algorithm/copy.h> 18181ad6265SDimitry Andric#include <__algorithm/copy_backward.h> 18206c3fb27SDimitry Andric#include <__algorithm/copy_n.h> 18381ad6265SDimitry Andric#include <__algorithm/equal.h> 18481ad6265SDimitry Andric#include <__algorithm/fill_n.h> 18581ad6265SDimitry Andric#include <__algorithm/lexicographical_compare.h> 18606c3fb27SDimitry Andric#include <__algorithm/lexicographical_compare_three_way.h> 18781ad6265SDimitry Andric#include <__algorithm/min.h> 18881ad6265SDimitry Andric#include <__algorithm/remove.h> 18981ad6265SDimitry Andric#include <__algorithm/remove_if.h> 19081ad6265SDimitry Andric#include <__algorithm/unwrap_iter.h> 19181ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 19206c3fb27SDimitry Andric#include <__availability> 1930b57cec5SDimitry Andric#include <__config> 19481ad6265SDimitry Andric#include <__format/enable_insertable.h> 19506c3fb27SDimitry Andric#include <__iterator/distance.h> 196349cc55cSDimitry Andric#include <__iterator/iterator_traits.h> 19781ad6265SDimitry Andric#include <__iterator/next.h> 19881ad6265SDimitry Andric#include <__iterator/prev.h> 19981ad6265SDimitry Andric#include <__iterator/reverse_iterator.h> 200bdd1243dSDimitry Andric#include <__iterator/segmented_iterator.h> 20106c3fb27SDimitry Andric#include <__memory/addressof.h> 202bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h> 203bdd1243dSDimitry Andric#include <__memory/pointer_traits.h> 204bdd1243dSDimitry Andric#include <__memory/temp_value.h> 205bdd1243dSDimitry Andric#include <__memory/unique_ptr.h> 206bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h> 20706c3fb27SDimitry Andric#include <__ranges/access.h> 20806c3fb27SDimitry Andric#include <__ranges/concepts.h> 20906c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h> 21006c3fb27SDimitry Andric#include <__ranges/from_range.h> 21106c3fb27SDimitry Andric#include <__ranges/size.h> 2120b57cec5SDimitry Andric#include <__split_buffer> 213bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h> 21406c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 21506c3fb27SDimitry Andric#include <__type_traits/is_same.h> 21606c3fb27SDimitry Andric#include <__type_traits/type_identity.h> 217fe6060f1SDimitry Andric#include <__utility/forward.h> 21881ad6265SDimitry Andric#include <__utility/move.h> 21906c3fb27SDimitry Andric#include <__utility/pair.h> 22081ad6265SDimitry Andric#include <__utility/swap.h> 221fe6060f1SDimitry Andric#include <limits> 2220b57cec5SDimitry Andric#include <stdexcept> 2230b57cec5SDimitry Andric#include <version> 2240b57cec5SDimitry Andric 22581ad6265SDimitry Andric// standard-mandated includes 22681ad6265SDimitry Andric 22781ad6265SDimitry Andric// [iterator.range] 22881ad6265SDimitry Andric#include <__iterator/access.h> 22981ad6265SDimitry Andric#include <__iterator/data.h> 23081ad6265SDimitry Andric#include <__iterator/empty.h> 23181ad6265SDimitry Andric#include <__iterator/reverse_access.h> 23281ad6265SDimitry Andric#include <__iterator/size.h> 23381ad6265SDimitry Andric 23481ad6265SDimitry Andric// [deque.syn] 23581ad6265SDimitry Andric#include <compare> 23681ad6265SDimitry Andric#include <initializer_list> 23781ad6265SDimitry Andric 2380b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2390b57cec5SDimitry Andric# pragma GCC system_header 2400b57cec5SDimitry Andric#endif 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 2430b57cec5SDimitry Andric#include <__undef_macros> 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2460b57cec5SDimitry Andric 247*cb14a3feSDimitry Andrictemplate <class _Tp, class _Allocator = allocator<_Tp> > 248*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andrictemplate <class _ValueType, class _DiffType> 2510b57cec5SDimitry Andricstruct __deque_block_size { 2520b57cec5SDimitry Andric static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16; 2530b57cec5SDimitry Andric}; 2540b57cec5SDimitry Andric 255*cb14a3feSDimitry Andrictemplate <class _ValueType, 256*cb14a3feSDimitry Andric class _Pointer, 257*cb14a3feSDimitry Andric class _Reference, 258*cb14a3feSDimitry Andric class _MapPointer, 259*cb14a3feSDimitry Andric class _DiffType, 260*cb14a3feSDimitry Andric _DiffType _BS = 2610b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE 2620b57cec5SDimitry Andric // Keep template parameter to avoid changing all template declarations thoughout 2630b57cec5SDimitry Andric // this file. 2640b57cec5SDimitry Andric 0 2650b57cec5SDimitry Andric#else 2660b57cec5SDimitry Andric __deque_block_size<_ValueType, _DiffType>::value 2670b57cec5SDimitry Andric#endif 2680b57cec5SDimitry Andric > 269*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __deque_iterator { 2700b57cec5SDimitry Andric typedef _MapPointer __map_iterator; 271*cb14a3feSDimitry Andric 2720b57cec5SDimitry Andricpublic: 2730b57cec5SDimitry Andric typedef _Pointer pointer; 2740b57cec5SDimitry Andric typedef _DiffType difference_type; 275*cb14a3feSDimitry Andric 2760b57cec5SDimitry Andricprivate: 2770b57cec5SDimitry Andric __map_iterator __m_iter_; 2780b57cec5SDimitry Andric pointer __ptr_; 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric static const difference_type __block_size; 281*cb14a3feSDimitry Andric 2820b57cec5SDimitry Andricpublic: 2830b57cec5SDimitry Andric typedef _ValueType value_type; 2840b57cec5SDimitry Andric typedef random_access_iterator_tag iterator_category; 2850b57cec5SDimitry Andric typedef _Reference reference; 2860b57cec5SDimitry Andric 287bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT 28806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 289*cb14a3feSDimitry Andric : __m_iter_(nullptr), 290*cb14a3feSDimitry Andric __ptr_(nullptr) 2910b57cec5SDimitry Andric#endif 292*cb14a3feSDimitry Andric { 293*cb14a3feSDimitry Andric } 2940b57cec5SDimitry Andric 2955f757f3fSDimitry Andric template <class _Pp, class _Rp, class _MP, __enable_if_t<is_convertible<_Pp, pointer>::value, int> = 0> 296bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 2975f757f3fSDimitry Andric __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it) _NOEXCEPT 298*cb14a3feSDimitry Andric : __m_iter_(__it.__m_iter_), 299*cb14a3feSDimitry Andric __ptr_(__it.__ptr_) {} 3000b57cec5SDimitry Andric 301bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__ptr_; } 302bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return __ptr_; } 3030b57cec5SDimitry Andric 304*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++() { 305*cb14a3feSDimitry Andric if (++__ptr_ - *__m_iter_ == __block_size) { 3060b57cec5SDimitry Andric ++__m_iter_; 3070b57cec5SDimitry Andric __ptr_ = *__m_iter_; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric return *this; 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 312*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int) { 3130b57cec5SDimitry Andric __deque_iterator __tmp = *this; 3140b57cec5SDimitry Andric ++(*this); 3150b57cec5SDimitry Andric return __tmp; 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 318*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--() { 319*cb14a3feSDimitry Andric if (__ptr_ == *__m_iter_) { 3200b57cec5SDimitry Andric --__m_iter_; 3210b57cec5SDimitry Andric __ptr_ = *__m_iter_ + __block_size; 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric --__ptr_; 3240b57cec5SDimitry Andric return *this; 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 327*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int) { 3280b57cec5SDimitry Andric __deque_iterator __tmp = *this; 3290b57cec5SDimitry Andric --(*this); 3300b57cec5SDimitry Andric return __tmp; 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric 333*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n) { 334*cb14a3feSDimitry Andric if (__n != 0) { 3350b57cec5SDimitry Andric __n += __ptr_ - *__m_iter_; 336*cb14a3feSDimitry Andric if (__n > 0) { 3370b57cec5SDimitry Andric __m_iter_ += __n / __block_size; 3380b57cec5SDimitry Andric __ptr_ = *__m_iter_ + __n % __block_size; 339*cb14a3feSDimitry Andric } else // (__n < 0) 3400b57cec5SDimitry Andric { 3410b57cec5SDimitry Andric difference_type __z = __block_size - 1 - __n; 3420b57cec5SDimitry Andric __m_iter_ -= __z / __block_size; 3430b57cec5SDimitry Andric __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size); 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric return *this; 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 349*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n) { return *this += -__n; } 3500b57cec5SDimitry Andric 351*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const { 3520b57cec5SDimitry Andric __deque_iterator __t(*this); 3530b57cec5SDimitry Andric __t += __n; 3540b57cec5SDimitry Andric return __t; 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric 357*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const { 3580b57cec5SDimitry Andric __deque_iterator __t(*this); 3590b57cec5SDimitry Andric __t -= __n; 3600b57cec5SDimitry Andric return __t; 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 363*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) { 364*cb14a3feSDimitry Andric return __it + __n; 365*cb14a3feSDimitry Andric } 3660b57cec5SDimitry Andric 367*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) { 3680b57cec5SDimitry Andric if (__x != __y) 369*cb14a3feSDimitry Andric return (__x.__m_iter_ - __y.__m_iter_) * __block_size + (__x.__ptr_ - *__x.__m_iter_) - 370*cb14a3feSDimitry Andric (__y.__ptr_ - *__y.__m_iter_); 3710b57cec5SDimitry Andric return 0; 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 374*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const { return *(*this + __n); } 3750b57cec5SDimitry Andric 376*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) { 377*cb14a3feSDimitry Andric return __x.__ptr_ == __y.__ptr_; 378*cb14a3feSDimitry Andric } 3790b57cec5SDimitry Andric 380*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) { 381*cb14a3feSDimitry Andric return !(__x == __y); 382*cb14a3feSDimitry Andric } 3830b57cec5SDimitry Andric 384*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) { 385*cb14a3feSDimitry Andric return __x.__m_iter_ < __y.__m_iter_ || (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_); 386*cb14a3feSDimitry Andric } 3870b57cec5SDimitry Andric 388*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) { 389*cb14a3feSDimitry Andric return __y < __x; 390*cb14a3feSDimitry Andric } 3910b57cec5SDimitry Andric 392*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) { 393*cb14a3feSDimitry Andric return !(__y < __x); 394*cb14a3feSDimitry Andric } 3950b57cec5SDimitry Andric 396*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) { 397*cb14a3feSDimitry Andric return !(__x < __y); 398*cb14a3feSDimitry Andric } 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andricprivate: 401bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT 402*cb14a3feSDimitry Andric : __m_iter_(__m), 403*cb14a3feSDimitry Andric __ptr_(__p) {} 4040b57cec5SDimitry Andric 405*cb14a3feSDimitry Andric template <class _Tp, class _Ap> 406*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS deque; 4070b57cec5SDimitry Andric template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp> 4080b57cec5SDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __deque_iterator; 4090b57cec5SDimitry Andric 410bdd1243dSDimitry Andric template <class> 411bdd1243dSDimitry Andric friend struct __segmented_iterator_traits; 412bdd1243dSDimitry Andric}; 4130b57cec5SDimitry Andric 414bdd1243dSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 415bdd1243dSDimitry Andricstruct __segmented_iterator_traits< 416bdd1243dSDimitry Andric __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > { 417bdd1243dSDimitry Andricprivate: 418bdd1243dSDimitry Andric using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; 4190b57cec5SDimitry Andric 420bdd1243dSDimitry Andricpublic: 421bdd1243dSDimitry Andric using __is_segmented_iterator = true_type; 422bdd1243dSDimitry Andric using __segment_iterator = _MapPointer; 423bdd1243dSDimitry Andric using __local_iterator = _Pointer; 4240b57cec5SDimitry Andric 425bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } 426bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } 427bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; } 4280b57cec5SDimitry Andric 429bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) { 430bdd1243dSDimitry Andric return *__iter + _Iterator::__block_size; 431bdd1243dSDimitry Andric } 4320b57cec5SDimitry Andric 433bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) { 4345f757f3fSDimitry Andric if (__segment && __local == __end(__segment)) { 435bdd1243dSDimitry Andric ++__segment; 436bdd1243dSDimitry Andric return _Iterator(__segment, *__segment); 437bdd1243dSDimitry Andric } 438bdd1243dSDimitry Andric return _Iterator(__segment, __local); 439bdd1243dSDimitry Andric } 4400b57cec5SDimitry Andric}; 4410b57cec5SDimitry Andric 442*cb14a3feSDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize> 443*cb14a3feSDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>::__block_size = 4440b57cec5SDimitry Andric __deque_block_size<_ValueType, _DiffType>::value; 4450b57cec5SDimitry Andric 446bdd1243dSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/> 447*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque { 4480b57cec5SDimitry Andricpublic: 449bdd1243dSDimitry Andric // types: 450e40139ffSDimitry Andric 451bdd1243dSDimitry Andric using value_type = _Tp; 4520b57cec5SDimitry Andric 453bdd1243dSDimitry Andric static_assert((is_same<typename _Allocator::value_type, value_type>::value), 454bdd1243dSDimitry Andric "Allocator::value_type must be same type as value_type"); 4550b57cec5SDimitry Andric 456bdd1243dSDimitry Andric using allocator_type = _Allocator; 457bdd1243dSDimitry Andric using __alloc_traits = allocator_traits<allocator_type>; 4580b57cec5SDimitry Andric 459bdd1243dSDimitry Andric using size_type = typename __alloc_traits::size_type; 460bdd1243dSDimitry Andric using difference_type = typename __alloc_traits::difference_type; 4610b57cec5SDimitry Andric 462bdd1243dSDimitry Andric using pointer = typename __alloc_traits::pointer; 463bdd1243dSDimitry Andric using const_pointer = typename __alloc_traits::const_pointer; 464bdd1243dSDimitry Andric 465bdd1243dSDimitry Andric using __pointer_allocator = __rebind_alloc<__alloc_traits, pointer>; 466bdd1243dSDimitry Andric using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>; 467bdd1243dSDimitry Andric using __map = __split_buffer<pointer, __pointer_allocator>; 468bdd1243dSDimitry Andric using __map_alloc_traits = allocator_traits<__pointer_allocator>; 469bdd1243dSDimitry Andric using __map_pointer = typename __map_alloc_traits::pointer; 470bdd1243dSDimitry Andric using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer; 47106c3fb27SDimitry Andric using __map_const_iterator = typename __map::const_iterator; 472bdd1243dSDimitry Andric 473bdd1243dSDimitry Andric using reference = value_type&; 474bdd1243dSDimitry Andric using const_reference = const value_type&; 475bdd1243dSDimitry Andric 476bdd1243dSDimitry Andric using iterator = __deque_iterator<value_type, pointer, reference, __map_pointer, difference_type>; 477bdd1243dSDimitry Andric using const_iterator = 478bdd1243dSDimitry Andric __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer, difference_type>; 479bdd1243dSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 480bdd1243dSDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>; 481bdd1243dSDimitry Andric 482bdd1243dSDimitry Andric static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value, 483bdd1243dSDimitry Andric "[allocator.requirements] states that rebinding an allocator to the same type should result in the " 484bdd1243dSDimitry Andric "original allocator"); 485bdd1243dSDimitry Andric static_assert(is_nothrow_default_constructible<allocator_type>::value == 486bdd1243dSDimitry Andric is_nothrow_default_constructible<__pointer_allocator>::value, 487bdd1243dSDimitry Andric "rebinding an allocator should not change excpetion guarantees"); 488bdd1243dSDimitry Andric static_assert(is_nothrow_move_constructible<allocator_type>::value == 489bdd1243dSDimitry Andric is_nothrow_move_constructible<typename __map::allocator_type>::value, 490bdd1243dSDimitry Andric "rebinding an allocator should not change excpetion guarantees"); 491bdd1243dSDimitry Andric 492bdd1243dSDimitry Andricprivate: 493e40139ffSDimitry Andric struct __deque_block_range { 494*cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI __deque_block_range(pointer __b, pointer __e) _NOEXCEPT 495*cb14a3feSDimitry Andric : __begin_(__b), 496*cb14a3feSDimitry Andric __end_(__e) {} 497e40139ffSDimitry Andric const pointer __begin_; 498e40139ffSDimitry Andric const pointer __end_; 499e40139ffSDimitry Andric }; 500e40139ffSDimitry Andric 501e40139ffSDimitry Andric struct __deque_range { 502e40139ffSDimitry Andric iterator __pos_; 503e40139ffSDimitry Andric const iterator __end_; 504e40139ffSDimitry Andric 505*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range(iterator __pos, iterator __e) _NOEXCEPT : __pos_(__pos), __end_(__e) {} 506e40139ffSDimitry Andric 507*cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { return __pos_ != __end_; } 508e40139ffSDimitry Andric 509*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range begin() const { return *this; } 510e40139ffSDimitry Andric 511*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range end() const { return __deque_range(__end_, __end_); } 512bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_block_range operator*() const _NOEXCEPT { 513e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 514e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, __end_.__ptr_); 515e40139ffSDimitry Andric } 516e40139ffSDimitry Andric return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size); 517e40139ffSDimitry Andric } 518e40139ffSDimitry Andric 519bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI __deque_range& operator++() _NOEXCEPT { 520e40139ffSDimitry Andric if (__pos_.__m_iter_ == __end_.__m_iter_) { 521e40139ffSDimitry Andric __pos_ = __end_; 522e40139ffSDimitry Andric } else { 523e40139ffSDimitry Andric ++__pos_.__m_iter_; 524e40139ffSDimitry Andric __pos_.__ptr_ = *__pos_.__m_iter_; 525e40139ffSDimitry Andric } 526e40139ffSDimitry Andric return *this; 527e40139ffSDimitry Andric } 528e40139ffSDimitry Andric 529bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) { 530e40139ffSDimitry Andric return __lhs.__pos_ == __rhs.__pos_; 531e40139ffSDimitry Andric } 532bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) { 533e40139ffSDimitry Andric return !(__lhs == __rhs); 534e40139ffSDimitry Andric } 535e40139ffSDimitry Andric }; 536e40139ffSDimitry Andric 537e40139ffSDimitry Andric struct _ConstructTransaction { 538bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _ConstructTransaction(deque* __db, __deque_block_range& __r) 539e40139ffSDimitry Andric : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} 540e40139ffSDimitry Andric 541*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { __base_->__size() += (__pos_ - __begin_); } 542e40139ffSDimitry Andric 543e40139ffSDimitry Andric pointer __pos_; 544e40139ffSDimitry Andric const pointer __end_; 545*cb14a3feSDimitry Andric 546e40139ffSDimitry Andric private: 547e40139ffSDimitry Andric const pointer __begin_; 548bdd1243dSDimitry Andric deque* const __base_; 549e40139ffSDimitry Andric }; 550e40139ffSDimitry Andric 551bdd1243dSDimitry Andric static const difference_type __block_size; 552bdd1243dSDimitry Andric 5530b57cec5SDimitry Andric __map __map_; 5540b57cec5SDimitry Andric size_type __start_; 5550b57cec5SDimitry Andric __compressed_pair<size_type, allocator_type> __size_; 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andricpublic: 558bdd1243dSDimitry Andric // construct/copy/destroy: 559*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 56006c3fb27SDimitry Andric : __start_(0), __size_(0, __default_init_tag()) { 56106c3fb27SDimitry Andric __annotate_new(0); 56206c3fb27SDimitry Andric } 563bdd1243dSDimitry Andric 564bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~deque() { 565bdd1243dSDimitry Andric clear(); 56606c3fb27SDimitry Andric __annotate_delete(); 567bdd1243dSDimitry Andric typename __map::iterator __i = __map_.begin(); 568bdd1243dSDimitry Andric typename __map::iterator __e = __map_.end(); 569bdd1243dSDimitry Andric for (; __i != __e; ++__i) 570bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), *__i, __block_size); 571bdd1243dSDimitry Andric } 572bdd1243dSDimitry Andric 573bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) 57406c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 57506c3fb27SDimitry Andric __annotate_new(0); 57606c3fb27SDimitry Andric } 577bdd1243dSDimitry Andric 578bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); 57906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 580bdd1243dSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); 581bdd1243dSDimitry Andric#endif 582bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); 583bdd1243dSDimitry Andric 584bdd1243dSDimitry Andric template <class = __enable_if_t<__is_allocator<_Allocator>::value> > 585bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) 586*cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 58706c3fb27SDimitry Andric __annotate_new(0); 588bdd1243dSDimitry Andric if (__n > 0) 589bdd1243dSDimitry Andric __append(__n, __v); 590bdd1243dSDimitry Andric } 591bdd1243dSDimitry Andric 5925f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 5935f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l); 5945f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 5955f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a); 59606c3fb27SDimitry Andric 59706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 59806c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 599*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) 60006c3fb27SDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 60106c3fb27SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 60206c3fb27SDimitry Andric __append_with_size(ranges::begin(__range), ranges::distance(__range)); 60306c3fb27SDimitry Andric 60406c3fb27SDimitry Andric } else { 60506c3fb27SDimitry Andric for (auto&& __e : __range) { 60606c3fb27SDimitry Andric emplace_back(std::forward<decltype(__e)>(__e)); 60706c3fb27SDimitry Andric } 60806c3fb27SDimitry Andric } 60906c3fb27SDimitry Andric } 61006c3fb27SDimitry Andric#endif 61106c3fb27SDimitry Andric 612bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); 613bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); 614bdd1243dSDimitry Andric 615bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(const deque& __c); 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 618bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il); 619bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(initializer_list<value_type> __il, const allocator_type& __a); 620bdd1243dSDimitry Andric 621*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(initializer_list<value_type> __il) { 622*cb14a3feSDimitry Andric assign(__il); 623*cb14a3feSDimitry Andric return *this; 624*cb14a3feSDimitry Andric } 625bdd1243dSDimitry Andric 626*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); 627*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque(deque&& __c, const __type_identity_t<allocator_type>& __a); 628*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI deque& operator=(deque&& __c) 629bdd1243dSDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value&& 630bdd1243dSDimitry Andric is_nothrow_move_assignable<allocator_type>::value); 631bdd1243dSDimitry Andric 632*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il) { assign(__il.begin(), __il.end()); } 6330b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 6340b57cec5SDimitry Andric 635*cb14a3feSDimitry Andric template <class _InputIter, 636*cb14a3feSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIter>::value && 637*cb14a3feSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, 638*cb14a3feSDimitry Andric int> = 0> 6395f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l); 6405f757f3fSDimitry Andric template <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> = 0> 6415f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l); 64206c3fb27SDimitry Andric 64306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 64406c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 645*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) { 64606c3fb27SDimitry Andric if constexpr (ranges::random_access_range<_Range>) { 64706c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 64806c3fb27SDimitry Andric __assign_with_size_random_access(ranges::begin(__range), __n); 64906c3fb27SDimitry Andric 65006c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 65106c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 65206c3fb27SDimitry Andric __assign_with_size(ranges::begin(__range), __n); 65306c3fb27SDimitry Andric 65406c3fb27SDimitry Andric } else { 65506c3fb27SDimitry Andric __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 65606c3fb27SDimitry Andric } 65706c3fb27SDimitry Andric } 65806c3fb27SDimitry Andric#endif 65906c3fb27SDimitry Andric 660bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); 661bdd1243dSDimitry Andric 662*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; 663bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __size_.second(); } 664bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __size_.second(); } 665bdd1243dSDimitry Andric 666bdd1243dSDimitry Andric // iterators: 667bdd1243dSDimitry Andric 668bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { 669bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __start_ / __block_size; 670bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 671bdd1243dSDimitry Andric } 672bdd1243dSDimitry Andric 673bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { 674*cb14a3feSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); 675bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); 676bdd1243dSDimitry Andric } 677bdd1243dSDimitry Andric 678bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { 679bdd1243dSDimitry Andric size_type __p = size() + __start_; 680bdd1243dSDimitry Andric __map_pointer __mp = __map_.begin() + __p / __block_size; 681bdd1243dSDimitry Andric return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 682bdd1243dSDimitry Andric } 683bdd1243dSDimitry Andric 684bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { 685bdd1243dSDimitry Andric size_type __p = size() + __start_; 686bdd1243dSDimitry Andric __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); 687bdd1243dSDimitry Andric return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); 688bdd1243dSDimitry Andric } 689bdd1243dSDimitry Andric 690*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } 691*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 692*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } 693*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 694bdd1243dSDimitry Andric 695*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } 696*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } 697*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 698*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 699bdd1243dSDimitry Andric 700bdd1243dSDimitry Andric // capacity: 701*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); } 702bdd1243dSDimitry Andric 703bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_.first(); } 704bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_.first(); } 705bdd1243dSDimitry Andric 706*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { 707*cb14a3feSDimitry Andric return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max()); 708*cb14a3feSDimitry Andric } 709bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); 710bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); 711bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; 712*cb14a3feSDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; } 713bdd1243dSDimitry Andric 714bdd1243dSDimitry Andric // element access: 715*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT; 716*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT; 717*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference at(size_type __i); 718*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const; 719*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT; 720*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT; 721*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT; 722*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT; 723bdd1243dSDimitry Andric 724bdd1243dSDimitry Andric // 23.2.2.3 modifiers: 725bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); 726bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); 727bdd1243dSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 72806c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 729*cb14a3feSDimitry Andric template <class... _Args> 730*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); 731*cb14a3feSDimitry Andric template <class... _Args> 732*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args); 733bdd1243dSDimitry Andric# else 734*cb14a3feSDimitry Andric template <class... _Args> 735*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); 736*cb14a3feSDimitry Andric template <class... _Args> 737*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args); 738bdd1243dSDimitry Andric# endif 739*cb14a3feSDimitry Andric template <class... _Args> 740*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); 741bdd1243dSDimitry Andric 742bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); 743bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v); 74406c3fb27SDimitry Andric 74506c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 23 74606c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 747*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) { 74806c3fb27SDimitry Andric insert_range(begin(), std::forward<_Range>(__range)); 74906c3fb27SDimitry Andric } 75006c3fb27SDimitry Andric 75106c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 752*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void append_range(_Range&& __range) { 75306c3fb27SDimitry Andric insert_range(end(), std::forward<_Range>(__range)); 75406c3fb27SDimitry Andric } 75506c3fb27SDimitry Andric# endif 75606c3fb27SDimitry Andric 757bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v); 758bdd1243dSDimitry Andric 759*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, initializer_list<value_type> __il) { 760*cb14a3feSDimitry Andric return insert(__p, __il.begin(), __il.end()); 761*cb14a3feSDimitry Andric } 762bdd1243dSDimitry Andric#endif // _LIBCPP_CXX03_LANG 763bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v); 764bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); 7655f757f3fSDimitry Andric template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0> 7665f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l); 767*cb14a3feSDimitry Andric template <class _ForwardIterator, 768*cb14a3feSDimitry Andric __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> = 0> 7695f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l); 7705f757f3fSDimitry Andric template <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> = 0> 7715f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l); 77206c3fb27SDimitry Andric 77306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 77406c3fb27SDimitry Andric template <_ContainerCompatibleRange<_Tp> _Range> 775*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert_range(const_iterator __position, _Range&& __range) { 77606c3fb27SDimitry Andric if constexpr (ranges::bidirectional_range<_Range>) { 77706c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 77806c3fb27SDimitry Andric return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n); 77906c3fb27SDimitry Andric 78006c3fb27SDimitry Andric } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 78106c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 78206c3fb27SDimitry Andric return __insert_with_size(__position, ranges::begin(__range), __n); 78306c3fb27SDimitry Andric 78406c3fb27SDimitry Andric } else { 78506c3fb27SDimitry Andric return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); 78606c3fb27SDimitry Andric } 78706c3fb27SDimitry Andric } 78806c3fb27SDimitry Andric#endif 789bdd1243dSDimitry Andric 790bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_front(); 791bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void pop_back(); 792bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); 793bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); 794bdd1243dSDimitry Andric 795*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(deque& __c) 7960b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 7970b57cec5SDimitry Andric _NOEXCEPT; 7980b57cec5SDimitry Andric#else 799*cb14a3feSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); 8000b57cec5SDimitry Andric#endif 801*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; 8020b57cec5SDimitry Andric 803*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __invariants() const { 8040b57cec5SDimitry Andric if (!__map_.__invariants()) 8050b57cec5SDimitry Andric return false; 8060b57cec5SDimitry Andric if (__map_.size() >= size_type(-1) / __block_size) 8070b57cec5SDimitry Andric return false; 808*cb14a3feSDimitry Andric for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); __i != __e; ++__i) 8090b57cec5SDimitry Andric if (*__i == nullptr) 8100b57cec5SDimitry Andric return false; 811*cb14a3feSDimitry Andric if (__map_.size() != 0) { 8120b57cec5SDimitry Andric if (size() >= __map_.size() * __block_size) 8130b57cec5SDimitry Andric return false; 8140b57cec5SDimitry Andric if (__start_ >= __map_.size() * __block_size - size()) 8150b57cec5SDimitry Andric return false; 816*cb14a3feSDimitry Andric } else { 8170b57cec5SDimitry Andric if (size() != 0) 8180b57cec5SDimitry Andric return false; 8190b57cec5SDimitry Andric if (__start_ != 0) 8200b57cec5SDimitry Andric return false; 8210b57cec5SDimitry Andric } 8220b57cec5SDimitry Andric return true; 8230b57cec5SDimitry Andric } 8240b57cec5SDimitry Andric 825*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c) 826bdd1243dSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || 827*cb14a3feSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 828*cb14a3feSDimitry Andric __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 829*cb14a3feSDimitry Andric } 830bdd1243dSDimitry Andric 831*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque& __c, true_type) 832*cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 8335f757f3fSDimitry Andric __alloc() = std::move(__c.__alloc()); 8340b57cec5SDimitry Andric } 8350b57cec5SDimitry Andric 836*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(deque&, false_type) _NOEXCEPT {} 8374824e7fdSDimitry Andric 838*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c) 839bdd1243dSDimitry Andric _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value&& 840*cb14a3feSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 8415f757f3fSDimitry Andric __map_ = std::move(__c.__map_); 842bdd1243dSDimitry Andric __start_ = __c.__start_; 843bdd1243dSDimitry Andric __size() = __c.size(); 844bdd1243dSDimitry Andric __move_assign_alloc(__c); 845bdd1243dSDimitry Andric __c.__start_ = __c.__size() = 0; 8464824e7fdSDimitry Andric } 8474824e7fdSDimitry Andric 848*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static size_type __recommend_blocks(size_type __n) { 849bdd1243dSDimitry Andric return __n / __block_size + (__n % __block_size != 0); 8500b57cec5SDimitry Andric } 851*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __capacity() const { 852bdd1243dSDimitry Andric return __map_.size() == 0 ? 0 : __map_.size() * __block_size - 1; 8530b57cec5SDimitry Andric } 854*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __block_count() const { return __map_.size(); } 855e40139ffSDimitry Andric 856*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const { return __start_; } 857*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __front_spare_blocks() const { return __front_spare() / __block_size; } 858*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const { return __capacity() - (__start_ + size()); } 859*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __back_spare_blocks() const { return __back_spare() / __block_size; } 860e40139ffSDimitry Andric 861e40139ffSDimitry Andricprivate: 862*cb14a3feSDimitry Andric enum __asan_annotation_type { __asan_unposion, __asan_poison }; 86306c3fb27SDimitry Andric 86406c3fb27SDimitry Andric enum __asan_annotation_place { 86506c3fb27SDimitry Andric __asan_front_moved, 86606c3fb27SDimitry Andric __asan_back_moved, 86706c3fb27SDimitry Andric }; 86806c3fb27SDimitry Andric 86906c3fb27SDimitry Andric // The following functions are no-ops outside of AddressSanitizer mode. 87006c3fb27SDimitry Andric // We call annotations for every allocator, unless explicitly disabled. 87106c3fb27SDimitry Andric // 87206c3fb27SDimitry Andric // To disable annotations for a particular allocator, change value of 87306c3fb27SDimitry Andric // __asan_annotate_container_with_allocator to false. 87406c3fb27SDimitry Andric // For more details, see the "Using libc++" documentation page or 87506c3fb27SDimitry Andric // the documentation for __sanitizer_annotate_contiguous_container. 87606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( 87706c3fb27SDimitry Andric const void* __beg, 87806c3fb27SDimitry Andric const void* __end, 87906c3fb27SDimitry Andric const void* __old_con_beg, 88006c3fb27SDimitry Andric const void* __old_con_end, 88106c3fb27SDimitry Andric const void* __new_con_beg, 88206c3fb27SDimitry Andric const void* __new_con_end) const { 8835f757f3fSDimitry Andric (void)__beg; 8845f757f3fSDimitry Andric (void)__end; 8855f757f3fSDimitry Andric (void)__old_con_beg; 8865f757f3fSDimitry Andric (void)__old_con_end; 8875f757f3fSDimitry Andric (void)__new_con_beg; 8885f757f3fSDimitry Andric (void)__new_con_end; 8895f757f3fSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 89006c3fb27SDimitry Andric if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value) 89106c3fb27SDimitry Andric __sanitizer_annotate_double_ended_contiguous_container( 89206c3fb27SDimitry Andric __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end); 8935f757f3fSDimitry Andric#endif 89406c3fb27SDimitry Andric } 89506c3fb27SDimitry Andric 896*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_from_to( 8975f757f3fSDimitry Andric size_type __beg, 8985f757f3fSDimitry Andric size_type __end, 8995f757f3fSDimitry Andric __asan_annotation_type __annotation_type, 9005f757f3fSDimitry Andric __asan_annotation_place __place) const _NOEXCEPT { 9015f757f3fSDimitry Andric (void)__beg; 9025f757f3fSDimitry Andric (void)__end; 9035f757f3fSDimitry Andric (void)__annotation_type; 9045f757f3fSDimitry Andric (void)__place; 9055f757f3fSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 90606c3fb27SDimitry Andric // __beg - index of the first item to annotate 90706c3fb27SDimitry Andric // __end - index behind the last item to annotate (so last item + 1) 90806c3fb27SDimitry Andric // __annotation_type - __asan_unposion or __asan_poison 90906c3fb27SDimitry Andric // __place - __asan_front_moved or __asan_back_moved 91006c3fb27SDimitry Andric // Note: All indexes in __map_ 91106c3fb27SDimitry Andric if (__beg == __end) 91206c3fb27SDimitry Andric return; 91306c3fb27SDimitry Andric // __annotations_beg_map - first chunk which annotations we want to modify 91406c3fb27SDimitry Andric // __annotations_end_map - last chunk which annotations we want to modify 91506c3fb27SDimitry Andric // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist 91606c3fb27SDimitry Andric __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; 91706c3fb27SDimitry Andric __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; 91806c3fb27SDimitry Andric 91906c3fb27SDimitry Andric bool const __poisoning = __annotation_type == __asan_poison; 92006c3fb27SDimitry Andric // __old_c_beg_index - index of the first element in old container 92106c3fb27SDimitry Andric // __old_c_end_index - index of the end of old container (last + 1) 92206c3fb27SDimitry Andric // Note: may be outside the area we are annotating 92306c3fb27SDimitry Andric size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; 92406c3fb27SDimitry Andric size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); 92506c3fb27SDimitry Andric bool const __front = __place == __asan_front_moved; 92606c3fb27SDimitry Andric 92706c3fb27SDimitry Andric if (__poisoning && empty()) { 92806c3fb27SDimitry Andric // Special case: we shouldn't trust __start_ 92906c3fb27SDimitry Andric __old_c_beg_index = __beg; 93006c3fb27SDimitry Andric __old_c_end_index = __end; 93106c3fb27SDimitry Andric } 93206c3fb27SDimitry Andric // __old_c_beg_map - memory block (chunk) with first element 93306c3fb27SDimitry Andric // __old_c_end_map - memory block (chunk) with end of old container 93406c3fb27SDimitry Andric // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, 93506c3fb27SDimitry Andric // which may not exist 93606c3fb27SDimitry Andric __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; 93706c3fb27SDimitry Andric __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; 93806c3fb27SDimitry Andric 93906c3fb27SDimitry Andric // One edge (front/end) of the container was moved and one was not modified. 94006c3fb27SDimitry Andric // __new_edge_index - index of new edge 94106c3fb27SDimitry Andric // __new_edge_map - memory block (chunk) with new edge, it always equals to 94206c3fb27SDimitry Andric // __annotations_beg_map or __annotations_end_map 94306c3fb27SDimitry Andric // __old_edge_map - memory block (chunk) with old edge, it always equals to 94406c3fb27SDimitry Andric // __old_c_beg_map or __old_c_end_map 94506c3fb27SDimitry Andric size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; 94606c3fb27SDimitry Andric __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; 94706c3fb27SDimitry Andric __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; 94806c3fb27SDimitry Andric 94906c3fb27SDimitry Andric // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. 95006c3fb27SDimitry Andric // First and last chunk may be partially poisoned. 95106c3fb27SDimitry Andric // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. 95206c3fb27SDimitry Andric for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { 95306c3fb27SDimitry Andric if (__map_it == __annotations_end_map && __end % __block_size == 0) 95406c3fb27SDimitry Andric // Chunk may not exist, but nothing to do here anyway 95506c3fb27SDimitry Andric break; 95606c3fb27SDimitry Andric 95706c3fb27SDimitry Andric // The beginning and the end of the current memory block 95806c3fb27SDimitry Andric const void* __mem_beg = std::__to_address(*__map_it); 95906c3fb27SDimitry Andric const void* __mem_end = std::__to_address(*__map_it + __block_size); 96006c3fb27SDimitry Andric 96106c3fb27SDimitry Andric // The beginning of memory-in-use in the memory block before container modification 96206c3fb27SDimitry Andric const void* __old_beg = 96306c3fb27SDimitry Andric (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; 96406c3fb27SDimitry Andric 96506c3fb27SDimitry Andric // The end of memory-in-use in the memory block before container modification 96606c3fb27SDimitry Andric const void* __old_end; 96706c3fb27SDimitry Andric if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) 96806c3fb27SDimitry Andric __old_end = __old_beg; 96906c3fb27SDimitry Andric else 970*cb14a3feSDimitry Andric __old_end = (__map_it == __old_c_end_map) 971*cb14a3feSDimitry Andric ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) 97206c3fb27SDimitry Andric : __mem_end; 97306c3fb27SDimitry Andric 97406c3fb27SDimitry Andric // New edge of the container in current memory block 97506c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 97606c3fb27SDimitry Andric const void* __new_edge; 97706c3fb27SDimitry Andric if (__map_it == __new_edge_map) 97806c3fb27SDimitry Andric __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); 97906c3fb27SDimitry Andric else 98006c3fb27SDimitry Andric __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; 98106c3fb27SDimitry Andric 98206c3fb27SDimitry Andric // Not modified edge of the container 98306c3fb27SDimitry Andric // If the edge is in a different chunk it points on corresponding end of the memory block 98406c3fb27SDimitry Andric const void* __old_edge; 98506c3fb27SDimitry Andric if (__map_it == __old_edge_map) 98606c3fb27SDimitry Andric __old_edge = __front ? __old_end : __old_beg; 98706c3fb27SDimitry Andric else 98806c3fb27SDimitry Andric __old_edge = __front ? __mem_end : __mem_beg; 98906c3fb27SDimitry Andric 99006c3fb27SDimitry Andric // __new_beg - the beginning of memory-in-use in the memory block after container modification 99106c3fb27SDimitry Andric // __new_end - the end of memory-in-use in the memory block after container modification 99206c3fb27SDimitry Andric const void* __new_beg = __front ? __new_edge : __old_edge; 99306c3fb27SDimitry Andric const void* __new_end = __front ? __old_edge : __new_edge; 99406c3fb27SDimitry Andric 99506c3fb27SDimitry Andric __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); 99606c3fb27SDimitry Andric } 9975f757f3fSDimitry Andric#endif // !_LIBCPP_HAS_NO_ASAN 99806c3fb27SDimitry Andric } 99906c3fb27SDimitry Andric 1000*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT { 1001*cb14a3feSDimitry Andric (void)__current_size; 1002*cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 100306c3fb27SDimitry Andric if (__current_size == 0) 100406c3fb27SDimitry Andric __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 100506c3fb27SDimitry Andric else { 100606c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); 100706c3fb27SDimitry Andric __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); 100806c3fb27SDimitry Andric } 1009*cb14a3feSDimitry Andric#endif 101006c3fb27SDimitry Andric } 101106c3fb27SDimitry Andric 1012*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT { 1013*cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 101406c3fb27SDimitry Andric if (empty()) { 101506c3fb27SDimitry Andric for (size_t __i = 0; __i < __map_.size(); ++__i) { 101606c3fb27SDimitry Andric __annotate_whole_block(__i, __asan_unposion); 101706c3fb27SDimitry Andric } 1018*cb14a3feSDimitry Andric } else { 101906c3fb27SDimitry Andric __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); 102006c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); 102106c3fb27SDimitry Andric } 1022*cb14a3feSDimitry Andric#endif 102306c3fb27SDimitry Andric } 102406c3fb27SDimitry Andric 1025*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_increase_front(size_type __n) const _NOEXCEPT { 1026*cb14a3feSDimitry Andric (void)__n; 1027*cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 102806c3fb27SDimitry Andric __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); 1029*cb14a3feSDimitry Andric#endif 103006c3fb27SDimitry Andric } 103106c3fb27SDimitry Andric 1032*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_increase_back(size_type __n) const _NOEXCEPT { 1033*cb14a3feSDimitry Andric (void)__n; 1034*cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 103506c3fb27SDimitry Andric __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); 1036*cb14a3feSDimitry Andric#endif 103706c3fb27SDimitry Andric } 103806c3fb27SDimitry Andric 1039*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { 1040*cb14a3feSDimitry Andric (void)__old_size; 1041*cb14a3feSDimitry Andric (void)__old_start; 1042*cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 104306c3fb27SDimitry Andric __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); 1044*cb14a3feSDimitry Andric#endif 104506c3fb27SDimitry Andric } 104606c3fb27SDimitry Andric 1047*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { 1048*cb14a3feSDimitry Andric (void)__old_size; 1049*cb14a3feSDimitry Andric (void)__old_start; 1050*cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 105106c3fb27SDimitry Andric __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); 1052*cb14a3feSDimitry Andric#endif 105306c3fb27SDimitry Andric } 105406c3fb27SDimitry Andric 1055*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_poison_block(const void* __beginning, const void* __end) const _NOEXCEPT { 1056*cb14a3feSDimitry Andric (void)__beginning; 1057*cb14a3feSDimitry Andric (void)__end; 1058*cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 105906c3fb27SDimitry Andric __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end); 1060*cb14a3feSDimitry Andric#endif 106106c3fb27SDimitry Andric } 106206c3fb27SDimitry Andric 1063*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 1064*cb14a3feSDimitry Andric __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { 1065*cb14a3feSDimitry Andric (void)__block_index; 1066*cb14a3feSDimitry Andric (void)__annotation_type; 1067*cb14a3feSDimitry Andric#ifndef _LIBCPP_HAS_NO_ASAN 106806c3fb27SDimitry Andric __map_const_iterator __block_it = __map_.begin() + __block_index; 106906c3fb27SDimitry Andric const void* __block_start = std::__to_address(*__block_it); 107006c3fb27SDimitry Andric const void* __block_end = std::__to_address(*__block_it + __block_size); 107106c3fb27SDimitry Andric 107206c3fb27SDimitry Andric if (__annotation_type == __asan_poison) 107306c3fb27SDimitry Andric __annotate_poison_block(__block_start, __block_end); 107406c3fb27SDimitry Andric else { 107506c3fb27SDimitry Andric __annotate_double_ended_contiguous_container( 107606c3fb27SDimitry Andric __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); 107706c3fb27SDimitry Andric } 1078*cb14a3feSDimitry Andric#endif 107906c3fb27SDimitry Andric } 108006c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) 108106c3fb27SDimitry Andric 108206c3fb27SDimitry Andricpublic: 1083*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __verify_asan_annotations() const _NOEXCEPT { 108406c3fb27SDimitry Andric // This function tests deque object annotations. 108506c3fb27SDimitry Andric if (empty()) { 108606c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 108706c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 108806c3fb27SDimitry Andric std::__to_address(*__it), 108906c3fb27SDimitry Andric std::__to_address(*__it), 109006c3fb27SDimitry Andric std::__to_address(*__it), 109106c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 109206c3fb27SDimitry Andric return false; 109306c3fb27SDimitry Andric } 109406c3fb27SDimitry Andric 109506c3fb27SDimitry Andric return true; 109606c3fb27SDimitry Andric } 109706c3fb27SDimitry Andric 109806c3fb27SDimitry Andric size_type __end = __start_ + size(); 109906c3fb27SDimitry Andric __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; 110006c3fb27SDimitry Andric __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; 110106c3fb27SDimitry Andric 110206c3fb27SDimitry Andric // Pointers to first and after last elements 110306c3fb27SDimitry Andric // Those can be in different deque blocks 110406c3fb27SDimitry Andric const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); 110506c3fb27SDimitry Andric const void* __p_end = 110606c3fb27SDimitry Andric std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); 110706c3fb27SDimitry Andric 110806c3fb27SDimitry Andric for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { 110906c3fb27SDimitry Andric // Go over all blocks, find the place we are in and verify its annotations 111006c3fb27SDimitry Andric // Note that __p_end points *behind* the last item. 111106c3fb27SDimitry Andric 111206c3fb27SDimitry Andric // - blocks before the first block with container elements 111306c3fb27SDimitry Andric // - first block with items 111406c3fb27SDimitry Andric // - last block with items 111506c3fb27SDimitry Andric // - blocks after last block with ciontainer elements 111606c3fb27SDimitry Andric 111706c3fb27SDimitry Andric // Is the block before or after deque blocks that contain elements? 111806c3fb27SDimitry Andric if (__it < __first_mp || __it > __last_mp) { 111906c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 112006c3fb27SDimitry Andric std::__to_address(*__it), 112106c3fb27SDimitry Andric std::__to_address(*__it), 112206c3fb27SDimitry Andric std::__to_address(*__it), 112306c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) 112406c3fb27SDimitry Andric return false; 112506c3fb27SDimitry Andric } else { 112606c3fb27SDimitry Andric const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); 112706c3fb27SDimitry Andric const void* __containers_buffer_end = 112806c3fb27SDimitry Andric (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); 112906c3fb27SDimitry Andric if (!__sanitizer_verify_double_ended_contiguous_container( 113006c3fb27SDimitry Andric std::__to_address(*__it), 113106c3fb27SDimitry Andric __containers_buffer_beg, 113206c3fb27SDimitry Andric __containers_buffer_end, 113306c3fb27SDimitry Andric std::__to_address(*__it + __block_size))) { 113406c3fb27SDimitry Andric return false; 113506c3fb27SDimitry Andric } 113606c3fb27SDimitry Andric } 113706c3fb27SDimitry Andric } 113806c3fb27SDimitry Andric return true; 113906c3fb27SDimitry Andric } 114006c3fb27SDimitry Andric 114106c3fb27SDimitry Andricprivate: 114206c3fb27SDimitry Andric#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS 1143*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_front_spare(bool __keep_one = true) { 1144e40139ffSDimitry Andric if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { 114506c3fb27SDimitry Andric __annotate_whole_block(0, __asan_unposion); 1146*cb14a3feSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.front(), __block_size); 1147bdd1243dSDimitry Andric __map_.pop_front(); 1148bdd1243dSDimitry Andric __start_ -= __block_size; 1149e40139ffSDimitry Andric return true; 1150e40139ffSDimitry Andric } 1151e40139ffSDimitry Andric return false; 1152e40139ffSDimitry Andric } 1153e40139ffSDimitry Andric 1154*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __maybe_remove_back_spare(bool __keep_one = true) { 1155e40139ffSDimitry Andric if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { 115606c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_unposion); 1157*cb14a3feSDimitry Andric __alloc_traits::deallocate(__alloc(), __map_.back(), __block_size); 1158bdd1243dSDimitry Andric __map_.pop_back(); 1159e40139ffSDimitry Andric return true; 1160e40139ffSDimitry Andric } 1161e40139ffSDimitry Andric return false; 1162e40139ffSDimitry Andric } 11630b57cec5SDimitry Andric 116406c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1165*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __f, _Sentinel __l); 116606c3fb27SDimitry Andric 116706c3fb27SDimitry Andric template <class _RandomAccessIterator> 1168*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); 116906c3fb27SDimitry Andric template <class _Iterator> 1170*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_with_size(_Iterator __f, difference_type __n); 117106c3fb27SDimitry Andric 117206c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1173*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); 117406c3fb27SDimitry Andric 117506c3fb27SDimitry Andric template <class _Iterator> 1176*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); 117706c3fb27SDimitry Andric 117806c3fb27SDimitry Andric template <class _BiIter, class _Sentinel> 1179*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 1180*cb14a3feSDimitry Andric __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); 118106c3fb27SDimitry Andric template <class _BiIter> 1182*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); 118306c3fb27SDimitry Andric 11845f757f3fSDimitry Andric template <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> = 0> 11855f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l); 11865f757f3fSDimitry Andric template <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> = 0> 11875f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l); 118806c3fb27SDimitry Andric 118906c3fb27SDimitry Andric template <class _InputIterator> 119006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); 119106c3fb27SDimitry Andric template <class _InputIterator, class _Sentinel> 119206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); 119306c3fb27SDimitry Andric 1194bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); 1195bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); 1196bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); 1197bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(); 1198bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_front_capacity(size_type __n); 1199bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(); 1200bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __add_back_capacity(size_type __n); 1201*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1202*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 1203*cb14a3feSDimitry Andric __move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1204*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 1205*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 1206*cb14a3feSDimitry Andric __move_construct_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt); 12070b57cec5SDimitry Andric 1208*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c) { 1209*cb14a3feSDimitry Andric __copy_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); 1210*cb14a3feSDimitry Andric } 12110b57cec5SDimitry Andric 1212*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque& __c, true_type) { 1213*cb14a3feSDimitry Andric if (__alloc() != __c.__alloc()) { 12140b57cec5SDimitry Andric clear(); 12150b57cec5SDimitry Andric shrink_to_fit(); 12160b57cec5SDimitry Andric } 1217bdd1243dSDimitry Andric __alloc() = __c.__alloc(); 1218bdd1243dSDimitry Andric __map_.__alloc() = __c.__map_.__alloc(); 12190b57cec5SDimitry Andric } 12200b57cec5SDimitry Andric 1221*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {} 12220b57cec5SDimitry Andric 1223bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, true_type) 12240b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 1225bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(deque& __c, false_type); 12260b57cec5SDimitry Andric}; 12270b57cec5SDimitry Andric 1228bdd1243dSDimitry Andrictemplate <class _Tp, class _Alloc> 1229bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque<_Tp, _Alloc>::__block_size = 1230bdd1243dSDimitry Andric __deque_block_size<value_type, difference_type>::value; 1231bdd1243dSDimitry Andric 1232349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17 12330b57cec5SDimitry Andrictemplate <class _InputIterator, 1234fe6060f1SDimitry Andric class _Alloc = allocator<__iter_value_type<_InputIterator>>, 123506c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1236*cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1237*cb14a3feSDimitry Andricdeque(_InputIterator, _InputIterator) -> deque<__iter_value_type<_InputIterator>, _Alloc>; 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andrictemplate <class _InputIterator, 12400b57cec5SDimitry Andric class _Alloc, 124106c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 1242*cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1243*cb14a3feSDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc) -> deque<__iter_value_type<_InputIterator>, _Alloc>; 12440b57cec5SDimitry Andric#endif 12450b57cec5SDimitry Andric 124606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 124706c3fb27SDimitry Andrictemplate <ranges::input_range _Range, 124806c3fb27SDimitry Andric class _Alloc = allocator<ranges::range_value_t<_Range>>, 1249*cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Alloc>::value> > 1250*cb14a3feSDimitry Andricdeque(from_range_t, _Range&&, _Alloc = _Alloc()) -> deque<ranges::range_value_t<_Range>, _Alloc>; 125106c3fb27SDimitry Andric#endif 125206c3fb27SDimitry Andric 12530b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1254*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n) : __start_(0), __size_(0, __default_init_tag()) { 125506c3fb27SDimitry Andric __annotate_new(0); 12560b57cec5SDimitry Andric if (__n > 0) 12570b57cec5SDimitry Andric __append(__n); 12580b57cec5SDimitry Andric} 12590b57cec5SDimitry Andric 126006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 12610b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12620b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) 1263*cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 126406c3fb27SDimitry Andric __annotate_new(0); 12650b57cec5SDimitry Andric if (__n > 0) 12660b57cec5SDimitry Andric __append(__n); 12670b57cec5SDimitry Andric} 12680b57cec5SDimitry Andric#endif 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1271*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) : __start_(0), __size_(0, __default_init_tag()) { 127206c3fb27SDimitry Andric __annotate_new(0); 12730b57cec5SDimitry Andric if (__n > 0) 12740b57cec5SDimitry Andric __append(__n, __v); 12750b57cec5SDimitry Andric} 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12785f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 1279*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l) : __start_(0), __size_(0, __default_init_tag()) { 128006c3fb27SDimitry Andric __annotate_new(0); 12810b57cec5SDimitry Andric __append(__f, __l); 12820b57cec5SDimitry Andric} 12830b57cec5SDimitry Andric 12840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12855f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> > 12865f757f3fSDimitry Andricdeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a) 1287*cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 128806c3fb27SDimitry Andric __annotate_new(0); 12890b57cec5SDimitry Andric __append(__f, __l); 12900b57cec5SDimitry Andric} 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 12930b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c) 1294bdd1243dSDimitry Andric : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))), 1295bdd1243dSDimitry Andric __start_(0), 1296*cb14a3feSDimitry Andric __size_(0, __map_.__alloc()) { 129706c3fb27SDimitry Andric __annotate_new(0); 12980b57cec5SDimitry Andric __append(__c.begin(), __c.end()); 12990b57cec5SDimitry Andric} 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 130281ad6265SDimitry Andricdeque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a) 1303*cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 130406c3fb27SDimitry Andric __annotate_new(0); 13050b57cec5SDimitry Andric __append(__c.begin(), __c.end()); 13060b57cec5SDimitry Andric} 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1309*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(const deque& __c) { 1310*cb14a3feSDimitry Andric if (this != std::addressof(__c)) { 13110b57cec5SDimitry Andric __copy_assign_alloc(__c); 13120b57cec5SDimitry Andric assign(__c.begin(), __c.end()); 13130b57cec5SDimitry Andric } 13140b57cec5SDimitry Andric return *this; 13150b57cec5SDimitry Andric} 13160b57cec5SDimitry Andric 13170b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1320*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il) : __start_(0), __size_(0, __default_init_tag()) { 132106c3fb27SDimitry Andric __annotate_new(0); 13220b57cec5SDimitry Andric __append(__il.begin(), __il.end()); 13230b57cec5SDimitry Andric} 13240b57cec5SDimitry Andric 13250b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 13260b57cec5SDimitry Andricdeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a) 1327*cb14a3feSDimitry Andric : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { 132806c3fb27SDimitry Andric __annotate_new(0); 13290b57cec5SDimitry Andric __append(__il.begin(), __il.end()); 13300b57cec5SDimitry Andric} 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1333*cb14a3feSDimitry Andricinline deque<_Tp, _Allocator>::deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 1334*cb14a3feSDimitry Andric : __map_(std::move(__c.__map_)), __start_(std::move(__c.__start_)), __size_(std::move(__c.__size_)) { 1335bdd1243dSDimitry Andric __c.__start_ = 0; 1336bdd1243dSDimitry Andric __c.__size() = 0; 13370b57cec5SDimitry Andric} 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1340*cb14a3feSDimitry Andricinline deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a) 1341bdd1243dSDimitry Andric : __map_(std::move(__c.__map_), __pointer_allocator(__a)), 1342bdd1243dSDimitry Andric __start_(std::move(__c.__start_)), 1343*cb14a3feSDimitry Andric __size_(std::move(__c.__size()), __a) { 1344*cb14a3feSDimitry Andric if (__a == __c.__alloc()) { 1345bdd1243dSDimitry Andric __c.__start_ = 0; 1346bdd1243dSDimitry Andric __c.__size() = 0; 1347*cb14a3feSDimitry Andric } else { 1348bdd1243dSDimitry Andric __map_.clear(); 1349bdd1243dSDimitry Andric __start_ = 0; 1350bdd1243dSDimitry Andric __size() = 0; 13510b57cec5SDimitry Andric typedef move_iterator<iterator> _Ip; 13520b57cec5SDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end())); 13530b57cec5SDimitry Andric } 13540b57cec5SDimitry Andric} 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1357*cb14a3feSDimitry Andricinline deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(deque&& __c) _NOEXCEPT_( 1358*cb14a3feSDimitry Andric __alloc_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<allocator_type>::value) { 1359*cb14a3feSDimitry Andric __move_assign(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 13600b57cec5SDimitry Andric return *this; 13610b57cec5SDimitry Andric} 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1364*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) { 1365*cb14a3feSDimitry Andric if (__alloc() != __c.__alloc()) { 13660b57cec5SDimitry Andric typedef move_iterator<iterator> _Ip; 13670b57cec5SDimitry Andric assign(_Ip(__c.begin()), _Ip(__c.end())); 1368*cb14a3feSDimitry Andric } else 13690b57cec5SDimitry Andric __move_assign(__c, true_type()); 13700b57cec5SDimitry Andric} 13710b57cec5SDimitry Andric 13720b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1373*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type) 1374*cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 13750b57cec5SDimitry Andric clear(); 13760b57cec5SDimitry Andric shrink_to_fit(); 1377bdd1243dSDimitry Andric __move_assign(__c); 13780b57cec5SDimitry Andric} 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 13810b57cec5SDimitry Andric 13820b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1383*cb14a3feSDimitry Andrictemplate <class _InputIter, 1384*cb14a3feSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIter>::value && 1385*cb14a3feSDimitry Andric !__has_random_access_iterator_category<_InputIter>::value, 1386*cb14a3feSDimitry Andric int> > 1387*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l) { 138806c3fb27SDimitry Andric __assign_with_sentinel(__f, __l); 138906c3fb27SDimitry Andric} 139006c3fb27SDimitry Andric 139106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 139206c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 1393*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { 1394bdd1243dSDimitry Andric iterator __i = begin(); 1395bdd1243dSDimitry Andric iterator __e = end(); 13960b57cec5SDimitry Andric for (; __f != __l && __i != __e; ++__f, (void)++__i) 13970b57cec5SDimitry Andric *__i = *__f; 13980b57cec5SDimitry Andric if (__f != __l) 139906c3fb27SDimitry Andric __append_with_sentinel(std::move(__f), std::move(__l)); 14000b57cec5SDimitry Andric else 14010b57cec5SDimitry Andric __erase_to_end(__i); 14020b57cec5SDimitry Andric} 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 14055f757f3fSDimitry Andrictemplate <class _RAIter, __enable_if_t<__has_random_access_iterator_category<_RAIter>::value, int> > 1406*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l) { 140706c3fb27SDimitry Andric __assign_with_size_random_access(__f, __l - __f); 140806c3fb27SDimitry Andric} 140906c3fb27SDimitry Andric 141006c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 141106c3fb27SDimitry Andrictemplate <class _RandomAccessIterator> 1412*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void 1413*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { 1414*cb14a3feSDimitry Andric if (static_cast<size_type>(__n) > size()) { 141506c3fb27SDimitry Andric auto __l = __f + size(); 141606c3fb27SDimitry Andric std::copy(__f, __l, begin()); 141706c3fb27SDimitry Andric __append_with_size(__l, __n - size()); 1418*cb14a3feSDimitry Andric } else 141906c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 142006c3fb27SDimitry Andric} 142106c3fb27SDimitry Andric 142206c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 142306c3fb27SDimitry Andrictemplate <class _Iterator> 1424*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { 142506c3fb27SDimitry Andric if (static_cast<size_type>(__n) > size()) { 142606c3fb27SDimitry Andric auto __added_size = __n - size(); 142706c3fb27SDimitry Andric 142806c3fb27SDimitry Andric auto __i = begin(); 142906c3fb27SDimitry Andric for (auto __count = size(); __count != 0; --__count) { 143006c3fb27SDimitry Andric *__i++ = *__f++; 143106c3fb27SDimitry Andric } 143206c3fb27SDimitry Andric 143306c3fb27SDimitry Andric __append_with_size(__f, __added_size); 143406c3fb27SDimitry Andric 143506c3fb27SDimitry Andric } else { 143606c3fb27SDimitry Andric __erase_to_end(std::copy_n(__f, __n, begin())); 143706c3fb27SDimitry Andric } 14380b57cec5SDimitry Andric} 14390b57cec5SDimitry Andric 14400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1441*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) { 1442*cb14a3feSDimitry Andric if (__n > size()) { 14435f757f3fSDimitry Andric std::fill_n(begin(), size(), __v); 1444bdd1243dSDimitry Andric __n -= size(); 14450b57cec5SDimitry Andric __append(__n, __v); 1446*cb14a3feSDimitry Andric } else 14475f757f3fSDimitry Andric __erase_to_end(std::fill_n(begin(), __n, __v)); 14480b57cec5SDimitry Andric} 14490b57cec5SDimitry Andric 14500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1451*cb14a3feSDimitry Andricinline _Allocator deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT { 1452bdd1243dSDimitry Andric return __alloc(); 14530b57cec5SDimitry Andric} 14540b57cec5SDimitry Andric 14550b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1456*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::resize(size_type __n) { 1457bdd1243dSDimitry Andric if (__n > size()) 1458bdd1243dSDimitry Andric __append(__n - size()); 1459bdd1243dSDimitry Andric else if (__n < size()) 1460bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 14610b57cec5SDimitry Andric} 14620b57cec5SDimitry Andric 14630b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1464*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) { 1465bdd1243dSDimitry Andric if (__n > size()) 1466bdd1243dSDimitry Andric __append(__n - size(), __v); 1467bdd1243dSDimitry Andric else if (__n < size()) 1468bdd1243dSDimitry Andric __erase_to_end(begin() + __n); 14690b57cec5SDimitry Andric} 14700b57cec5SDimitry Andric 14710b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1472*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT { 1473bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1474*cb14a3feSDimitry Andric if (empty()) { 147506c3fb27SDimitry Andric __annotate_delete(); 1476*cb14a3feSDimitry Andric while (__map_.size() > 0) { 1477bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.back(), __block_size); 1478bdd1243dSDimitry Andric __map_.pop_back(); 14790b57cec5SDimitry Andric } 1480bdd1243dSDimitry Andric __start_ = 0; 1481*cb14a3feSDimitry Andric } else { 1482e40139ffSDimitry Andric __maybe_remove_front_spare(/*__keep_one=*/false); 1483e40139ffSDimitry Andric __maybe_remove_back_spare(/*__keep_one=*/false); 14840b57cec5SDimitry Andric } 1485bdd1243dSDimitry Andric __map_.shrink_to_fit(); 14860b57cec5SDimitry Andric} 14870b57cec5SDimitry Andric 14880b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1489*cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT { 1490bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1491bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 14920b57cec5SDimitry Andric} 14930b57cec5SDimitry Andric 14940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1495*cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference 1496*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT { 1497bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1498bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 14990b57cec5SDimitry Andric} 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1502*cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::at(size_type __i) { 1503bdd1243dSDimitry Andric if (__i >= size()) 15045f757f3fSDimitry Andric std::__throw_out_of_range("deque"); 1505bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1506bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15070b57cec5SDimitry Andric} 15080b57cec5SDimitry Andric 15090b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1510*cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::at(size_type __i) const { 1511bdd1243dSDimitry Andric if (__i >= size()) 15125f757f3fSDimitry Andric std::__throw_out_of_range("deque"); 1513bdd1243dSDimitry Andric size_type __p = __start_ + __i; 1514bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15150b57cec5SDimitry Andric} 15160b57cec5SDimitry Andric 15170b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1518*cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::front() _NOEXCEPT { 1519*cb14a3feSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); 15200b57cec5SDimitry Andric} 15210b57cec5SDimitry Andric 15220b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1523*cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::front() const _NOEXCEPT { 1524*cb14a3feSDimitry Andric return *(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size); 15250b57cec5SDimitry Andric} 15260b57cec5SDimitry Andric 15270b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1528*cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::back() _NOEXCEPT { 1529bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1530bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15310b57cec5SDimitry Andric} 15320b57cec5SDimitry Andric 15330b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1534*cb14a3feSDimitry Andricinline typename deque<_Tp, _Allocator>::const_reference deque<_Tp, _Allocator>::back() const _NOEXCEPT { 1535bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 1536bdd1243dSDimitry Andric return *(*(__map_.begin() + __p / __block_size) + __p % __block_size); 15370b57cec5SDimitry Andric} 15380b57cec5SDimitry Andric 15390b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1540*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_back(const value_type& __v) { 1541bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15420b57cec5SDimitry Andric if (__back_spare() == 0) 15430b57cec5SDimitry Andric __add_back_capacity(); 15440b57cec5SDimitry Andric // __back_spare() >= 1 154506c3fb27SDimitry Andric __annotate_increase_back(1); 15465f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1547bdd1243dSDimitry Andric ++__size(); 15480b57cec5SDimitry Andric} 15490b57cec5SDimitry Andric 15500b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1551*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_front(const value_type& __v) { 1552bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15530b57cec5SDimitry Andric if (__front_spare() == 0) 15540b57cec5SDimitry Andric __add_front_capacity(); 15550b57cec5SDimitry Andric // __front_spare() >= 1 155606c3fb27SDimitry Andric __annotate_increase_front(1); 15575f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1558bdd1243dSDimitry Andric --__start_; 1559bdd1243dSDimitry Andric ++__size(); 15600b57cec5SDimitry Andric} 15610b57cec5SDimitry Andric 15620b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 15630b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1564*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_back(value_type&& __v) { 1565bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15660b57cec5SDimitry Andric if (__back_spare() == 0) 15670b57cec5SDimitry Andric __add_back_capacity(); 15680b57cec5SDimitry Andric // __back_spare() >= 1 156906c3fb27SDimitry Andric __annotate_increase_back(1); 15705f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); 1571bdd1243dSDimitry Andric ++__size(); 15720b57cec5SDimitry Andric} 15730b57cec5SDimitry Andric 15740b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 15750b57cec5SDimitry Andrictemplate <class... _Args> 157606c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 15770b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 15780b57cec5SDimitry Andric# else 15790b57cec5SDimitry Andricvoid 15800b57cec5SDimitry Andric# endif 1581*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::emplace_back(_Args&&... __args) { 1582bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15830b57cec5SDimitry Andric if (__back_spare() == 0) 15840b57cec5SDimitry Andric __add_back_capacity(); 15850b57cec5SDimitry Andric // __back_spare() >= 1 158606c3fb27SDimitry Andric __annotate_increase_back(1); 1587*cb14a3feSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); 1588bdd1243dSDimitry Andric ++__size(); 158906c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 1590bdd1243dSDimitry Andric return *--end(); 15910b57cec5SDimitry Andric# endif 15920b57cec5SDimitry Andric} 15930b57cec5SDimitry Andric 15940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1595*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::push_front(value_type&& __v) { 1596bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 15970b57cec5SDimitry Andric if (__front_spare() == 0) 15980b57cec5SDimitry Andric __add_front_capacity(); 15990b57cec5SDimitry Andric // __front_spare() >= 1 160006c3fb27SDimitry Andric __annotate_increase_front(1); 16015f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); 1602bdd1243dSDimitry Andric --__start_; 1603bdd1243dSDimitry Andric ++__size(); 16040b57cec5SDimitry Andric} 16050b57cec5SDimitry Andric 16060b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16070b57cec5SDimitry Andrictemplate <class... _Args> 160806c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 16090b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::reference 16100b57cec5SDimitry Andric# else 16110b57cec5SDimitry Andricvoid 16120b57cec5SDimitry Andric# endif 1613*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::emplace_front(_Args&&... __args) { 1614bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 16150b57cec5SDimitry Andric if (__front_spare() == 0) 16160b57cec5SDimitry Andric __add_front_capacity(); 16170b57cec5SDimitry Andric // __front_spare() >= 1 161806c3fb27SDimitry Andric __annotate_increase_front(1); 16195f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); 1620bdd1243dSDimitry Andric --__start_; 1621bdd1243dSDimitry Andric ++__size(); 162206c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 1623bdd1243dSDimitry Andric return *begin(); 16240b57cec5SDimitry Andric# endif 16250b57cec5SDimitry Andric} 16260b57cec5SDimitry Andric 16270b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1628*cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) { 1629bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1630bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1631bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1632*cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 16330b57cec5SDimitry Andric if (__front_spare() == 0) 16340b57cec5SDimitry Andric __add_front_capacity(); 16350b57cec5SDimitry Andric // __front_spare() >= 1 163606c3fb27SDimitry Andric __annotate_increase_front(1); 1637*cb14a3feSDimitry Andric if (__pos == 0) { 16385f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v)); 1639bdd1243dSDimitry Andric --__start_; 1640bdd1243dSDimitry Andric ++__size(); 1641*cb14a3feSDimitry Andric } else { 1642bdd1243dSDimitry Andric iterator __b = begin(); 16435f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 16445f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1645bdd1243dSDimitry Andric --__start_; 1646bdd1243dSDimitry Andric ++__size(); 16470b57cec5SDimitry Andric if (__pos > 1) 16485f757f3fSDimitry Andric __b = std::move(std::next(__b), __b + __pos, __b); 16495f757f3fSDimitry Andric *__b = std::move(__v); 16500b57cec5SDimitry Andric } 1651*cb14a3feSDimitry Andric } else { // insert by shifting things forward 16520b57cec5SDimitry Andric if (__back_spare() == 0) 16530b57cec5SDimitry Andric __add_back_capacity(); 16540b57cec5SDimitry Andric // __back_capacity >= 1 165506c3fb27SDimitry Andric __annotate_increase_back(1); 1656bdd1243dSDimitry Andric size_type __de = size() - __pos; 1657*cb14a3feSDimitry Andric if (__de == 0) { 16585f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v)); 1659bdd1243dSDimitry Andric ++__size(); 1660*cb14a3feSDimitry Andric } else { 1661bdd1243dSDimitry Andric iterator __e = end(); 16625f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 16635f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1664bdd1243dSDimitry Andric ++__size(); 16650b57cec5SDimitry Andric if (__de > 1) 16665f757f3fSDimitry Andric __e = std::move_backward(__e - __de, __em1, __e); 16675f757f3fSDimitry Andric *--__e = std::move(__v); 16680b57cec5SDimitry Andric } 16690b57cec5SDimitry Andric } 1670bdd1243dSDimitry Andric return begin() + __pos; 16710b57cec5SDimitry Andric} 16720b57cec5SDimitry Andric 16730b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 16740b57cec5SDimitry Andrictemplate <class... _Args> 1675*cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) { 1676bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1677bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1678bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1679*cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 16800b57cec5SDimitry Andric if (__front_spare() == 0) 16810b57cec5SDimitry Andric __add_front_capacity(); 16820b57cec5SDimitry Andric // __front_spare() >= 1 168306c3fb27SDimitry Andric __annotate_increase_front(1); 1684*cb14a3feSDimitry Andric if (__pos == 0) { 16855f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), std::forward<_Args>(__args)...); 1686bdd1243dSDimitry Andric --__start_; 1687bdd1243dSDimitry Andric ++__size(); 1688*cb14a3feSDimitry Andric } else { 16895f757f3fSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); 1690bdd1243dSDimitry Andric iterator __b = begin(); 16915f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 16925f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1693bdd1243dSDimitry Andric --__start_; 1694bdd1243dSDimitry Andric ++__size(); 16950b57cec5SDimitry Andric if (__pos > 1) 16965f757f3fSDimitry Andric __b = std::move(std::next(__b), __b + __pos, __b); 16975f757f3fSDimitry Andric *__b = std::move(__tmp.get()); 16980b57cec5SDimitry Andric } 1699*cb14a3feSDimitry Andric } else { // insert by shifting things forward 17000b57cec5SDimitry Andric if (__back_spare() == 0) 17010b57cec5SDimitry Andric __add_back_capacity(); 17020b57cec5SDimitry Andric // __back_capacity >= 1 170306c3fb27SDimitry Andric __annotate_increase_back(1); 1704bdd1243dSDimitry Andric size_type __de = size() - __pos; 1705*cb14a3feSDimitry Andric if (__de == 0) { 17065f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), std::forward<_Args>(__args)...); 1707bdd1243dSDimitry Andric ++__size(); 1708*cb14a3feSDimitry Andric } else { 17095f757f3fSDimitry Andric __temp_value<value_type, _Allocator> __tmp(__alloc(), std::forward<_Args>(__args)...); 1710bdd1243dSDimitry Andric iterator __e = end(); 17115f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 17125f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1713bdd1243dSDimitry Andric ++__size(); 17140b57cec5SDimitry Andric if (__de > 1) 17155f757f3fSDimitry Andric __e = std::move_backward(__e - __de, __em1, __e); 17165f757f3fSDimitry Andric *--__e = std::move(__tmp.get()); 17170b57cec5SDimitry Andric } 17180b57cec5SDimitry Andric } 1719bdd1243dSDimitry Andric return begin() + __pos; 17200b57cec5SDimitry Andric} 17210b57cec5SDimitry Andric 17220b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 17230b57cec5SDimitry Andric 17240b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1725*cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) { 1726bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1727bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1728bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1729*cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 17300b57cec5SDimitry Andric if (__front_spare() == 0) 17310b57cec5SDimitry Andric __add_front_capacity(); 17320b57cec5SDimitry Andric // __front_spare() >= 1 173306c3fb27SDimitry Andric __annotate_increase_front(1); 1734*cb14a3feSDimitry Andric if (__pos == 0) { 17355f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--begin()), __v); 1736bdd1243dSDimitry Andric --__start_; 1737bdd1243dSDimitry Andric ++__size(); 1738*cb14a3feSDimitry Andric } else { 17390b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1740bdd1243dSDimitry Andric iterator __b = begin(); 17415f757f3fSDimitry Andric iterator __bm1 = std::prev(__b); 17420b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__b)) 17430b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__bm1); 17445f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b)); 1745bdd1243dSDimitry Andric --__start_; 1746bdd1243dSDimitry Andric ++__size(); 17470b57cec5SDimitry Andric if (__pos > 1) 17485f757f3fSDimitry Andric __b = __move_and_check(std::next(__b), __b + __pos, __b, __vt); 17490b57cec5SDimitry Andric *__b = *__vt; 17500b57cec5SDimitry Andric } 1751*cb14a3feSDimitry Andric } else { // insert by shifting things forward 17520b57cec5SDimitry Andric if (__back_spare() == 0) 17530b57cec5SDimitry Andric __add_back_capacity(); 17540b57cec5SDimitry Andric // __back_capacity >= 1 175506c3fb27SDimitry Andric __annotate_increase_back(1); 1756bdd1243dSDimitry Andric size_type __de = size() - __pos; 1757*cb14a3feSDimitry Andric if (__de == 0) { 17585f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*end()), __v); 1759bdd1243dSDimitry Andric ++__size(); 1760*cb14a3feSDimitry Andric } else { 17610b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 1762bdd1243dSDimitry Andric iterator __e = end(); 17635f757f3fSDimitry Andric iterator __em1 = std::prev(__e); 17640b57cec5SDimitry Andric if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1)) 17650b57cec5SDimitry Andric __vt = pointer_traits<const_pointer>::pointer_to(*__e); 17665f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1)); 1767bdd1243dSDimitry Andric ++__size(); 17680b57cec5SDimitry Andric if (__de > 1) 17690b57cec5SDimitry Andric __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); 17700b57cec5SDimitry Andric *--__e = *__vt; 17710b57cec5SDimitry Andric } 17720b57cec5SDimitry Andric } 1773bdd1243dSDimitry Andric return begin() + __pos; 17740b57cec5SDimitry Andric} 17750b57cec5SDimitry Andric 17760b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 17770b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1778*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) { 1779bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1780bdd1243dSDimitry Andric size_type __to_end = __size() - __pos; 1781bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1782*cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 17830b57cec5SDimitry Andric if (__n > __front_spare()) 17840b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 17850b57cec5SDimitry Andric // __n <= __front_spare() 178606c3fb27SDimitry Andric __annotate_increase_front(__n); 1787bdd1243dSDimitry Andric iterator __old_begin = begin(); 17880b57cec5SDimitry Andric iterator __i = __old_begin; 1789*cb14a3feSDimitry Andric if (__n > __pos) { 1790bdd1243dSDimitry Andric for (size_type __m = __n - __pos; __m; --__m, --__start_, ++__size()) 17915f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), __v); 17920b57cec5SDimitry Andric __n = __pos; 17930b57cec5SDimitry Andric } 1794*cb14a3feSDimitry Andric if (__n > 0) { 17950b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 17960b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 17970b57cec5SDimitry Andric __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); 17980b57cec5SDimitry Andric if (__n < __pos) 17990b57cec5SDimitry Andric __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); 18005f757f3fSDimitry Andric std::fill_n(__old_begin, __n, *__vt); 18010b57cec5SDimitry Andric } 1802*cb14a3feSDimitry Andric } else { // insert by shifting things forward 18030b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 18040b57cec5SDimitry Andric if (__n > __back_capacity) 18050b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 18060b57cec5SDimitry Andric // __n <= __back_capacity 180706c3fb27SDimitry Andric __annotate_increase_back(__n); 1808bdd1243dSDimitry Andric iterator __old_end = end(); 18090b57cec5SDimitry Andric iterator __i = __old_end; 1810bdd1243dSDimitry Andric size_type __de = size() - __pos; 1811*cb14a3feSDimitry Andric if (__n > __de) { 1812bdd1243dSDimitry Andric for (size_type __m = __n - __de; __m; --__m, (void)++__i, ++__size()) 18135f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), __v); 18140b57cec5SDimitry Andric __n = __de; 18150b57cec5SDimitry Andric } 1816*cb14a3feSDimitry Andric if (__n > 0) { 18170b57cec5SDimitry Andric const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v); 18180b57cec5SDimitry Andric iterator __oen = __old_end - __n; 18190b57cec5SDimitry Andric __move_construct_and_check(__oen, __old_end, __i, __vt); 18200b57cec5SDimitry Andric if (__n < __de) 18210b57cec5SDimitry Andric __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); 18225f757f3fSDimitry Andric std::fill_n(__old_end - __n, __n, *__vt); 18230b57cec5SDimitry Andric } 18240b57cec5SDimitry Andric } 1825bdd1243dSDimitry Andric return begin() + __pos; 18260b57cec5SDimitry Andric} 18270b57cec5SDimitry Andric 18280b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18295f757f3fSDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> > 18300b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1831*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l) { 183206c3fb27SDimitry Andric return __insert_with_sentinel(__p, __f, __l); 183306c3fb27SDimitry Andric} 183406c3fb27SDimitry Andric 183506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 183606c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 1837*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 183806c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { 1839bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__alloc()); 184006c3fb27SDimitry Andric __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); 18410b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; 18420b57cec5SDimitry Andric return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); 18430b57cec5SDimitry Andric} 18440b57cec5SDimitry Andric 18450b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18465f757f3fSDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_exactly_forward_iterator_category<_ForwardIterator>::value, int> > 18470b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 1848*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l) { 184906c3fb27SDimitry Andric return __insert_with_size(__p, __f, std::distance(__f, __l)); 185006c3fb27SDimitry Andric} 185106c3fb27SDimitry Andric 185206c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 185306c3fb27SDimitry Andrictemplate <class _Iterator> 1854*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 185506c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) { 1856bdd1243dSDimitry Andric __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); 185706c3fb27SDimitry Andric __buf.__construct_at_end_with_size(__f, __n); 18580b57cec5SDimitry Andric typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; 18590b57cec5SDimitry Andric return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); 18600b57cec5SDimitry Andric} 18610b57cec5SDimitry Andric 18620b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 18635f757f3fSDimitry Andrictemplate <class _BiIter, __enable_if_t<__has_bidirectional_iterator_category<_BiIter>::value, int> > 1864*cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l) { 186506c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l)); 186606c3fb27SDimitry Andric} 186706c3fb27SDimitry Andric 186806c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 186906c3fb27SDimitry Andrictemplate <class _BiIter, class _Sentinel> 1870*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 187106c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) { 187206c3fb27SDimitry Andric return __insert_bidirectional(__p, __f, std::next(__f, __n), __n); 187306c3fb27SDimitry Andric} 187406c3fb27SDimitry Andric 187506c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 187606c3fb27SDimitry Andrictemplate <class _BiIter> 1877*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator 187806c3fb27SDimitry Andricdeque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) { 1879bdd1243dSDimitry Andric size_type __pos = __p - begin(); 1880bdd1243dSDimitry Andric size_type __to_end = size() - __pos; 1881bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 1882*cb14a3feSDimitry Andric if (__pos < __to_end) { // insert by shifting things backward 18830b57cec5SDimitry Andric if (__n > __front_spare()) 18840b57cec5SDimitry Andric __add_front_capacity(__n - __front_spare()); 18850b57cec5SDimitry Andric // __n <= __front_spare() 188606c3fb27SDimitry Andric __annotate_increase_front(__n); 1887bdd1243dSDimitry Andric iterator __old_begin = begin(); 18880b57cec5SDimitry Andric iterator __i = __old_begin; 18890b57cec5SDimitry Andric _BiIter __m = __f; 1890*cb14a3feSDimitry Andric if (__n > __pos) { 18915f757f3fSDimitry Andric __m = __pos < __n / 2 ? std::prev(__l, __pos) : std::next(__f, __n - __pos); 1892bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __f; --__start_, ++__size()) 18935f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), *--__j); 18940b57cec5SDimitry Andric __n = __pos; 18950b57cec5SDimitry Andric } 1896*cb14a3feSDimitry Andric if (__n > 0) { 18970b57cec5SDimitry Andric iterator __obn = __old_begin + __n; 1898*cb14a3feSDimitry Andric for (iterator __j = __obn; __j != __old_begin;) { 18995f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__i), std::move(*--__j)); 1900bdd1243dSDimitry Andric --__start_; 1901bdd1243dSDimitry Andric ++__size(); 19020b57cec5SDimitry Andric } 19030b57cec5SDimitry Andric if (__n < __pos) 19045f757f3fSDimitry Andric __old_begin = std::move(__obn, __old_begin + __pos, __old_begin); 19055f757f3fSDimitry Andric std::copy(__m, __l, __old_begin); 19060b57cec5SDimitry Andric } 1907*cb14a3feSDimitry Andric } else { // insert by shifting things forward 19080b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19090b57cec5SDimitry Andric if (__n > __back_capacity) 19100b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 19110b57cec5SDimitry Andric // __n <= __back_capacity 191206c3fb27SDimitry Andric __annotate_increase_back(__n); 1913bdd1243dSDimitry Andric iterator __old_end = end(); 19140b57cec5SDimitry Andric iterator __i = __old_end; 19150b57cec5SDimitry Andric _BiIter __m = __l; 1916bdd1243dSDimitry Andric size_type __de = size() - __pos; 1917*cb14a3feSDimitry Andric if (__n > __de) { 19185f757f3fSDimitry Andric __m = __de < __n / 2 ? std::next(__f, __de) : std::prev(__l, __n - __de); 1919bdd1243dSDimitry Andric for (_BiIter __j = __m; __j != __l; ++__i, (void)++__j, ++__size()) 19205f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), *__j); 19210b57cec5SDimitry Andric __n = __de; 19220b57cec5SDimitry Andric } 1923*cb14a3feSDimitry Andric if (__n > 0) { 19240b57cec5SDimitry Andric iterator __oen = __old_end - __n; 1925bdd1243dSDimitry Andric for (iterator __j = __oen; __j != __old_end; ++__i, (void)++__j, ++__size()) 19265f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__i), std::move(*__j)); 19270b57cec5SDimitry Andric if (__n < __de) 19285f757f3fSDimitry Andric __old_end = std::move_backward(__old_end - __de, __oen, __old_end); 19295f757f3fSDimitry Andric std::copy_backward(__f, __m, __old_end); 19300b57cec5SDimitry Andric } 19310b57cec5SDimitry Andric } 1932bdd1243dSDimitry Andric return begin() + __pos; 19330b57cec5SDimitry Andric} 19340b57cec5SDimitry Andric 19350b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 19365f757f3fSDimitry Andrictemplate <class _InpIter, __enable_if_t<__has_exactly_input_iterator_category<_InpIter>::value, int> > 1937*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l) { 193806c3fb27SDimitry Andric __append_with_sentinel(__f, __l); 193906c3fb27SDimitry Andric} 194006c3fb27SDimitry Andric 194106c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 194206c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 1943*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { 19440b57cec5SDimitry Andric for (; __f != __l; ++__f) 19450b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 19460b57cec5SDimitry Andric push_back(*__f); 19470b57cec5SDimitry Andric#else 19480b57cec5SDimitry Andric emplace_back(*__f); 19490b57cec5SDimitry Andric#endif 19500b57cec5SDimitry Andric} 19510b57cec5SDimitry Andric 19520b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 19535f757f3fSDimitry Andrictemplate <class _ForIter, __enable_if_t<__has_forward_iterator_category<_ForIter>::value, int> > 1954*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l) { 195506c3fb27SDimitry Andric __append_with_size(__f, std::distance(__f, __l)); 195606c3fb27SDimitry Andric} 195706c3fb27SDimitry Andric 195806c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 195906c3fb27SDimitry Andrictemplate <class _InputIterator> 1960*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { 1961bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19620b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19630b57cec5SDimitry Andric if (__n > __back_capacity) 19640b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 196506c3fb27SDimitry Andric 19660b57cec5SDimitry Andric // __n <= __back_capacity 196706c3fb27SDimitry Andric __annotate_increase_back(__n); 1968bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1969e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 1970e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { 19715f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); 1972e40139ffSDimitry Andric } 1973e40139ffSDimitry Andric } 19740b57cec5SDimitry Andric} 19750b57cec5SDimitry Andric 19760b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1977*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(size_type __n) { 1978bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19790b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19800b57cec5SDimitry Andric if (__n > __back_capacity) 19810b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 19820b57cec5SDimitry Andric // __n <= __back_capacity 198306c3fb27SDimitry Andric __annotate_increase_back(__n); 1984bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 1985e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 1986e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 19875f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); 1988e40139ffSDimitry Andric } 1989e40139ffSDimitry Andric } 19900b57cec5SDimitry Andric} 19910b57cec5SDimitry Andric 19920b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 1993*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) { 1994bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 19950b57cec5SDimitry Andric size_type __back_capacity = __back_spare(); 19960b57cec5SDimitry Andric if (__n > __back_capacity) 19970b57cec5SDimitry Andric __add_back_capacity(__n - __back_capacity); 19980b57cec5SDimitry Andric // __n <= __back_capacity 199906c3fb27SDimitry Andric __annotate_increase_back(__n); 2000bdd1243dSDimitry Andric for (__deque_block_range __br : __deque_range(end(), end() + __n)) { 2001e40139ffSDimitry Andric _ConstructTransaction __tx(this, __br); 2002e40139ffSDimitry Andric for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 20035f757f3fSDimitry Andric __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); 2004e40139ffSDimitry Andric } 2005e40139ffSDimitry Andric } 20060b57cec5SDimitry Andric} 20070b57cec5SDimitry Andric 20080b57cec5SDimitry Andric// Create front capacity for one block of elements. 20090b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 20100b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2011*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_front_capacity() { 2012bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2013*cb14a3feSDimitry Andric if (__back_spare() >= __block_size) { 2014bdd1243dSDimitry Andric __start_ += __block_size; 2015bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2016bdd1243dSDimitry Andric __map_.pop_back(); 2017bdd1243dSDimitry Andric __map_.push_front(__pt); 20180b57cec5SDimitry Andric } 2019bdd1243dSDimitry Andric // Else if __map_.size() < __map_.capacity() then we need to allocate 1 buffer 2020*cb14a3feSDimitry Andric else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around 20210b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 20220b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2023bdd1243dSDimitry Andric if (__map_.__front_spare() > 0) 2024bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 2025*cb14a3feSDimitry Andric else { 2026bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 20270b57cec5SDimitry Andric // Done allocating, reorder capacity 2028bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2029bdd1243dSDimitry Andric __map_.pop_back(); 2030bdd1243dSDimitry Andric __map_.push_front(__pt); 20310b57cec5SDimitry Andric } 2032*cb14a3feSDimitry Andric __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; 20330b57cec5SDimitry Andric } 20340b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 2035*cb14a3feSDimitry Andric else { 2036*cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2037*cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__alloc()); 20380b57cec5SDimitry Andric 20390b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 2040*cb14a3feSDimitry Andric unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); 20410b57cec5SDimitry Andric __buf.push_back(__hold.get()); 20420b57cec5SDimitry Andric __hold.release(); 20430b57cec5SDimitry Andric 2044*cb14a3feSDimitry Andric for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) 20450b57cec5SDimitry Andric __buf.push_back(*__i); 20465f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 20475f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 20485f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 20495f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2050*cb14a3feSDimitry Andric __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size; 20510b57cec5SDimitry Andric } 205206c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 20530b57cec5SDimitry Andric} 20540b57cec5SDimitry Andric 20550b57cec5SDimitry Andric// Create front capacity for __n elements. 20560b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 20570b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2058*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) { 2059bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2060bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 20610b57cec5SDimitry Andric // Number of unused blocks at back: 2062bdd1243dSDimitry Andric size_type __back_capacity = __back_spare() / __block_size; 20635f757f3fSDimitry Andric __back_capacity = std::min(__back_capacity, __nb); // don't take more than you need 20640b57cec5SDimitry Andric __nb -= __back_capacity; // number of blocks need to allocate 20650b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 2066*cb14a3feSDimitry Andric if (__nb == 0) { 2067bdd1243dSDimitry Andric __start_ += __block_size * __back_capacity; 2068*cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2069bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2070bdd1243dSDimitry Andric __map_.pop_back(); 2071bdd1243dSDimitry Andric __map_.push_front(__pt); 20720b57cec5SDimitry Andric } 20730b57cec5SDimitry Andric } 20740b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2075*cb14a3feSDimitry Andric else if (__nb <= __map_.capacity() - 2076*cb14a3feSDimitry Andric __map_.size()) { // we can put the new buffers into the map, but don't shift things around 20770b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 20780b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2079*cb14a3feSDimitry Andric for (; __nb > 0; --__nb, __start_ += __block_size - (__map_.size() == 1)) { 2080bdd1243dSDimitry Andric if (__map_.__front_spare() == 0) 20810b57cec5SDimitry Andric break; 2082bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 208306c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 20840b57cec5SDimitry Andric } 20850b57cec5SDimitry Andric for (; __nb > 0; --__nb, ++__back_capacity) 2086bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 20870b57cec5SDimitry Andric // Done allocating, reorder capacity 2088bdd1243dSDimitry Andric __start_ += __back_capacity * __block_size; 2089*cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2090bdd1243dSDimitry Andric pointer __pt = __map_.back(); 2091bdd1243dSDimitry Andric __map_.pop_back(); 2092bdd1243dSDimitry Andric __map_.push_front(__pt); 209306c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 20940b57cec5SDimitry Andric } 20950b57cec5SDimitry Andric } 20960b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 2097*cb14a3feSDimitry Andric else { 2098bdd1243dSDimitry Andric size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty(); 2099*cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2100*cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__alloc()); 210106c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2102*cb14a3feSDimitry Andric try { 210306c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 210406c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2105bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 210606c3fb27SDimitry Andric // ASan: this is empty container, we have to poison whole block 2107*cb14a3feSDimitry Andric __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); 210806c3fb27SDimitry Andric } 210906c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2110*cb14a3feSDimitry Andric } catch (...) { 211106c3fb27SDimitry Andric __annotate_delete(); 2112*cb14a3feSDimitry Andric for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) 2113bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 21140b57cec5SDimitry Andric throw; 21150b57cec5SDimitry Andric } 211606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2117*cb14a3feSDimitry Andric for (; __back_capacity > 0; --__back_capacity) { 2118bdd1243dSDimitry Andric __buf.push_back(__map_.back()); 2119bdd1243dSDimitry Andric __map_.pop_back(); 21200b57cec5SDimitry Andric } 2121*cb14a3feSDimitry Andric for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i) 21220b57cec5SDimitry Andric __buf.push_back(*__i); 21235f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 21245f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 21255f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 21265f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2127bdd1243dSDimitry Andric __start_ += __ds; 21280b57cec5SDimitry Andric } 21290b57cec5SDimitry Andric} 21300b57cec5SDimitry Andric 21310b57cec5SDimitry Andric// Create back capacity for one block of elements. 21320b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 21330b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2134*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_back_capacity() { 2135bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2136*cb14a3feSDimitry Andric if (__front_spare() >= __block_size) { 2137bdd1243dSDimitry Andric __start_ -= __block_size; 2138bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2139bdd1243dSDimitry Andric __map_.pop_front(); 2140bdd1243dSDimitry Andric __map_.push_back(__pt); 21410b57cec5SDimitry Andric } 21420b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2143*cb14a3feSDimitry Andric else if (__map_.size() < __map_.capacity()) { // we can put the new buffer into the map, but don't shift things around 21440b57cec5SDimitry Andric // until it is allocated. If we throw, we don't need to fix 21450b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2146bdd1243dSDimitry Andric if (__map_.__back_spare() != 0) 2147bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 2148*cb14a3feSDimitry Andric else { 2149bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 21500b57cec5SDimitry Andric // Done allocating, reorder capacity 2151bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2152bdd1243dSDimitry Andric __map_.pop_front(); 2153bdd1243dSDimitry Andric __map_.push_back(__pt); 21540b57cec5SDimitry Andric } 215506c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 21560b57cec5SDimitry Andric } 21570b57cec5SDimitry Andric // Else need to allocate 1 buffer, *and* we need to reallocate __map_. 2158*cb14a3feSDimitry Andric else { 2159*cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2160*cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__alloc()); 21610b57cec5SDimitry Andric 21620b57cec5SDimitry Andric typedef __allocator_destructor<_Allocator> _Dp; 2163*cb14a3feSDimitry Andric unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size)); 21640b57cec5SDimitry Andric __buf.push_back(__hold.get()); 21650b57cec5SDimitry Andric __hold.release(); 21660b57cec5SDimitry Andric 2167*cb14a3feSDimitry Andric for (__map_pointer __i = __map_.end(); __i != __map_.begin();) 21680b57cec5SDimitry Andric __buf.push_front(*--__i); 21695f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 21705f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 21715f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 21725f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 217306c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 21740b57cec5SDimitry Andric } 21750b57cec5SDimitry Andric} 21760b57cec5SDimitry Andric 21770b57cec5SDimitry Andric// Create back capacity for __n elements. 21780b57cec5SDimitry Andric// Strong guarantee. Either do it or don't touch anything. 21790b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2180*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) { 2181bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2182bdd1243dSDimitry Andric size_type __nb = __recommend_blocks(__n + __map_.empty()); 21830b57cec5SDimitry Andric // Number of unused blocks at front: 2184bdd1243dSDimitry Andric size_type __front_capacity = __front_spare() / __block_size; 21855f757f3fSDimitry Andric __front_capacity = std::min(__front_capacity, __nb); // don't take more than you need 21860b57cec5SDimitry Andric __nb -= __front_capacity; // number of blocks need to allocate 21870b57cec5SDimitry Andric // If __nb == 0, then we have sufficient capacity. 2188*cb14a3feSDimitry Andric if (__nb == 0) { 2189bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 2190*cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2191bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2192bdd1243dSDimitry Andric __map_.pop_front(); 2193bdd1243dSDimitry Andric __map_.push_back(__pt); 21940b57cec5SDimitry Andric } 21950b57cec5SDimitry Andric } 21960b57cec5SDimitry Andric // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers 2197*cb14a3feSDimitry Andric else if (__nb <= __map_.capacity() - 2198*cb14a3feSDimitry Andric __map_.size()) { // we can put the new buffers into the map, but don't shift things around 21990b57cec5SDimitry Andric // until all buffers are allocated. If we throw, we don't need to fix 22000b57cec5SDimitry Andric // anything up (any added buffers are undetectible) 2201*cb14a3feSDimitry Andric for (; __nb > 0; --__nb) { 2202bdd1243dSDimitry Andric if (__map_.__back_spare() == 0) 22030b57cec5SDimitry Andric break; 2204bdd1243dSDimitry Andric __map_.push_back(__alloc_traits::allocate(__a, __block_size)); 220506c3fb27SDimitry Andric __annotate_whole_block(__map_.size() - 1, __asan_poison); 22060b57cec5SDimitry Andric } 2207*cb14a3feSDimitry Andric for (; __nb > 0; --__nb, ++__front_capacity, __start_ += __block_size - (__map_.size() == 1)) { 2208bdd1243dSDimitry Andric __map_.push_front(__alloc_traits::allocate(__a, __block_size)); 220906c3fb27SDimitry Andric __annotate_whole_block(0, __asan_poison); 221006c3fb27SDimitry Andric } 22110b57cec5SDimitry Andric // Done allocating, reorder capacity 2212bdd1243dSDimitry Andric __start_ -= __block_size * __front_capacity; 2213*cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2214bdd1243dSDimitry Andric pointer __pt = __map_.front(); 2215bdd1243dSDimitry Andric __map_.pop_front(); 2216bdd1243dSDimitry Andric __map_.push_back(__pt); 22170b57cec5SDimitry Andric } 22180b57cec5SDimitry Andric } 22190b57cec5SDimitry Andric // Else need to allocate __nb buffers, *and* we need to reallocate __map_. 2220*cb14a3feSDimitry Andric else { 2221bdd1243dSDimitry Andric size_type __ds = __front_capacity * __block_size; 2222*cb14a3feSDimitry Andric __split_buffer<pointer, __pointer_allocator&> __buf( 2223*cb14a3feSDimitry Andric std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 2224bdd1243dSDimitry Andric __map_.size() - __front_capacity, 2225bdd1243dSDimitry Andric __map_.__alloc()); 222606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2227*cb14a3feSDimitry Andric try { 222806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 222906c3fb27SDimitry Andric for (; __nb > 0; --__nb) { 2230bdd1243dSDimitry Andric __buf.push_back(__alloc_traits::allocate(__a, __block_size)); 223106c3fb27SDimitry Andric // ASan: this is an empty container, we have to poison the whole block 2232*cb14a3feSDimitry Andric __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size)); 223306c3fb27SDimitry Andric } 223406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2235*cb14a3feSDimitry Andric } catch (...) { 223606c3fb27SDimitry Andric __annotate_delete(); 2237*cb14a3feSDimitry Andric for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i) 2238bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, *__i, __block_size); 22390b57cec5SDimitry Andric throw; 22400b57cec5SDimitry Andric } 224106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2242*cb14a3feSDimitry Andric for (; __front_capacity > 0; --__front_capacity) { 2243bdd1243dSDimitry Andric __buf.push_back(__map_.front()); 2244bdd1243dSDimitry Andric __map_.pop_front(); 22450b57cec5SDimitry Andric } 2246*cb14a3feSDimitry Andric for (__map_pointer __i = __map_.end(); __i != __map_.begin();) 22470b57cec5SDimitry Andric __buf.push_front(*--__i); 22485f757f3fSDimitry Andric std::swap(__map_.__first_, __buf.__first_); 22495f757f3fSDimitry Andric std::swap(__map_.__begin_, __buf.__begin_); 22505f757f3fSDimitry Andric std::swap(__map_.__end_, __buf.__end_); 22515f757f3fSDimitry Andric std::swap(__map_.__end_cap(), __buf.__end_cap()); 2252bdd1243dSDimitry Andric __start_ -= __ds; 22530b57cec5SDimitry Andric } 22540b57cec5SDimitry Andric} 22550b57cec5SDimitry Andric 22560b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2257*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::pop_front() { 225806c3fb27SDimitry Andric size_type __old_sz = size(); 225906c3fb27SDimitry Andric size_type __old_start = __start_; 2260bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2261*cb14a3feSDimitry Andric __alloc_traits::destroy( 2262*cb14a3feSDimitry Andric __a, std::__to_address(*(__map_.begin() + __start_ / __block_size) + __start_ % __block_size)); 2263bdd1243dSDimitry Andric --__size(); 2264bdd1243dSDimitry Andric ++__start_; 226506c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2266e40139ffSDimitry Andric __maybe_remove_front_spare(); 22670b57cec5SDimitry Andric} 22680b57cec5SDimitry Andric 22690b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2270*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::pop_back() { 227106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); 227206c3fb27SDimitry Andric size_type __old_sz = size(); 227306c3fb27SDimitry Andric size_type __old_start = __start_; 2274bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2275bdd1243dSDimitry Andric size_type __p = size() + __start_ - 1; 2276*cb14a3feSDimitry Andric __alloc_traits::destroy(__a, std::__to_address(*(__map_.begin() + __p / __block_size) + __p % __block_size)); 2277bdd1243dSDimitry Andric --__size(); 227806c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2279e40139ffSDimitry Andric __maybe_remove_back_spare(); 22800b57cec5SDimitry Andric} 22810b57cec5SDimitry Andric 22820b57cec5SDimitry Andric// move assign [__f, __l) to [__r, __r + (__l-__f)). 22830b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__f - __r) from __vt. 22840b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 22850b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2286*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 22870b57cec5SDimitry Andric // as if 22880b57cec5SDimitry Andric // for (; __f != __l; ++__f, ++__r) 22895f757f3fSDimitry Andric // *__r = std::move(*__f); 22900b57cec5SDimitry Andric difference_type __n = __l - __f; 2291*cb14a3feSDimitry Andric while (__n > 0) { 22920b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2293bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 22940b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 2295*cb14a3feSDimitry Andric if (__bs > __n) { 22960b57cec5SDimitry Andric __bs = __n; 22970b57cec5SDimitry Andric __fe = __fb + __bs; 22980b57cec5SDimitry Andric } 22990b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 23000b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; 23015f757f3fSDimitry Andric __r = std::move(__fb, __fe, __r); 23020b57cec5SDimitry Andric __n -= __bs; 23030b57cec5SDimitry Andric __f += __bs; 23040b57cec5SDimitry Andric } 23050b57cec5SDimitry Andric return __r; 23060b57cec5SDimitry Andric} 23070b57cec5SDimitry Andric 23080b57cec5SDimitry Andric// move assign [__f, __l) to [__r - (__l-__f), __r) backwards. 23090b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __l) to __vt. 23100b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 23110b57cec5SDimitry Andrictypename deque<_Tp, _Allocator>::iterator 2312*cb14a3feSDimitry Andricdeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 23130b57cec5SDimitry Andric // as if 23140b57cec5SDimitry Andric // while (__f != __l) 23155f757f3fSDimitry Andric // *--__r = std::move(*--__l); 23160b57cec5SDimitry Andric difference_type __n = __l - __f; 2317*cb14a3feSDimitry Andric while (__n > 0) { 23180b57cec5SDimitry Andric --__l; 23190b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 23200b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 23210b57cec5SDimitry Andric difference_type __bs = __le - __lb; 2322*cb14a3feSDimitry Andric if (__bs > __n) { 23230b57cec5SDimitry Andric __bs = __n; 23240b57cec5SDimitry Andric __lb = __le - __bs; 23250b57cec5SDimitry Andric } 23260b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 23270b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; 23285f757f3fSDimitry Andric __r = std::move_backward(__lb, __le, __r); 23290b57cec5SDimitry Andric __n -= __bs; 23300b57cec5SDimitry Andric __l -= __bs - 1; 23310b57cec5SDimitry Andric } 23320b57cec5SDimitry Andric return __r; 23330b57cec5SDimitry Andric} 23340b57cec5SDimitry Andric 23350b57cec5SDimitry Andric// move construct [__f, __l) to [__r, __r + (__l-__f)). 23360b57cec5SDimitry Andric// If __vt points into [__f, __l), then add (__r - __f) to __vt. 23370b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2338*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 2339bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 23400b57cec5SDimitry Andric // as if 2341bdd1243dSDimitry Andric // for (; __f != __l; ++__r, ++__f, ++__size()) 23425f757f3fSDimitry Andric // __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__f)); 23430b57cec5SDimitry Andric difference_type __n = __l - __f; 2344*cb14a3feSDimitry Andric while (__n > 0) { 23450b57cec5SDimitry Andric pointer __fb = __f.__ptr_; 2346bdd1243dSDimitry Andric pointer __fe = *__f.__m_iter_ + __block_size; 23470b57cec5SDimitry Andric difference_type __bs = __fe - __fb; 2348*cb14a3feSDimitry Andric if (__bs > __n) { 23490b57cec5SDimitry Andric __bs = __n; 23500b57cec5SDimitry Andric __fe = __fb + __bs; 23510b57cec5SDimitry Andric } 23520b57cec5SDimitry Andric if (__fb <= __vt && __vt < __fe) 23530b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; 2354bdd1243dSDimitry Andric for (; __fb != __fe; ++__fb, ++__r, ++__size()) 23555f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*__r), std::move(*__fb)); 23560b57cec5SDimitry Andric __n -= __bs; 23570b57cec5SDimitry Andric __f += __bs; 23580b57cec5SDimitry Andric } 23590b57cec5SDimitry Andric} 23600b57cec5SDimitry Andric 23610b57cec5SDimitry Andric// move construct [__f, __l) to [__r - (__l-__f), __r) backwards. 23620b57cec5SDimitry Andric// If __vt points into [__f, __l), then subtract (__l - __r) from __vt. 23630b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2364*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__move_construct_backward_and_check( 2365*cb14a3feSDimitry Andric iterator __f, iterator __l, iterator __r, const_pointer& __vt) { 2366bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 23670b57cec5SDimitry Andric // as if 23680b57cec5SDimitry Andric // for (iterator __j = __l; __j != __f;) 23690b57cec5SDimitry Andric // { 23705f757f3fSDimitry Andric // __alloc_traitsconstruct(__a, std::addressof(*--__r), std::move(*--__j)); 2371bdd1243dSDimitry Andric // --__start_; 2372bdd1243dSDimitry Andric // ++__size(); 23730b57cec5SDimitry Andric // } 23740b57cec5SDimitry Andric difference_type __n = __l - __f; 2375*cb14a3feSDimitry Andric while (__n > 0) { 23760b57cec5SDimitry Andric --__l; 23770b57cec5SDimitry Andric pointer __lb = *__l.__m_iter_; 23780b57cec5SDimitry Andric pointer __le = __l.__ptr_ + 1; 23790b57cec5SDimitry Andric difference_type __bs = __le - __lb; 2380*cb14a3feSDimitry Andric if (__bs > __n) { 23810b57cec5SDimitry Andric __bs = __n; 23820b57cec5SDimitry Andric __lb = __le - __bs; 23830b57cec5SDimitry Andric } 23840b57cec5SDimitry Andric if (__lb <= __vt && __vt < __le) 23850b57cec5SDimitry Andric __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; 2386*cb14a3feSDimitry Andric while (__le != __lb) { 23875f757f3fSDimitry Andric __alloc_traits::construct(__a, std::addressof(*--__r), std::move(*--__le)); 2388bdd1243dSDimitry Andric --__start_; 2389bdd1243dSDimitry Andric ++__size(); 23900b57cec5SDimitry Andric } 23910b57cec5SDimitry Andric __n -= __bs; 23920b57cec5SDimitry Andric __l -= __bs - 1; 23930b57cec5SDimitry Andric } 23940b57cec5SDimitry Andric} 23950b57cec5SDimitry Andric 23960b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2397*cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f) { 239806c3fb27SDimitry Andric size_type __old_sz = size(); 239906c3fb27SDimitry Andric size_type __old_start = __start_; 2400bdd1243dSDimitry Andric iterator __b = begin(); 24010b57cec5SDimitry Andric difference_type __pos = __f - __b; 24020b57cec5SDimitry Andric iterator __p = __b + __pos; 2403bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2404*cb14a3feSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - 1) / 2) { // erase from front 24055f757f3fSDimitry Andric std::move_backward(__b, __p, std::next(__p)); 24065f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2407bdd1243dSDimitry Andric --__size(); 2408bdd1243dSDimitry Andric ++__start_; 240906c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2410e40139ffSDimitry Andric __maybe_remove_front_spare(); 2411*cb14a3feSDimitry Andric } else { // erase from back 24125f757f3fSDimitry Andric iterator __i = std::move(std::next(__p), end(), __p); 24135f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2414bdd1243dSDimitry Andric --__size(); 241506c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2416e40139ffSDimitry Andric __maybe_remove_back_spare(); 24170b57cec5SDimitry Andric } 2418bdd1243dSDimitry Andric return begin() + __pos; 24190b57cec5SDimitry Andric} 24200b57cec5SDimitry Andric 24210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2422*cb14a3feSDimitry Andrictypename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) { 242306c3fb27SDimitry Andric size_type __old_sz = size(); 242406c3fb27SDimitry Andric size_type __old_start = __start_; 24250b57cec5SDimitry Andric difference_type __n = __l - __f; 2426bdd1243dSDimitry Andric iterator __b = begin(); 24270b57cec5SDimitry Andric difference_type __pos = __f - __b; 24280b57cec5SDimitry Andric iterator __p = __b + __pos; 2429*cb14a3feSDimitry Andric if (__n > 0) { 2430bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2431*cb14a3feSDimitry Andric if (static_cast<size_t>(__pos) <= (size() - __n) / 2) { // erase from front 24325f757f3fSDimitry Andric iterator __i = std::move_backward(__b, __p, __p + __n); 24330b57cec5SDimitry Andric for (; __b != __i; ++__b) 24345f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__b)); 2435bdd1243dSDimitry Andric __size() -= __n; 2436bdd1243dSDimitry Andric __start_ += __n; 243706c3fb27SDimitry Andric __annotate_shrink_front(__old_sz, __old_start); 2438e40139ffSDimitry Andric while (__maybe_remove_front_spare()) { 24390b57cec5SDimitry Andric } 2440*cb14a3feSDimitry Andric } else { // erase from back 24415f757f3fSDimitry Andric iterator __i = std::move(__p + __n, end(), __p); 2442bdd1243dSDimitry Andric for (iterator __e = end(); __i != __e; ++__i) 24435f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2444bdd1243dSDimitry Andric __size() -= __n; 244506c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2446e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 24470b57cec5SDimitry Andric } 24480b57cec5SDimitry Andric } 24490b57cec5SDimitry Andric } 2450bdd1243dSDimitry Andric return begin() + __pos; 24510b57cec5SDimitry Andric} 24520b57cec5SDimitry Andric 24530b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2454*cb14a3feSDimitry Andricvoid deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) { 245506c3fb27SDimitry Andric size_type __old_sz = size(); 245606c3fb27SDimitry Andric size_type __old_start = __start_; 2457bdd1243dSDimitry Andric iterator __e = end(); 24580b57cec5SDimitry Andric difference_type __n = __e - __f; 2459*cb14a3feSDimitry Andric if (__n > 0) { 2460bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2461bdd1243dSDimitry Andric iterator __b = begin(); 24620b57cec5SDimitry Andric difference_type __pos = __f - __b; 24630b57cec5SDimitry Andric for (iterator __p = __b + __pos; __p != __e; ++__p) 24645f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__p)); 2465bdd1243dSDimitry Andric __size() -= __n; 246606c3fb27SDimitry Andric __annotate_shrink_back(__old_sz, __old_start); 2467e40139ffSDimitry Andric while (__maybe_remove_back_spare()) { 24680b57cec5SDimitry Andric } 24690b57cec5SDimitry Andric } 24700b57cec5SDimitry Andric} 24710b57cec5SDimitry Andric 24720b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2473*cb14a3feSDimitry Andricinline void deque<_Tp, _Allocator>::swap(deque& __c) 24740b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 24750b57cec5SDimitry Andric _NOEXCEPT 24760b57cec5SDimitry Andric#else 2477*cb14a3feSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) 24780b57cec5SDimitry Andric#endif 24790b57cec5SDimitry Andric{ 2480bdd1243dSDimitry Andric __map_.swap(__c.__map_); 24815f757f3fSDimitry Andric std::swap(__start_, __c.__start_); 24825f757f3fSDimitry Andric std::swap(__size(), __c.__size()); 24835f757f3fSDimitry Andric std::__swap_allocator(__alloc(), __c.__alloc()); 24840b57cec5SDimitry Andric} 24850b57cec5SDimitry Andric 24860b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2487*cb14a3feSDimitry Andricinline void deque<_Tp, _Allocator>::clear() _NOEXCEPT { 248806c3fb27SDimitry Andric __annotate_delete(); 2489bdd1243dSDimitry Andric allocator_type& __a = __alloc(); 2490bdd1243dSDimitry Andric for (iterator __i = begin(), __e = end(); __i != __e; ++__i) 24915f757f3fSDimitry Andric __alloc_traits::destroy(__a, std::addressof(*__i)); 2492bdd1243dSDimitry Andric __size() = 0; 2493*cb14a3feSDimitry Andric while (__map_.size() > 2) { 2494bdd1243dSDimitry Andric __alloc_traits::deallocate(__a, __map_.front(), __block_size); 2495bdd1243dSDimitry Andric __map_.pop_front(); 2496bdd1243dSDimitry Andric } 2497*cb14a3feSDimitry Andric switch (__map_.size()) { 2498bdd1243dSDimitry Andric case 1: 2499bdd1243dSDimitry Andric __start_ = __block_size / 2; 2500bdd1243dSDimitry Andric break; 2501bdd1243dSDimitry Andric case 2: 2502bdd1243dSDimitry Andric __start_ = __block_size; 2503bdd1243dSDimitry Andric break; 2504bdd1243dSDimitry Andric } 250506c3fb27SDimitry Andric __annotate_new(0); 25060b57cec5SDimitry Andric} 25070b57cec5SDimitry Andric 25080b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2509*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25100b57cec5SDimitry Andric const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); 25115f757f3fSDimitry Andric return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); 25120b57cec5SDimitry Andric} 25130b57cec5SDimitry Andric 251406c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 251506c3fb27SDimitry Andric 25160b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2517*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25180b57cec5SDimitry Andric return !(__x == __y); 25190b57cec5SDimitry Andric} 25200b57cec5SDimitry Andric 25210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2522*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25235f757f3fSDimitry Andric return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 25240b57cec5SDimitry Andric} 25250b57cec5SDimitry Andric 25260b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2527*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25280b57cec5SDimitry Andric return __y < __x; 25290b57cec5SDimitry Andric} 25300b57cec5SDimitry Andric 25310b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2532*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25330b57cec5SDimitry Andric return !(__x < __y); 25340b57cec5SDimitry Andric} 25350b57cec5SDimitry Andric 25360b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2537*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 25380b57cec5SDimitry Andric return !(__y < __x); 25390b57cec5SDimitry Andric} 25400b57cec5SDimitry Andric 254106c3fb27SDimitry Andric#else // _LIBCPP_STD_VER <= 17 254206c3fb27SDimitry Andric 254306c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator> 254406c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> 254506c3fb27SDimitry Andricoperator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { 254606c3fb27SDimitry Andric return std::lexicographical_compare_three_way( 254706c3fb27SDimitry Andric __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); 254806c3fb27SDimitry Andric} 254906c3fb27SDimitry Andric 255006c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER <= 17 255106c3fb27SDimitry Andric 25520b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator> 2553*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) 2554*cb14a3feSDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { 25550b57cec5SDimitry Andric __x.swap(__y); 25560b57cec5SDimitry Andric} 25570b57cec5SDimitry Andric 255806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 25590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up> 2560bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 25615ffd83dbSDimitry Andricerase(deque<_Tp, _Allocator>& __c, const _Up& __v) { 25625ffd83dbSDimitry Andric auto __old_size = __c.size(); 25635f757f3fSDimitry Andric __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end()); 25645ffd83dbSDimitry Andric return __old_size - __c.size(); 25655ffd83dbSDimitry Andric} 25660b57cec5SDimitry Andric 25670b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate> 2568bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type 25695ffd83dbSDimitry Andricerase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) { 25705ffd83dbSDimitry Andric auto __old_size = __c.size(); 25715f757f3fSDimitry Andric __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end()); 25725ffd83dbSDimitry Andric return __old_size - __c.size(); 25735ffd83dbSDimitry Andric} 257481ad6265SDimitry Andric 257581ad6265SDimitry Andrictemplate <> 257681ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<char>> = true; 257781ad6265SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 257881ad6265SDimitry Andrictemplate <> 257981ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true; 25800b57cec5SDimitry Andric# endif 25810b57cec5SDimitry Andric 258206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 25830b57cec5SDimitry Andric 25840b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 25850b57cec5SDimitry Andric 258606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 2587bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2588bdd1243dSDimitry Andricnamespace pmr { 2589bdd1243dSDimitry Andrictemplate <class _ValueT> 259006c3fb27SDimitry Andricusing deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>; 2591bdd1243dSDimitry Andric} // namespace pmr 2592bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD 2593bdd1243dSDimitry Andric#endif 2594bdd1243dSDimitry Andric 25950b57cec5SDimitry Andric_LIBCPP_POP_MACROS 25960b57cec5SDimitry Andric 2597bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 2598bdd1243dSDimitry Andric# include <algorithm> 2599bdd1243dSDimitry Andric# include <atomic> 2600bdd1243dSDimitry Andric# include <concepts> 260106c3fb27SDimitry Andric# include <cstdlib> 2602bdd1243dSDimitry Andric# include <functional> 2603bdd1243dSDimitry Andric# include <iosfwd> 2604bdd1243dSDimitry Andric# include <iterator> 260506c3fb27SDimitry Andric# include <type_traits> 2606bdd1243dSDimitry Andric# include <typeinfo> 2607bdd1243dSDimitry Andric#endif 2608bdd1243dSDimitry Andric 26090b57cec5SDimitry Andric#endif // _LIBCPP_DEQUE 2610