blob: 6f7d04be52be4785aba8c1ccc03d32fdc91f8122 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===---------------------------- deque -----------------------------------===//
3//
Howard Hinnantc566dc32010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00005//
Howard Hinnantee11c312010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc51e1022010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_DEQUE
12#define _LIBCPP_DEQUE
13
14/*
15 deque synopsis
16
17namespace std
18{
19
20template <class T, class Allocator = allocator<T> >
21class deque
22{
23public:
24 // types:
25 typedef T value_type;
26 typedef Allocator allocator_type;
27
28 typedef typename allocator_type::reference reference;
29 typedef typename allocator_type::const_reference const_reference;
30 typedef implementation-defined iterator;
31 typedef implementation-defined const_iterator;
32 typedef typename allocator_type::size_type size_type;
33 typedef typename allocator_type::difference_type difference_type;
34
35 typedef typename allocator_type::pointer pointer;
36 typedef typename allocator_type::const_pointer const_pointer;
37 typedef std::reverse_iterator<iterator> reverse_iterator;
38 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
39
40 // construct/copy/destroy:
Howard Hinnantad979ba2011-06-03 15:16:49 +000041 deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +000042 explicit deque(const allocator_type& a);
43 explicit deque(size_type n);
Marshall Clow68098692013-09-09 18:19:45 +000044 explicit deque(size_type n, const allocator_type& a); // C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000045 deque(size_type n, const value_type& v);
46 deque(size_type n, const value_type& v, const allocator_type& a);
47 template <class InputIterator>
48 deque(InputIterator f, InputIterator l);
49 template <class InputIterator>
50 deque(InputIterator f, InputIterator l, const allocator_type& a);
51 deque(const deque& c);
Howard Hinnant4931e092011-06-02 21:38:57 +000052 deque(deque&& c)
53 noexcept(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +000054 deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
55 deque(const deque& c, const allocator_type& a);
56 deque(deque&& c, const allocator_type& a);
57 ~deque();
58
59 deque& operator=(const deque& c);
Howard Hinnant4931e092011-06-02 21:38:57 +000060 deque& operator=(deque&& c)
61 noexcept(
62 allocator_type::propagate_on_container_move_assignment::value &&
63 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +000064 deque& operator=(initializer_list<value_type> il);
65
66 template <class InputIterator>
67 void assign(InputIterator f, InputIterator l);
68 void assign(size_type n, const value_type& v);
69 void assign(initializer_list<value_type> il);
70
Howard Hinnantda2df912011-06-02 16:10:22 +000071 allocator_type get_allocator() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000072
73 // iterators:
74
Howard Hinnantda2df912011-06-02 16:10:22 +000075 iterator begin() noexcept;
76 const_iterator begin() const noexcept;
77 iterator end() noexcept;
78 const_iterator end() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000079
Howard Hinnantda2df912011-06-02 16:10:22 +000080 reverse_iterator rbegin() noexcept;
81 const_reverse_iterator rbegin() const noexcept;
82 reverse_iterator rend() noexcept;
83 const_reverse_iterator rend() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000084
Howard Hinnantda2df912011-06-02 16:10:22 +000085 const_iterator cbegin() const noexcept;
86 const_iterator cend() const noexcept;
87 const_reverse_iterator crbegin() const noexcept;
88 const_reverse_iterator crend() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000089
90 // capacity:
Howard Hinnantda2df912011-06-02 16:10:22 +000091 size_type size() const noexcept;
92 size_type max_size() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000093 void resize(size_type n);
94 void resize(size_type n, const value_type& v);
95 void shrink_to_fit();
Howard Hinnantda2df912011-06-02 16:10:22 +000096 bool empty() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000097
98 // element access:
99 reference operator[](size_type i);
100 const_reference operator[](size_type i) const;
101 reference at(size_type i);
102 const_reference at(size_type i) const;
103 reference front();
104 const_reference front() const;
105 reference back();
106 const_reference back() const;
107
108 // modifiers:
109 void push_front(const value_type& v);
110 void push_front(value_type&& v);
111 void push_back(const value_type& v);
112 void push_back(value_type&& v);
Marshall Clowea52cc42017-01-24 23:09:12 +0000113 template <class... Args> reference emplace_front(Args&&... args); // reference in C++17
114 template <class... Args> reference emplace_back(Args&&... args); // reference in C++17
Howard Hinnantc51e1022010-05-11 19:42:16 +0000115 template <class... Args> iterator emplace(const_iterator p, Args&&... args);
116 iterator insert(const_iterator p, const value_type& v);
117 iterator insert(const_iterator p, value_type&& v);
118 iterator insert(const_iterator p, size_type n, const value_type& v);
119 template <class InputIterator>
Marshall Clow6b612cf2015-01-22 18:33:29 +0000120 iterator insert(const_iterator p, InputIterator f, InputIterator l);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000121 iterator insert(const_iterator p, initializer_list<value_type> il);
122 void pop_front();
123 void pop_back();
124 iterator erase(const_iterator p);
125 iterator erase(const_iterator f, const_iterator l);
Howard Hinnant4931e092011-06-02 21:38:57 +0000126 void swap(deque& c)
Marshall Clow8982dcd2015-07-13 20:04:56 +0000127 noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
Howard Hinnantda2df912011-06-02 16:10:22 +0000128 void clear() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000129};
130
Marshall Clow4cc3a452018-05-18 23:44:13 +0000131template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
132 deque(InputIterator, InputIterator, Allocator = Allocator())
133 -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
134
Howard Hinnantc51e1022010-05-11 19:42:16 +0000135template <class T, class Allocator>
136 bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
137template <class T, class Allocator>
138 bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
139template <class T, class Allocator>
140 bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
141template <class T, class Allocator>
142 bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
143template <class T, class Allocator>
144 bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
145template <class T, class Allocator>
146 bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
147
148// specialized algorithms:
149template <class T, class Allocator>
Howard Hinnant287548a2011-06-03 17:30:28 +0000150 void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
151 noexcept(noexcept(x.swap(y)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000152
Marshall Clow29b53f22018-12-14 18:49:35 +0000153template <class T, class Allocator, class U>
154 void erase(deque<T, Allocator>& c, const U& value); // C++20
155template <class T, class Allocator, class Predicate>
156 void erase_if(deque<T, Allocator>& c, Predicate pred); // C++20
157
Howard Hinnantc51e1022010-05-11 19:42:16 +0000158} // std
159
160*/
161
Howard Hinnantc51e1022010-05-11 19:42:16 +0000162#include <__config>
163#include <__split_buffer>
164#include <type_traits>
165#include <initializer_list>
166#include <iterator>
167#include <algorithm>
168#include <stdexcept>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000169#include <version>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000170
Eric Fiselierf4433a32017-05-31 22:07:49 +0000171#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
172#pragma GCC system_header
173#endif
174
175_LIBCPP_PUSH_MACROS
176#include <__undef_macros>
177
Howard Hinnantc5a5fbd2011-11-29 16:45:27 +0000178
Howard Hinnantc51e1022010-05-11 19:42:16 +0000179_LIBCPP_BEGIN_NAMESPACE_STD
180
181template <class _Tp, class _Allocator> class __deque_base;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000182template <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000183
184template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
185 class _DiffType, _DiffType _BlockSize>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000186class _LIBCPP_TEMPLATE_VIS __deque_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187
188template <class _RAIter,
189 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
190__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
191copy(_RAIter __f,
192 _RAIter __l,
193 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
194 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
195
196template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
197 class _OutputIterator>
198_OutputIterator
199copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
200 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
201 _OutputIterator __r);
202
203template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
204 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
205__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
206copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
207 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
208 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
209
210template <class _RAIter,
211 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
212__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
213copy_backward(_RAIter __f,
214 _RAIter __l,
215 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
216 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
217
218template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
219 class _OutputIterator>
220_OutputIterator
221copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
222 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
223 _OutputIterator __r);
224
225template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
226 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
227__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
228copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
229 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
230 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
231
232template <class _RAIter,
233 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
234__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
235move(_RAIter __f,
236 _RAIter __l,
237 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
238 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
239
240template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
241 class _OutputIterator>
242_OutputIterator
243move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
244 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
245 _OutputIterator __r);
246
247template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
248 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
249__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
250move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
251 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
252 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
253
254template <class _RAIter,
255 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
256__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
257move_backward(_RAIter __f,
258 _RAIter __l,
259 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
260 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
261
262template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
263 class _OutputIterator>
264_OutputIterator
265move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
266 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
267 _OutputIterator __r);
268
269template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
270 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
271__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
272move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
273 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
274 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
275
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000276template <class _ValueType, class _DiffType>
277struct __deque_block_size {
278 static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
279};
280
Howard Hinnantc51e1022010-05-11 19:42:16 +0000281template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000282 class _DiffType, _DiffType _BS =
283#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
284// Keep template parameter to avoid changing all template declarations thoughout
285// this file.
286 0
287#else
288 __deque_block_size<_ValueType, _DiffType>::value
289#endif
290 >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000291class _LIBCPP_TEMPLATE_VIS __deque_iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +0000292{
293 typedef _MapPointer __map_iterator;
294public:
295 typedef _Pointer pointer;
296 typedef _DiffType difference_type;
297private:
298 __map_iterator __m_iter_;
299 pointer __ptr_;
300
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000301 static const difference_type __block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000302public:
303 typedef _ValueType value_type;
304 typedef random_access_iterator_tag iterator_category;
305 typedef _Reference reference;
306
Marshall Clow7a3a61d2013-08-06 16:14:36 +0000307 _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT
308#if _LIBCPP_STD_VER > 11
309 : __m_iter_(nullptr), __ptr_(nullptr)
310#endif
311 {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000312
Howard Hinnantc834c512011-11-29 18:15:50 +0000313 template <class _Pp, class _Rp, class _MP>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000314 _LIBCPP_INLINE_VISIBILITY
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000315 __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
Howard Hinnantc834c512011-11-29 18:15:50 +0000316 typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000317 : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
318
319 _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;}
320 _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;}
321
322 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++()
323 {
324 if (++__ptr_ - *__m_iter_ == __block_size)
325 {
326 ++__m_iter_;
327 __ptr_ = *__m_iter_;
328 }
329 return *this;
330 }
331
332 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int)
333 {
334 __deque_iterator __tmp = *this;
335 ++(*this);
336 return __tmp;
337 }
338
339 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--()
340 {
341 if (__ptr_ == *__m_iter_)
342 {
343 --__m_iter_;
344 __ptr_ = *__m_iter_ + __block_size;
345 }
346 --__ptr_;
347 return *this;
348 }
349
350 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int)
351 {
352 __deque_iterator __tmp = *this;
353 --(*this);
354 return __tmp;
355 }
356
357 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n)
358 {
359 if (__n != 0)
360 {
361 __n += __ptr_ - *__m_iter_;
362 if (__n > 0)
363 {
364 __m_iter_ += __n / __block_size;
365 __ptr_ = *__m_iter_ + __n % __block_size;
366 }
367 else // (__n < 0)
368 {
369 difference_type __z = __block_size - 1 - __n;
370 __m_iter_ -= __z / __block_size;
371 __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
372 }
373 }
374 return *this;
375 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000376
Howard Hinnantc51e1022010-05-11 19:42:16 +0000377 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n)
378 {
379 return *this += -__n;
380 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000381
Howard Hinnantc51e1022010-05-11 19:42:16 +0000382 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const
383 {
384 __deque_iterator __t(*this);
385 __t += __n;
386 return __t;
387 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000388
Howard Hinnantc51e1022010-05-11 19:42:16 +0000389 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const
390 {
391 __deque_iterator __t(*this);
392 __t -= __n;
393 return __t;
394 }
395
396 _LIBCPP_INLINE_VISIBILITY
397 friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
398 {return __it + __n;}
399
400 _LIBCPP_INLINE_VISIBILITY
401 friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
402 {
403 if (__x != __y)
404 return (__x.__m_iter_ - __y.__m_iter_) * __block_size
405 + (__x.__ptr_ - *__x.__m_iter_)
406 - (__y.__ptr_ - *__y.__m_iter_);
407 return 0;
408 }
409
410 _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
411 {return *(*this + __n);}
412
413 _LIBCPP_INLINE_VISIBILITY friend
414 bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
415 {return __x.__ptr_ == __y.__ptr_;}
416
417 _LIBCPP_INLINE_VISIBILITY friend
418 bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
419 {return !(__x == __y);}
420
421 _LIBCPP_INLINE_VISIBILITY friend
422 bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
423 {return __x.__m_iter_ < __y.__m_iter_ ||
424 (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
425
426 _LIBCPP_INLINE_VISIBILITY friend
427 bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
428 {return __y < __x;}
429
430 _LIBCPP_INLINE_VISIBILITY friend
431 bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
432 {return !(__y < __x);}
433
434 _LIBCPP_INLINE_VISIBILITY friend
435 bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
436 {return !(__x < __y);}
437
438private:
Howard Hinnantda2df912011-06-02 16:10:22 +0000439 _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000440 : __m_iter_(__m), __ptr_(__p) {}
441
Howard Hinnantc834c512011-11-29 18:15:50 +0000442 template <class _Tp, class _Ap> friend class __deque_base;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000443 template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque;
Howard Hinnantc834c512011-11-29 18:15:50 +0000444 template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000445 friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000446
447 template <class _RAIter,
448 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
449 friend
450 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
451 copy(_RAIter __f,
452 _RAIter __l,
453 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
454 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
455
456 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
457 class _OutputIterator>
458 friend
459 _OutputIterator
460 copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
461 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
462 _OutputIterator __r);
463
464 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
465 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
466 friend
467 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
468 copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
469 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
470 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
471
472 template <class _RAIter,
473 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
474 friend
475 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
476 copy_backward(_RAIter __f,
477 _RAIter __l,
478 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
479 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
480
481 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
482 class _OutputIterator>
483 friend
484 _OutputIterator
485 copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
486 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
487 _OutputIterator __r);
488
489 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
490 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
491 friend
492 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
493 copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
494 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
495 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
496
497 template <class _RAIter,
498 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
499 friend
500 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
501 move(_RAIter __f,
502 _RAIter __l,
503 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
504 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
505
506 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
507 class _OutputIterator>
508 friend
509 _OutputIterator
510 move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
511 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
512 _OutputIterator __r);
513
514 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
515 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
516 friend
517 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
518 move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
519 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
520 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
521
522 template <class _RAIter,
523 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
524 friend
525 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
526 move_backward(_RAIter __f,
527 _RAIter __l,
528 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
529 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
530
531 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
532 class _OutputIterator>
533 friend
534 _OutputIterator
535 move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
536 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
537 _OutputIterator __r);
538
539 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
540 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
541 friend
542 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
543 move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
544 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
545 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
546};
547
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000548template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
549 class _DiffType, _DiffType _BlockSize>
550const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
551 _DiffType, _BlockSize>::__block_size =
552 __deque_block_size<_ValueType, _DiffType>::value;
553
Howard Hinnantc51e1022010-05-11 19:42:16 +0000554// copy
555
556template <class _RAIter,
557 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
558__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
559copy(_RAIter __f,
560 _RAIter __l,
561 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
562 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
563{
564 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
565 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000566 const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000567 while (__f != __l)
568 {
569 pointer __rb = __r.__ptr_;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000570 pointer __re = *__r.__m_iter_ + __block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000571 difference_type __bs = __re - __rb;
572 difference_type __n = __l - __f;
573 _RAIter __m = __l;
574 if (__n > __bs)
575 {
576 __n = __bs;
577 __m = __f + __n;
578 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000579 _VSTD::copy(__f, __m, __rb);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000580 __f = __m;
581 __r += __n;
582 }
583 return __r;
584}
585
586template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
587 class _OutputIterator>
588_OutputIterator
589copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
590 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
591 _OutputIterator __r)
592{
593 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
594 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000595 const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000596 difference_type __n = __l - __f;
597 while (__n > 0)
598 {
599 pointer __fb = __f.__ptr_;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000600 pointer __fe = *__f.__m_iter_ + __block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000601 difference_type __bs = __fe - __fb;
602 if (__bs > __n)
603 {
604 __bs = __n;
605 __fe = __fb + __bs;
606 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000607 __r = _VSTD::copy(__fb, __fe, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000608 __n -= __bs;
609 __f += __bs;
610 }
611 return __r;
612}
613
614template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
615 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
616__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
617copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
618 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
619 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
620{
621 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
622 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000623 const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000624 difference_type __n = __l - __f;
625 while (__n > 0)
626 {
627 pointer __fb = __f.__ptr_;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000628 pointer __fe = *__f.__m_iter_ + __block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000629 difference_type __bs = __fe - __fb;
630 if (__bs > __n)
631 {
632 __bs = __n;
633 __fe = __fb + __bs;
634 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000635 __r = _VSTD::copy(__fb, __fe, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000636 __n -= __bs;
637 __f += __bs;
638 }
639 return __r;
640}
641
642// copy_backward
643
644template <class _RAIter,
645 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
646__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
647copy_backward(_RAIter __f,
648 _RAIter __l,
649 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
650 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
651{
652 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
653 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
654 while (__f != __l)
655 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000656 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000657 pointer __rb = *__rp.__m_iter_;
658 pointer __re = __rp.__ptr_ + 1;
659 difference_type __bs = __re - __rb;
660 difference_type __n = __l - __f;
661 _RAIter __m = __f;
662 if (__n > __bs)
663 {
664 __n = __bs;
665 __m = __l - __n;
666 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000667 _VSTD::copy_backward(__m, __l, __re);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000668 __l = __m;
669 __r -= __n;
670 }
671 return __r;
672}
673
674template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
675 class _OutputIterator>
676_OutputIterator
677copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
678 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
679 _OutputIterator __r)
680{
681 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
682 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
683 difference_type __n = __l - __f;
684 while (__n > 0)
685 {
686 --__l;
687 pointer __lb = *__l.__m_iter_;
688 pointer __le = __l.__ptr_ + 1;
689 difference_type __bs = __le - __lb;
690 if (__bs > __n)
691 {
692 __bs = __n;
693 __lb = __le - __bs;
694 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000695 __r = _VSTD::copy_backward(__lb, __le, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000696 __n -= __bs;
697 __l -= __bs - 1;
698 }
699 return __r;
700}
701
702template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
703 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
704__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
705copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
706 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
707 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
708{
709 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
710 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
711 difference_type __n = __l - __f;
712 while (__n > 0)
713 {
714 --__l;
715 pointer __lb = *__l.__m_iter_;
716 pointer __le = __l.__ptr_ + 1;
717 difference_type __bs = __le - __lb;
718 if (__bs > __n)
719 {
720 __bs = __n;
721 __lb = __le - __bs;
722 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000723 __r = _VSTD::copy_backward(__lb, __le, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000724 __n -= __bs;
725 __l -= __bs - 1;
726 }
727 return __r;
728}
729
730// move
731
732template <class _RAIter,
733 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
734__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
735move(_RAIter __f,
736 _RAIter __l,
737 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
738 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
739{
740 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
741 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000742 const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000743 while (__f != __l)
744 {
745 pointer __rb = __r.__ptr_;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000746 pointer __re = *__r.__m_iter_ + __block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000747 difference_type __bs = __re - __rb;
748 difference_type __n = __l - __f;
749 _RAIter __m = __l;
750 if (__n > __bs)
751 {
752 __n = __bs;
753 __m = __f + __n;
754 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000755 _VSTD::move(__f, __m, __rb);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000756 __f = __m;
757 __r += __n;
758 }
759 return __r;
760}
761
762template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
763 class _OutputIterator>
764_OutputIterator
765move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
766 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
767 _OutputIterator __r)
768{
769 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
770 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000771 const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000772 difference_type __n = __l - __f;
773 while (__n > 0)
774 {
775 pointer __fb = __f.__ptr_;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000776 pointer __fe = *__f.__m_iter_ + __block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000777 difference_type __bs = __fe - __fb;
778 if (__bs > __n)
779 {
780 __bs = __n;
781 __fe = __fb + __bs;
782 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000783 __r = _VSTD::move(__fb, __fe, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000784 __n -= __bs;
785 __f += __bs;
786 }
787 return __r;
788}
789
790template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
791 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
792__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
793move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
794 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
795 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
796{
797 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
798 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000799 const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000800 difference_type __n = __l - __f;
801 while (__n > 0)
802 {
803 pointer __fb = __f.__ptr_;
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000804 pointer __fe = *__f.__m_iter_ + __block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000805 difference_type __bs = __fe - __fb;
806 if (__bs > __n)
807 {
808 __bs = __n;
809 __fe = __fb + __bs;
810 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000811 __r = _VSTD::move(__fb, __fe, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000812 __n -= __bs;
813 __f += __bs;
814 }
815 return __r;
816}
817
818// move_backward
819
820template <class _RAIter,
821 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
822__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
823move_backward(_RAIter __f,
824 _RAIter __l,
825 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
826 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
827{
828 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
829 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
830 while (__f != __l)
831 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000832 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000833 pointer __rb = *__rp.__m_iter_;
834 pointer __re = __rp.__ptr_ + 1;
835 difference_type __bs = __re - __rb;
836 difference_type __n = __l - __f;
837 _RAIter __m = __f;
838 if (__n > __bs)
839 {
840 __n = __bs;
841 __m = __l - __n;
842 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000843 _VSTD::move_backward(__m, __l, __re);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000844 __l = __m;
845 __r -= __n;
846 }
847 return __r;
848}
849
850template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
851 class _OutputIterator>
852_OutputIterator
853move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
854 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
855 _OutputIterator __r)
856{
857 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
858 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
859 difference_type __n = __l - __f;
860 while (__n > 0)
861 {
862 --__l;
863 pointer __lb = *__l.__m_iter_;
864 pointer __le = __l.__ptr_ + 1;
865 difference_type __bs = __le - __lb;
866 if (__bs > __n)
867 {
868 __bs = __n;
869 __lb = __le - __bs;
870 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000871 __r = _VSTD::move_backward(__lb, __le, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000872 __n -= __bs;
873 __l -= __bs - 1;
874 }
875 return __r;
876}
877
878template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
879 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
880__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
881move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
882 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
883 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
884{
885 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
886 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
887 difference_type __n = __l - __f;
888 while (__n > 0)
889 {
890 --__l;
891 pointer __lb = *__l.__m_iter_;
892 pointer __le = __l.__ptr_ + 1;
893 difference_type __bs = __le - __lb;
894 if (__bs > __n)
895 {
896 __bs = __n;
897 __lb = __le - __bs;
898 }
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000899 __r = _VSTD::move_backward(__lb, __le, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000900 __n -= __bs;
901 __l -= __bs - 1;
902 }
903 return __r;
904}
905
906template <bool>
907class __deque_base_common
908{
909protected:
Marshall Clow8fea1612016-08-25 15:09:01 +0000910 _LIBCPP_NORETURN void __throw_length_error() const;
911 _LIBCPP_NORETURN void __throw_out_of_range() const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000912};
913
914template <bool __b>
915void
916__deque_base_common<__b>::__throw_length_error() const
917{
Marshall Clow8fea1612016-08-25 15:09:01 +0000918 _VSTD::__throw_length_error("deque");
Howard Hinnantc51e1022010-05-11 19:42:16 +0000919}
920
921template <bool __b>
922void
923__deque_base_common<__b>::__throw_out_of_range() const
924{
Marshall Clow8fea1612016-08-25 15:09:01 +0000925 _VSTD::__throw_out_of_range("deque");
Howard Hinnantc51e1022010-05-11 19:42:16 +0000926}
927
928template <class _Tp, class _Allocator>
929class __deque_base
930 : protected __deque_base_common<true>
931{
932 __deque_base(const __deque_base& __c);
933 __deque_base& operator=(const __deque_base& __c);
Marshall Clow4cc3a452018-05-18 23:44:13 +0000934public:
Howard Hinnantc51e1022010-05-11 19:42:16 +0000935 typedef _Allocator allocator_type;
936 typedef allocator_traits<allocator_type> __alloc_traits;
Marshall Clow4cc3a452018-05-18 23:44:13 +0000937 typedef typename __alloc_traits::size_type size_type;
938protected:
939 typedef _Tp value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000940 typedef value_type& reference;
941 typedef const value_type& const_reference;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000942 typedef typename __alloc_traits::difference_type difference_type;
943 typedef typename __alloc_traits::pointer pointer;
944 typedef typename __alloc_traits::const_pointer const_pointer;
945
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000946 static const difference_type __block_size;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000947
Marshall Clow940e01c2015-04-07 05:21:38 +0000948 typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000949 typedef allocator_traits<__pointer_allocator> __map_traits;
950 typedef typename __map_traits::pointer __map_pointer;
Marshall Clow940e01c2015-04-07 05:21:38 +0000951 typedef typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type __const_pointer_allocator;
Howard Hinnantdcb73a32013-06-23 21:17:24 +0000952 typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000953 typedef __split_buffer<pointer, __pointer_allocator> __map;
954
955 typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000956 difference_type> iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000957 typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
Evgeniy Stepanovc299de22015-11-06 22:02:29 +0000958 difference_type> const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000959
Marshall Clow4cc3a452018-05-18 23:44:13 +0000960protected:
Howard Hinnantc51e1022010-05-11 19:42:16 +0000961 __map __map_;
962 size_type __start_;
963 __compressed_pair<size_type, allocator_type> __size_;
964
Howard Hinnantda2df912011-06-02 16:10:22 +0000965 iterator begin() _NOEXCEPT;
966 const_iterator begin() const _NOEXCEPT;
967 iterator end() _NOEXCEPT;
968 const_iterator end() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000969
970 _LIBCPP_INLINE_VISIBILITY size_type& size() {return __size_.first();}
Howard Hinnantda2df912011-06-02 16:10:22 +0000971 _LIBCPP_INLINE_VISIBILITY
972 const size_type& size() const _NOEXCEPT {return __size_.first();}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000973 _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() {return __size_.second();}
Howard Hinnantda2df912011-06-02 16:10:22 +0000974 _LIBCPP_INLINE_VISIBILITY
975 const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000976
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000977 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantad979ba2011-06-03 15:16:49 +0000978 __deque_base()
979 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000980 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000981 explicit __deque_base(const allocator_type& __a);
Howard Hinnantca2fc222011-06-02 20:00:14 +0000982public:
Howard Hinnantc51e1022010-05-11 19:42:16 +0000983 ~__deque_base();
984
Eric Fiselier212e3f22017-04-16 03:17:01 +0000985#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantca2fc222011-06-02 20:00:14 +0000986 __deque_base(__deque_base&& __c)
987 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000988 __deque_base(__deque_base&& __c, const allocator_type& __a);
Eric Fiselier212e3f22017-04-16 03:17:01 +0000989#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +0000990
Howard Hinnantca2fc222011-06-02 20:00:14 +0000991 void swap(__deque_base& __c)
Marshall Clow8982dcd2015-07-13 20:04:56 +0000992#if _LIBCPP_STD_VER >= 14
993 _NOEXCEPT;
994#else
Louis Dionne72f24392018-12-12 23:58:25 +0000995 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
Marshall Clow8982dcd2015-07-13 20:04:56 +0000996 __is_nothrow_swappable<allocator_type>::value);
997#endif
Howard Hinnantca2fc222011-06-02 20:00:14 +0000998protected:
Howard Hinnantda2df912011-06-02 16:10:22 +0000999 void clear() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001000
1001 bool __invariants() const;
1002
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001003 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001004 void __move_assign(__deque_base& __c)
Howard Hinnant4931e092011-06-02 21:38:57 +00001005 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1006 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001007 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001008 __map_ = _VSTD::move(__c.__map_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001009 __start_ = __c.__start_;
1010 size() = __c.size();
1011 __move_assign_alloc(__c);
1012 __c.__start_ = __c.size() = 0;
1013 }
1014
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001015 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001016 void __move_assign_alloc(__deque_base& __c)
Howard Hinnantca2fc222011-06-02 20:00:14 +00001017 _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
1018 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001019 {__move_assign_alloc(__c, integral_constant<bool,
1020 __alloc_traits::propagate_on_container_move_assignment::value>());}
1021
1022private:
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001023 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc2734962011-09-02 20:42:31 +00001024 void __move_assign_alloc(__deque_base& __c, true_type)
Howard Hinnantca2fc222011-06-02 20:00:14 +00001025 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001026 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001027 __alloc() = _VSTD::move(__c.__alloc());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001028 }
1029
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001030 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant28b24882011-12-01 20:21:04 +00001031 void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001032 {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001033};
1034
1035template <class _Tp, class _Allocator>
Evgeniy Stepanovc299de22015-11-06 22:02:29 +00001036const typename __deque_base<_Tp, _Allocator>::difference_type
1037 __deque_base<_Tp, _Allocator>::__block_size =
1038 __deque_block_size<value_type, difference_type>::value;
1039
1040template <class _Tp, class _Allocator>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001041bool
1042__deque_base<_Tp, _Allocator>::__invariants() const
1043{
1044 if (!__map_.__invariants())
1045 return false;
1046 if (__map_.size() >= size_type(-1) / __block_size)
1047 return false;
1048 for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
1049 __i != __e; ++__i)
1050 if (*__i == nullptr)
1051 return false;
1052 if (__map_.size() != 0)
1053 {
1054 if (size() >= __map_.size() * __block_size)
1055 return false;
1056 if (__start_ >= __map_.size() * __block_size - size())
1057 return false;
1058 }
1059 else
1060 {
1061 if (size() != 0)
1062 return false;
1063 if (__start_ != 0)
1064 return false;
1065 }
1066 return true;
1067}
1068
1069template <class _Tp, class _Allocator>
1070typename __deque_base<_Tp, _Allocator>::iterator
Howard Hinnantda2df912011-06-02 16:10:22 +00001071__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001072{
1073 __map_pointer __mp = __map_.begin() + __start_ / __block_size;
1074 return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1075}
1076
1077template <class _Tp, class _Allocator>
1078typename __deque_base<_Tp, _Allocator>::const_iterator
Howard Hinnantda2df912011-06-02 16:10:22 +00001079__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001080{
Howard Hinnantdcb73a32013-06-23 21:17:24 +00001081 __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001082 return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1083}
1084
1085template <class _Tp, class _Allocator>
1086typename __deque_base<_Tp, _Allocator>::iterator
Howard Hinnantda2df912011-06-02 16:10:22 +00001087__deque_base<_Tp, _Allocator>::end() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001088{
1089 size_type __p = size() + __start_;
1090 __map_pointer __mp = __map_.begin() + __p / __block_size;
1091 return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1092}
1093
1094template <class _Tp, class _Allocator>
1095typename __deque_base<_Tp, _Allocator>::const_iterator
Howard Hinnantda2df912011-06-02 16:10:22 +00001096__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001097{
1098 size_type __p = size() + __start_;
Howard Hinnantdcb73a32013-06-23 21:17:24 +00001099 __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001100 return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1101}
1102
1103template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001104inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001105__deque_base<_Tp, _Allocator>::__deque_base()
Howard Hinnantad979ba2011-06-03 15:16:49 +00001106 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001107 : __start_(0), __size_(0) {}
1108
1109template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001110inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001111__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
1112 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
1113
1114template <class _Tp, class _Allocator>
1115__deque_base<_Tp, _Allocator>::~__deque_base()
1116{
1117 clear();
1118 typename __map::iterator __i = __map_.begin();
1119 typename __map::iterator __e = __map_.end();
1120 for (; __i != __e; ++__i)
1121 __alloc_traits::deallocate(__alloc(), *__i, __block_size);
1122}
1123
Eric Fiselier212e3f22017-04-16 03:17:01 +00001124#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001125
1126template <class _Tp, class _Allocator>
1127__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)
Howard Hinnantca2fc222011-06-02 20:00:14 +00001128 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001129 : __map_(_VSTD::move(__c.__map_)),
1130 __start_(_VSTD::move(__c.__start_)),
1131 __size_(_VSTD::move(__c.__size_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001132{
1133 __c.__start_ = 0;
1134 __c.size() = 0;
1135}
1136
1137template <class _Tp, class _Allocator>
1138__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001139 : __map_(_VSTD::move(__c.__map_), __pointer_allocator(__a)),
1140 __start_(_VSTD::move(__c.__start_)),
1141 __size_(_VSTD::move(__c.size()), __a)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001142{
1143 if (__a == __c.__alloc())
1144 {
1145 __c.__start_ = 0;
1146 __c.size() = 0;
1147 }
1148 else
1149 {
1150 __map_.clear();
1151 __start_ = 0;
1152 size() = 0;
1153 }
1154}
1155
Eric Fiselier212e3f22017-04-16 03:17:01 +00001156#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001157
1158template <class _Tp, class _Allocator>
1159void
1160__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
Marshall Clow8982dcd2015-07-13 20:04:56 +00001161#if _LIBCPP_STD_VER >= 14
1162 _NOEXCEPT
1163#else
Louis Dionne72f24392018-12-12 23:58:25 +00001164 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
Marshall Clow8982dcd2015-07-13 20:04:56 +00001165 __is_nothrow_swappable<allocator_type>::value)
1166#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001167{
1168 __map_.swap(__c.__map_);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001169 _VSTD::swap(__start_, __c.__start_);
1170 _VSTD::swap(size(), __c.size());
Marshall Clow8982dcd2015-07-13 20:04:56 +00001171 __swap_allocator(__alloc(), __c.__alloc());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001172}
1173
1174template <class _Tp, class _Allocator>
1175void
Howard Hinnantda2df912011-06-02 16:10:22 +00001176__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001177{
1178 allocator_type& __a = __alloc();
1179 for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001180 __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001181 size() = 0;
1182 while (__map_.size() > 2)
1183 {
1184 __alloc_traits::deallocate(__a, __map_.front(), __block_size);
1185 __map_.pop_front();
1186 }
1187 switch (__map_.size())
1188 {
1189 case 1:
1190 __start_ = __block_size / 2;
1191 break;
1192 case 2:
1193 __start_ = __block_size;
1194 break;
1195 }
1196}
1197
Marshall Clow65cd4c62015-02-18 17:24:08 +00001198template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001199class _LIBCPP_TEMPLATE_VIS deque
Howard Hinnantc51e1022010-05-11 19:42:16 +00001200 : private __deque_base<_Tp, _Allocator>
1201{
1202public:
1203 // types:
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001204
Howard Hinnantc51e1022010-05-11 19:42:16 +00001205 typedef _Tp value_type;
1206 typedef _Allocator allocator_type;
1207
Marshall Clow5128cf32015-11-26 01:24:04 +00001208 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
1209 "Allocator::value_type must be same type as value_type");
1210
Howard Hinnantc51e1022010-05-11 19:42:16 +00001211 typedef __deque_base<value_type, allocator_type> __base;
1212
1213 typedef typename __base::__alloc_traits __alloc_traits;
1214 typedef typename __base::reference reference;
1215 typedef typename __base::const_reference const_reference;
1216 typedef typename __base::iterator iterator;
1217 typedef typename __base::const_iterator const_iterator;
1218 typedef typename __base::size_type size_type;
1219 typedef typename __base::difference_type difference_type;
1220
1221 typedef typename __base::pointer pointer;
1222 typedef typename __base::const_pointer const_pointer;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001223 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
1224 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001225
1226 // construct/copy/destroy:
Howard Hinnantad979ba2011-06-03 15:16:49 +00001227 _LIBCPP_INLINE_VISIBILITY
1228 deque()
1229 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
1230 {}
Marshall Clow7ed23a72014-03-05 19:06:20 +00001231 _LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001232 explicit deque(size_type __n);
Marshall Clowbc4fcb42013-09-07 16:16:19 +00001233#if _LIBCPP_STD_VER > 11
1234 explicit deque(size_type __n, const _Allocator& __a);
1235#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001236 deque(size_type __n, const value_type& __v);
1237 deque(size_type __n, const value_type& __v, const allocator_type& __a);
1238 template <class _InputIter>
1239 deque(_InputIter __f, _InputIter __l,
1240 typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
1241 template <class _InputIter>
1242 deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1243 typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
1244 deque(const deque& __c);
1245 deque(const deque& __c, const allocator_type& __a);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001246
1247 deque& operator=(const deque& __c);
Eric Fiselier212e3f22017-04-16 03:17:01 +00001248
1249#ifndef _LIBCPP_CXX03_LANG
1250 deque(initializer_list<value_type> __il);
1251 deque(initializer_list<value_type> __il, const allocator_type& __a);
1252
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001253 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001254 deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
1255
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantca2fc222011-06-02 20:00:14 +00001257 deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001258 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001259 deque(deque&& __c, const allocator_type& __a);
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001260 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantca2fc222011-06-02 20:00:14 +00001261 deque& operator=(deque&& __c)
Howard Hinnant4931e092011-06-02 21:38:57 +00001262 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1263 is_nothrow_move_assignable<allocator_type>::value);
Eric Fiselier212e3f22017-04-16 03:17:01 +00001264
1265 _LIBCPP_INLINE_VISIBILITY
1266 void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
1267#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001268
1269 template <class _InputIter>
1270 void assign(_InputIter __f, _InputIter __l,
1271 typename enable_if<__is_input_iterator<_InputIter>::value &&
1272 !__is_random_access_iterator<_InputIter>::value>::type* = 0);
1273 template <class _RAIter>
1274 void assign(_RAIter __f, _RAIter __l,
1275 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
1276 void assign(size_type __n, const value_type& __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001277
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001278 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001279 allocator_type get_allocator() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001280
1281 // iterators:
1282
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001284 iterator begin() _NOEXCEPT {return __base::begin();}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001285 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001286 const_iterator begin() const _NOEXCEPT {return __base::begin();}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001287 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001288 iterator end() _NOEXCEPT {return __base::end();}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001289 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001290 const_iterator end() const _NOEXCEPT {return __base::end();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001291
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001293 reverse_iterator rbegin() _NOEXCEPT
1294 {return reverse_iterator(__base::end());}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001295 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001296 const_reverse_iterator rbegin() const _NOEXCEPT
1297 {return const_reverse_iterator(__base::end());}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001298 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001299 reverse_iterator rend() _NOEXCEPT
1300 {return reverse_iterator(__base::begin());}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001301 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001302 const_reverse_iterator rend() const _NOEXCEPT
1303 {return const_reverse_iterator(__base::begin());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001304
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001306 const_iterator cbegin() const _NOEXCEPT
1307 {return __base::begin();}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001309 const_iterator cend() const _NOEXCEPT
1310 {return __base::end();}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001312 const_reverse_iterator crbegin() const _NOEXCEPT
1313 {return const_reverse_iterator(__base::end());}
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001315 const_reverse_iterator crend() const _NOEXCEPT
1316 {return const_reverse_iterator(__base::begin());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001317
1318 // capacity:
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001319 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001320 size_type size() const _NOEXCEPT {return __base::size();}
1321 _LIBCPP_INLINE_VISIBILITY
1322 size_type max_size() const _NOEXCEPT
Eric Fiselierb5d9f442016-11-23 01:18:56 +00001323 {return std::min<size_type>(
1324 __alloc_traits::max_size(__base::__alloc()),
1325 numeric_limits<difference_type>::max());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001326 void resize(size_type __n);
1327 void resize(size_type __n, const value_type& __v);
Howard Hinnant4931e092011-06-02 21:38:57 +00001328 void shrink_to_fit() _NOEXCEPT;
Marshall Clow425f5752017-11-15 05:51:26 +00001329 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001330 bool empty() const _NOEXCEPT {return __base::size() == 0;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001331
1332 // element access:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001334 reference operator[](size_type __i);
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001335 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001336 const_reference operator[](size_type __i) const;
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001337 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001338 reference at(size_type __i);
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001339 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001340 const_reference at(size_type __i) const;
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001341 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001342 reference front();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001343 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001344 const_reference front() const;
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001345 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001346 reference back();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001347 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001348 const_reference back() const;
1349
1350 // 23.2.2.3 modifiers:
1351 void push_front(const value_type& __v);
1352 void push_back(const value_type& __v);
Eric Fiselier212e3f22017-04-16 03:17:01 +00001353#ifndef _LIBCPP_CXX03_LANG
Marshall Clowea52cc42017-01-24 23:09:12 +00001354#if _LIBCPP_STD_VER > 14
Eric Fiselier34ba5b92016-07-21 03:20:17 +00001355 template <class... _Args> reference emplace_front(_Args&&... __args);
Marshall Clowea52cc42017-01-24 23:09:12 +00001356 template <class... _Args> reference emplace_back (_Args&&... __args);
1357#else
1358 template <class... _Args> void emplace_front(_Args&&... __args);
1359 template <class... _Args> void emplace_back (_Args&&... __args);
1360#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001361 template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);
Eric Fiselier212e3f22017-04-16 03:17:01 +00001362
Howard Hinnantc51e1022010-05-11 19:42:16 +00001363 void push_front(value_type&& __v);
1364 void push_back(value_type&& __v);
1365 iterator insert(const_iterator __p, value_type&& __v);
Eric Fiselier212e3f22017-04-16 03:17:01 +00001366
1367 _LIBCPP_INLINE_VISIBILITY
1368 iterator insert(const_iterator __p, initializer_list<value_type> __il)
1369 {return insert(__p, __il.begin(), __il.end());}
1370#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001371 iterator insert(const_iterator __p, const value_type& __v);
1372 iterator insert(const_iterator __p, size_type __n, const value_type& __v);
1373 template <class _InputIter>
Marshall Clow6b612cf2015-01-22 18:33:29 +00001374 iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001375 typename enable_if<__is_input_iterator<_InputIter>::value
Marshall Clow6b612cf2015-01-22 18:33:29 +00001376 &&!__is_forward_iterator<_InputIter>::value>::type* = 0);
1377 template <class _ForwardIterator>
1378 iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
1379 typename enable_if<__is_forward_iterator<_ForwardIterator>::value
1380 &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type* = 0);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001381 template <class _BiIter>
Marshall Clow6b612cf2015-01-22 18:33:29 +00001382 iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001383 typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0);
Eric Fiselier212e3f22017-04-16 03:17:01 +00001384
Howard Hinnantc51e1022010-05-11 19:42:16 +00001385 void pop_front();
1386 void pop_back();
1387 iterator erase(const_iterator __p);
1388 iterator erase(const_iterator __f, const_iterator __l);
1389
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001390 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantca2fc222011-06-02 20:00:14 +00001391 void swap(deque& __c)
Marshall Clow8982dcd2015-07-13 20:04:56 +00001392#if _LIBCPP_STD_VER >= 14
1393 _NOEXCEPT;
1394#else
Howard Hinnantca2fc222011-06-02 20:00:14 +00001395 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1396 __is_nothrow_swappable<allocator_type>::value);
Marshall Clow8982dcd2015-07-13 20:04:56 +00001397#endif
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001398 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantda2df912011-06-02 16:10:22 +00001399 void clear() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001400
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001402 bool __invariants() const {return __base::__invariants();}
1403private:
Howard Hinnantdcb73a32013-06-23 21:17:24 +00001404 typedef typename __base::__map_const_pointer __map_const_pointer;
1405
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001406 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001407 static size_type __recommend_blocks(size_type __n)
1408 {
1409 return __n / __base::__block_size + (__n % __base::__block_size != 0);
1410 }
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001412 size_type __capacity() const
1413 {
1414 return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;
1415 }
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001417 size_type __front_spare() const
1418 {
1419 return __base::__start_;
1420 }
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001422 size_type __back_spare() const
1423 {
1424 return __capacity() - (__base::__start_ + __base::size());
1425 }
1426
1427 template <class _InpIter>
1428 void __append(_InpIter __f, _InpIter __l,
1429 typename enable_if<__is_input_iterator<_InpIter>::value &&
1430 !__is_forward_iterator<_InpIter>::value>::type* = 0);
1431 template <class _ForIter>
1432 void __append(_ForIter __f, _ForIter __l,
1433 typename enable_if<__is_forward_iterator<_ForIter>::value>::type* = 0);
1434 void __append(size_type __n);
1435 void __append(size_type __n, const value_type& __v);
1436 void __erase_to_end(const_iterator __f);
1437 void __add_front_capacity();
1438 void __add_front_capacity(size_type __n);
1439 void __add_back_capacity();
1440 void __add_back_capacity(size_type __n);
1441 iterator __move_and_check(iterator __f, iterator __l, iterator __r,
1442 const_pointer& __vt);
1443 iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
1444 const_pointer& __vt);
1445 void __move_construct_and_check(iterator __f, iterator __l,
1446 iterator __r, const_pointer& __vt);
1447 void __move_construct_backward_and_check(iterator __f, iterator __l,
1448 iterator __r, const_pointer& __vt);
1449
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001451 void __copy_assign_alloc(const deque& __c)
1452 {__copy_assign_alloc(__c, integral_constant<bool,
1453 __alloc_traits::propagate_on_container_copy_assignment::value>());}
1454
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001455 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001456 void __copy_assign_alloc(const deque& __c, true_type)
1457 {
1458 if (__base::__alloc() != __c.__alloc())
1459 {
1460 clear();
1461 shrink_to_fit();
1462 }
1463 __base::__alloc() = __c.__alloc();
1464 __base::__map_.__alloc() = __c.__map_.__alloc();
1465 }
1466
Howard Hinnant874ad9a2010-09-21 21:28:23 +00001467 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant28b24882011-12-01 20:21:04 +00001468 void __copy_assign_alloc(const deque&, false_type)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001469 {}
1470
Howard Hinnant4931e092011-06-02 21:38:57 +00001471 void __move_assign(deque& __c, true_type)
1472 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001473 void __move_assign(deque& __c, false_type);
1474};
1475
Marshall Clow4cc3a452018-05-18 23:44:13 +00001476#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1477template<class _InputIterator,
1478 class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
1479 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
1480 >
1481deque(_InputIterator, _InputIterator)
1482 -> deque<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
1483
1484template<class _InputIterator,
1485 class _Alloc,
1486 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
1487 >
1488deque(_InputIterator, _InputIterator, _Alloc)
1489 -> deque<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
1490#endif
1491
1492
Howard Hinnantc51e1022010-05-11 19:42:16 +00001493template <class _Tp, class _Allocator>
1494deque<_Tp, _Allocator>::deque(size_type __n)
1495{
1496 if (__n > 0)
1497 __append(__n);
1498}
1499
Marshall Clowbc4fcb42013-09-07 16:16:19 +00001500#if _LIBCPP_STD_VER > 11
1501template <class _Tp, class _Allocator>
1502deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
1503 : __base(__a)
1504{
1505 if (__n > 0)
1506 __append(__n);
1507}
1508#endif
1509
Howard Hinnantc51e1022010-05-11 19:42:16 +00001510template <class _Tp, class _Allocator>
1511deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
1512{
1513 if (__n > 0)
1514 __append(__n, __v);
1515}
1516
1517template <class _Tp, class _Allocator>
1518deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
1519 : __base(__a)
1520{
1521 if (__n > 0)
1522 __append(__n, __v);
1523}
1524
1525template <class _Tp, class _Allocator>
1526template <class _InputIter>
1527deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
1528 typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
1529{
1530 __append(__f, __l);
1531}
1532
1533template <class _Tp, class _Allocator>
1534template <class _InputIter>
1535deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1536 typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
1537 : __base(__a)
1538{
1539 __append(__f, __l);
1540}
1541
1542template <class _Tp, class _Allocator>
1543deque<_Tp, _Allocator>::deque(const deque& __c)
1544 : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
1545{
1546 __append(__c.begin(), __c.end());
1547}
1548
1549template <class _Tp, class _Allocator>
1550deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
1551 : __base(__a)
1552{
1553 __append(__c.begin(), __c.end());
1554}
1555
Eric Fiselier212e3f22017-04-16 03:17:01 +00001556template <class _Tp, class _Allocator>
1557deque<_Tp, _Allocator>&
1558deque<_Tp, _Allocator>::operator=(const deque& __c)
1559{
1560 if (this != &__c)
1561 {
1562 __copy_assign_alloc(__c);
1563 assign(__c.begin(), __c.end());
1564 }
1565 return *this;
1566}
1567
1568#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant33711792011-08-12 21:56:02 +00001569
Howard Hinnantc51e1022010-05-11 19:42:16 +00001570template <class _Tp, class _Allocator>
1571deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
1572{
1573 __append(__il.begin(), __il.end());
1574}
1575
1576template <class _Tp, class _Allocator>
1577deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
1578 : __base(__a)
1579{
1580 __append(__il.begin(), __il.end());
1581}
1582
Howard Hinnantc51e1022010-05-11 19:42:16 +00001583template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001584inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001585deque<_Tp, _Allocator>::deque(deque&& __c)
Howard Hinnantca2fc222011-06-02 20:00:14 +00001586 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001587 : __base(_VSTD::move(__c))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001588{
1589}
1590
1591template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001592inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001593deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001594 : __base(_VSTD::move(__c), __a)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001595{
1596 if (__a != __c.__alloc())
1597 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001598 typedef move_iterator<iterator> _Ip;
1599 assign(_Ip(__c.begin()), _Ip(__c.end()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001600 }
1601}
1602
1603template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001604inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001605deque<_Tp, _Allocator>&
1606deque<_Tp, _Allocator>::operator=(deque&& __c)
Howard Hinnant4931e092011-06-02 21:38:57 +00001607 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1608 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001609{
1610 __move_assign(__c, integral_constant<bool,
1611 __alloc_traits::propagate_on_container_move_assignment::value>());
1612 return *this;
1613}
1614
1615template <class _Tp, class _Allocator>
1616void
1617deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
1618{
1619 if (__base::__alloc() != __c.__alloc())
1620 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001621 typedef move_iterator<iterator> _Ip;
1622 assign(_Ip(__c.begin()), _Ip(__c.end()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001623 }
1624 else
1625 __move_assign(__c, true_type());
1626}
1627
1628template <class _Tp, class _Allocator>
1629void
1630deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
Howard Hinnant4931e092011-06-02 21:38:57 +00001631 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001632{
1633 clear();
1634 shrink_to_fit();
1635 __base::__move_assign(__c);
1636}
1637
Eric Fiselier212e3f22017-04-16 03:17:01 +00001638#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001639
1640template <class _Tp, class _Allocator>
1641template <class _InputIter>
1642void
1643deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
1644 typename enable_if<__is_input_iterator<_InputIter>::value &&
1645 !__is_random_access_iterator<_InputIter>::value>::type*)
1646{
1647 iterator __i = __base::begin();
1648 iterator __e = __base::end();
Eric Fiseliera09a3b42014-10-27 19:28:20 +00001649 for (; __f != __l && __i != __e; ++__f, (void) ++__i)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001650 *__i = *__f;
1651 if (__f != __l)
1652 __append(__f, __l);
1653 else
1654 __erase_to_end(__i);
1655}
1656
1657template <class _Tp, class _Allocator>
1658template <class _RAIter>
1659void
1660deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
1661 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
1662{
1663 if (static_cast<size_type>(__l - __f) > __base::size())
1664 {
1665 _RAIter __m = __f + __base::size();
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001666 _VSTD::copy(__f, __m, __base::begin());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001667 __append(__m, __l);
1668 }
1669 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001670 __erase_to_end(_VSTD::copy(__f, __l, __base::begin()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001671}
1672
1673template <class _Tp, class _Allocator>
1674void
1675deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
1676{
1677 if (__n > __base::size())
1678 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001679 _VSTD::fill_n(__base::begin(), __base::size(), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001680 __n -= __base::size();
1681 __append(__n, __v);
1682 }
1683 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001684 __erase_to_end(_VSTD::fill_n(__base::begin(), __n, __v));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001685}
1686
1687template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001688inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001689_Allocator
Howard Hinnantda2df912011-06-02 16:10:22 +00001690deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001691{
1692 return __base::__alloc();
1693}
1694
1695template <class _Tp, class _Allocator>
1696void
1697deque<_Tp, _Allocator>::resize(size_type __n)
1698{
1699 if (__n > __base::size())
1700 __append(__n - __base::size());
1701 else if (__n < __base::size())
1702 __erase_to_end(__base::begin() + __n);
1703}
1704
1705template <class _Tp, class _Allocator>
1706void
1707deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
1708{
1709 if (__n > __base::size())
1710 __append(__n - __base::size(), __v);
1711 else if (__n < __base::size())
1712 __erase_to_end(__base::begin() + __n);
1713}
1714
1715template <class _Tp, class _Allocator>
1716void
Howard Hinnant4931e092011-06-02 21:38:57 +00001717deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001718{
1719 allocator_type& __a = __base::__alloc();
1720 if (empty())
1721 {
1722 while (__base::__map_.size() > 0)
1723 {
1724 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
1725 __base::__map_.pop_back();
1726 }
1727 __base::__start_ = 0;
1728 }
1729 else
1730 {
1731 if (__front_spare() >= __base::__block_size)
1732 {
1733 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
1734 __base::__map_.pop_front();
1735 __base::__start_ -= __base::__block_size;
1736 }
1737 if (__back_spare() >= __base::__block_size)
1738 {
1739 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
1740 __base::__map_.pop_back();
1741 }
1742 }
1743 __base::__map_.shrink_to_fit();
1744}
1745
1746template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001747inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001748typename deque<_Tp, _Allocator>::reference
1749deque<_Tp, _Allocator>::operator[](size_type __i)
1750{
1751 size_type __p = __base::__start_ + __i;
1752 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1753}
1754
1755template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001756inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001757typename deque<_Tp, _Allocator>::const_reference
1758deque<_Tp, _Allocator>::operator[](size_type __i) const
1759{
1760 size_type __p = __base::__start_ + __i;
1761 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1762}
1763
1764template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001765inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001766typename deque<_Tp, _Allocator>::reference
1767deque<_Tp, _Allocator>::at(size_type __i)
1768{
1769 if (__i >= __base::size())
1770 __base::__throw_out_of_range();
1771 size_type __p = __base::__start_ + __i;
1772 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1773}
1774
1775template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001776inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001777typename deque<_Tp, _Allocator>::const_reference
1778deque<_Tp, _Allocator>::at(size_type __i) const
1779{
1780 if (__i >= __base::size())
1781 __base::__throw_out_of_range();
1782 size_type __p = __base::__start_ + __i;
1783 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1784}
1785
1786template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001787inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001788typename deque<_Tp, _Allocator>::reference
1789deque<_Tp, _Allocator>::front()
1790{
1791 return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1792 + __base::__start_ % __base::__block_size);
1793}
1794
1795template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001796inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001797typename deque<_Tp, _Allocator>::const_reference
1798deque<_Tp, _Allocator>::front() const
1799{
1800 return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1801 + __base::__start_ % __base::__block_size);
1802}
1803
1804template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001805inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001806typename deque<_Tp, _Allocator>::reference
1807deque<_Tp, _Allocator>::back()
1808{
1809 size_type __p = __base::size() + __base::__start_ - 1;
1810 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1811}
1812
1813template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001814inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00001815typename deque<_Tp, _Allocator>::const_reference
1816deque<_Tp, _Allocator>::back() const
1817{
1818 size_type __p = __base::size() + __base::__start_ - 1;
1819 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1820}
1821
1822template <class _Tp, class _Allocator>
1823void
1824deque<_Tp, _Allocator>::push_back(const value_type& __v)
1825{
1826 allocator_type& __a = __base::__alloc();
1827 if (__back_spare() == 0)
1828 __add_back_capacity();
1829 // __back_spare() >= 1
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001830 __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001831 ++__base::size();
1832}
1833
Eric Fiselier212e3f22017-04-16 03:17:01 +00001834template <class _Tp, class _Allocator>
1835void
1836deque<_Tp, _Allocator>::push_front(const value_type& __v)
1837{
1838 allocator_type& __a = __base::__alloc();
1839 if (__front_spare() == 0)
1840 __add_front_capacity();
1841 // __front_spare() >= 1
1842 __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
1843 --__base::__start_;
1844 ++__base::size();
1845}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001846
Eric Fiselier212e3f22017-04-16 03:17:01 +00001847#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001848template <class _Tp, class _Allocator>
1849void
1850deque<_Tp, _Allocator>::push_back(value_type&& __v)
1851{
1852 allocator_type& __a = __base::__alloc();
1853 if (__back_spare() == 0)
1854 __add_back_capacity();
1855 // __back_spare() >= 1
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001856 __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001857 ++__base::size();
1858}
1859
1860template <class _Tp, class _Allocator>
1861template <class... _Args>
Marshall Clowea52cc42017-01-24 23:09:12 +00001862#if _LIBCPP_STD_VER > 14
Eric Fiselier34ba5b92016-07-21 03:20:17 +00001863typename deque<_Tp, _Allocator>::reference
Marshall Clowea52cc42017-01-24 23:09:12 +00001864#else
1865void
1866#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001867deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
1868{
1869 allocator_type& __a = __base::__alloc();
1870 if (__back_spare() == 0)
1871 __add_back_capacity();
1872 // __back_spare() >= 1
Eric Fiselier34ba5b92016-07-21 03:20:17 +00001873 __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()),
1874 _VSTD::forward<_Args>(__args)...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001875 ++__base::size();
Marshall Clowea52cc42017-01-24 23:09:12 +00001876#if _LIBCPP_STD_VER > 14
Eric Fiselier34ba5b92016-07-21 03:20:17 +00001877 return *--__base::end();
Marshall Clowea52cc42017-01-24 23:09:12 +00001878#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001879}
1880
Howard Hinnantc51e1022010-05-11 19:42:16 +00001881template <class _Tp, class _Allocator>
1882void
1883deque<_Tp, _Allocator>::push_front(value_type&& __v)
1884{
1885 allocator_type& __a = __base::__alloc();
1886 if (__front_spare() == 0)
1887 __add_front_capacity();
1888 // __front_spare() >= 1
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001889 __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001890 --__base::__start_;
1891 ++__base::size();
1892}
1893
Howard Hinnant74279a52010-09-04 23:28:19 +00001894
Howard Hinnantc51e1022010-05-11 19:42:16 +00001895template <class _Tp, class _Allocator>
1896template <class... _Args>
Marshall Clowea52cc42017-01-24 23:09:12 +00001897#if _LIBCPP_STD_VER > 14
Eric Fiselier34ba5b92016-07-21 03:20:17 +00001898typename deque<_Tp, _Allocator>::reference
Marshall Clowea52cc42017-01-24 23:09:12 +00001899#else
1900void
1901#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001902deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
1903{
1904 allocator_type& __a = __base::__alloc();
1905 if (__front_spare() == 0)
1906 __add_front_capacity();
1907 // __front_spare() >= 1
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001908 __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001909 --__base::__start_;
1910 ++__base::size();
Marshall Clowea52cc42017-01-24 23:09:12 +00001911#if _LIBCPP_STD_VER > 14
Eric Fiselier34ba5b92016-07-21 03:20:17 +00001912 return *__base::begin();
Marshall Clowea52cc42017-01-24 23:09:12 +00001913#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001914}
1915
Eric Fiselier212e3f22017-04-16 03:17:01 +00001916template <class _Tp, class _Allocator>
1917typename deque<_Tp, _Allocator>::iterator
1918deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
1919{
1920 size_type __pos = __p - __base::begin();
1921 size_type __to_end = __base::size() - __pos;
1922 allocator_type& __a = __base::__alloc();
1923 if (__pos < __to_end)
1924 { // insert by shifting things backward
1925 if (__front_spare() == 0)
1926 __add_front_capacity();
1927 // __front_spare() >= 1
1928 if (__pos == 0)
1929 {
1930 __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
1931 --__base::__start_;
1932 ++__base::size();
1933 }
1934 else
1935 {
1936 iterator __b = __base::begin();
1937 iterator __bm1 = _VSTD::prev(__b);
1938 __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1939 --__base::__start_;
1940 ++__base::size();
1941 if (__pos > 1)
1942 __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
1943 *__b = _VSTD::move(__v);
1944 }
1945 }
1946 else
1947 { // insert by shifting things forward
1948 if (__back_spare() == 0)
1949 __add_back_capacity();
1950 // __back_capacity >= 1
1951 size_type __de = __base::size() - __pos;
1952 if (__de == 0)
1953 {
1954 __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
1955 ++__base::size();
1956 }
1957 else
1958 {
1959 iterator __e = __base::end();
1960 iterator __em1 = _VSTD::prev(__e);
1961 __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
1962 ++__base::size();
1963 if (__de > 1)
1964 __e = _VSTD::move_backward(__e - __de, __em1, __e);
1965 *--__e = _VSTD::move(__v);
1966 }
1967 }
1968 return __base::begin() + __pos;
1969}
1970
1971template <class _Tp, class _Allocator>
1972template <class... _Args>
1973typename deque<_Tp, _Allocator>::iterator
1974deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
1975{
1976 size_type __pos = __p - __base::begin();
1977 size_type __to_end = __base::size() - __pos;
1978 allocator_type& __a = __base::__alloc();
1979 if (__pos < __to_end)
1980 { // insert by shifting things backward
1981 if (__front_spare() == 0)
1982 __add_front_capacity();
1983 // __front_spare() >= 1
1984 if (__pos == 0)
1985 {
1986 __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
1987 --__base::__start_;
1988 ++__base::size();
1989 }
1990 else
1991 {
1992 __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
1993 iterator __b = __base::begin();
1994 iterator __bm1 = _VSTD::prev(__b);
1995 __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1996 --__base::__start_;
1997 ++__base::size();
1998 if (__pos > 1)
1999 __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
2000 *__b = _VSTD::move(__tmp.get());
2001 }
2002 }
2003 else
2004 { // insert by shifting things forward
2005 if (__back_spare() == 0)
2006 __add_back_capacity();
2007 // __back_capacity >= 1
2008 size_type __de = __base::size() - __pos;
2009 if (__de == 0)
2010 {
2011 __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);
2012 ++__base::size();
2013 }
2014 else
2015 {
2016 __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
2017 iterator __e = __base::end();
2018 iterator __em1 = _VSTD::prev(__e);
2019 __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
2020 ++__base::size();
2021 if (__de > 1)
2022 __e = _VSTD::move_backward(__e - __de, __em1, __e);
2023 *--__e = _VSTD::move(__tmp.get());
2024 }
2025 }
2026 return __base::begin() + __pos;
2027}
2028
2029#endif // _LIBCPP_CXX03_LANG
2030
Howard Hinnantc51e1022010-05-11 19:42:16 +00002031
2032template <class _Tp, class _Allocator>
2033typename deque<_Tp, _Allocator>::iterator
2034deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
2035{
2036 size_type __pos = __p - __base::begin();
2037 size_type __to_end = __base::size() - __pos;
2038 allocator_type& __a = __base::__alloc();
2039 if (__pos < __to_end)
2040 { // insert by shifting things backward
2041 if (__front_spare() == 0)
2042 __add_front_capacity();
2043 // __front_spare() >= 1
2044 if (__pos == 0)
2045 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002046 __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002047 --__base::__start_;
2048 ++__base::size();
2049 }
2050 else
2051 {
2052 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2053 iterator __b = __base::begin();
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002054 iterator __bm1 = _VSTD::prev(__b);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002055 if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
2056 __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002057 __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002058 --__base::__start_;
2059 ++__base::size();
2060 if (__pos > 1)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002061 __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002062 *__b = *__vt;
2063 }
2064 }
2065 else
2066 { // insert by shifting things forward
2067 if (__back_spare() == 0)
2068 __add_back_capacity();
2069 // __back_capacity >= 1
2070 size_type __de = __base::size() - __pos;
2071 if (__de == 0)
2072 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002073 __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002074 ++__base::size();
2075 }
2076 else
2077 {
2078 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2079 iterator __e = __base::end();
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002080 iterator __em1 = _VSTD::prev(__e);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002081 if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
2082 __vt = pointer_traits<const_pointer>::pointer_to(*__e);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002083 __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002084 ++__base::size();
2085 if (__de > 1)
2086 __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
2087 *--__e = *__vt;
2088 }
2089 }
2090 return __base::begin() + __pos;
2091}
2092
Howard Hinnantc51e1022010-05-11 19:42:16 +00002093template <class _Tp, class _Allocator>
2094typename deque<_Tp, _Allocator>::iterator
2095deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
2096{
2097 size_type __pos = __p - __base::begin();
2098 size_type __to_end = __base::size() - __pos;
2099 allocator_type& __a = __base::__alloc();
2100 if (__pos < __to_end)
2101 { // insert by shifting things backward
2102 if (__n > __front_spare())
2103 __add_front_capacity(__n - __front_spare());
2104 // __n <= __front_spare()
Howard Hinnantc51e1022010-05-11 19:42:16 +00002105 iterator __old_begin = __base::begin();
2106 iterator __i = __old_begin;
2107 if (__n > __pos)
2108 {
2109 for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002110 __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002111 __n = __pos;
2112 }
2113 if (__n > 0)
2114 {
2115 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2116 iterator __obn = __old_begin + __n;
2117 __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
2118 if (__n < __pos)
2119 __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002120 _VSTD::fill_n(__old_begin, __n, *__vt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002121 }
2122 }
2123 else
2124 { // insert by shifting things forward
2125 size_type __back_capacity = __back_spare();
2126 if (__n > __back_capacity)
2127 __add_back_capacity(__n - __back_capacity);
2128 // __n <= __back_capacity
Howard Hinnantc51e1022010-05-11 19:42:16 +00002129 iterator __old_end = __base::end();
2130 iterator __i = __old_end;
2131 size_type __de = __base::size() - __pos;
2132 if (__n > __de)
2133 {
2134 for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002135 __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002136 __n = __de;
2137 }
2138 if (__n > 0)
2139 {
2140 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2141 iterator __oen = __old_end - __n;
2142 __move_construct_and_check(__oen, __old_end, __i, __vt);
2143 if (__n < __de)
2144 __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002145 _VSTD::fill_n(__old_end - __n, __n, *__vt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002146 }
2147 }
2148 return __base::begin() + __pos;
2149}
2150
2151template <class _Tp, class _Allocator>
2152template <class _InputIter>
2153typename deque<_Tp, _Allocator>::iterator
2154deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
2155 typename enable_if<__is_input_iterator<_InputIter>::value
Marshall Clow6b612cf2015-01-22 18:33:29 +00002156 &&!__is_forward_iterator<_InputIter>::value>::type*)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002157{
2158 __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
2159 __buf.__construct_at_end(__f, __l);
2160 typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
2161 return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
2162}
2163
2164template <class _Tp, class _Allocator>
Marshall Clow6b612cf2015-01-22 18:33:29 +00002165template <class _ForwardIterator>
2166typename deque<_Tp, _Allocator>::iterator
2167deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
2168 typename enable_if<__is_forward_iterator<_ForwardIterator>::value
2169 &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type*)
2170{
2171 size_type __n = _VSTD::distance(__f, __l);
2172 __split_buffer<value_type, allocator_type&> __buf(__n, 0, __base::__alloc());
2173 __buf.__construct_at_end(__f, __l);
2174 typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
2175 return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
2176}
2177
2178template <class _Tp, class _Allocator>
Howard Hinnantc51e1022010-05-11 19:42:16 +00002179template <class _BiIter>
2180typename deque<_Tp, _Allocator>::iterator
2181deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
2182 typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type*)
2183{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002184 size_type __n = _VSTD::distance(__f, __l);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002185 size_type __pos = __p - __base::begin();
2186 size_type __to_end = __base::size() - __pos;
2187 allocator_type& __a = __base::__alloc();
2188 if (__pos < __to_end)
2189 { // insert by shifting things backward
2190 if (__n > __front_spare())
2191 __add_front_capacity(__n - __front_spare());
2192 // __n <= __front_spare()
Howard Hinnantc51e1022010-05-11 19:42:16 +00002193 iterator __old_begin = __base::begin();
2194 iterator __i = __old_begin;
2195 _BiIter __m = __f;
2196 if (__n > __pos)
2197 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002198 __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002199 for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002200 __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002201 __n = __pos;
2202 }
2203 if (__n > 0)
2204 {
2205 iterator __obn = __old_begin + __n;
2206 for (iterator __j = __obn; __j != __old_begin;)
2207 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002208 __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002209 --__base::__start_;
2210 ++__base::size();
2211 }
2212 if (__n < __pos)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002213 __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);
2214 _VSTD::copy(__m, __l, __old_begin);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002215 }
2216 }
2217 else
2218 { // insert by shifting things forward
2219 size_type __back_capacity = __back_spare();
2220 if (__n > __back_capacity)
2221 __add_back_capacity(__n - __back_capacity);
2222 // __n <= __back_capacity
Howard Hinnantc51e1022010-05-11 19:42:16 +00002223 iterator __old_end = __base::end();
2224 iterator __i = __old_end;
2225 _BiIter __m = __l;
2226 size_type __de = __base::size() - __pos;
2227 if (__n > __de)
2228 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002229 __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
Eric Fiseliera09a3b42014-10-27 19:28:20 +00002230 for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002231 __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002232 __n = __de;
2233 }
2234 if (__n > 0)
2235 {
2236 iterator __oen = __old_end - __n;
2237 for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002238 __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002239 if (__n < __de)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002240 __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);
2241 _VSTD::copy_backward(__f, __m, __old_end);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002242 }
2243 }
2244 return __base::begin() + __pos;
2245}
2246
2247template <class _Tp, class _Allocator>
2248template <class _InpIter>
2249void
2250deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
2251 typename enable_if<__is_input_iterator<_InpIter>::value &&
2252 !__is_forward_iterator<_InpIter>::value>::type*)
2253{
2254 for (; __f != __l; ++__f)
Eric Fiselier96919722017-10-17 13:03:17 +00002255#ifdef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00002256 push_back(*__f);
Eric Fiselier96919722017-10-17 13:03:17 +00002257#else
2258 emplace_back(*__f);
2259#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00002260}
2261
2262template <class _Tp, class _Allocator>
2263template <class _ForIter>
2264void
2265deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
2266 typename enable_if<__is_forward_iterator<_ForIter>::value>::type*)
2267{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002268 size_type __n = _VSTD::distance(__f, __l);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002269 allocator_type& __a = __base::__alloc();
2270 size_type __back_capacity = __back_spare();
2271 if (__n > __back_capacity)
2272 __add_back_capacity(__n - __back_capacity);
2273 // __n <= __back_capacity
Eric Fiseliera09a3b42014-10-27 19:28:20 +00002274 for (iterator __i = __base::end(); __f != __l; ++__i, (void) ++__f, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002275 __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__f);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002276}
2277
2278template <class _Tp, class _Allocator>
2279void
2280deque<_Tp, _Allocator>::__append(size_type __n)
2281{
2282 allocator_type& __a = __base::__alloc();
2283 size_type __back_capacity = __back_spare();
2284 if (__n > __back_capacity)
2285 __add_back_capacity(__n - __back_capacity);
2286 // __n <= __back_capacity
2287 for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002288 __alloc_traits::construct(__a, _VSTD::addressof(*__i));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002289}
2290
2291template <class _Tp, class _Allocator>
2292void
2293deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
2294{
2295 allocator_type& __a = __base::__alloc();
2296 size_type __back_capacity = __back_spare();
2297 if (__n > __back_capacity)
2298 __add_back_capacity(__n - __back_capacity);
2299 // __n <= __back_capacity
2300 for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002301 __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002302}
2303
2304// Create front capacity for one block of elements.
2305// Strong guarantee. Either do it or don't touch anything.
2306template <class _Tp, class _Allocator>
2307void
2308deque<_Tp, _Allocator>::__add_front_capacity()
2309{
2310 allocator_type& __a = __base::__alloc();
2311 if (__back_spare() >= __base::__block_size)
2312 {
2313 __base::__start_ += __base::__block_size;
2314 pointer __pt = __base::__map_.back();
2315 __base::__map_.pop_back();
2316 __base::__map_.push_front(__pt);
2317 }
2318 // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer
2319 else if (__base::__map_.size() < __base::__map_.capacity())
2320 { // we can put the new buffer into the map, but don't shift things around
2321 // until all buffers are allocated. If we throw, we don't need to fix
2322 // anything up (any added buffers are undetectible)
2323 if (__base::__map_.__front_spare() > 0)
2324 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2325 else
2326 {
2327 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2328 // Done allocating, reorder capacity
2329 pointer __pt = __base::__map_.back();
2330 __base::__map_.pop_back();
2331 __base::__map_.push_front(__pt);
2332 }
2333 __base::__start_ = __base::__map_.size() == 1 ?
2334 __base::__block_size / 2 :
2335 __base::__start_ + __base::__block_size;
2336 }
2337 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2338 else
2339 {
2340 __split_buffer<pointer, typename __base::__pointer_allocator&>
2341 __buf(max<size_type>(2 * __base::__map_.capacity(), 1),
2342 0, __base::__map_.__alloc());
Marshall Clow5fd466b2015-03-09 17:08:51 +00002343
Marshall Clow8982dcd2015-07-13 20:04:56 +00002344 typedef __allocator_destructor<_Allocator> _Dp;
2345 unique_ptr<pointer, _Dp> __hold(
2346 __alloc_traits::allocate(__a, __base::__block_size),
2347 _Dp(__a, __base::__block_size));
2348 __buf.push_back(__hold.get());
2349 __hold.release();
Louis Dionne72f24392018-12-12 23:58:25 +00002350
Howard Hinnantc51e1022010-05-11 19:42:16 +00002351 for (typename __base::__map_pointer __i = __base::__map_.begin();
2352 __i != __base::__map_.end(); ++__i)
2353 __buf.push_back(*__i);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002354 _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2355 _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2356 _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2357 _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002358 __base::__start_ = __base::__map_.size() == 1 ?
2359 __base::__block_size / 2 :
2360 __base::__start_ + __base::__block_size;
2361 }
2362}
2363
2364// Create front capacity for __n elements.
2365// Strong guarantee. Either do it or don't touch anything.
2366template <class _Tp, class _Allocator>
2367void
2368deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
2369{
2370 allocator_type& __a = __base::__alloc();
2371 size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2372 // Number of unused blocks at back:
2373 size_type __back_capacity = __back_spare() / __base::__block_size;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002374 __back_capacity = _VSTD::min(__back_capacity, __nb); // don't take more than you need
Howard Hinnantc51e1022010-05-11 19:42:16 +00002375 __nb -= __back_capacity; // number of blocks need to allocate
2376 // If __nb == 0, then we have sufficient capacity.
2377 if (__nb == 0)
2378 {
2379 __base::__start_ += __base::__block_size * __back_capacity;
2380 for (; __back_capacity > 0; --__back_capacity)
2381 {
2382 pointer __pt = __base::__map_.back();
2383 __base::__map_.pop_back();
2384 __base::__map_.push_front(__pt);
2385 }
2386 }
2387 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2388 else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2389 { // we can put the new buffers into the map, but don't shift things around
2390 // until all buffers are allocated. If we throw, we don't need to fix
2391 // anything up (any added buffers are undetectible)
2392 for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))
2393 {
2394 if (__base::__map_.__front_spare() == 0)
2395 break;
2396 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2397 }
2398 for (; __nb > 0; --__nb, ++__back_capacity)
2399 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2400 // Done allocating, reorder capacity
2401 __base::__start_ += __back_capacity * __base::__block_size;
2402 for (; __back_capacity > 0; --__back_capacity)
2403 {
2404 pointer __pt = __base::__map_.back();
2405 __base::__map_.pop_back();
2406 __base::__map_.push_front(__pt);
2407 }
2408 }
2409 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2410 else
2411 {
2412 size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();
2413 __split_buffer<pointer, typename __base::__pointer_allocator&>
2414 __buf(max<size_type>(2* __base::__map_.capacity(),
2415 __nb + __base::__map_.size()),
2416 0, __base::__map_.__alloc());
2417#ifndef _LIBCPP_NO_EXCEPTIONS
2418 try
2419 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +00002420#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00002421 for (; __nb > 0; --__nb)
2422 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2423#ifndef _LIBCPP_NO_EXCEPTIONS
2424 }
2425 catch (...)
2426 {
2427 for (typename __base::__map_pointer __i = __buf.begin();
2428 __i != __buf.end(); ++__i)
2429 __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2430 throw;
2431 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00002432#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00002433 for (; __back_capacity > 0; --__back_capacity)
2434 {
2435 __buf.push_back(__base::__map_.back());
2436 __base::__map_.pop_back();
2437 }
2438 for (typename __base::__map_pointer __i = __base::__map_.begin();
2439 __i != __base::__map_.end(); ++__i)
2440 __buf.push_back(*__i);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002441 _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2442 _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2443 _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2444 _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002445 __base::__start_ += __ds;
2446 }
2447}
2448
2449// Create back capacity for one block of elements.
2450// Strong guarantee. Either do it or don't touch anything.
2451template <class _Tp, class _Allocator>
2452void
2453deque<_Tp, _Allocator>::__add_back_capacity()
2454{
2455 allocator_type& __a = __base::__alloc();
2456 if (__front_spare() >= __base::__block_size)
2457 {
2458 __base::__start_ -= __base::__block_size;
2459 pointer __pt = __base::__map_.front();
2460 __base::__map_.pop_front();
2461 __base::__map_.push_back(__pt);
2462 }
2463 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2464 else if (__base::__map_.size() < __base::__map_.capacity())
2465 { // we can put the new buffer into the map, but don't shift things around
2466 // until it is allocated. If we throw, we don't need to fix
2467 // anything up (any added buffers are undetectible)
2468 if (__base::__map_.__back_spare() != 0)
2469 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2470 else
2471 {
2472 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2473 // Done allocating, reorder capacity
2474 pointer __pt = __base::__map_.front();
2475 __base::__map_.pop_front();
2476 __base::__map_.push_back(__pt);
2477 }
2478 }
2479 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2480 else
2481 {
2482 __split_buffer<pointer, typename __base::__pointer_allocator&>
2483 __buf(max<size_type>(2* __base::__map_.capacity(), 1),
2484 __base::__map_.size(),
2485 __base::__map_.__alloc());
Marshall Clow5fd466b2015-03-09 17:08:51 +00002486
Marshall Clow8982dcd2015-07-13 20:04:56 +00002487 typedef __allocator_destructor<_Allocator> _Dp;
2488 unique_ptr<pointer, _Dp> __hold(
2489 __alloc_traits::allocate(__a, __base::__block_size),
2490 _Dp(__a, __base::__block_size));
2491 __buf.push_back(__hold.get());
2492 __hold.release();
Marshall Clow5fd466b2015-03-09 17:08:51 +00002493
Howard Hinnantc51e1022010-05-11 19:42:16 +00002494 for (typename __base::__map_pointer __i = __base::__map_.end();
2495 __i != __base::__map_.begin();)
2496 __buf.push_front(*--__i);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002497 _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2498 _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2499 _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2500 _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002501 }
2502}
2503
2504// Create back capacity for __n elements.
2505// Strong guarantee. Either do it or don't touch anything.
2506template <class _Tp, class _Allocator>
2507void
2508deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
2509{
2510 allocator_type& __a = __base::__alloc();
2511 size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2512 // Number of unused blocks at front:
2513 size_type __front_capacity = __front_spare() / __base::__block_size;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002514 __front_capacity = _VSTD::min(__front_capacity, __nb); // don't take more than you need
Howard Hinnantc51e1022010-05-11 19:42:16 +00002515 __nb -= __front_capacity; // number of blocks need to allocate
2516 // If __nb == 0, then we have sufficient capacity.
2517 if (__nb == 0)
2518 {
2519 __base::__start_ -= __base::__block_size * __front_capacity;
2520 for (; __front_capacity > 0; --__front_capacity)
2521 {
2522 pointer __pt = __base::__map_.front();
2523 __base::__map_.pop_front();
2524 __base::__map_.push_back(__pt);
2525 }
2526 }
2527 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2528 else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2529 { // we can put the new buffers into the map, but don't shift things around
2530 // until all buffers are allocated. If we throw, we don't need to fix
2531 // anything up (any added buffers are undetectible)
2532 for (; __nb > 0; --__nb)
2533 {
2534 if (__base::__map_.__back_spare() == 0)
2535 break;
2536 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2537 }
2538 for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=
2539 __base::__block_size - (__base::__map_.size() == 1))
2540 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2541 // Done allocating, reorder capacity
2542 __base::__start_ -= __base::__block_size * __front_capacity;
2543 for (; __front_capacity > 0; --__front_capacity)
2544 {
2545 pointer __pt = __base::__map_.front();
2546 __base::__map_.pop_front();
2547 __base::__map_.push_back(__pt);
2548 }
2549 }
2550 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2551 else
2552 {
2553 size_type __ds = __front_capacity * __base::__block_size;
2554 __split_buffer<pointer, typename __base::__pointer_allocator&>
2555 __buf(max<size_type>(2* __base::__map_.capacity(),
2556 __nb + __base::__map_.size()),
2557 __base::__map_.size() - __front_capacity,
2558 __base::__map_.__alloc());
2559#ifndef _LIBCPP_NO_EXCEPTIONS
2560 try
2561 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +00002562#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00002563 for (; __nb > 0; --__nb)
2564 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2565#ifndef _LIBCPP_NO_EXCEPTIONS
2566 }
2567 catch (...)
2568 {
2569 for (typename __base::__map_pointer __i = __buf.begin();
2570 __i != __buf.end(); ++__i)
2571 __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2572 throw;
2573 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00002574#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00002575 for (; __front_capacity > 0; --__front_capacity)
2576 {
2577 __buf.push_back(__base::__map_.front());
2578 __base::__map_.pop_front();
2579 }
2580 for (typename __base::__map_pointer __i = __base::__map_.end();
2581 __i != __base::__map_.begin();)
2582 __buf.push_front(*--__i);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002583 _VSTD::swap(__base::__map_.__first_, __buf.__first_);
2584 _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
2585 _VSTD::swap(__base::__map_.__end_, __buf.__end_);
2586 _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002587 __base::__start_ -= __ds;
2588 }
2589}
2590
2591template <class _Tp, class _Allocator>
2592void
2593deque<_Tp, _Allocator>::pop_front()
2594{
2595 allocator_type& __a = __base::__alloc();
Howard Hinnantdcb73a32013-06-23 21:17:24 +00002596 __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
2597 __base::__start_ / __base::__block_size) +
2598 __base::__start_ % __base::__block_size));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002599 --__base::size();
2600 if (++__base::__start_ >= 2 * __base::__block_size)
2601 {
2602 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2603 __base::__map_.pop_front();
2604 __base::__start_ -= __base::__block_size;
2605 }
2606}
2607
2608template <class _Tp, class _Allocator>
2609void
2610deque<_Tp, _Allocator>::pop_back()
2611{
Louis Dionne72f24392018-12-12 23:58:25 +00002612 _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque");
Howard Hinnantc51e1022010-05-11 19:42:16 +00002613 allocator_type& __a = __base::__alloc();
2614 size_type __p = __base::size() + __base::__start_ - 1;
Howard Hinnantdcb73a32013-06-23 21:17:24 +00002615 __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
2616 __p / __base::__block_size) +
2617 __p % __base::__block_size));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002618 --__base::size();
2619 if (__back_spare() >= 2 * __base::__block_size)
2620 {
2621 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2622 __base::__map_.pop_back();
2623 }
2624}
2625
2626// move assign [__f, __l) to [__r, __r + (__l-__f)).
2627// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
2628template <class _Tp, class _Allocator>
2629typename deque<_Tp, _Allocator>::iterator
2630deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
2631 const_pointer& __vt)
2632{
2633 // as if
2634 // for (; __f != __l; ++__f, ++__r)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002635 // *__r = _VSTD::move(*__f);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002636 difference_type __n = __l - __f;
2637 while (__n > 0)
2638 {
2639 pointer __fb = __f.__ptr_;
2640 pointer __fe = *__f.__m_iter_ + __base::__block_size;
2641 difference_type __bs = __fe - __fb;
2642 if (__bs > __n)
2643 {
2644 __bs = __n;
2645 __fe = __fb + __bs;
2646 }
2647 if (__fb <= __vt && __vt < __fe)
Howard Hinnantdcb73a32013-06-23 21:17:24 +00002648 __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002649 __r = _VSTD::move(__fb, __fe, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002650 __n -= __bs;
2651 __f += __bs;
2652 }
2653 return __r;
2654}
2655
2656// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
2657// If __vt points into [__f, __l), then add (__r - __l) to __vt.
2658template <class _Tp, class _Allocator>
2659typename deque<_Tp, _Allocator>::iterator
2660deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
2661 const_pointer& __vt)
2662{
2663 // as if
2664 // while (__f != __l)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002665 // *--__r = _VSTD::move(*--__l);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002666 difference_type __n = __l - __f;
2667 while (__n > 0)
2668 {
2669 --__l;
2670 pointer __lb = *__l.__m_iter_;
2671 pointer __le = __l.__ptr_ + 1;
2672 difference_type __bs = __le - __lb;
2673 if (__bs > __n)
2674 {
2675 __bs = __n;
2676 __lb = __le - __bs;
2677 }
2678 if (__lb <= __vt && __vt < __le)
Howard Hinnantdcb73a32013-06-23 21:17:24 +00002679 __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002680 __r = _VSTD::move_backward(__lb, __le, __r);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002681 __n -= __bs;
2682 __l -= __bs - 1;
2683 }
2684 return __r;
2685}
2686
2687// move construct [__f, __l) to [__r, __r + (__l-__f)).
2688// If __vt points into [__f, __l), then add (__r - __f) to __vt.
2689template <class _Tp, class _Allocator>
2690void
2691deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
2692 iterator __r, const_pointer& __vt)
2693{
2694 allocator_type& __a = __base::__alloc();
2695 // as if
2696 // for (; __f != __l; ++__r, ++__f, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002697 // __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002698 difference_type __n = __l - __f;
2699 while (__n > 0)
2700 {
2701 pointer __fb = __f.__ptr_;
2702 pointer __fe = *__f.__m_iter_ + __base::__block_size;
2703 difference_type __bs = __fe - __fb;
2704 if (__bs > __n)
2705 {
2706 __bs = __n;
2707 __fe = __fb + __bs;
2708 }
2709 if (__fb <= __vt && __vt < __fe)
Howard Hinnantdcb73a32013-06-23 21:17:24 +00002710 __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002711 for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002712 __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002713 __n -= __bs;
2714 __f += __bs;
2715 }
2716}
2717
2718// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
2719// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
2720template <class _Tp, class _Allocator>
2721void
2722deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
2723 iterator __r, const_pointer& __vt)
2724{
2725 allocator_type& __a = __base::__alloc();
2726 // as if
2727 // for (iterator __j = __l; __j != __f;)
2728 // {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002729 // __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002730 // --__base::__start_;
2731 // ++__base::size();
2732 // }
2733 difference_type __n = __l - __f;
2734 while (__n > 0)
2735 {
2736 --__l;
2737 pointer __lb = *__l.__m_iter_;
2738 pointer __le = __l.__ptr_ + 1;
2739 difference_type __bs = __le - __lb;
2740 if (__bs > __n)
2741 {
2742 __bs = __n;
2743 __lb = __le - __bs;
2744 }
2745 if (__lb <= __vt && __vt < __le)
Howard Hinnantdcb73a32013-06-23 21:17:24 +00002746 __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002747 while (__le != __lb)
2748 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002749 __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002750 --__base::__start_;
2751 ++__base::size();
2752 }
2753 __n -= __bs;
2754 __l -= __bs - 1;
2755 }
2756}
2757
2758template <class _Tp, class _Allocator>
2759typename deque<_Tp, _Allocator>::iterator
2760deque<_Tp, _Allocator>::erase(const_iterator __f)
2761{
Howard Hinnantc51e1022010-05-11 19:42:16 +00002762 iterator __b = __base::begin();
2763 difference_type __pos = __f - __b;
2764 iterator __p = __b + __pos;
2765 allocator_type& __a = __base::__alloc();
Eric Fiselier37c22152016-12-24 00:24:44 +00002766 if (static_cast<size_t>(__pos) <= (__base::size() - 1) / 2)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002767 { // erase from front
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002768 _VSTD::move_backward(__b, __p, _VSTD::next(__p));
2769 __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002770 --__base::size();
2771 ++__base::__start_;
2772 if (__front_spare() >= 2 * __base::__block_size)
2773 {
2774 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2775 __base::__map_.pop_front();
2776 __base::__start_ -= __base::__block_size;
2777 }
2778 }
2779 else
2780 { // erase from back
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002781 iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p);
2782 __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002783 --__base::size();
2784 if (__back_spare() >= 2 * __base::__block_size)
2785 {
2786 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2787 __base::__map_.pop_back();
2788 }
2789 }
2790 return __base::begin() + __pos;
2791}
2792
2793template <class _Tp, class _Allocator>
2794typename deque<_Tp, _Allocator>::iterator
2795deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
2796{
2797 difference_type __n = __l - __f;
2798 iterator __b = __base::begin();
2799 difference_type __pos = __f - __b;
2800 iterator __p = __b + __pos;
2801 if (__n > 0)
2802 {
2803 allocator_type& __a = __base::__alloc();
Eric Fiselier37c22152016-12-24 00:24:44 +00002804 if (static_cast<size_t>(__pos) <= (__base::size() - __n) / 2)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002805 { // erase from front
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002806 iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002807 for (; __b != __i; ++__b)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002808 __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002809 __base::size() -= __n;
2810 __base::__start_ += __n;
2811 while (__front_spare() >= 2 * __base::__block_size)
2812 {
2813 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2814 __base::__map_.pop_front();
2815 __base::__start_ -= __base::__block_size;
2816 }
2817 }
2818 else
2819 { // erase from back
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002820 iterator __i = _VSTD::move(__p + __n, __base::end(), __p);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002821 for (iterator __e = __base::end(); __i != __e; ++__i)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002822 __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002823 __base::size() -= __n;
2824 while (__back_spare() >= 2 * __base::__block_size)
2825 {
2826 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2827 __base::__map_.pop_back();
2828 }
2829 }
2830 }
2831 return __base::begin() + __pos;
2832}
2833
2834template <class _Tp, class _Allocator>
2835void
2836deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
2837{
2838 iterator __e = __base::end();
2839 difference_type __n = __e - __f;
2840 if (__n > 0)
2841 {
2842 allocator_type& __a = __base::__alloc();
2843 iterator __b = __base::begin();
2844 difference_type __pos = __f - __b;
2845 for (iterator __p = __b + __pos; __p != __e; ++__p)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002846 __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002847 __base::size() -= __n;
2848 while (__back_spare() >= 2 * __base::__block_size)
2849 {
2850 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2851 __base::__map_.pop_back();
2852 }
2853 }
2854}
2855
2856template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002857inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00002858void
2859deque<_Tp, _Allocator>::swap(deque& __c)
Marshall Clow8982dcd2015-07-13 20:04:56 +00002860#if _LIBCPP_STD_VER >= 14
2861 _NOEXCEPT
2862#else
Louis Dionne72f24392018-12-12 23:58:25 +00002863 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
Marshall Clow8982dcd2015-07-13 20:04:56 +00002864 __is_nothrow_swappable<allocator_type>::value)
2865#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00002866{
2867 __base::swap(__c);
2868}
2869
2870template <class _Tp, class _Allocator>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002871inline
Howard Hinnantc51e1022010-05-11 19:42:16 +00002872void
Howard Hinnantda2df912011-06-02 16:10:22 +00002873deque<_Tp, _Allocator>::clear() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002874{
2875 __base::clear();
2876}
2877
2878template <class _Tp, class _Allocator>
Howard Hinnantb8a8ca22013-10-04 22:09:00 +00002879inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002880bool
2881operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2882{
2883 const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002884 return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002885}
2886
2887template <class _Tp, class _Allocator>
Howard Hinnantb8a8ca22013-10-04 22:09:00 +00002888inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002889bool
2890operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2891{
2892 return !(__x == __y);
2893}
2894
2895template <class _Tp, class _Allocator>
Howard Hinnantb8a8ca22013-10-04 22:09:00 +00002896inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002897bool
2898operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2899{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002900 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002901}
2902
2903template <class _Tp, class _Allocator>
Howard Hinnantb8a8ca22013-10-04 22:09:00 +00002904inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002905bool
2906operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2907{
2908 return __y < __x;
2909}
2910
2911template <class _Tp, class _Allocator>
Howard Hinnantb8a8ca22013-10-04 22:09:00 +00002912inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002913bool
2914operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2915{
2916 return !(__x < __y);
2917}
2918
2919template <class _Tp, class _Allocator>
Howard Hinnantb8a8ca22013-10-04 22:09:00 +00002920inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002921bool
2922operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2923{
2924 return !(__y < __x);
2925}
2926
2927template <class _Tp, class _Allocator>
Howard Hinnantb8a8ca22013-10-04 22:09:00 +00002928inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002929void
2930swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
Howard Hinnantca2fc222011-06-02 20:00:14 +00002931 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnantc51e1022010-05-11 19:42:16 +00002932{
2933 __x.swap(__y);
2934}
2935
Marshall Clow29b53f22018-12-14 18:49:35 +00002936#if _LIBCPP_STD_VER > 17
2937template <class _Tp, class _Allocator, class _Up>
2938inline _LIBCPP_INLINE_VISIBILITY
2939void erase(deque<_Tp, _Allocator>& __c, const _Up& __v)
2940{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); }
2941
2942template <class _Tp, class _Allocator, class _Predicate>
2943inline _LIBCPP_INLINE_VISIBILITY
2944void erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred)
2945{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); }
2946#endif
2947
2948
Howard Hinnantc51e1022010-05-11 19:42:16 +00002949_LIBCPP_END_NAMESPACE_STD
2950
Eric Fiselierf4433a32017-05-31 22:07:49 +00002951_LIBCPP_POP_MACROS
2952
Howard Hinnantc51e1022010-05-11 19:42:16 +00002953#endif // _LIBCPP_DEQUE