blob: a49205987ca21bcf7631c94e92d84187d1ad6214 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===---------------------------- deque -----------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-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 Hinnantbc8d3f92010-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:
41 deque();
42 explicit deque(const allocator_type& a);
43 explicit deque(size_type n);
44 deque(size_type n, const value_type& v);
45 deque(size_type n, const value_type& v, const allocator_type& a);
46 template <class InputIterator>
47 deque(InputIterator f, InputIterator l);
48 template <class InputIterator>
49 deque(InputIterator f, InputIterator l, const allocator_type& a);
50 deque(const deque& c);
Howard Hinnant18884f42011-06-02 21:38:57 +000051 deque(deque&& c)
52 noexcept(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000053 deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
54 deque(const deque& c, const allocator_type& a);
55 deque(deque&& c, const allocator_type& a);
56 ~deque();
57
58 deque& operator=(const deque& c);
Howard Hinnant18884f42011-06-02 21:38:57 +000059 deque& operator=(deque&& c)
60 noexcept(
61 allocator_type::propagate_on_container_move_assignment::value &&
62 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000063 deque& operator=(initializer_list<value_type> il);
64
65 template <class InputIterator>
66 void assign(InputIterator f, InputIterator l);
67 void assign(size_type n, const value_type& v);
68 void assign(initializer_list<value_type> il);
69
Howard Hinnanta12beb32011-06-02 16:10:22 +000070 allocator_type get_allocator() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071
72 // iterators:
73
Howard Hinnanta12beb32011-06-02 16:10:22 +000074 iterator begin() noexcept;
75 const_iterator begin() const noexcept;
76 iterator end() noexcept;
77 const_iterator end() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000078
Howard Hinnanta12beb32011-06-02 16:10:22 +000079 reverse_iterator rbegin() noexcept;
80 const_reverse_iterator rbegin() const noexcept;
81 reverse_iterator rend() noexcept;
82 const_reverse_iterator rend() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000083
Howard Hinnanta12beb32011-06-02 16:10:22 +000084 const_iterator cbegin() const noexcept;
85 const_iterator cend() const noexcept;
86 const_reverse_iterator crbegin() const noexcept;
87 const_reverse_iterator crend() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000088
89 // capacity:
Howard Hinnanta12beb32011-06-02 16:10:22 +000090 size_type size() const noexcept;
91 size_type max_size() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000092 void resize(size_type n);
93 void resize(size_type n, const value_type& v);
94 void shrink_to_fit();
Howard Hinnanta12beb32011-06-02 16:10:22 +000095 bool empty() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000096
97 // element access:
98 reference operator[](size_type i);
99 const_reference operator[](size_type i) const;
100 reference at(size_type i);
101 const_reference at(size_type i) const;
102 reference front();
103 const_reference front() const;
104 reference back();
105 const_reference back() const;
106
107 // modifiers:
108 void push_front(const value_type& v);
109 void push_front(value_type&& v);
110 void push_back(const value_type& v);
111 void push_back(value_type&& v);
112 template <class... Args> void emplace_front(Args&&... args);
113 template <class... Args> void emplace_back(Args&&... args);
114 template <class... Args> iterator emplace(const_iterator p, Args&&... args);
115 iterator insert(const_iterator p, const value_type& v);
116 iterator insert(const_iterator p, value_type&& v);
117 iterator insert(const_iterator p, size_type n, const value_type& v);
118 template <class InputIterator>
119 iterator insert (const_iterator p, InputIterator f, InputIterator l);
120 iterator insert(const_iterator p, initializer_list<value_type> il);
121 void pop_front();
122 void pop_back();
123 iterator erase(const_iterator p);
124 iterator erase(const_iterator f, const_iterator l);
Howard Hinnant18884f42011-06-02 21:38:57 +0000125 void swap(deque& c)
126 noexcept(!allocator_type::propagate_on_container_swap::value ||
127 __is_nothrow_swappable<allocator_type>::value);
Howard Hinnanta12beb32011-06-02 16:10:22 +0000128 void clear() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129};
130
131template <class T, class Allocator>
132 bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
133template <class T, class Allocator>
134 bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
135template <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);
143
144// specialized algorithms:
145template <class T, class Allocator>
Howard Hinnant18884f42011-06-02 21:38:57 +0000146 void swap(deque<T,Allocator>& x, deque<T,Allocator>& y) noexcept(x.swap(y));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000147
148} // std
149
150*/
151
152#pragma GCC system_header
153
154#include <__config>
155#include <__split_buffer>
156#include <type_traits>
157#include <initializer_list>
158#include <iterator>
159#include <algorithm>
160#include <stdexcept>
161
162_LIBCPP_BEGIN_NAMESPACE_STD
163
164template <class _Tp, class _Allocator> class __deque_base;
165
166template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
167 class _DiffType, _DiffType _BlockSize>
Howard Hinnant422a53f2010-09-21 21:28:23 +0000168class _LIBCPP_VISIBLE __deque_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000169
170template <class _RAIter,
171 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
172__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
173copy(_RAIter __f,
174 _RAIter __l,
175 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
176 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
177
178template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
179 class _OutputIterator>
180_OutputIterator
181copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
182 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
183 _OutputIterator __r);
184
185template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
186 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
187__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
188copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
189 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
190 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
191
192template <class _RAIter,
193 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
194__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
195copy_backward(_RAIter __f,
196 _RAIter __l,
197 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
198 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
199
200template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
201 class _OutputIterator>
202_OutputIterator
203copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
204 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
205 _OutputIterator __r);
206
207template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
208 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
209__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
210copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
211 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
212 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
213
214template <class _RAIter,
215 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
216__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
217move(_RAIter __f,
218 _RAIter __l,
219 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
220 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
221
222template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
223 class _OutputIterator>
224_OutputIterator
225move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
226 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
227 _OutputIterator __r);
228
229template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
230 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
231__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
232move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
233 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
234 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
235
236template <class _RAIter,
237 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
238__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
239move_backward(_RAIter __f,
240 _RAIter __l,
241 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
242 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
243
244template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
245 class _OutputIterator>
246_OutputIterator
247move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
248 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
249 _OutputIterator __r);
250
251template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
252 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
253__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
254move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
255 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
256 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
257
258template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
259 class _DiffType, _DiffType _BlockSize>
Howard Hinnant422a53f2010-09-21 21:28:23 +0000260class _LIBCPP_VISIBLE __deque_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000261{
262 typedef _MapPointer __map_iterator;
263public:
264 typedef _Pointer pointer;
265 typedef _DiffType difference_type;
266private:
267 __map_iterator __m_iter_;
268 pointer __ptr_;
269
270 static const difference_type __block_size = _BlockSize;
271public:
272 typedef _ValueType value_type;
273 typedef random_access_iterator_tag iterator_category;
274 typedef _Reference reference;
275
Howard Hinnanta12beb32011-06-02 16:10:22 +0000276 _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000277
278 template <class _P, class _R, class _MP>
279 _LIBCPP_INLINE_VISIBILITY
280 __deque_iterator(const __deque_iterator<value_type, _P, _R, _MP, difference_type, __block_size>& __it,
Howard Hinnanta12beb32011-06-02 16:10:22 +0000281 typename enable_if<is_convertible<_P, pointer>::value>::type* = 0) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000282 : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
283
284 _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;}
285 _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;}
286
287 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++()
288 {
289 if (++__ptr_ - *__m_iter_ == __block_size)
290 {
291 ++__m_iter_;
292 __ptr_ = *__m_iter_;
293 }
294 return *this;
295 }
296
297 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int)
298 {
299 __deque_iterator __tmp = *this;
300 ++(*this);
301 return __tmp;
302 }
303
304 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--()
305 {
306 if (__ptr_ == *__m_iter_)
307 {
308 --__m_iter_;
309 __ptr_ = *__m_iter_ + __block_size;
310 }
311 --__ptr_;
312 return *this;
313 }
314
315 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int)
316 {
317 __deque_iterator __tmp = *this;
318 --(*this);
319 return __tmp;
320 }
321
322 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n)
323 {
324 if (__n != 0)
325 {
326 __n += __ptr_ - *__m_iter_;
327 if (__n > 0)
328 {
329 __m_iter_ += __n / __block_size;
330 __ptr_ = *__m_iter_ + __n % __block_size;
331 }
332 else // (__n < 0)
333 {
334 difference_type __z = __block_size - 1 - __n;
335 __m_iter_ -= __z / __block_size;
336 __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
337 }
338 }
339 return *this;
340 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000341
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000342 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n)
343 {
344 return *this += -__n;
345 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000346
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000347 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const
348 {
349 __deque_iterator __t(*this);
350 __t += __n;
351 return __t;
352 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000353
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000354 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const
355 {
356 __deque_iterator __t(*this);
357 __t -= __n;
358 return __t;
359 }
360
361 _LIBCPP_INLINE_VISIBILITY
362 friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
363 {return __it + __n;}
364
365 _LIBCPP_INLINE_VISIBILITY
366 friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
367 {
368 if (__x != __y)
369 return (__x.__m_iter_ - __y.__m_iter_) * __block_size
370 + (__x.__ptr_ - *__x.__m_iter_)
371 - (__y.__ptr_ - *__y.__m_iter_);
372 return 0;
373 }
374
375 _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
376 {return *(*this + __n);}
377
378 _LIBCPP_INLINE_VISIBILITY friend
379 bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
380 {return __x.__ptr_ == __y.__ptr_;}
381
382 _LIBCPP_INLINE_VISIBILITY friend
383 bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
384 {return !(__x == __y);}
385
386 _LIBCPP_INLINE_VISIBILITY friend
387 bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
388 {return __x.__m_iter_ < __y.__m_iter_ ||
389 (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
390
391 _LIBCPP_INLINE_VISIBILITY friend
392 bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
393 {return __y < __x;}
394
395 _LIBCPP_INLINE_VISIBILITY friend
396 bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
397 {return !(__y < __x);}
398
399 _LIBCPP_INLINE_VISIBILITY friend
400 bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
401 {return !(__x < __y);}
402
403private:
Howard Hinnanta12beb32011-06-02 16:10:22 +0000404 _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000405 : __m_iter_(__m), __ptr_(__p) {}
406
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000407 template <class _Tp, class _A> friend class __deque_base;
Howard Hinnant422a53f2010-09-21 21:28:23 +0000408 template <class _Tp, class _A> friend class _LIBCPP_VISIBLE deque;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409 template <class _V, class _P, class _R, class _MP, class _D, _D>
Howard Hinnant422a53f2010-09-21 21:28:23 +0000410 friend class _LIBCPP_VISIBLE __deque_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000411
412 template <class _RAIter,
413 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
414 friend
415 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
416 copy(_RAIter __f,
417 _RAIter __l,
418 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
419 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
420
421 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
422 class _OutputIterator>
423 friend
424 _OutputIterator
425 copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
426 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
427 _OutputIterator __r);
428
429 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
430 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
431 friend
432 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
433 copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
434 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
435 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
436
437 template <class _RAIter,
438 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
439 friend
440 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
441 copy_backward(_RAIter __f,
442 _RAIter __l,
443 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
444 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
445
446 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
447 class _OutputIterator>
448 friend
449 _OutputIterator
450 copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
451 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
452 _OutputIterator __r);
453
454 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
455 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
456 friend
457 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
458 copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
459 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
460 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
461
462 template <class _RAIter,
463 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
464 friend
465 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
466 move(_RAIter __f,
467 _RAIter __l,
468 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
469 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
470
471 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
472 class _OutputIterator>
473 friend
474 _OutputIterator
475 move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
476 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
477 _OutputIterator __r);
478
479 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
480 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
481 friend
482 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
483 move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
484 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
485 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
486
487 template <class _RAIter,
488 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
489 friend
490 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
491 move_backward(_RAIter __f,
492 _RAIter __l,
493 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
494 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
495
496 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
497 class _OutputIterator>
498 friend
499 _OutputIterator
500 move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
501 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
502 _OutputIterator __r);
503
504 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
505 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
506 friend
507 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
508 move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
509 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
510 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
511};
512
513// copy
514
515template <class _RAIter,
516 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
517__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
518copy(_RAIter __f,
519 _RAIter __l,
520 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
521 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
522{
523 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
524 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
525 while (__f != __l)
526 {
527 pointer __rb = __r.__ptr_;
528 pointer __re = *__r.__m_iter_ + _B2;
529 difference_type __bs = __re - __rb;
530 difference_type __n = __l - __f;
531 _RAIter __m = __l;
532 if (__n > __bs)
533 {
534 __n = __bs;
535 __m = __f + __n;
536 }
537 _STD::copy(__f, __m, __rb);
538 __f = __m;
539 __r += __n;
540 }
541 return __r;
542}
543
544template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
545 class _OutputIterator>
546_OutputIterator
547copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
548 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
549 _OutputIterator __r)
550{
551 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
552 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
553 difference_type __n = __l - __f;
554 while (__n > 0)
555 {
556 pointer __fb = __f.__ptr_;
557 pointer __fe = *__f.__m_iter_ + _B1;
558 difference_type __bs = __fe - __fb;
559 if (__bs > __n)
560 {
561 __bs = __n;
562 __fe = __fb + __bs;
563 }
564 __r = _STD::copy(__fb, __fe, __r);
565 __n -= __bs;
566 __f += __bs;
567 }
568 return __r;
569}
570
571template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
572 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
573__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
574copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
575 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
576 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
577{
578 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
579 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
580 difference_type __n = __l - __f;
581 while (__n > 0)
582 {
583 pointer __fb = __f.__ptr_;
584 pointer __fe = *__f.__m_iter_ + _B1;
585 difference_type __bs = __fe - __fb;
586 if (__bs > __n)
587 {
588 __bs = __n;
589 __fe = __fb + __bs;
590 }
591 __r = _STD::copy(__fb, __fe, __r);
592 __n -= __bs;
593 __f += __bs;
594 }
595 return __r;
596}
597
598// copy_backward
599
600template <class _RAIter,
601 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
602__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
603copy_backward(_RAIter __f,
604 _RAIter __l,
605 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
606 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
607{
608 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
609 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
610 while (__f != __l)
611 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +0000612 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _STD::prev(__r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000613 pointer __rb = *__rp.__m_iter_;
614 pointer __re = __rp.__ptr_ + 1;
615 difference_type __bs = __re - __rb;
616 difference_type __n = __l - __f;
617 _RAIter __m = __f;
618 if (__n > __bs)
619 {
620 __n = __bs;
621 __m = __l - __n;
622 }
623 _STD::copy_backward(__m, __l, __re);
624 __l = __m;
625 __r -= __n;
626 }
627 return __r;
628}
629
630template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
631 class _OutputIterator>
632_OutputIterator
633copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
634 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
635 _OutputIterator __r)
636{
637 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
638 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
639 difference_type __n = __l - __f;
640 while (__n > 0)
641 {
642 --__l;
643 pointer __lb = *__l.__m_iter_;
644 pointer __le = __l.__ptr_ + 1;
645 difference_type __bs = __le - __lb;
646 if (__bs > __n)
647 {
648 __bs = __n;
649 __lb = __le - __bs;
650 }
651 __r = _STD::copy_backward(__lb, __le, __r);
652 __n -= __bs;
653 __l -= __bs - 1;
654 }
655 return __r;
656}
657
658template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
659 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
660__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
661copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
662 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
663 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
664{
665 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
666 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
667 difference_type __n = __l - __f;
668 while (__n > 0)
669 {
670 --__l;
671 pointer __lb = *__l.__m_iter_;
672 pointer __le = __l.__ptr_ + 1;
673 difference_type __bs = __le - __lb;
674 if (__bs > __n)
675 {
676 __bs = __n;
677 __lb = __le - __bs;
678 }
679 __r = _STD::copy_backward(__lb, __le, __r);
680 __n -= __bs;
681 __l -= __bs - 1;
682 }
683 return __r;
684}
685
686// move
687
688template <class _RAIter,
689 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
690__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
691move(_RAIter __f,
692 _RAIter __l,
693 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
694 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
695{
696 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
697 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
698 while (__f != __l)
699 {
700 pointer __rb = __r.__ptr_;
701 pointer __re = *__r.__m_iter_ + _B2;
702 difference_type __bs = __re - __rb;
703 difference_type __n = __l - __f;
704 _RAIter __m = __l;
705 if (__n > __bs)
706 {
707 __n = __bs;
708 __m = __f + __n;
709 }
710 _STD::move(__f, __m, __rb);
711 __f = __m;
712 __r += __n;
713 }
714 return __r;
715}
716
717template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
718 class _OutputIterator>
719_OutputIterator
720move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
721 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
722 _OutputIterator __r)
723{
724 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
725 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
726 difference_type __n = __l - __f;
727 while (__n > 0)
728 {
729 pointer __fb = __f.__ptr_;
730 pointer __fe = *__f.__m_iter_ + _B1;
731 difference_type __bs = __fe - __fb;
732 if (__bs > __n)
733 {
734 __bs = __n;
735 __fe = __fb + __bs;
736 }
737 __r = _STD::move(__fb, __fe, __r);
738 __n -= __bs;
739 __f += __bs;
740 }
741 return __r;
742}
743
744template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
745 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
746__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
747move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
748 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
749 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
750{
751 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
752 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
753 difference_type __n = __l - __f;
754 while (__n > 0)
755 {
756 pointer __fb = __f.__ptr_;
757 pointer __fe = *__f.__m_iter_ + _B1;
758 difference_type __bs = __fe - __fb;
759 if (__bs > __n)
760 {
761 __bs = __n;
762 __fe = __fb + __bs;
763 }
764 __r = _STD::move(__fb, __fe, __r);
765 __n -= __bs;
766 __f += __bs;
767 }
768 return __r;
769}
770
771// move_backward
772
773template <class _RAIter,
774 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
775__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
776move_backward(_RAIter __f,
777 _RAIter __l,
778 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
779 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
780{
781 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
782 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
783 while (__f != __l)
784 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +0000785 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _STD::prev(__r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000786 pointer __rb = *__rp.__m_iter_;
787 pointer __re = __rp.__ptr_ + 1;
788 difference_type __bs = __re - __rb;
789 difference_type __n = __l - __f;
790 _RAIter __m = __f;
791 if (__n > __bs)
792 {
793 __n = __bs;
794 __m = __l - __n;
795 }
796 _STD::move_backward(__m, __l, __re);
797 __l = __m;
798 __r -= __n;
799 }
800 return __r;
801}
802
803template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
804 class _OutputIterator>
805_OutputIterator
806move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
807 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
808 _OutputIterator __r)
809{
810 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
811 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
812 difference_type __n = __l - __f;
813 while (__n > 0)
814 {
815 --__l;
816 pointer __lb = *__l.__m_iter_;
817 pointer __le = __l.__ptr_ + 1;
818 difference_type __bs = __le - __lb;
819 if (__bs > __n)
820 {
821 __bs = __n;
822 __lb = __le - __bs;
823 }
824 __r = _STD::move_backward(__lb, __le, __r);
825 __n -= __bs;
826 __l -= __bs - 1;
827 }
828 return __r;
829}
830
831template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
832 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
833__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
834move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
835 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
836 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
837{
838 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
839 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
840 difference_type __n = __l - __f;
841 while (__n > 0)
842 {
843 --__l;
844 pointer __lb = *__l.__m_iter_;
845 pointer __le = __l.__ptr_ + 1;
846 difference_type __bs = __le - __lb;
847 if (__bs > __n)
848 {
849 __bs = __n;
850 __lb = __le - __bs;
851 }
852 __r = _STD::move_backward(__lb, __le, __r);
853 __n -= __bs;
854 __l -= __bs - 1;
855 }
856 return __r;
857}
858
859template <bool>
860class __deque_base_common
861{
862protected:
863 void __throw_length_error() const;
864 void __throw_out_of_range() const;
865};
866
867template <bool __b>
868void
869__deque_base_common<__b>::__throw_length_error() const
870{
871#ifndef _LIBCPP_NO_EXCEPTIONS
872 throw length_error("deque");
873#endif
874}
875
876template <bool __b>
877void
878__deque_base_common<__b>::__throw_out_of_range() const
879{
880#ifndef _LIBCPP_NO_EXCEPTIONS
881 throw out_of_range("deque");
882#endif
883}
884
885template <class _Tp, class _Allocator>
886class __deque_base
887 : protected __deque_base_common<true>
888{
889 __deque_base(const __deque_base& __c);
890 __deque_base& operator=(const __deque_base& __c);
891protected:
892 typedef _Tp value_type;
893 typedef _Allocator allocator_type;
894 typedef allocator_traits<allocator_type> __alloc_traits;
895 typedef value_type& reference;
896 typedef const value_type& const_reference;
897 typedef typename __alloc_traits::size_type size_type;
898 typedef typename __alloc_traits::difference_type difference_type;
899 typedef typename __alloc_traits::pointer pointer;
900 typedef typename __alloc_traits::const_pointer const_pointer;
901
902 static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;
903
904 typedef typename __alloc_traits::template
905#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
906 rebind_alloc<pointer>
907#else
908 rebind_alloc<pointer>::other
909#endif
910 __pointer_allocator;
911 typedef allocator_traits<__pointer_allocator> __map_traits;
912 typedef typename __map_traits::pointer __map_pointer;
913 typedef typename __map_traits::const_pointer __map_const_pointer;
914 typedef __split_buffer<pointer, __pointer_allocator> __map;
915
916 typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
917 difference_type, __block_size> iterator;
918 typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
919 difference_type, __block_size> const_iterator;
920
921 __map __map_;
922 size_type __start_;
923 __compressed_pair<size_type, allocator_type> __size_;
924
Howard Hinnanta12beb32011-06-02 16:10:22 +0000925 iterator begin() _NOEXCEPT;
926 const_iterator begin() const _NOEXCEPT;
927 iterator end() _NOEXCEPT;
928 const_iterator end() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000929
930 _LIBCPP_INLINE_VISIBILITY size_type& size() {return __size_.first();}
Howard Hinnanta12beb32011-06-02 16:10:22 +0000931 _LIBCPP_INLINE_VISIBILITY
932 const size_type& size() const _NOEXCEPT {return __size_.first();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000933 _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() {return __size_.second();}
Howard Hinnanta12beb32011-06-02 16:10:22 +0000934 _LIBCPP_INLINE_VISIBILITY
935 const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000936
937 __deque_base();
938 explicit __deque_base(const allocator_type& __a);
Howard Hinnant0a612b02011-06-02 20:00:14 +0000939public:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000940 ~__deque_base();
941
Howard Hinnant73d21a42010-09-04 23:28:19 +0000942#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000943
Howard Hinnant0a612b02011-06-02 20:00:14 +0000944 __deque_base(__deque_base&& __c)
945 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000946 __deque_base(__deque_base&& __c, const allocator_type& __a);
947
Howard Hinnant73d21a42010-09-04 23:28:19 +0000948#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0a612b02011-06-02 20:00:14 +0000949 void swap(__deque_base& __c)
950 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
951 __is_nothrow_swappable<allocator_type>::value);
952protected:
Howard Hinnanta12beb32011-06-02 16:10:22 +0000953 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000954
955 bool __invariants() const;
956
Howard Hinnant422a53f2010-09-21 21:28:23 +0000957 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000958 void __move_assign(__deque_base& __c)
Howard Hinnant18884f42011-06-02 21:38:57 +0000959 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
960 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000961 {
962 __map_ = _STD::move(__c.__map_);
963 __start_ = __c.__start_;
964 size() = __c.size();
965 __move_assign_alloc(__c);
966 __c.__start_ = __c.size() = 0;
967 }
968
Howard Hinnant422a53f2010-09-21 21:28:23 +0000969 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000970 void __move_assign_alloc(__deque_base& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000971 _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
972 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000973 {__move_assign_alloc(__c, integral_constant<bool,
974 __alloc_traits::propagate_on_container_move_assignment::value>());}
975
976private:
Howard Hinnant422a53f2010-09-21 21:28:23 +0000977 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000978 void __move_assign_alloc(const __deque_base& __c, true_type)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000979 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000980 {
981 __alloc() = _STD::move(__c.__alloc());
982 }
983
Howard Hinnant422a53f2010-09-21 21:28:23 +0000984 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0a612b02011-06-02 20:00:14 +0000985 void __move_assign_alloc(const __deque_base& __c, false_type) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000986 {}
987
Howard Hinnant422a53f2010-09-21 21:28:23 +0000988 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000989 static void __swap_alloc(allocator_type& __x, allocator_type& __y)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000990 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
991 __is_nothrow_swappable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000992 {__swap_alloc(__x, __y, integral_constant<bool,
993 __alloc_traits::propagate_on_container_swap::value>());}
994
Howard Hinnant422a53f2010-09-21 21:28:23 +0000995 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000996 static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000997 _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000998 {
999 using _STD::swap;
1000 swap(__x, __y);
1001 }
Howard Hinnant422a53f2010-09-21 21:28:23 +00001002
1003 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001004 static void __swap_alloc(allocator_type& __x, allocator_type& __y, false_type)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001005 _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001006 {}
1007};
1008
1009template <class _Tp, class _Allocator>
1010bool
1011__deque_base<_Tp, _Allocator>::__invariants() const
1012{
1013 if (!__map_.__invariants())
1014 return false;
1015 if (__map_.size() >= size_type(-1) / __block_size)
1016 return false;
1017 for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
1018 __i != __e; ++__i)
1019 if (*__i == nullptr)
1020 return false;
1021 if (__map_.size() != 0)
1022 {
1023 if (size() >= __map_.size() * __block_size)
1024 return false;
1025 if (__start_ >= __map_.size() * __block_size - size())
1026 return false;
1027 }
1028 else
1029 {
1030 if (size() != 0)
1031 return false;
1032 if (__start_ != 0)
1033 return false;
1034 }
1035 return true;
1036}
1037
1038template <class _Tp, class _Allocator>
1039typename __deque_base<_Tp, _Allocator>::iterator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001040__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001041{
1042 __map_pointer __mp = __map_.begin() + __start_ / __block_size;
1043 return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1044}
1045
1046template <class _Tp, class _Allocator>
1047typename __deque_base<_Tp, _Allocator>::const_iterator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001048__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001049{
1050 __map_const_pointer __mp = __map_.begin() + __start_ / __block_size;
1051 return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1052}
1053
1054template <class _Tp, class _Allocator>
1055typename __deque_base<_Tp, _Allocator>::iterator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001056__deque_base<_Tp, _Allocator>::end() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001057{
1058 size_type __p = size() + __start_;
1059 __map_pointer __mp = __map_.begin() + __p / __block_size;
1060 return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1061}
1062
1063template <class _Tp, class _Allocator>
1064typename __deque_base<_Tp, _Allocator>::const_iterator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001065__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001066{
1067 size_type __p = size() + __start_;
1068 __map_const_pointer __mp = __map_.begin() + __p / __block_size;
1069 return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1070}
1071
1072template <class _Tp, class _Allocator>
1073inline _LIBCPP_INLINE_VISIBILITY
1074__deque_base<_Tp, _Allocator>::__deque_base()
1075 : __start_(0), __size_(0) {}
1076
1077template <class _Tp, class _Allocator>
1078inline _LIBCPP_INLINE_VISIBILITY
1079__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
1080 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
1081
1082template <class _Tp, class _Allocator>
1083__deque_base<_Tp, _Allocator>::~__deque_base()
1084{
1085 clear();
1086 typename __map::iterator __i = __map_.begin();
1087 typename __map::iterator __e = __map_.end();
1088 for (; __i != __e; ++__i)
1089 __alloc_traits::deallocate(__alloc(), *__i, __block_size);
1090}
1091
Howard Hinnant73d21a42010-09-04 23:28:19 +00001092#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001093
1094template <class _Tp, class _Allocator>
1095__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001096 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001097 : __map_(_STD::move(__c.__map_)),
1098 __start_(_STD::move(__c.__start_)),
1099 __size_(_STD::move(__c.__size_))
1100{
1101 __c.__start_ = 0;
1102 __c.size() = 0;
1103}
1104
1105template <class _Tp, class _Allocator>
1106__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)
1107 : __map_(_STD::move(__c.__map_), __pointer_allocator(__a)),
1108 __start_(_STD::move(__c.__start_)),
1109 __size_(_STD::move(__c.size()), __a)
1110{
1111 if (__a == __c.__alloc())
1112 {
1113 __c.__start_ = 0;
1114 __c.size() = 0;
1115 }
1116 else
1117 {
1118 __map_.clear();
1119 __start_ = 0;
1120 size() = 0;
1121 }
1122}
1123
Howard Hinnant73d21a42010-09-04 23:28:19 +00001124#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001125
1126template <class _Tp, class _Allocator>
1127void
1128__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001129 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
1130 __is_nothrow_swappable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001131{
1132 __map_.swap(__c.__map_);
1133 _STD::swap(__start_, __c.__start_);
1134 _STD::swap(size(), __c.size());
1135 __swap_alloc(__alloc(), __c.__alloc());
1136}
1137
1138template <class _Tp, class _Allocator>
1139void
Howard Hinnanta12beb32011-06-02 16:10:22 +00001140__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001141{
1142 allocator_type& __a = __alloc();
1143 for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
Howard Hinnant2529d022011-02-02 17:36:20 +00001144 __alloc_traits::destroy(__a, _STD::addressof(*__i));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001145 size() = 0;
1146 while (__map_.size() > 2)
1147 {
1148 __alloc_traits::deallocate(__a, __map_.front(), __block_size);
1149 __map_.pop_front();
1150 }
1151 switch (__map_.size())
1152 {
1153 case 1:
1154 __start_ = __block_size / 2;
1155 break;
1156 case 2:
1157 __start_ = __block_size;
1158 break;
1159 }
1160}
1161
1162template <class _Tp, class _Allocator = allocator<_Tp> >
Howard Hinnant422a53f2010-09-21 21:28:23 +00001163class _LIBCPP_VISIBLE deque
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001164 : private __deque_base<_Tp, _Allocator>
1165{
1166public:
1167 // types:
Howard Hinnant324bb032010-08-22 00:02:43 +00001168
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001169 typedef _Tp value_type;
1170 typedef _Allocator allocator_type;
1171
1172 typedef __deque_base<value_type, allocator_type> __base;
1173
1174 typedef typename __base::__alloc_traits __alloc_traits;
1175 typedef typename __base::reference reference;
1176 typedef typename __base::const_reference const_reference;
1177 typedef typename __base::iterator iterator;
1178 typedef typename __base::const_iterator const_iterator;
1179 typedef typename __base::size_type size_type;
1180 typedef typename __base::difference_type difference_type;
1181
1182 typedef typename __base::pointer pointer;
1183 typedef typename __base::const_pointer const_pointer;
1184 typedef _STD::reverse_iterator<iterator> reverse_iterator;
1185 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
1186
1187 // construct/copy/destroy:
1188 _LIBCPP_INLINE_VISIBILITY deque() {}
1189 _LIBCPP_INLINE_VISIBILITY deque(const allocator_type& __a) : __base(__a) {}
1190 explicit deque(size_type __n);
1191 deque(size_type __n, const value_type& __v);
1192 deque(size_type __n, const value_type& __v, const allocator_type& __a);
1193 template <class _InputIter>
1194 deque(_InputIter __f, _InputIter __l,
1195 typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
1196 template <class _InputIter>
1197 deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1198 typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
1199 deque(const deque& __c);
1200 deque(const deque& __c, const allocator_type& __a);
1201 deque(initializer_list<value_type> __il);
1202 deque(initializer_list<value_type> __il, const allocator_type& __a);
1203
1204 deque& operator=(const deque& __c);
Howard Hinnant422a53f2010-09-21 21:28:23 +00001205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001206 deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
1207
Howard Hinnant73d21a42010-09-04 23:28:19 +00001208#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0a612b02011-06-02 20:00:14 +00001209 deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001210 deque(deque&& __c, const allocator_type& __a);
Howard Hinnant0a612b02011-06-02 20:00:14 +00001211 deque& operator=(deque&& __c)
Howard Hinnant18884f42011-06-02 21:38:57 +00001212 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1213 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001214#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001215
1216 template <class _InputIter>
1217 void assign(_InputIter __f, _InputIter __l,
1218 typename enable_if<__is_input_iterator<_InputIter>::value &&
1219 !__is_random_access_iterator<_InputIter>::value>::type* = 0);
1220 template <class _RAIter>
1221 void assign(_RAIter __f, _RAIter __l,
1222 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
1223 void assign(size_type __n, const value_type& __v);
Howard Hinnant422a53f2010-09-21 21:28:23 +00001224 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001225 void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
1226
Howard Hinnanta12beb32011-06-02 16:10:22 +00001227 allocator_type get_allocator() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001228
1229 // iterators:
1230
Howard Hinnant422a53f2010-09-21 21:28:23 +00001231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001232 iterator begin() _NOEXCEPT {return __base::begin();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001233 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001234 const_iterator begin() const _NOEXCEPT {return __base::begin();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001235 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001236 iterator end() _NOEXCEPT {return __base::end();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001237 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001238 const_iterator end() const _NOEXCEPT {return __base::end();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001239
Howard Hinnant422a53f2010-09-21 21:28:23 +00001240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001241 reverse_iterator rbegin() _NOEXCEPT
1242 {return reverse_iterator(__base::end());}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001243 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001244 const_reverse_iterator rbegin() const _NOEXCEPT
1245 {return const_reverse_iterator(__base::end());}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001246 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001247 reverse_iterator rend() _NOEXCEPT
1248 {return reverse_iterator(__base::begin());}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001250 const_reverse_iterator rend() const _NOEXCEPT
1251 {return const_reverse_iterator(__base::begin());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001252
Howard Hinnant422a53f2010-09-21 21:28:23 +00001253 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001254 const_iterator cbegin() const _NOEXCEPT
1255 {return __base::begin();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001257 const_iterator cend() const _NOEXCEPT
1258 {return __base::end();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001259 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001260 const_reverse_iterator crbegin() const _NOEXCEPT
1261 {return const_reverse_iterator(__base::end());}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001262 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001263 const_reverse_iterator crend() const _NOEXCEPT
1264 {return const_reverse_iterator(__base::begin());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001265
1266 // capacity:
Howard Hinnant422a53f2010-09-21 21:28:23 +00001267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001268 size_type size() const _NOEXCEPT {return __base::size();}
1269 _LIBCPP_INLINE_VISIBILITY
1270 size_type max_size() const _NOEXCEPT
1271 {return __alloc_traits::max_size(__base::__alloc());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001272 void resize(size_type __n);
1273 void resize(size_type __n, const value_type& __v);
Howard Hinnant18884f42011-06-02 21:38:57 +00001274 void shrink_to_fit() _NOEXCEPT;
Howard Hinnanta12beb32011-06-02 16:10:22 +00001275 _LIBCPP_INLINE_VISIBILITY
1276 bool empty() const _NOEXCEPT {return __base::size() == 0;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001277
1278 // element access:
1279 reference operator[](size_type __i);
1280 const_reference operator[](size_type __i) const;
1281 reference at(size_type __i);
1282 const_reference at(size_type __i) const;
1283 reference front();
1284 const_reference front() const;
1285 reference back();
1286 const_reference back() const;
1287
1288 // 23.2.2.3 modifiers:
1289 void push_front(const value_type& __v);
1290 void push_back(const value_type& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001291#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1292#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001293 template <class... _Args> void emplace_front(_Args&&... __args);
1294 template <class... _Args> void emplace_back(_Args&&... __args);
1295 template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001296#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001297 void push_front(value_type&& __v);
1298 void push_back(value_type&& __v);
1299 iterator insert(const_iterator __p, value_type&& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001300#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001301 iterator insert(const_iterator __p, const value_type& __v);
1302 iterator insert(const_iterator __p, size_type __n, const value_type& __v);
1303 template <class _InputIter>
1304 iterator insert (const_iterator __p, _InputIter __f, _InputIter __l,
1305 typename enable_if<__is_input_iterator<_InputIter>::value
1306 &&!__is_bidirectional_iterator<_InputIter>::value>::type* = 0);
1307 template <class _BiIter>
1308 iterator insert (const_iterator __p, _BiIter __f, _BiIter __l,
1309 typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0);
Howard Hinnant422a53f2010-09-21 21:28:23 +00001310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001311 iterator insert(const_iterator __p, initializer_list<value_type> __il)
1312 {return insert(__p, __il.begin(), __il.end());}
1313 void pop_front();
1314 void pop_back();
1315 iterator erase(const_iterator __p);
1316 iterator erase(const_iterator __f, const_iterator __l);
1317
Howard Hinnant0a612b02011-06-02 20:00:14 +00001318 void swap(deque& __c)
1319 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1320 __is_nothrow_swappable<allocator_type>::value);
Howard Hinnanta12beb32011-06-02 16:10:22 +00001321 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001322
Howard Hinnant422a53f2010-09-21 21:28:23 +00001323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001324 bool __invariants() const {return __base::__invariants();}
1325private:
Howard Hinnant422a53f2010-09-21 21:28:23 +00001326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001327 static size_type __recommend_blocks(size_type __n)
1328 {
1329 return __n / __base::__block_size + (__n % __base::__block_size != 0);
1330 }
Howard Hinnant422a53f2010-09-21 21:28:23 +00001331 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001332 size_type __capacity() const
1333 {
1334 return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;
1335 }
Howard Hinnant422a53f2010-09-21 21:28:23 +00001336 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001337 size_type __front_spare() const
1338 {
1339 return __base::__start_;
1340 }
Howard Hinnant422a53f2010-09-21 21:28:23 +00001341 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001342 size_type __back_spare() const
1343 {
1344 return __capacity() - (__base::__start_ + __base::size());
1345 }
1346
1347 template <class _InpIter>
1348 void __append(_InpIter __f, _InpIter __l,
1349 typename enable_if<__is_input_iterator<_InpIter>::value &&
1350 !__is_forward_iterator<_InpIter>::value>::type* = 0);
1351 template <class _ForIter>
1352 void __append(_ForIter __f, _ForIter __l,
1353 typename enable_if<__is_forward_iterator<_ForIter>::value>::type* = 0);
1354 void __append(size_type __n);
1355 void __append(size_type __n, const value_type& __v);
1356 void __erase_to_end(const_iterator __f);
1357 void __add_front_capacity();
1358 void __add_front_capacity(size_type __n);
1359 void __add_back_capacity();
1360 void __add_back_capacity(size_type __n);
1361 iterator __move_and_check(iterator __f, iterator __l, iterator __r,
1362 const_pointer& __vt);
1363 iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
1364 const_pointer& __vt);
1365 void __move_construct_and_check(iterator __f, iterator __l,
1366 iterator __r, const_pointer& __vt);
1367 void __move_construct_backward_and_check(iterator __f, iterator __l,
1368 iterator __r, const_pointer& __vt);
1369
Howard Hinnant422a53f2010-09-21 21:28:23 +00001370 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001371 void __copy_assign_alloc(const deque& __c)
1372 {__copy_assign_alloc(__c, integral_constant<bool,
1373 __alloc_traits::propagate_on_container_copy_assignment::value>());}
1374
Howard Hinnant422a53f2010-09-21 21:28:23 +00001375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001376 void __copy_assign_alloc(const deque& __c, true_type)
1377 {
1378 if (__base::__alloc() != __c.__alloc())
1379 {
1380 clear();
1381 shrink_to_fit();
1382 }
1383 __base::__alloc() = __c.__alloc();
1384 __base::__map_.__alloc() = __c.__map_.__alloc();
1385 }
1386
Howard Hinnant422a53f2010-09-21 21:28:23 +00001387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001388 void __copy_assign_alloc(const deque& __c, false_type)
1389 {}
1390
Howard Hinnant18884f42011-06-02 21:38:57 +00001391 void __move_assign(deque& __c, true_type)
1392 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001393 void __move_assign(deque& __c, false_type);
1394};
1395
1396template <class _Tp, class _Allocator>
1397deque<_Tp, _Allocator>::deque(size_type __n)
1398{
1399 if (__n > 0)
1400 __append(__n);
1401}
1402
1403template <class _Tp, class _Allocator>
1404deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
1405{
1406 if (__n > 0)
1407 __append(__n, __v);
1408}
1409
1410template <class _Tp, class _Allocator>
1411deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
1412 : __base(__a)
1413{
1414 if (__n > 0)
1415 __append(__n, __v);
1416}
1417
1418template <class _Tp, class _Allocator>
1419template <class _InputIter>
1420deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
1421 typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
1422{
1423 __append(__f, __l);
1424}
1425
1426template <class _Tp, class _Allocator>
1427template <class _InputIter>
1428deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1429 typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
1430 : __base(__a)
1431{
1432 __append(__f, __l);
1433}
1434
1435template <class _Tp, class _Allocator>
1436deque<_Tp, _Allocator>::deque(const deque& __c)
1437 : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
1438{
1439 __append(__c.begin(), __c.end());
1440}
1441
1442template <class _Tp, class _Allocator>
1443deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
1444 : __base(__a)
1445{
1446 __append(__c.begin(), __c.end());
1447}
1448
1449template <class _Tp, class _Allocator>
1450deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
1451{
1452 __append(__il.begin(), __il.end());
1453}
1454
1455template <class _Tp, class _Allocator>
1456deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
1457 : __base(__a)
1458{
1459 __append(__il.begin(), __il.end());
1460}
1461
1462template <class _Tp, class _Allocator>
1463deque<_Tp, _Allocator>&
1464deque<_Tp, _Allocator>::operator=(const deque& __c)
1465{
1466 if (this != &__c)
1467 {
1468 __copy_assign_alloc(__c);
1469 assign(__c.begin(), __c.end());
1470 }
1471 return *this;
1472}
1473
Howard Hinnant73d21a42010-09-04 23:28:19 +00001474#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001475
1476template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001477inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001478deque<_Tp, _Allocator>::deque(deque&& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001479 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001480 : __base(_STD::move(__c))
1481{
1482}
1483
1484template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001485inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001486deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
1487 : __base(_STD::move(__c), __a)
1488{
1489 if (__a != __c.__alloc())
1490 {
1491 typedef move_iterator<iterator> _I;
1492 assign(_I(__c.begin()), _I(__c.end()));
1493 }
1494}
1495
1496template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001497inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001498deque<_Tp, _Allocator>&
1499deque<_Tp, _Allocator>::operator=(deque&& __c)
Howard Hinnant18884f42011-06-02 21:38:57 +00001500 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
1501 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001502{
1503 __move_assign(__c, integral_constant<bool,
1504 __alloc_traits::propagate_on_container_move_assignment::value>());
1505 return *this;
1506}
1507
1508template <class _Tp, class _Allocator>
1509void
1510deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
1511{
1512 if (__base::__alloc() != __c.__alloc())
1513 {
1514 typedef move_iterator<iterator> _I;
1515 assign(_I(__c.begin()), _I(__c.end()));
1516 }
1517 else
1518 __move_assign(__c, true_type());
1519}
1520
1521template <class _Tp, class _Allocator>
1522void
1523deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
Howard Hinnant18884f42011-06-02 21:38:57 +00001524 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001525{
1526 clear();
1527 shrink_to_fit();
1528 __base::__move_assign(__c);
1529}
1530
Howard Hinnant73d21a42010-09-04 23:28:19 +00001531#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001532
1533template <class _Tp, class _Allocator>
1534template <class _InputIter>
1535void
1536deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
1537 typename enable_if<__is_input_iterator<_InputIter>::value &&
1538 !__is_random_access_iterator<_InputIter>::value>::type*)
1539{
1540 iterator __i = __base::begin();
1541 iterator __e = __base::end();
1542 for (; __f != __l && __i != __e; ++__f, ++__i)
1543 *__i = *__f;
1544 if (__f != __l)
1545 __append(__f, __l);
1546 else
1547 __erase_to_end(__i);
1548}
1549
1550template <class _Tp, class _Allocator>
1551template <class _RAIter>
1552void
1553deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
1554 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
1555{
1556 if (static_cast<size_type>(__l - __f) > __base::size())
1557 {
1558 _RAIter __m = __f + __base::size();
1559 _STD::copy(__f, __m, __base::begin());
1560 __append(__m, __l);
1561 }
1562 else
1563 __erase_to_end(_STD::copy(__f, __l, __base::begin()));
1564}
1565
1566template <class _Tp, class _Allocator>
1567void
1568deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
1569{
1570 if (__n > __base::size())
1571 {
1572 _STD::fill_n(__base::begin(), __base::size(), __v);
1573 __n -= __base::size();
1574 __append(__n, __v);
1575 }
1576 else
1577 __erase_to_end(_STD::fill_n(__base::begin(), __n, __v));
1578}
1579
1580template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001581inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001582_Allocator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001583deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001584{
1585 return __base::__alloc();
1586}
1587
1588template <class _Tp, class _Allocator>
1589void
1590deque<_Tp, _Allocator>::resize(size_type __n)
1591{
1592 if (__n > __base::size())
1593 __append(__n - __base::size());
1594 else if (__n < __base::size())
1595 __erase_to_end(__base::begin() + __n);
1596}
1597
1598template <class _Tp, class _Allocator>
1599void
1600deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
1601{
1602 if (__n > __base::size())
1603 __append(__n - __base::size(), __v);
1604 else if (__n < __base::size())
1605 __erase_to_end(__base::begin() + __n);
1606}
1607
1608template <class _Tp, class _Allocator>
1609void
Howard Hinnant18884f42011-06-02 21:38:57 +00001610deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001611{
1612 allocator_type& __a = __base::__alloc();
1613 if (empty())
1614 {
1615 while (__base::__map_.size() > 0)
1616 {
1617 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
1618 __base::__map_.pop_back();
1619 }
1620 __base::__start_ = 0;
1621 }
1622 else
1623 {
1624 if (__front_spare() >= __base::__block_size)
1625 {
1626 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
1627 __base::__map_.pop_front();
1628 __base::__start_ -= __base::__block_size;
1629 }
1630 if (__back_spare() >= __base::__block_size)
1631 {
1632 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
1633 __base::__map_.pop_back();
1634 }
1635 }
1636 __base::__map_.shrink_to_fit();
1637}
1638
1639template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001640inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001641typename deque<_Tp, _Allocator>::reference
1642deque<_Tp, _Allocator>::operator[](size_type __i)
1643{
1644 size_type __p = __base::__start_ + __i;
1645 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1646}
1647
1648template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001649inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001650typename deque<_Tp, _Allocator>::const_reference
1651deque<_Tp, _Allocator>::operator[](size_type __i) const
1652{
1653 size_type __p = __base::__start_ + __i;
1654 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1655}
1656
1657template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001658inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001659typename deque<_Tp, _Allocator>::reference
1660deque<_Tp, _Allocator>::at(size_type __i)
1661{
1662 if (__i >= __base::size())
1663 __base::__throw_out_of_range();
1664 size_type __p = __base::__start_ + __i;
1665 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1666}
1667
1668template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001669inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001670typename deque<_Tp, _Allocator>::const_reference
1671deque<_Tp, _Allocator>::at(size_type __i) const
1672{
1673 if (__i >= __base::size())
1674 __base::__throw_out_of_range();
1675 size_type __p = __base::__start_ + __i;
1676 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1677}
1678
1679template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001680inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001681typename deque<_Tp, _Allocator>::reference
1682deque<_Tp, _Allocator>::front()
1683{
1684 return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1685 + __base::__start_ % __base::__block_size);
1686}
1687
1688template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001689inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001690typename deque<_Tp, _Allocator>::const_reference
1691deque<_Tp, _Allocator>::front() const
1692{
1693 return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1694 + __base::__start_ % __base::__block_size);
1695}
1696
1697template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001698inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001699typename deque<_Tp, _Allocator>::reference
1700deque<_Tp, _Allocator>::back()
1701{
1702 size_type __p = __base::size() + __base::__start_ - 1;
1703 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1704}
1705
1706template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001707inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001708typename deque<_Tp, _Allocator>::const_reference
1709deque<_Tp, _Allocator>::back() const
1710{
1711 size_type __p = __base::size() + __base::__start_ - 1;
1712 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1713}
1714
1715template <class _Tp, class _Allocator>
1716void
1717deque<_Tp, _Allocator>::push_back(const value_type& __v)
1718{
1719 allocator_type& __a = __base::__alloc();
1720 if (__back_spare() == 0)
1721 __add_back_capacity();
1722 // __back_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001723 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001724 ++__base::size();
1725}
1726
Howard Hinnant73d21a42010-09-04 23:28:19 +00001727#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001728
1729template <class _Tp, class _Allocator>
1730void
1731deque<_Tp, _Allocator>::push_back(value_type&& __v)
1732{
1733 allocator_type& __a = __base::__alloc();
1734 if (__back_spare() == 0)
1735 __add_back_capacity();
1736 // __back_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001737 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001738 ++__base::size();
1739}
1740
Howard Hinnant73d21a42010-09-04 23:28:19 +00001741#ifndef _LIBCPP_HAS_NO_VARIADICS
1742
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001743template <class _Tp, class _Allocator>
1744template <class... _Args>
1745void
1746deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
1747{
1748 allocator_type& __a = __base::__alloc();
1749 if (__back_spare() == 0)
1750 __add_back_capacity();
1751 // __back_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001752 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001753 ++__base::size();
1754}
1755
Howard Hinnant73d21a42010-09-04 23:28:19 +00001756#endif // _LIBCPP_HAS_NO_VARIADICS
1757#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001758
1759template <class _Tp, class _Allocator>
1760void
1761deque<_Tp, _Allocator>::push_front(const value_type& __v)
1762{
1763 allocator_type& __a = __base::__alloc();
1764 if (__front_spare() == 0)
1765 __add_front_capacity();
1766 // __front_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001767 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001768 --__base::__start_;
1769 ++__base::size();
1770}
1771
Howard Hinnant73d21a42010-09-04 23:28:19 +00001772#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001773
1774template <class _Tp, class _Allocator>
1775void
1776deque<_Tp, _Allocator>::push_front(value_type&& __v)
1777{
1778 allocator_type& __a = __base::__alloc();
1779 if (__front_spare() == 0)
1780 __add_front_capacity();
1781 // __front_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001782 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001783 --__base::__start_;
1784 ++__base::size();
1785}
1786
Howard Hinnant73d21a42010-09-04 23:28:19 +00001787#ifndef _LIBCPP_HAS_NO_VARIADICS
1788
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001789template <class _Tp, class _Allocator>
1790template <class... _Args>
1791void
1792deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
1793{
1794 allocator_type& __a = __base::__alloc();
1795 if (__front_spare() == 0)
1796 __add_front_capacity();
1797 // __front_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001798 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001799 --__base::__start_;
1800 ++__base::size();
1801}
1802
Howard Hinnant73d21a42010-09-04 23:28:19 +00001803#endif // _LIBCPP_HAS_NO_VARIADICS
1804#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001805
1806template <class _Tp, class _Allocator>
1807typename deque<_Tp, _Allocator>::iterator
1808deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
1809{
1810 size_type __pos = __p - __base::begin();
1811 size_type __to_end = __base::size() - __pos;
1812 allocator_type& __a = __base::__alloc();
1813 if (__pos < __to_end)
1814 { // insert by shifting things backward
1815 if (__front_spare() == 0)
1816 __add_front_capacity();
1817 // __front_spare() >= 1
1818 if (__pos == 0)
1819 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001820 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001821 --__base::__start_;
1822 ++__base::size();
1823 }
1824 else
1825 {
1826 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1827 iterator __b = __base::begin();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001828 iterator __bm1 = _STD::prev(__b);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001829 if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
1830 __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
Howard Hinnant2529d022011-02-02 17:36:20 +00001831 __alloc_traits::construct(__a, _STD::addressof(*__bm1), _STD::move(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001832 --__base::__start_;
1833 ++__base::size();
1834 if (__pos > 1)
Douglas Gregor7ac6af72011-04-29 16:20:26 +00001835 __b = __move_and_check(_STD::next(__b), __b + __pos, __b, __vt);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001836 *__b = *__vt;
1837 }
1838 }
1839 else
1840 { // insert by shifting things forward
1841 if (__back_spare() == 0)
1842 __add_back_capacity();
1843 // __back_capacity >= 1
1844 size_type __de = __base::size() - __pos;
1845 if (__de == 0)
1846 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001847 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001848 ++__base::size();
1849 }
1850 else
1851 {
1852 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1853 iterator __e = __base::end();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001854 iterator __em1 = _STD::prev(__e);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001855 if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
1856 __vt = pointer_traits<const_pointer>::pointer_to(*__e);
Howard Hinnant2529d022011-02-02 17:36:20 +00001857 __alloc_traits::construct(__a, _STD::addressof(*__e), _STD::move(*__em1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001858 ++__base::size();
1859 if (__de > 1)
1860 __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
1861 *--__e = *__vt;
1862 }
1863 }
1864 return __base::begin() + __pos;
1865}
1866
Howard Hinnant73d21a42010-09-04 23:28:19 +00001867#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001868
1869template <class _Tp, class _Allocator>
1870typename deque<_Tp, _Allocator>::iterator
1871deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
1872{
1873 size_type __pos = __p - __base::begin();
1874 size_type __to_end = __base::size() - __pos;
1875 allocator_type& __a = __base::__alloc();
1876 if (__pos < __to_end)
1877 { // insert by shifting things backward
1878 if (__front_spare() == 0)
1879 __add_front_capacity();
1880 // __front_spare() >= 1
1881 if (__pos == 0)
1882 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001883 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001884 --__base::__start_;
1885 ++__base::size();
1886 }
1887 else
1888 {
1889 iterator __b = __base::begin();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001890 iterator __bm1 = _STD::prev(__b);
Howard Hinnant2529d022011-02-02 17:36:20 +00001891 __alloc_traits::construct(__a, _STD::addressof(*__bm1), _STD::move(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001892 --__base::__start_;
1893 ++__base::size();
1894 if (__pos > 1)
Douglas Gregor7ac6af72011-04-29 16:20:26 +00001895 __b = _STD::move(_STD::next(__b), __b + __pos, __b);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001896 *__b = _STD::move(__v);
1897 }
1898 }
1899 else
1900 { // insert by shifting things forward
1901 if (__back_spare() == 0)
1902 __add_back_capacity();
1903 // __back_capacity >= 1
1904 size_type __de = __base::size() - __pos;
1905 if (__de == 0)
1906 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001907 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001908 ++__base::size();
1909 }
1910 else
1911 {
1912 iterator __e = __base::end();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001913 iterator __em1 = _STD::prev(__e);
Howard Hinnant2529d022011-02-02 17:36:20 +00001914 __alloc_traits::construct(__a, _STD::addressof(*__e), _STD::move(*__em1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001915 ++__base::size();
1916 if (__de > 1)
1917 __e = _STD::move_backward(__e - __de, __em1, __e);
1918 *--__e = _STD::move(__v);
1919 }
1920 }
1921 return __base::begin() + __pos;
1922}
1923
Howard Hinnant73d21a42010-09-04 23:28:19 +00001924#ifndef _LIBCPP_HAS_NO_VARIADICS
1925
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001926template <class _Tp, class _Allocator>
1927template <class... _Args>
1928typename deque<_Tp, _Allocator>::iterator
1929deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
1930{
1931 size_type __pos = __p - __base::begin();
1932 size_type __to_end = __base::size() - __pos;
1933 allocator_type& __a = __base::__alloc();
1934 if (__pos < __to_end)
1935 { // insert by shifting things backward
1936 if (__front_spare() == 0)
1937 __add_front_capacity();
1938 // __front_spare() >= 1
1939 if (__pos == 0)
1940 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001941 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001942 --__base::__start_;
1943 ++__base::size();
1944 }
1945 else
1946 {
1947 iterator __b = __base::begin();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001948 iterator __bm1 = _STD::prev(__b);
Howard Hinnant2529d022011-02-02 17:36:20 +00001949 __alloc_traits::construct(__a, _STD::addressof(*__bm1), _STD::move(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001950 --__base::__start_;
1951 ++__base::size();
1952 if (__pos > 1)
Douglas Gregor7ac6af72011-04-29 16:20:26 +00001953 __b = _STD::move(_STD::next(__b), __b + __pos, __b);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001954 *__b = value_type(_STD::forward<_Args>(__args)...);
1955 }
1956 }
1957 else
1958 { // insert by shifting things forward
1959 if (__back_spare() == 0)
1960 __add_back_capacity();
1961 // __back_capacity >= 1
1962 size_type __de = __base::size() - __pos;
1963 if (__de == 0)
1964 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001965 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001966 ++__base::size();
1967 }
1968 else
1969 {
1970 iterator __e = __base::end();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001971 iterator __em1 = _STD::prev(__e);
Howard Hinnant2529d022011-02-02 17:36:20 +00001972 __alloc_traits::construct(__a, _STD::addressof(*__e), _STD::move(*__em1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001973 ++__base::size();
1974 if (__de > 1)
1975 __e = _STD::move_backward(__e - __de, __em1, __e);
1976 *--__e = value_type(_STD::forward<_Args>(__args)...);
1977 }
1978 }
1979 return __base::begin() + __pos;
1980}
1981
Howard Hinnant73d21a42010-09-04 23:28:19 +00001982#endif // _LIBCPP_HAS_NO_VARIADICS
1983#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001984
1985template <class _Tp, class _Allocator>
1986typename deque<_Tp, _Allocator>::iterator
1987deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
1988{
1989 size_type __pos = __p - __base::begin();
1990 size_type __to_end = __base::size() - __pos;
1991 allocator_type& __a = __base::__alloc();
1992 if (__pos < __to_end)
1993 { // insert by shifting things backward
1994 if (__n > __front_spare())
1995 __add_front_capacity(__n - __front_spare());
1996 // __n <= __front_spare()
1997 size_type __old_n = __n;
1998 iterator __old_begin = __base::begin();
1999 iterator __i = __old_begin;
2000 if (__n > __pos)
2001 {
2002 for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002003 __alloc_traits::construct(__a, _STD::addressof(*--__i), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002004 __n = __pos;
2005 }
2006 if (__n > 0)
2007 {
2008 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2009 iterator __obn = __old_begin + __n;
2010 __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
2011 if (__n < __pos)
2012 __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
2013 _STD::fill_n(__old_begin, __n, *__vt);
2014 }
2015 }
2016 else
2017 { // insert by shifting things forward
2018 size_type __back_capacity = __back_spare();
2019 if (__n > __back_capacity)
2020 __add_back_capacity(__n - __back_capacity);
2021 // __n <= __back_capacity
2022 size_type __old_n = __n;
2023 iterator __old_end = __base::end();
2024 iterator __i = __old_end;
2025 size_type __de = __base::size() - __pos;
2026 if (__n > __de)
2027 {
2028 for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002029 __alloc_traits::construct(__a, _STD::addressof(*__i), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002030 __n = __de;
2031 }
2032 if (__n > 0)
2033 {
2034 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2035 iterator __oen = __old_end - __n;
2036 __move_construct_and_check(__oen, __old_end, __i, __vt);
2037 if (__n < __de)
2038 __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
2039 _STD::fill_n(__old_end - __n, __n, *__vt);
2040 }
2041 }
2042 return __base::begin() + __pos;
2043}
2044
2045template <class _Tp, class _Allocator>
2046template <class _InputIter>
2047typename deque<_Tp, _Allocator>::iterator
2048deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
2049 typename enable_if<__is_input_iterator<_InputIter>::value
2050 &&!__is_bidirectional_iterator<_InputIter>::value>::type*)
2051{
2052 __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
2053 __buf.__construct_at_end(__f, __l);
2054 typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
2055 return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
2056}
2057
2058template <class _Tp, class _Allocator>
2059template <class _BiIter>
2060typename deque<_Tp, _Allocator>::iterator
2061deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
2062 typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type*)
2063{
2064 size_type __n = _STD::distance(__f, __l);
2065 size_type __pos = __p - __base::begin();
2066 size_type __to_end = __base::size() - __pos;
2067 allocator_type& __a = __base::__alloc();
2068 if (__pos < __to_end)
2069 { // insert by shifting things backward
2070 if (__n > __front_spare())
2071 __add_front_capacity(__n - __front_spare());
2072 // __n <= __front_spare()
2073 size_type __old_n = __n;
2074 iterator __old_begin = __base::begin();
2075 iterator __i = __old_begin;
2076 _BiIter __m = __f;
2077 if (__n > __pos)
2078 {
2079 __m = __pos < __n / 2 ? _STD::prev(__l, __pos) : _STD::next(__f, __n - __pos);
2080 for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002081 __alloc_traits::construct(__a, _STD::addressof(*--__i), *--__j);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002082 __n = __pos;
2083 }
2084 if (__n > 0)
2085 {
2086 iterator __obn = __old_begin + __n;
2087 for (iterator __j = __obn; __j != __old_begin;)
2088 {
Howard Hinnant2529d022011-02-02 17:36:20 +00002089 __alloc_traits::construct(__a, _STD::addressof(*--__i), _STD::move(*--__j));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002090 --__base::__start_;
2091 ++__base::size();
2092 }
2093 if (__n < __pos)
2094 __old_begin = _STD::move(__obn, __old_begin + __pos, __old_begin);
2095 _STD::copy(__m, __l, __old_begin);
2096 }
2097 }
2098 else
2099 { // insert by shifting things forward
2100 size_type __back_capacity = __back_spare();
2101 if (__n > __back_capacity)
2102 __add_back_capacity(__n - __back_capacity);
2103 // __n <= __back_capacity
2104 size_type __old_n = __n;
2105 iterator __old_end = __base::end();
2106 iterator __i = __old_end;
2107 _BiIter __m = __l;
2108 size_type __de = __base::size() - __pos;
2109 if (__n > __de)
2110 {
2111 __m = __de < __n / 2 ? _STD::next(__f, __de) : _STD::prev(__l, __n - __de);
2112 for (_BiIter __j = __m; __j != __l; ++__i, ++__j, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002113 __alloc_traits::construct(__a, _STD::addressof(*__i), *__j);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002114 __n = __de;
2115 }
2116 if (__n > 0)
2117 {
2118 iterator __oen = __old_end - __n;
2119 for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002120 __alloc_traits::construct(__a, _STD::addressof(*__i), _STD::move(*__j));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002121 if (__n < __de)
2122 __old_end = _STD::move_backward(__old_end - __de, __oen, __old_end);
2123 _STD::copy_backward(__f, __m, __old_end);
2124 }
2125 }
2126 return __base::begin() + __pos;
2127}
2128
2129template <class _Tp, class _Allocator>
2130template <class _InpIter>
2131void
2132deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
2133 typename enable_if<__is_input_iterator<_InpIter>::value &&
2134 !__is_forward_iterator<_InpIter>::value>::type*)
2135{
2136 for (; __f != __l; ++__f)
2137 push_back(*__f);
2138}
2139
2140template <class _Tp, class _Allocator>
2141template <class _ForIter>
2142void
2143deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
2144 typename enable_if<__is_forward_iterator<_ForIter>::value>::type*)
2145{
2146 size_type __n = _STD::distance(__f, __l);
2147 allocator_type& __a = __base::__alloc();
2148 size_type __back_capacity = __back_spare();
2149 if (__n > __back_capacity)
2150 __add_back_capacity(__n - __back_capacity);
2151 // __n <= __back_capacity
2152 for (iterator __i = __base::end(); __f != __l; ++__i, ++__f, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002153 __alloc_traits::construct(__a, _STD::addressof(*__i), *__f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002154}
2155
2156template <class _Tp, class _Allocator>
2157void
2158deque<_Tp, _Allocator>::__append(size_type __n)
2159{
2160 allocator_type& __a = __base::__alloc();
2161 size_type __back_capacity = __back_spare();
2162 if (__n > __back_capacity)
2163 __add_back_capacity(__n - __back_capacity);
2164 // __n <= __back_capacity
2165 for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002166 __alloc_traits::construct(__a, _STD::addressof(*__i));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002167}
2168
2169template <class _Tp, class _Allocator>
2170void
2171deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
2172{
2173 allocator_type& __a = __base::__alloc();
2174 size_type __back_capacity = __back_spare();
2175 if (__n > __back_capacity)
2176 __add_back_capacity(__n - __back_capacity);
2177 // __n <= __back_capacity
2178 for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002179 __alloc_traits::construct(__a, _STD::addressof(*__i), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002180}
2181
2182// Create front capacity for one block of elements.
2183// Strong guarantee. Either do it or don't touch anything.
2184template <class _Tp, class _Allocator>
2185void
2186deque<_Tp, _Allocator>::__add_front_capacity()
2187{
2188 allocator_type& __a = __base::__alloc();
2189 if (__back_spare() >= __base::__block_size)
2190 {
2191 __base::__start_ += __base::__block_size;
2192 pointer __pt = __base::__map_.back();
2193 __base::__map_.pop_back();
2194 __base::__map_.push_front(__pt);
2195 }
2196 // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer
2197 else if (__base::__map_.size() < __base::__map_.capacity())
2198 { // we can put the new buffer into the map, but don't shift things around
2199 // until all buffers are allocated. If we throw, we don't need to fix
2200 // anything up (any added buffers are undetectible)
2201 if (__base::__map_.__front_spare() > 0)
2202 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2203 else
2204 {
2205 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2206 // Done allocating, reorder capacity
2207 pointer __pt = __base::__map_.back();
2208 __base::__map_.pop_back();
2209 __base::__map_.push_front(__pt);
2210 }
2211 __base::__start_ = __base::__map_.size() == 1 ?
2212 __base::__block_size / 2 :
2213 __base::__start_ + __base::__block_size;
2214 }
2215 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2216 else
2217 {
2218 __split_buffer<pointer, typename __base::__pointer_allocator&>
2219 __buf(max<size_type>(2 * __base::__map_.capacity(), 1),
2220 0, __base::__map_.__alloc());
2221#ifndef _LIBCPP_NO_EXCEPTIONS
2222 try
2223 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002224#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002225 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2226#ifndef _LIBCPP_NO_EXCEPTIONS
2227 }
2228 catch (...)
2229 {
2230 __alloc_traits::deallocate(__a, __buf.front(), __base::__block_size);
2231 throw;
2232 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002233#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002234 for (typename __base::__map_pointer __i = __base::__map_.begin();
2235 __i != __base::__map_.end(); ++__i)
2236 __buf.push_back(*__i);
2237 _STD::swap(__base::__map_.__first_, __buf.__first_);
2238 _STD::swap(__base::__map_.__begin_, __buf.__begin_);
2239 _STD::swap(__base::__map_.__end_, __buf.__end_);
2240 _STD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2241 __base::__start_ = __base::__map_.size() == 1 ?
2242 __base::__block_size / 2 :
2243 __base::__start_ + __base::__block_size;
2244 }
2245}
2246
2247// Create front capacity for __n elements.
2248// Strong guarantee. Either do it or don't touch anything.
2249template <class _Tp, class _Allocator>
2250void
2251deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
2252{
2253 allocator_type& __a = __base::__alloc();
2254 size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2255 // Number of unused blocks at back:
2256 size_type __back_capacity = __back_spare() / __base::__block_size;
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00002257 __back_capacity = _STD::min(__back_capacity, __nb); // don't take more than you need
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002258 __nb -= __back_capacity; // number of blocks need to allocate
2259 // If __nb == 0, then we have sufficient capacity.
2260 if (__nb == 0)
2261 {
2262 __base::__start_ += __base::__block_size * __back_capacity;
2263 for (; __back_capacity > 0; --__back_capacity)
2264 {
2265 pointer __pt = __base::__map_.back();
2266 __base::__map_.pop_back();
2267 __base::__map_.push_front(__pt);
2268 }
2269 }
2270 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2271 else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2272 { // we can put the new buffers into the map, but don't shift things around
2273 // until all buffers are allocated. If we throw, we don't need to fix
2274 // anything up (any added buffers are undetectible)
2275 for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))
2276 {
2277 if (__base::__map_.__front_spare() == 0)
2278 break;
2279 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2280 }
2281 for (; __nb > 0; --__nb, ++__back_capacity)
2282 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2283 // Done allocating, reorder capacity
2284 __base::__start_ += __back_capacity * __base::__block_size;
2285 for (; __back_capacity > 0; --__back_capacity)
2286 {
2287 pointer __pt = __base::__map_.back();
2288 __base::__map_.pop_back();
2289 __base::__map_.push_front(__pt);
2290 }
2291 }
2292 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2293 else
2294 {
2295 size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();
2296 __split_buffer<pointer, typename __base::__pointer_allocator&>
2297 __buf(max<size_type>(2* __base::__map_.capacity(),
2298 __nb + __base::__map_.size()),
2299 0, __base::__map_.__alloc());
2300#ifndef _LIBCPP_NO_EXCEPTIONS
2301 try
2302 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002303#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002304 for (; __nb > 0; --__nb)
2305 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2306#ifndef _LIBCPP_NO_EXCEPTIONS
2307 }
2308 catch (...)
2309 {
2310 for (typename __base::__map_pointer __i = __buf.begin();
2311 __i != __buf.end(); ++__i)
2312 __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2313 throw;
2314 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002315#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002316 for (; __back_capacity > 0; --__back_capacity)
2317 {
2318 __buf.push_back(__base::__map_.back());
2319 __base::__map_.pop_back();
2320 }
2321 for (typename __base::__map_pointer __i = __base::__map_.begin();
2322 __i != __base::__map_.end(); ++__i)
2323 __buf.push_back(*__i);
2324 _STD::swap(__base::__map_.__first_, __buf.__first_);
2325 _STD::swap(__base::__map_.__begin_, __buf.__begin_);
2326 _STD::swap(__base::__map_.__end_, __buf.__end_);
2327 _STD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2328 __base::__start_ += __ds;
2329 }
2330}
2331
2332// Create back capacity for one block of elements.
2333// Strong guarantee. Either do it or don't touch anything.
2334template <class _Tp, class _Allocator>
2335void
2336deque<_Tp, _Allocator>::__add_back_capacity()
2337{
2338 allocator_type& __a = __base::__alloc();
2339 if (__front_spare() >= __base::__block_size)
2340 {
2341 __base::__start_ -= __base::__block_size;
2342 pointer __pt = __base::__map_.front();
2343 __base::__map_.pop_front();
2344 __base::__map_.push_back(__pt);
2345 }
2346 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2347 else if (__base::__map_.size() < __base::__map_.capacity())
2348 { // we can put the new buffer into the map, but don't shift things around
2349 // until it is allocated. If we throw, we don't need to fix
2350 // anything up (any added buffers are undetectible)
2351 if (__base::__map_.__back_spare() != 0)
2352 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2353 else
2354 {
2355 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2356 // Done allocating, reorder capacity
2357 pointer __pt = __base::__map_.front();
2358 __base::__map_.pop_front();
2359 __base::__map_.push_back(__pt);
2360 }
2361 }
2362 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2363 else
2364 {
2365 __split_buffer<pointer, typename __base::__pointer_allocator&>
2366 __buf(max<size_type>(2* __base::__map_.capacity(), 1),
2367 __base::__map_.size(),
2368 __base::__map_.__alloc());
2369#ifndef _LIBCPP_NO_EXCEPTIONS
2370 try
2371 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002372#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002373 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2374#ifndef _LIBCPP_NO_EXCEPTIONS
2375 }
2376 catch (...)
2377 {
2378 __alloc_traits::deallocate(__a, __buf.back(), __base::__block_size);
2379 throw;
2380 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002381#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002382 for (typename __base::__map_pointer __i = __base::__map_.end();
2383 __i != __base::__map_.begin();)
2384 __buf.push_front(*--__i);
2385 _STD::swap(__base::__map_.__first_, __buf.__first_);
2386 _STD::swap(__base::__map_.__begin_, __buf.__begin_);
2387 _STD::swap(__base::__map_.__end_, __buf.__end_);
2388 _STD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2389 }
2390}
2391
2392// Create back capacity for __n elements.
2393// Strong guarantee. Either do it or don't touch anything.
2394template <class _Tp, class _Allocator>
2395void
2396deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
2397{
2398 allocator_type& __a = __base::__alloc();
2399 size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2400 // Number of unused blocks at front:
2401 size_type __front_capacity = __front_spare() / __base::__block_size;
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00002402 __front_capacity = _STD::min(__front_capacity, __nb); // don't take more than you need
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002403 __nb -= __front_capacity; // number of blocks need to allocate
2404 // If __nb == 0, then we have sufficient capacity.
2405 if (__nb == 0)
2406 {
2407 __base::__start_ -= __base::__block_size * __front_capacity;
2408 for (; __front_capacity > 0; --__front_capacity)
2409 {
2410 pointer __pt = __base::__map_.front();
2411 __base::__map_.pop_front();
2412 __base::__map_.push_back(__pt);
2413 }
2414 }
2415 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2416 else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2417 { // we can put the new buffers into the map, but don't shift things around
2418 // until all buffers are allocated. If we throw, we don't need to fix
2419 // anything up (any added buffers are undetectible)
2420 for (; __nb > 0; --__nb)
2421 {
2422 if (__base::__map_.__back_spare() == 0)
2423 break;
2424 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2425 }
2426 for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=
2427 __base::__block_size - (__base::__map_.size() == 1))
2428 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2429 // Done allocating, reorder capacity
2430 __base::__start_ -= __base::__block_size * __front_capacity;
2431 for (; __front_capacity > 0; --__front_capacity)
2432 {
2433 pointer __pt = __base::__map_.front();
2434 __base::__map_.pop_front();
2435 __base::__map_.push_back(__pt);
2436 }
2437 }
2438 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2439 else
2440 {
2441 size_type __ds = __front_capacity * __base::__block_size;
2442 __split_buffer<pointer, typename __base::__pointer_allocator&>
2443 __buf(max<size_type>(2* __base::__map_.capacity(),
2444 __nb + __base::__map_.size()),
2445 __base::__map_.size() - __front_capacity,
2446 __base::__map_.__alloc());
2447#ifndef _LIBCPP_NO_EXCEPTIONS
2448 try
2449 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002450#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002451 for (; __nb > 0; --__nb)
2452 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2453#ifndef _LIBCPP_NO_EXCEPTIONS
2454 }
2455 catch (...)
2456 {
2457 for (typename __base::__map_pointer __i = __buf.begin();
2458 __i != __buf.end(); ++__i)
2459 __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2460 throw;
2461 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002462#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002463 for (; __front_capacity > 0; --__front_capacity)
2464 {
2465 __buf.push_back(__base::__map_.front());
2466 __base::__map_.pop_front();
2467 }
2468 for (typename __base::__map_pointer __i = __base::__map_.end();
2469 __i != __base::__map_.begin();)
2470 __buf.push_front(*--__i);
2471 _STD::swap(__base::__map_.__first_, __buf.__first_);
2472 _STD::swap(__base::__map_.__begin_, __buf.__begin_);
2473 _STD::swap(__base::__map_.__end_, __buf.__end_);
2474 _STD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2475 __base::__start_ -= __ds;
2476 }
2477}
2478
2479template <class _Tp, class _Allocator>
2480void
2481deque<_Tp, _Allocator>::pop_front()
2482{
2483 allocator_type& __a = __base::__alloc();
2484 __alloc_traits::destroy(__a, *(__base::__map_.begin() +
2485 __base::__start_ / __base::__block_size) +
2486 __base::__start_ % __base::__block_size);
2487 --__base::size();
2488 if (++__base::__start_ >= 2 * __base::__block_size)
2489 {
2490 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2491 __base::__map_.pop_front();
2492 __base::__start_ -= __base::__block_size;
2493 }
2494}
2495
2496template <class _Tp, class _Allocator>
2497void
2498deque<_Tp, _Allocator>::pop_back()
2499{
2500 allocator_type& __a = __base::__alloc();
2501 size_type __p = __base::size() + __base::__start_ - 1;
2502 __alloc_traits::destroy(__a, *(__base::__map_.begin() +
2503 __p / __base::__block_size) +
2504 __p % __base::__block_size);
2505 --__base::size();
2506 if (__back_spare() >= 2 * __base::__block_size)
2507 {
2508 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2509 __base::__map_.pop_back();
2510 }
2511}
2512
2513// move assign [__f, __l) to [__r, __r + (__l-__f)).
2514// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
2515template <class _Tp, class _Allocator>
2516typename deque<_Tp, _Allocator>::iterator
2517deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
2518 const_pointer& __vt)
2519{
2520 // as if
2521 // for (; __f != __l; ++__f, ++__r)
2522 // *__r = _STD::move(*__f);
2523 difference_type __n = __l - __f;
2524 while (__n > 0)
2525 {
2526 pointer __fb = __f.__ptr_;
2527 pointer __fe = *__f.__m_iter_ + __base::__block_size;
2528 difference_type __bs = __fe - __fb;
2529 if (__bs > __n)
2530 {
2531 __bs = __n;
2532 __fe = __fb + __bs;
2533 }
2534 if (__fb <= __vt && __vt < __fe)
2535 __vt = (const_iterator(__f.__m_iter_, __vt) -= __f - __r).__ptr_;
2536 __r = _STD::move(__fb, __fe, __r);
2537 __n -= __bs;
2538 __f += __bs;
2539 }
2540 return __r;
2541}
2542
2543// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
2544// If __vt points into [__f, __l), then add (__r - __l) to __vt.
2545template <class _Tp, class _Allocator>
2546typename deque<_Tp, _Allocator>::iterator
2547deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
2548 const_pointer& __vt)
2549{
2550 // as if
2551 // while (__f != __l)
2552 // *--__r = _STD::move(*--__l);
2553 difference_type __n = __l - __f;
2554 while (__n > 0)
2555 {
2556 --__l;
2557 pointer __lb = *__l.__m_iter_;
2558 pointer __le = __l.__ptr_ + 1;
2559 difference_type __bs = __le - __lb;
2560 if (__bs > __n)
2561 {
2562 __bs = __n;
2563 __lb = __le - __bs;
2564 }
2565 if (__lb <= __vt && __vt < __le)
2566 __vt = (const_iterator(__l.__m_iter_, __vt) += __r - __l - 1).__ptr_;
2567 __r = _STD::move_backward(__lb, __le, __r);
2568 __n -= __bs;
2569 __l -= __bs - 1;
2570 }
2571 return __r;
2572}
2573
2574// move construct [__f, __l) to [__r, __r + (__l-__f)).
2575// If __vt points into [__f, __l), then add (__r - __f) to __vt.
2576template <class _Tp, class _Allocator>
2577void
2578deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
2579 iterator __r, const_pointer& __vt)
2580{
2581 allocator_type& __a = __base::__alloc();
2582 // as if
2583 // for (; __f != __l; ++__r, ++__f, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002584 // __alloc_traits::construct(__a, _STD::addressof(*__r), _STD::move(*__f));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002585 difference_type __n = __l - __f;
2586 while (__n > 0)
2587 {
2588 pointer __fb = __f.__ptr_;
2589 pointer __fe = *__f.__m_iter_ + __base::__block_size;
2590 difference_type __bs = __fe - __fb;
2591 if (__bs > __n)
2592 {
2593 __bs = __n;
2594 __fe = __fb + __bs;
2595 }
2596 if (__fb <= __vt && __vt < __fe)
2597 __vt = (const_iterator(__f.__m_iter_, __vt) += __r - __f).__ptr_;
2598 for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002599 __alloc_traits::construct(__a, _STD::addressof(*__r), _STD::move(*__fb));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002600 __n -= __bs;
2601 __f += __bs;
2602 }
2603}
2604
2605// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
2606// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
2607template <class _Tp, class _Allocator>
2608void
2609deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
2610 iterator __r, const_pointer& __vt)
2611{
2612 allocator_type& __a = __base::__alloc();
2613 // as if
2614 // for (iterator __j = __l; __j != __f;)
2615 // {
Howard Hinnant2529d022011-02-02 17:36:20 +00002616 // __alloc_traitsconstruct(__a, _STD::addressof(*--__r), _STD::move(*--__j));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002617 // --__base::__start_;
2618 // ++__base::size();
2619 // }
2620 difference_type __n = __l - __f;
2621 while (__n > 0)
2622 {
2623 --__l;
2624 pointer __lb = *__l.__m_iter_;
2625 pointer __le = __l.__ptr_ + 1;
2626 difference_type __bs = __le - __lb;
2627 if (__bs > __n)
2628 {
2629 __bs = __n;
2630 __lb = __le - __bs;
2631 }
2632 if (__lb <= __vt && __vt < __le)
2633 __vt = (const_iterator(__l.__m_iter_, __vt) -= __l - __r + 1).__ptr_;
2634 while (__le != __lb)
2635 {
Howard Hinnant2529d022011-02-02 17:36:20 +00002636 __alloc_traits::construct(__a, _STD::addressof(*--__r), _STD::move(*--__le));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002637 --__base::__start_;
2638 ++__base::size();
2639 }
2640 __n -= __bs;
2641 __l -= __bs - 1;
2642 }
2643}
2644
2645template <class _Tp, class _Allocator>
2646typename deque<_Tp, _Allocator>::iterator
2647deque<_Tp, _Allocator>::erase(const_iterator __f)
2648{
2649 difference_type __n = 1;
2650 iterator __b = __base::begin();
2651 difference_type __pos = __f - __b;
2652 iterator __p = __b + __pos;
2653 allocator_type& __a = __base::__alloc();
2654 if (__pos < (__base::size() - 1) / 2)
2655 { // erase from front
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00002656 _STD::move_backward(__b, __p, _STD::next(__p));
Howard Hinnant2529d022011-02-02 17:36:20 +00002657 __alloc_traits::destroy(__a, _STD::addressof(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002658 --__base::size();
2659 ++__base::__start_;
2660 if (__front_spare() >= 2 * __base::__block_size)
2661 {
2662 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2663 __base::__map_.pop_front();
2664 __base::__start_ -= __base::__block_size;
2665 }
2666 }
2667 else
2668 { // erase from back
Douglas Gregor7ac6af72011-04-29 16:20:26 +00002669 iterator __i = _STD::move(_STD::next(__p), __base::end(), __p);
Howard Hinnant2529d022011-02-02 17:36:20 +00002670 __alloc_traits::destroy(__a, _STD::addressof(*__i));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002671 --__base::size();
2672 if (__back_spare() >= 2 * __base::__block_size)
2673 {
2674 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2675 __base::__map_.pop_back();
2676 }
2677 }
2678 return __base::begin() + __pos;
2679}
2680
2681template <class _Tp, class _Allocator>
2682typename deque<_Tp, _Allocator>::iterator
2683deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
2684{
2685 difference_type __n = __l - __f;
2686 iterator __b = __base::begin();
2687 difference_type __pos = __f - __b;
2688 iterator __p = __b + __pos;
2689 if (__n > 0)
2690 {
2691 allocator_type& __a = __base::__alloc();
2692 if (__pos < (__base::size() - __n) / 2)
2693 { // erase from front
2694 iterator __i = _STD::move_backward(__b, __p, __p + __n);
2695 for (; __b != __i; ++__b)
Howard Hinnant2529d022011-02-02 17:36:20 +00002696 __alloc_traits::destroy(__a, _STD::addressof(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002697 __base::size() -= __n;
2698 __base::__start_ += __n;
2699 while (__front_spare() >= 2 * __base::__block_size)
2700 {
2701 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2702 __base::__map_.pop_front();
2703 __base::__start_ -= __base::__block_size;
2704 }
2705 }
2706 else
2707 { // erase from back
2708 iterator __i = _STD::move(__p + __n, __base::end(), __p);
2709 for (iterator __e = __base::end(); __i != __e; ++__i)
Howard Hinnant2529d022011-02-02 17:36:20 +00002710 __alloc_traits::destroy(__a, _STD::addressof(*__i));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002711 __base::size() -= __n;
2712 while (__back_spare() >= 2 * __base::__block_size)
2713 {
2714 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2715 __base::__map_.pop_back();
2716 }
2717 }
2718 }
2719 return __base::begin() + __pos;
2720}
2721
2722template <class _Tp, class _Allocator>
2723void
2724deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
2725{
2726 iterator __e = __base::end();
2727 difference_type __n = __e - __f;
2728 if (__n > 0)
2729 {
2730 allocator_type& __a = __base::__alloc();
2731 iterator __b = __base::begin();
2732 difference_type __pos = __f - __b;
2733 for (iterator __p = __b + __pos; __p != __e; ++__p)
Howard Hinnant2529d022011-02-02 17:36:20 +00002734 __alloc_traits::destroy(__a, _STD::addressof(*__p));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002735 __base::size() -= __n;
2736 while (__back_spare() >= 2 * __base::__block_size)
2737 {
2738 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2739 __base::__map_.pop_back();
2740 }
2741 }
2742}
2743
2744template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00002745inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002746void
2747deque<_Tp, _Allocator>::swap(deque& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00002748 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
2749 __is_nothrow_swappable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002750{
2751 __base::swap(__c);
2752}
2753
2754template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00002755inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002756void
Howard Hinnanta12beb32011-06-02 16:10:22 +00002757deque<_Tp, _Allocator>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002758{
2759 __base::clear();
2760}
2761
2762template <class _Tp, class _Allocator>
2763_LIBCPP_INLINE_VISIBILITY inline
2764bool
2765operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2766{
2767 const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
2768 return __sz == __y.size() && _STD::equal(__x.begin(), __x.end(), __y.begin());
2769}
2770
2771template <class _Tp, class _Allocator>
2772_LIBCPP_INLINE_VISIBILITY inline
2773bool
2774operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2775{
2776 return !(__x == __y);
2777}
2778
2779template <class _Tp, class _Allocator>
2780_LIBCPP_INLINE_VISIBILITY inline
2781bool
2782operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2783{
2784 return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
2785}
2786
2787template <class _Tp, class _Allocator>
2788_LIBCPP_INLINE_VISIBILITY inline
2789bool
2790operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2791{
2792 return __y < __x;
2793}
2794
2795template <class _Tp, class _Allocator>
2796_LIBCPP_INLINE_VISIBILITY inline
2797bool
2798operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2799{
2800 return !(__x < __y);
2801}
2802
2803template <class _Tp, class _Allocator>
2804_LIBCPP_INLINE_VISIBILITY inline
2805bool
2806operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2807{
2808 return !(__y < __x);
2809}
2810
2811template <class _Tp, class _Allocator>
2812_LIBCPP_INLINE_VISIBILITY inline
2813void
2814swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
Howard Hinnant0a612b02011-06-02 20:00:14 +00002815 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002816{
2817 __x.swap(__y);
2818}
2819
2820_LIBCPP_END_NAMESPACE_STD
2821
2822#endif // _LIBCPP_DEQUE