blob: 1ffd9d81d8769cadc1ff013867b7f26f69fde6fd [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);
51 deque(deque&& c);
52 deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
53 deque(const deque& c, const allocator_type& a);
54 deque(deque&& c, const allocator_type& a);
55 ~deque();
56
57 deque& operator=(const deque& c);
58 deque& operator=(deque&& c);
59 deque& operator=(initializer_list<value_type> il);
60
61 template <class InputIterator>
62 void assign(InputIterator f, InputIterator l);
63 void assign(size_type n, const value_type& v);
64 void assign(initializer_list<value_type> il);
65
Howard Hinnanta12beb32011-06-02 16:10:22 +000066 allocator_type get_allocator() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000067
68 // iterators:
69
Howard Hinnanta12beb32011-06-02 16:10:22 +000070 iterator begin() noexcept;
71 const_iterator begin() const noexcept;
72 iterator end() noexcept;
73 const_iterator end() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000074
Howard Hinnanta12beb32011-06-02 16:10:22 +000075 reverse_iterator rbegin() noexcept;
76 const_reverse_iterator rbegin() const noexcept;
77 reverse_iterator rend() noexcept;
78 const_reverse_iterator rend() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000079
Howard Hinnanta12beb32011-06-02 16:10:22 +000080 const_iterator cbegin() const noexcept;
81 const_iterator cend() const noexcept;
82 const_reverse_iterator crbegin() const noexcept;
83 const_reverse_iterator crend() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000084
85 // capacity:
Howard Hinnanta12beb32011-06-02 16:10:22 +000086 size_type size() const noexcept;
87 size_type max_size() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000088 void resize(size_type n);
89 void resize(size_type n, const value_type& v);
90 void shrink_to_fit();
Howard Hinnanta12beb32011-06-02 16:10:22 +000091 bool empty() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000092
93 // element access:
94 reference operator[](size_type i);
95 const_reference operator[](size_type i) const;
96 reference at(size_type i);
97 const_reference at(size_type i) const;
98 reference front();
99 const_reference front() const;
100 reference back();
101 const_reference back() const;
102
103 // modifiers:
104 void push_front(const value_type& v);
105 void push_front(value_type&& v);
106 void push_back(const value_type& v);
107 void push_back(value_type&& v);
108 template <class... Args> void emplace_front(Args&&... args);
109 template <class... Args> void emplace_back(Args&&... args);
110 template <class... Args> iterator emplace(const_iterator p, Args&&... args);
111 iterator insert(const_iterator p, const value_type& v);
112 iterator insert(const_iterator p, value_type&& v);
113 iterator insert(const_iterator p, size_type n, const value_type& v);
114 template <class InputIterator>
115 iterator insert (const_iterator p, InputIterator f, InputIterator l);
116 iterator insert(const_iterator p, initializer_list<value_type> il);
117 void pop_front();
118 void pop_back();
119 iterator erase(const_iterator p);
120 iterator erase(const_iterator f, const_iterator l);
121 void swap(deque& c);
Howard Hinnanta12beb32011-06-02 16:10:22 +0000122 void clear() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000123};
124
125template <class T, class Allocator>
126 bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
127template <class T, class Allocator>
128 bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
129template <class T, class Allocator>
130 bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
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);
137
138// specialized algorithms:
139template <class T, class Allocator>
140 void swap(deque<T,Allocator>& x, deque<T,Allocator>& y);
141
142} // std
143
144*/
145
146#pragma GCC system_header
147
148#include <__config>
149#include <__split_buffer>
150#include <type_traits>
151#include <initializer_list>
152#include <iterator>
153#include <algorithm>
154#include <stdexcept>
155
156_LIBCPP_BEGIN_NAMESPACE_STD
157
158template <class _Tp, class _Allocator> class __deque_base;
159
160template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
161 class _DiffType, _DiffType _BlockSize>
Howard Hinnant422a53f2010-09-21 21:28:23 +0000162class _LIBCPP_VISIBLE __deque_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000163
164template <class _RAIter,
165 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
166__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
167copy(_RAIter __f,
168 _RAIter __l,
169 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
170 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
171
172template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
173 class _OutputIterator>
174_OutputIterator
175copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
176 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
177 _OutputIterator __r);
178
179template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
180 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
181__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
182copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
183 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
184 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
185
186template <class _RAIter,
187 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
188__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
189copy_backward(_RAIter __f,
190 _RAIter __l,
191 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
192 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
193
194template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
195 class _OutputIterator>
196_OutputIterator
197copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
198 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
199 _OutputIterator __r);
200
201template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
202 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
203__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
204copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
205 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
206 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
207
208template <class _RAIter,
209 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
210__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
211move(_RAIter __f,
212 _RAIter __l,
213 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
214 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
215
216template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
217 class _OutputIterator>
218_OutputIterator
219move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
220 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
221 _OutputIterator __r);
222
223template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
224 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
225__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
226move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
227 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
228 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
229
230template <class _RAIter,
231 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
232__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
233move_backward(_RAIter __f,
234 _RAIter __l,
235 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
236 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
237
238template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
239 class _OutputIterator>
240_OutputIterator
241move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
242 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
243 _OutputIterator __r);
244
245template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
246 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
247__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
248move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
249 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
250 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
251
252template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
253 class _DiffType, _DiffType _BlockSize>
Howard Hinnant422a53f2010-09-21 21:28:23 +0000254class _LIBCPP_VISIBLE __deque_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000255{
256 typedef _MapPointer __map_iterator;
257public:
258 typedef _Pointer pointer;
259 typedef _DiffType difference_type;
260private:
261 __map_iterator __m_iter_;
262 pointer __ptr_;
263
264 static const difference_type __block_size = _BlockSize;
265public:
266 typedef _ValueType value_type;
267 typedef random_access_iterator_tag iterator_category;
268 typedef _Reference reference;
269
Howard Hinnanta12beb32011-06-02 16:10:22 +0000270 _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000271
272 template <class _P, class _R, class _MP>
273 _LIBCPP_INLINE_VISIBILITY
274 __deque_iterator(const __deque_iterator<value_type, _P, _R, _MP, difference_type, __block_size>& __it,
Howard Hinnanta12beb32011-06-02 16:10:22 +0000275 typename enable_if<is_convertible<_P, pointer>::value>::type* = 0) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000276 : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
277
278 _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;}
279 _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;}
280
281 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++()
282 {
283 if (++__ptr_ - *__m_iter_ == __block_size)
284 {
285 ++__m_iter_;
286 __ptr_ = *__m_iter_;
287 }
288 return *this;
289 }
290
291 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int)
292 {
293 __deque_iterator __tmp = *this;
294 ++(*this);
295 return __tmp;
296 }
297
298 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--()
299 {
300 if (__ptr_ == *__m_iter_)
301 {
302 --__m_iter_;
303 __ptr_ = *__m_iter_ + __block_size;
304 }
305 --__ptr_;
306 return *this;
307 }
308
309 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int)
310 {
311 __deque_iterator __tmp = *this;
312 --(*this);
313 return __tmp;
314 }
315
316 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n)
317 {
318 if (__n != 0)
319 {
320 __n += __ptr_ - *__m_iter_;
321 if (__n > 0)
322 {
323 __m_iter_ += __n / __block_size;
324 __ptr_ = *__m_iter_ + __n % __block_size;
325 }
326 else // (__n < 0)
327 {
328 difference_type __z = __block_size - 1 - __n;
329 __m_iter_ -= __z / __block_size;
330 __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
331 }
332 }
333 return *this;
334 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000335
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000336 _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n)
337 {
338 return *this += -__n;
339 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000340
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000341 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const
342 {
343 __deque_iterator __t(*this);
344 __t += __n;
345 return __t;
346 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000347
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000348 _LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const
349 {
350 __deque_iterator __t(*this);
351 __t -= __n;
352 return __t;
353 }
354
355 _LIBCPP_INLINE_VISIBILITY
356 friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
357 {return __it + __n;}
358
359 _LIBCPP_INLINE_VISIBILITY
360 friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
361 {
362 if (__x != __y)
363 return (__x.__m_iter_ - __y.__m_iter_) * __block_size
364 + (__x.__ptr_ - *__x.__m_iter_)
365 - (__y.__ptr_ - *__y.__m_iter_);
366 return 0;
367 }
368
369 _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
370 {return *(*this + __n);}
371
372 _LIBCPP_INLINE_VISIBILITY friend
373 bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
374 {return __x.__ptr_ == __y.__ptr_;}
375
376 _LIBCPP_INLINE_VISIBILITY friend
377 bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
378 {return !(__x == __y);}
379
380 _LIBCPP_INLINE_VISIBILITY friend
381 bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
382 {return __x.__m_iter_ < __y.__m_iter_ ||
383 (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
384
385 _LIBCPP_INLINE_VISIBILITY friend
386 bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
387 {return __y < __x;}
388
389 _LIBCPP_INLINE_VISIBILITY friend
390 bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
391 {return !(__y < __x);}
392
393 _LIBCPP_INLINE_VISIBILITY friend
394 bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
395 {return !(__x < __y);}
396
397private:
Howard Hinnanta12beb32011-06-02 16:10:22 +0000398 _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000399 : __m_iter_(__m), __ptr_(__p) {}
400
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000401 template <class _Tp, class _A> friend class __deque_base;
Howard Hinnant422a53f2010-09-21 21:28:23 +0000402 template <class _Tp, class _A> friend class _LIBCPP_VISIBLE deque;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403 template <class _V, class _P, class _R, class _MP, class _D, _D>
Howard Hinnant422a53f2010-09-21 21:28:23 +0000404 friend class _LIBCPP_VISIBLE __deque_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000405
406 template <class _RAIter,
407 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
408 friend
409 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
410 copy(_RAIter __f,
411 _RAIter __l,
412 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
413 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
414
415 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
416 class _OutputIterator>
417 friend
418 _OutputIterator
419 copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
420 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
421 _OutputIterator __r);
422
423 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
424 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
425 friend
426 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
427 copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
428 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
429 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
430
431 template <class _RAIter,
432 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
433 friend
434 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
435 copy_backward(_RAIter __f,
436 _RAIter __l,
437 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
438 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
439
440 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
441 class _OutputIterator>
442 friend
443 _OutputIterator
444 copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
445 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
446 _OutputIterator __r);
447
448 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
449 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
450 friend
451 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
452 copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
453 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
454 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
455
456 template <class _RAIter,
457 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
458 friend
459 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
460 move(_RAIter __f,
461 _RAIter __l,
462 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
463 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
464
465 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
466 class _OutputIterator>
467 friend
468 _OutputIterator
469 move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
470 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
471 _OutputIterator __r);
472
473 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
474 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
475 friend
476 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
477 move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
478 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
479 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
480
481 template <class _RAIter,
482 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
483 friend
484 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
485 move_backward(_RAIter __f,
486 _RAIter __l,
487 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
488 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
489
490 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
491 class _OutputIterator>
492 friend
493 _OutputIterator
494 move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
495 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
496 _OutputIterator __r);
497
498 template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
499 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
500 friend
501 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
502 move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
503 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
504 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
505};
506
507// copy
508
509template <class _RAIter,
510 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
511__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
512copy(_RAIter __f,
513 _RAIter __l,
514 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
515 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
516{
517 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
518 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
519 while (__f != __l)
520 {
521 pointer __rb = __r.__ptr_;
522 pointer __re = *__r.__m_iter_ + _B2;
523 difference_type __bs = __re - __rb;
524 difference_type __n = __l - __f;
525 _RAIter __m = __l;
526 if (__n > __bs)
527 {
528 __n = __bs;
529 __m = __f + __n;
530 }
531 _STD::copy(__f, __m, __rb);
532 __f = __m;
533 __r += __n;
534 }
535 return __r;
536}
537
538template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
539 class _OutputIterator>
540_OutputIterator
541copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
542 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
543 _OutputIterator __r)
544{
545 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
546 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
547 difference_type __n = __l - __f;
548 while (__n > 0)
549 {
550 pointer __fb = __f.__ptr_;
551 pointer __fe = *__f.__m_iter_ + _B1;
552 difference_type __bs = __fe - __fb;
553 if (__bs > __n)
554 {
555 __bs = __n;
556 __fe = __fb + __bs;
557 }
558 __r = _STD::copy(__fb, __fe, __r);
559 __n -= __bs;
560 __f += __bs;
561 }
562 return __r;
563}
564
565template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
566 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
567__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
568copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
569 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
570 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
571{
572 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
573 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
574 difference_type __n = __l - __f;
575 while (__n > 0)
576 {
577 pointer __fb = __f.__ptr_;
578 pointer __fe = *__f.__m_iter_ + _B1;
579 difference_type __bs = __fe - __fb;
580 if (__bs > __n)
581 {
582 __bs = __n;
583 __fe = __fb + __bs;
584 }
585 __r = _STD::copy(__fb, __fe, __r);
586 __n -= __bs;
587 __f += __bs;
588 }
589 return __r;
590}
591
592// copy_backward
593
594template <class _RAIter,
595 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
596__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
597copy_backward(_RAIter __f,
598 _RAIter __l,
599 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
600 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
601{
602 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
603 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
604 while (__f != __l)
605 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +0000606 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _STD::prev(__r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000607 pointer __rb = *__rp.__m_iter_;
608 pointer __re = __rp.__ptr_ + 1;
609 difference_type __bs = __re - __rb;
610 difference_type __n = __l - __f;
611 _RAIter __m = __f;
612 if (__n > __bs)
613 {
614 __n = __bs;
615 __m = __l - __n;
616 }
617 _STD::copy_backward(__m, __l, __re);
618 __l = __m;
619 __r -= __n;
620 }
621 return __r;
622}
623
624template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
625 class _OutputIterator>
626_OutputIterator
627copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
628 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
629 _OutputIterator __r)
630{
631 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
632 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
633 difference_type __n = __l - __f;
634 while (__n > 0)
635 {
636 --__l;
637 pointer __lb = *__l.__m_iter_;
638 pointer __le = __l.__ptr_ + 1;
639 difference_type __bs = __le - __lb;
640 if (__bs > __n)
641 {
642 __bs = __n;
643 __lb = __le - __bs;
644 }
645 __r = _STD::copy_backward(__lb, __le, __r);
646 __n -= __bs;
647 __l -= __bs - 1;
648 }
649 return __r;
650}
651
652template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
653 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
654__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
655copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
656 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
657 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
658{
659 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
660 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
661 difference_type __n = __l - __f;
662 while (__n > 0)
663 {
664 --__l;
665 pointer __lb = *__l.__m_iter_;
666 pointer __le = __l.__ptr_ + 1;
667 difference_type __bs = __le - __lb;
668 if (__bs > __n)
669 {
670 __bs = __n;
671 __lb = __le - __bs;
672 }
673 __r = _STD::copy_backward(__lb, __le, __r);
674 __n -= __bs;
675 __l -= __bs - 1;
676 }
677 return __r;
678}
679
680// move
681
682template <class _RAIter,
683 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
684__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
685move(_RAIter __f,
686 _RAIter __l,
687 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
688 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
689{
690 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
691 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
692 while (__f != __l)
693 {
694 pointer __rb = __r.__ptr_;
695 pointer __re = *__r.__m_iter_ + _B2;
696 difference_type __bs = __re - __rb;
697 difference_type __n = __l - __f;
698 _RAIter __m = __l;
699 if (__n > __bs)
700 {
701 __n = __bs;
702 __m = __f + __n;
703 }
704 _STD::move(__f, __m, __rb);
705 __f = __m;
706 __r += __n;
707 }
708 return __r;
709}
710
711template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
712 class _OutputIterator>
713_OutputIterator
714move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
715 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
716 _OutputIterator __r)
717{
718 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
719 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
720 difference_type __n = __l - __f;
721 while (__n > 0)
722 {
723 pointer __fb = __f.__ptr_;
724 pointer __fe = *__f.__m_iter_ + _B1;
725 difference_type __bs = __fe - __fb;
726 if (__bs > __n)
727 {
728 __bs = __n;
729 __fe = __fb + __bs;
730 }
731 __r = _STD::move(__fb, __fe, __r);
732 __n -= __bs;
733 __f += __bs;
734 }
735 return __r;
736}
737
738template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
739 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
740__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
741move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
742 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
743 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
744{
745 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
746 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
747 difference_type __n = __l - __f;
748 while (__n > 0)
749 {
750 pointer __fb = __f.__ptr_;
751 pointer __fe = *__f.__m_iter_ + _B1;
752 difference_type __bs = __fe - __fb;
753 if (__bs > __n)
754 {
755 __bs = __n;
756 __fe = __fb + __bs;
757 }
758 __r = _STD::move(__fb, __fe, __r);
759 __n -= __bs;
760 __f += __bs;
761 }
762 return __r;
763}
764
765// move_backward
766
767template <class _RAIter,
768 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
769__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
770move_backward(_RAIter __f,
771 _RAIter __l,
772 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
773 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
774{
775 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
776 typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
777 while (__f != __l)
778 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +0000779 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _STD::prev(__r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000780 pointer __rb = *__rp.__m_iter_;
781 pointer __re = __rp.__ptr_ + 1;
782 difference_type __bs = __re - __rb;
783 difference_type __n = __l - __f;
784 _RAIter __m = __f;
785 if (__n > __bs)
786 {
787 __n = __bs;
788 __m = __l - __n;
789 }
790 _STD::move_backward(__m, __l, __re);
791 __l = __m;
792 __r -= __n;
793 }
794 return __r;
795}
796
797template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
798 class _OutputIterator>
799_OutputIterator
800move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
801 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
802 _OutputIterator __r)
803{
804 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
805 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
806 difference_type __n = __l - __f;
807 while (__n > 0)
808 {
809 --__l;
810 pointer __lb = *__l.__m_iter_;
811 pointer __le = __l.__ptr_ + 1;
812 difference_type __bs = __le - __lb;
813 if (__bs > __n)
814 {
815 __bs = __n;
816 __lb = __le - __bs;
817 }
818 __r = _STD::move_backward(__lb, __le, __r);
819 __n -= __bs;
820 __l -= __bs - 1;
821 }
822 return __r;
823}
824
825template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
826 class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
827__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
828move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
829 __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
830 __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
831{
832 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
833 typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
834 difference_type __n = __l - __f;
835 while (__n > 0)
836 {
837 --__l;
838 pointer __lb = *__l.__m_iter_;
839 pointer __le = __l.__ptr_ + 1;
840 difference_type __bs = __le - __lb;
841 if (__bs > __n)
842 {
843 __bs = __n;
844 __lb = __le - __bs;
845 }
846 __r = _STD::move_backward(__lb, __le, __r);
847 __n -= __bs;
848 __l -= __bs - 1;
849 }
850 return __r;
851}
852
853template <bool>
854class __deque_base_common
855{
856protected:
857 void __throw_length_error() const;
858 void __throw_out_of_range() const;
859};
860
861template <bool __b>
862void
863__deque_base_common<__b>::__throw_length_error() const
864{
865#ifndef _LIBCPP_NO_EXCEPTIONS
866 throw length_error("deque");
867#endif
868}
869
870template <bool __b>
871void
872__deque_base_common<__b>::__throw_out_of_range() const
873{
874#ifndef _LIBCPP_NO_EXCEPTIONS
875 throw out_of_range("deque");
876#endif
877}
878
879template <class _Tp, class _Allocator>
880class __deque_base
881 : protected __deque_base_common<true>
882{
883 __deque_base(const __deque_base& __c);
884 __deque_base& operator=(const __deque_base& __c);
885protected:
886 typedef _Tp value_type;
887 typedef _Allocator allocator_type;
888 typedef allocator_traits<allocator_type> __alloc_traits;
889 typedef value_type& reference;
890 typedef const value_type& const_reference;
891 typedef typename __alloc_traits::size_type size_type;
892 typedef typename __alloc_traits::difference_type difference_type;
893 typedef typename __alloc_traits::pointer pointer;
894 typedef typename __alloc_traits::const_pointer const_pointer;
895
896 static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;
897
898 typedef typename __alloc_traits::template
899#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
900 rebind_alloc<pointer>
901#else
902 rebind_alloc<pointer>::other
903#endif
904 __pointer_allocator;
905 typedef allocator_traits<__pointer_allocator> __map_traits;
906 typedef typename __map_traits::pointer __map_pointer;
907 typedef typename __map_traits::const_pointer __map_const_pointer;
908 typedef __split_buffer<pointer, __pointer_allocator> __map;
909
910 typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
911 difference_type, __block_size> iterator;
912 typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
913 difference_type, __block_size> const_iterator;
914
915 __map __map_;
916 size_type __start_;
917 __compressed_pair<size_type, allocator_type> __size_;
918
Howard Hinnanta12beb32011-06-02 16:10:22 +0000919 iterator begin() _NOEXCEPT;
920 const_iterator begin() const _NOEXCEPT;
921 iterator end() _NOEXCEPT;
922 const_iterator end() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000923
924 _LIBCPP_INLINE_VISIBILITY size_type& size() {return __size_.first();}
Howard Hinnanta12beb32011-06-02 16:10:22 +0000925 _LIBCPP_INLINE_VISIBILITY
926 const size_type& size() const _NOEXCEPT {return __size_.first();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000927 _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() {return __size_.second();}
Howard Hinnanta12beb32011-06-02 16:10:22 +0000928 _LIBCPP_INLINE_VISIBILITY
929 const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000930
931 __deque_base();
932 explicit __deque_base(const allocator_type& __a);
Howard Hinnant0a612b02011-06-02 20:00:14 +0000933public:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000934 ~__deque_base();
935
Howard Hinnant73d21a42010-09-04 23:28:19 +0000936#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000937
Howard Hinnant0a612b02011-06-02 20:00:14 +0000938 __deque_base(__deque_base&& __c)
939 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000940 __deque_base(__deque_base&& __c, const allocator_type& __a);
941
Howard Hinnant73d21a42010-09-04 23:28:19 +0000942#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0a612b02011-06-02 20:00:14 +0000943 void swap(__deque_base& __c)
944 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
945 __is_nothrow_swappable<allocator_type>::value);
946protected:
Howard Hinnanta12beb32011-06-02 16:10:22 +0000947 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000948
949 bool __invariants() const;
950
Howard Hinnant422a53f2010-09-21 21:28:23 +0000951 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000952 void __move_assign(__deque_base& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000953 _NOEXCEPT_(is_nothrow_move_assignable<__map>::value &&
954 (!__alloc_traits::propagate_on_container_move_assignment::value ||
955 is_nothrow_move_assignable<allocator_type>::value))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000956 {
957 __map_ = _STD::move(__c.__map_);
958 __start_ = __c.__start_;
959 size() = __c.size();
960 __move_assign_alloc(__c);
961 __c.__start_ = __c.size() = 0;
962 }
963
Howard Hinnant422a53f2010-09-21 21:28:23 +0000964 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000965 void __move_assign_alloc(__deque_base& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000966 _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
967 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000968 {__move_assign_alloc(__c, integral_constant<bool,
969 __alloc_traits::propagate_on_container_move_assignment::value>());}
970
971private:
Howard Hinnant422a53f2010-09-21 21:28:23 +0000972 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000973 void __move_assign_alloc(const __deque_base& __c, true_type)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000974 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000975 {
976 __alloc() = _STD::move(__c.__alloc());
977 }
978
Howard Hinnant422a53f2010-09-21 21:28:23 +0000979 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0a612b02011-06-02 20:00:14 +0000980 void __move_assign_alloc(const __deque_base& __c, false_type) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000981 {}
982
Howard Hinnant422a53f2010-09-21 21:28:23 +0000983 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000984 static void __swap_alloc(allocator_type& __x, allocator_type& __y)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000985 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
986 __is_nothrow_swappable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000987 {__swap_alloc(__x, __y, integral_constant<bool,
988 __alloc_traits::propagate_on_container_swap::value>());}
989
Howard Hinnant422a53f2010-09-21 21:28:23 +0000990 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000991 static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
Howard Hinnant0a612b02011-06-02 20:00:14 +0000992 _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000993 {
994 using _STD::swap;
995 swap(__x, __y);
996 }
Howard Hinnant422a53f2010-09-21 21:28:23 +0000997
998 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000999 static void __swap_alloc(allocator_type& __x, allocator_type& __y, false_type)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001000 _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001001 {}
1002};
1003
1004template <class _Tp, class _Allocator>
1005bool
1006__deque_base<_Tp, _Allocator>::__invariants() const
1007{
1008 if (!__map_.__invariants())
1009 return false;
1010 if (__map_.size() >= size_type(-1) / __block_size)
1011 return false;
1012 for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
1013 __i != __e; ++__i)
1014 if (*__i == nullptr)
1015 return false;
1016 if (__map_.size() != 0)
1017 {
1018 if (size() >= __map_.size() * __block_size)
1019 return false;
1020 if (__start_ >= __map_.size() * __block_size - size())
1021 return false;
1022 }
1023 else
1024 {
1025 if (size() != 0)
1026 return false;
1027 if (__start_ != 0)
1028 return false;
1029 }
1030 return true;
1031}
1032
1033template <class _Tp, class _Allocator>
1034typename __deque_base<_Tp, _Allocator>::iterator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001035__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001036{
1037 __map_pointer __mp = __map_.begin() + __start_ / __block_size;
1038 return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1039}
1040
1041template <class _Tp, class _Allocator>
1042typename __deque_base<_Tp, _Allocator>::const_iterator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001043__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001044{
1045 __map_const_pointer __mp = __map_.begin() + __start_ / __block_size;
1046 return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
1047}
1048
1049template <class _Tp, class _Allocator>
1050typename __deque_base<_Tp, _Allocator>::iterator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001051__deque_base<_Tp, _Allocator>::end() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001052{
1053 size_type __p = size() + __start_;
1054 __map_pointer __mp = __map_.begin() + __p / __block_size;
1055 return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1056}
1057
1058template <class _Tp, class _Allocator>
1059typename __deque_base<_Tp, _Allocator>::const_iterator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001060__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001061{
1062 size_type __p = size() + __start_;
1063 __map_const_pointer __mp = __map_.begin() + __p / __block_size;
1064 return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
1065}
1066
1067template <class _Tp, class _Allocator>
1068inline _LIBCPP_INLINE_VISIBILITY
1069__deque_base<_Tp, _Allocator>::__deque_base()
1070 : __start_(0), __size_(0) {}
1071
1072template <class _Tp, class _Allocator>
1073inline _LIBCPP_INLINE_VISIBILITY
1074__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
1075 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
1076
1077template <class _Tp, class _Allocator>
1078__deque_base<_Tp, _Allocator>::~__deque_base()
1079{
1080 clear();
1081 typename __map::iterator __i = __map_.begin();
1082 typename __map::iterator __e = __map_.end();
1083 for (; __i != __e; ++__i)
1084 __alloc_traits::deallocate(__alloc(), *__i, __block_size);
1085}
1086
Howard Hinnant73d21a42010-09-04 23:28:19 +00001087#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001088
1089template <class _Tp, class _Allocator>
1090__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001091 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001092 : __map_(_STD::move(__c.__map_)),
1093 __start_(_STD::move(__c.__start_)),
1094 __size_(_STD::move(__c.__size_))
1095{
1096 __c.__start_ = 0;
1097 __c.size() = 0;
1098}
1099
1100template <class _Tp, class _Allocator>
1101__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)
1102 : __map_(_STD::move(__c.__map_), __pointer_allocator(__a)),
1103 __start_(_STD::move(__c.__start_)),
1104 __size_(_STD::move(__c.size()), __a)
1105{
1106 if (__a == __c.__alloc())
1107 {
1108 __c.__start_ = 0;
1109 __c.size() = 0;
1110 }
1111 else
1112 {
1113 __map_.clear();
1114 __start_ = 0;
1115 size() = 0;
1116 }
1117}
1118
Howard Hinnant73d21a42010-09-04 23:28:19 +00001119#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001120
1121template <class _Tp, class _Allocator>
1122void
1123__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001124 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
1125 __is_nothrow_swappable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001126{
1127 __map_.swap(__c.__map_);
1128 _STD::swap(__start_, __c.__start_);
1129 _STD::swap(size(), __c.size());
1130 __swap_alloc(__alloc(), __c.__alloc());
1131}
1132
1133template <class _Tp, class _Allocator>
1134void
Howard Hinnanta12beb32011-06-02 16:10:22 +00001135__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001136{
1137 allocator_type& __a = __alloc();
1138 for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
Howard Hinnant2529d022011-02-02 17:36:20 +00001139 __alloc_traits::destroy(__a, _STD::addressof(*__i));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001140 size() = 0;
1141 while (__map_.size() > 2)
1142 {
1143 __alloc_traits::deallocate(__a, __map_.front(), __block_size);
1144 __map_.pop_front();
1145 }
1146 switch (__map_.size())
1147 {
1148 case 1:
1149 __start_ = __block_size / 2;
1150 break;
1151 case 2:
1152 __start_ = __block_size;
1153 break;
1154 }
1155}
1156
1157template <class _Tp, class _Allocator = allocator<_Tp> >
Howard Hinnant422a53f2010-09-21 21:28:23 +00001158class _LIBCPP_VISIBLE deque
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001159 : private __deque_base<_Tp, _Allocator>
1160{
1161public:
1162 // types:
Howard Hinnant324bb032010-08-22 00:02:43 +00001163
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001164 typedef _Tp value_type;
1165 typedef _Allocator allocator_type;
1166
1167 typedef __deque_base<value_type, allocator_type> __base;
1168
1169 typedef typename __base::__alloc_traits __alloc_traits;
1170 typedef typename __base::reference reference;
1171 typedef typename __base::const_reference const_reference;
1172 typedef typename __base::iterator iterator;
1173 typedef typename __base::const_iterator const_iterator;
1174 typedef typename __base::size_type size_type;
1175 typedef typename __base::difference_type difference_type;
1176
1177 typedef typename __base::pointer pointer;
1178 typedef typename __base::const_pointer const_pointer;
1179 typedef _STD::reverse_iterator<iterator> reverse_iterator;
1180 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
1181
1182 // construct/copy/destroy:
1183 _LIBCPP_INLINE_VISIBILITY deque() {}
1184 _LIBCPP_INLINE_VISIBILITY deque(const allocator_type& __a) : __base(__a) {}
1185 explicit deque(size_type __n);
1186 deque(size_type __n, const value_type& __v);
1187 deque(size_type __n, const value_type& __v, const allocator_type& __a);
1188 template <class _InputIter>
1189 deque(_InputIter __f, _InputIter __l,
1190 typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
1191 template <class _InputIter>
1192 deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1193 typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
1194 deque(const deque& __c);
1195 deque(const deque& __c, const allocator_type& __a);
1196 deque(initializer_list<value_type> __il);
1197 deque(initializer_list<value_type> __il, const allocator_type& __a);
1198
1199 deque& operator=(const deque& __c);
Howard Hinnant422a53f2010-09-21 21:28:23 +00001200 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001201 deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
1202
Howard Hinnant73d21a42010-09-04 23:28:19 +00001203#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0a612b02011-06-02 20:00:14 +00001204 deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001205 deque(deque&& __c, const allocator_type& __a);
Howard Hinnant0a612b02011-06-02 20:00:14 +00001206 deque& operator=(deque&& __c)
1207 _NOEXCEPT_(
1208 (__alloc_traits::propagate_on_container_move_assignment::value &&
1209 is_nothrow_move_assignable<allocator_type>::value) ||
1210 (!__alloc_traits::propagate_on_container_move_assignment::value &&
1211 is_nothrow_move_assignable<value_type>::value));
Howard Hinnant73d21a42010-09-04 23:28:19 +00001212#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001213
1214 template <class _InputIter>
1215 void assign(_InputIter __f, _InputIter __l,
1216 typename enable_if<__is_input_iterator<_InputIter>::value &&
1217 !__is_random_access_iterator<_InputIter>::value>::type* = 0);
1218 template <class _RAIter>
1219 void assign(_RAIter __f, _RAIter __l,
1220 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
1221 void assign(size_type __n, const value_type& __v);
Howard Hinnant422a53f2010-09-21 21:28:23 +00001222 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001223 void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
1224
Howard Hinnanta12beb32011-06-02 16:10:22 +00001225 allocator_type get_allocator() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001226
1227 // iterators:
1228
Howard Hinnant422a53f2010-09-21 21:28:23 +00001229 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001230 iterator begin() _NOEXCEPT {return __base::begin();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001232 const_iterator begin() const _NOEXCEPT {return __base::begin();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001233 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001234 iterator end() _NOEXCEPT {return __base::end();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001235 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001236 const_iterator end() const _NOEXCEPT {return __base::end();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001237
Howard Hinnant422a53f2010-09-21 21:28:23 +00001238 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001239 reverse_iterator rbegin() _NOEXCEPT
1240 {return reverse_iterator(__base::end());}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001241 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001242 const_reverse_iterator rbegin() const _NOEXCEPT
1243 {return const_reverse_iterator(__base::end());}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001245 reverse_iterator rend() _NOEXCEPT
1246 {return reverse_iterator(__base::begin());}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001248 const_reverse_iterator rend() const _NOEXCEPT
1249 {return const_reverse_iterator(__base::begin());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001250
Howard Hinnant422a53f2010-09-21 21:28:23 +00001251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001252 const_iterator cbegin() const _NOEXCEPT
1253 {return __base::begin();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001254 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001255 const_iterator cend() const _NOEXCEPT
1256 {return __base::end();}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001257 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001258 const_reverse_iterator crbegin() const _NOEXCEPT
1259 {return const_reverse_iterator(__base::end());}
Howard Hinnant422a53f2010-09-21 21:28:23 +00001260 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001261 const_reverse_iterator crend() const _NOEXCEPT
1262 {return const_reverse_iterator(__base::begin());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001263
1264 // capacity:
Howard Hinnant422a53f2010-09-21 21:28:23 +00001265 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta12beb32011-06-02 16:10:22 +00001266 size_type size() const _NOEXCEPT {return __base::size();}
1267 _LIBCPP_INLINE_VISIBILITY
1268 size_type max_size() const _NOEXCEPT
1269 {return __alloc_traits::max_size(__base::__alloc());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001270 void resize(size_type __n);
1271 void resize(size_type __n, const value_type& __v);
1272 void shrink_to_fit();
Howard Hinnanta12beb32011-06-02 16:10:22 +00001273 _LIBCPP_INLINE_VISIBILITY
1274 bool empty() const _NOEXCEPT {return __base::size() == 0;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001275
1276 // element access:
1277 reference operator[](size_type __i);
1278 const_reference operator[](size_type __i) const;
1279 reference at(size_type __i);
1280 const_reference at(size_type __i) const;
1281 reference front();
1282 const_reference front() const;
1283 reference back();
1284 const_reference back() const;
1285
1286 // 23.2.2.3 modifiers:
1287 void push_front(const value_type& __v);
1288 void push_back(const value_type& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001289#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1290#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001291 template <class... _Args> void emplace_front(_Args&&... __args);
1292 template <class... _Args> void emplace_back(_Args&&... __args);
1293 template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001294#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001295 void push_front(value_type&& __v);
1296 void push_back(value_type&& __v);
1297 iterator insert(const_iterator __p, value_type&& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001298#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001299 iterator insert(const_iterator __p, const value_type& __v);
1300 iterator insert(const_iterator __p, size_type __n, const value_type& __v);
1301 template <class _InputIter>
1302 iterator insert (const_iterator __p, _InputIter __f, _InputIter __l,
1303 typename enable_if<__is_input_iterator<_InputIter>::value
1304 &&!__is_bidirectional_iterator<_InputIter>::value>::type* = 0);
1305 template <class _BiIter>
1306 iterator insert (const_iterator __p, _BiIter __f, _BiIter __l,
1307 typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0);
Howard Hinnant422a53f2010-09-21 21:28:23 +00001308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001309 iterator insert(const_iterator __p, initializer_list<value_type> __il)
1310 {return insert(__p, __il.begin(), __il.end());}
1311 void pop_front();
1312 void pop_back();
1313 iterator erase(const_iterator __p);
1314 iterator erase(const_iterator __f, const_iterator __l);
1315
Howard Hinnant0a612b02011-06-02 20:00:14 +00001316 void swap(deque& __c)
1317 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1318 __is_nothrow_swappable<allocator_type>::value);
Howard Hinnanta12beb32011-06-02 16:10:22 +00001319 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001320
Howard Hinnant422a53f2010-09-21 21:28:23 +00001321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001322 bool __invariants() const {return __base::__invariants();}
1323private:
Howard Hinnant422a53f2010-09-21 21:28:23 +00001324 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001325 static size_type __recommend_blocks(size_type __n)
1326 {
1327 return __n / __base::__block_size + (__n % __base::__block_size != 0);
1328 }
Howard Hinnant422a53f2010-09-21 21:28:23 +00001329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001330 size_type __capacity() const
1331 {
1332 return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;
1333 }
Howard Hinnant422a53f2010-09-21 21:28:23 +00001334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001335 size_type __front_spare() const
1336 {
1337 return __base::__start_;
1338 }
Howard Hinnant422a53f2010-09-21 21:28:23 +00001339 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001340 size_type __back_spare() const
1341 {
1342 return __capacity() - (__base::__start_ + __base::size());
1343 }
1344
1345 template <class _InpIter>
1346 void __append(_InpIter __f, _InpIter __l,
1347 typename enable_if<__is_input_iterator<_InpIter>::value &&
1348 !__is_forward_iterator<_InpIter>::value>::type* = 0);
1349 template <class _ForIter>
1350 void __append(_ForIter __f, _ForIter __l,
1351 typename enable_if<__is_forward_iterator<_ForIter>::value>::type* = 0);
1352 void __append(size_type __n);
1353 void __append(size_type __n, const value_type& __v);
1354 void __erase_to_end(const_iterator __f);
1355 void __add_front_capacity();
1356 void __add_front_capacity(size_type __n);
1357 void __add_back_capacity();
1358 void __add_back_capacity(size_type __n);
1359 iterator __move_and_check(iterator __f, iterator __l, iterator __r,
1360 const_pointer& __vt);
1361 iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
1362 const_pointer& __vt);
1363 void __move_construct_and_check(iterator __f, iterator __l,
1364 iterator __r, const_pointer& __vt);
1365 void __move_construct_backward_and_check(iterator __f, iterator __l,
1366 iterator __r, const_pointer& __vt);
1367
Howard Hinnant422a53f2010-09-21 21:28:23 +00001368 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001369 void __copy_assign_alloc(const deque& __c)
1370 {__copy_assign_alloc(__c, integral_constant<bool,
1371 __alloc_traits::propagate_on_container_copy_assignment::value>());}
1372
Howard Hinnant422a53f2010-09-21 21:28:23 +00001373 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001374 void __copy_assign_alloc(const deque& __c, true_type)
1375 {
1376 if (__base::__alloc() != __c.__alloc())
1377 {
1378 clear();
1379 shrink_to_fit();
1380 }
1381 __base::__alloc() = __c.__alloc();
1382 __base::__map_.__alloc() = __c.__map_.__alloc();
1383 }
1384
Howard Hinnant422a53f2010-09-21 21:28:23 +00001385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001386 void __copy_assign_alloc(const deque& __c, false_type)
1387 {}
1388
1389 void __move_assign(deque& __c, true_type);
1390 void __move_assign(deque& __c, false_type);
1391};
1392
1393template <class _Tp, class _Allocator>
1394deque<_Tp, _Allocator>::deque(size_type __n)
1395{
1396 if (__n > 0)
1397 __append(__n);
1398}
1399
1400template <class _Tp, class _Allocator>
1401deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
1402{
1403 if (__n > 0)
1404 __append(__n, __v);
1405}
1406
1407template <class _Tp, class _Allocator>
1408deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
1409 : __base(__a)
1410{
1411 if (__n > 0)
1412 __append(__n, __v);
1413}
1414
1415template <class _Tp, class _Allocator>
1416template <class _InputIter>
1417deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
1418 typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
1419{
1420 __append(__f, __l);
1421}
1422
1423template <class _Tp, class _Allocator>
1424template <class _InputIter>
1425deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
1426 typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
1427 : __base(__a)
1428{
1429 __append(__f, __l);
1430}
1431
1432template <class _Tp, class _Allocator>
1433deque<_Tp, _Allocator>::deque(const deque& __c)
1434 : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
1435{
1436 __append(__c.begin(), __c.end());
1437}
1438
1439template <class _Tp, class _Allocator>
1440deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
1441 : __base(__a)
1442{
1443 __append(__c.begin(), __c.end());
1444}
1445
1446template <class _Tp, class _Allocator>
1447deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
1448{
1449 __append(__il.begin(), __il.end());
1450}
1451
1452template <class _Tp, class _Allocator>
1453deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
1454 : __base(__a)
1455{
1456 __append(__il.begin(), __il.end());
1457}
1458
1459template <class _Tp, class _Allocator>
1460deque<_Tp, _Allocator>&
1461deque<_Tp, _Allocator>::operator=(const deque& __c)
1462{
1463 if (this != &__c)
1464 {
1465 __copy_assign_alloc(__c);
1466 assign(__c.begin(), __c.end());
1467 }
1468 return *this;
1469}
1470
Howard Hinnant73d21a42010-09-04 23:28:19 +00001471#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001472
1473template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001474inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001475deque<_Tp, _Allocator>::deque(deque&& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001476 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001477 : __base(_STD::move(__c))
1478{
1479}
1480
1481template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001482inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001483deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
1484 : __base(_STD::move(__c), __a)
1485{
1486 if (__a != __c.__alloc())
1487 {
1488 typedef move_iterator<iterator> _I;
1489 assign(_I(__c.begin()), _I(__c.end()));
1490 }
1491}
1492
1493template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001494inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001495deque<_Tp, _Allocator>&
1496deque<_Tp, _Allocator>::operator=(deque&& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00001497 _NOEXCEPT_(
1498 (__alloc_traits::propagate_on_container_move_assignment::value &&
1499 is_nothrow_move_assignable<allocator_type>::value) ||
1500 (!__alloc_traits::propagate_on_container_move_assignment::value &&
1501 is_nothrow_move_assignable<value_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)
1524{
1525 clear();
1526 shrink_to_fit();
1527 __base::__move_assign(__c);
1528}
1529
Howard Hinnant73d21a42010-09-04 23:28:19 +00001530#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001531
1532template <class _Tp, class _Allocator>
1533template <class _InputIter>
1534void
1535deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
1536 typename enable_if<__is_input_iterator<_InputIter>::value &&
1537 !__is_random_access_iterator<_InputIter>::value>::type*)
1538{
1539 iterator __i = __base::begin();
1540 iterator __e = __base::end();
1541 for (; __f != __l && __i != __e; ++__f, ++__i)
1542 *__i = *__f;
1543 if (__f != __l)
1544 __append(__f, __l);
1545 else
1546 __erase_to_end(__i);
1547}
1548
1549template <class _Tp, class _Allocator>
1550template <class _RAIter>
1551void
1552deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
1553 typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
1554{
1555 if (static_cast<size_type>(__l - __f) > __base::size())
1556 {
1557 _RAIter __m = __f + __base::size();
1558 _STD::copy(__f, __m, __base::begin());
1559 __append(__m, __l);
1560 }
1561 else
1562 __erase_to_end(_STD::copy(__f, __l, __base::begin()));
1563}
1564
1565template <class _Tp, class _Allocator>
1566void
1567deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
1568{
1569 if (__n > __base::size())
1570 {
1571 _STD::fill_n(__base::begin(), __base::size(), __v);
1572 __n -= __base::size();
1573 __append(__n, __v);
1574 }
1575 else
1576 __erase_to_end(_STD::fill_n(__base::begin(), __n, __v));
1577}
1578
1579template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001580inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001581_Allocator
Howard Hinnanta12beb32011-06-02 16:10:22 +00001582deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001583{
1584 return __base::__alloc();
1585}
1586
1587template <class _Tp, class _Allocator>
1588void
1589deque<_Tp, _Allocator>::resize(size_type __n)
1590{
1591 if (__n > __base::size())
1592 __append(__n - __base::size());
1593 else if (__n < __base::size())
1594 __erase_to_end(__base::begin() + __n);
1595}
1596
1597template <class _Tp, class _Allocator>
1598void
1599deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
1600{
1601 if (__n > __base::size())
1602 __append(__n - __base::size(), __v);
1603 else if (__n < __base::size())
1604 __erase_to_end(__base::begin() + __n);
1605}
1606
1607template <class _Tp, class _Allocator>
1608void
1609deque<_Tp, _Allocator>::shrink_to_fit()
1610{
1611 allocator_type& __a = __base::__alloc();
1612 if (empty())
1613 {
1614 while (__base::__map_.size() > 0)
1615 {
1616 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
1617 __base::__map_.pop_back();
1618 }
1619 __base::__start_ = 0;
1620 }
1621 else
1622 {
1623 if (__front_spare() >= __base::__block_size)
1624 {
1625 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
1626 __base::__map_.pop_front();
1627 __base::__start_ -= __base::__block_size;
1628 }
1629 if (__back_spare() >= __base::__block_size)
1630 {
1631 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
1632 __base::__map_.pop_back();
1633 }
1634 }
1635 __base::__map_.shrink_to_fit();
1636}
1637
1638template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001639inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001640typename deque<_Tp, _Allocator>::reference
1641deque<_Tp, _Allocator>::operator[](size_type __i)
1642{
1643 size_type __p = __base::__start_ + __i;
1644 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1645}
1646
1647template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001648inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001649typename deque<_Tp, _Allocator>::const_reference
1650deque<_Tp, _Allocator>::operator[](size_type __i) const
1651{
1652 size_type __p = __base::__start_ + __i;
1653 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1654}
1655
1656template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001657inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001658typename deque<_Tp, _Allocator>::reference
1659deque<_Tp, _Allocator>::at(size_type __i)
1660{
1661 if (__i >= __base::size())
1662 __base::__throw_out_of_range();
1663 size_type __p = __base::__start_ + __i;
1664 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1665}
1666
1667template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001668inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001669typename deque<_Tp, _Allocator>::const_reference
1670deque<_Tp, _Allocator>::at(size_type __i) const
1671{
1672 if (__i >= __base::size())
1673 __base::__throw_out_of_range();
1674 size_type __p = __base::__start_ + __i;
1675 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1676}
1677
1678template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001679inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001680typename deque<_Tp, _Allocator>::reference
1681deque<_Tp, _Allocator>::front()
1682{
1683 return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1684 + __base::__start_ % __base::__block_size);
1685}
1686
1687template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001688inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001689typename deque<_Tp, _Allocator>::const_reference
1690deque<_Tp, _Allocator>::front() const
1691{
1692 return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
1693 + __base::__start_ % __base::__block_size);
1694}
1695
1696template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001697inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001698typename deque<_Tp, _Allocator>::reference
1699deque<_Tp, _Allocator>::back()
1700{
1701 size_type __p = __base::size() + __base::__start_ - 1;
1702 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1703}
1704
1705template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00001706inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001707typename deque<_Tp, _Allocator>::const_reference
1708deque<_Tp, _Allocator>::back() const
1709{
1710 size_type __p = __base::size() + __base::__start_ - 1;
1711 return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
1712}
1713
1714template <class _Tp, class _Allocator>
1715void
1716deque<_Tp, _Allocator>::push_back(const value_type& __v)
1717{
1718 allocator_type& __a = __base::__alloc();
1719 if (__back_spare() == 0)
1720 __add_back_capacity();
1721 // __back_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001722 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001723 ++__base::size();
1724}
1725
Howard Hinnant73d21a42010-09-04 23:28:19 +00001726#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001727
1728template <class _Tp, class _Allocator>
1729void
1730deque<_Tp, _Allocator>::push_back(value_type&& __v)
1731{
1732 allocator_type& __a = __base::__alloc();
1733 if (__back_spare() == 0)
1734 __add_back_capacity();
1735 // __back_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001736 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001737 ++__base::size();
1738}
1739
Howard Hinnant73d21a42010-09-04 23:28:19 +00001740#ifndef _LIBCPP_HAS_NO_VARIADICS
1741
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001742template <class _Tp, class _Allocator>
1743template <class... _Args>
1744void
1745deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
1746{
1747 allocator_type& __a = __base::__alloc();
1748 if (__back_spare() == 0)
1749 __add_back_capacity();
1750 // __back_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001751 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001752 ++__base::size();
1753}
1754
Howard Hinnant73d21a42010-09-04 23:28:19 +00001755#endif // _LIBCPP_HAS_NO_VARIADICS
1756#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001757
1758template <class _Tp, class _Allocator>
1759void
1760deque<_Tp, _Allocator>::push_front(const value_type& __v)
1761{
1762 allocator_type& __a = __base::__alloc();
1763 if (__front_spare() == 0)
1764 __add_front_capacity();
1765 // __front_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001766 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001767 --__base::__start_;
1768 ++__base::size();
1769}
1770
Howard Hinnant73d21a42010-09-04 23:28:19 +00001771#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001772
1773template <class _Tp, class _Allocator>
1774void
1775deque<_Tp, _Allocator>::push_front(value_type&& __v)
1776{
1777 allocator_type& __a = __base::__alloc();
1778 if (__front_spare() == 0)
1779 __add_front_capacity();
1780 // __front_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001781 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001782 --__base::__start_;
1783 ++__base::size();
1784}
1785
Howard Hinnant73d21a42010-09-04 23:28:19 +00001786#ifndef _LIBCPP_HAS_NO_VARIADICS
1787
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001788template <class _Tp, class _Allocator>
1789template <class... _Args>
1790void
1791deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
1792{
1793 allocator_type& __a = __base::__alloc();
1794 if (__front_spare() == 0)
1795 __add_front_capacity();
1796 // __front_spare() >= 1
Howard Hinnant2529d022011-02-02 17:36:20 +00001797 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001798 --__base::__start_;
1799 ++__base::size();
1800}
1801
Howard Hinnant73d21a42010-09-04 23:28:19 +00001802#endif // _LIBCPP_HAS_NO_VARIADICS
1803#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001804
1805template <class _Tp, class _Allocator>
1806typename deque<_Tp, _Allocator>::iterator
1807deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
1808{
1809 size_type __pos = __p - __base::begin();
1810 size_type __to_end = __base::size() - __pos;
1811 allocator_type& __a = __base::__alloc();
1812 if (__pos < __to_end)
1813 { // insert by shifting things backward
1814 if (__front_spare() == 0)
1815 __add_front_capacity();
1816 // __front_spare() >= 1
1817 if (__pos == 0)
1818 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001819 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001820 --__base::__start_;
1821 ++__base::size();
1822 }
1823 else
1824 {
1825 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1826 iterator __b = __base::begin();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001827 iterator __bm1 = _STD::prev(__b);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001828 if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
1829 __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
Howard Hinnant2529d022011-02-02 17:36:20 +00001830 __alloc_traits::construct(__a, _STD::addressof(*__bm1), _STD::move(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001831 --__base::__start_;
1832 ++__base::size();
1833 if (__pos > 1)
Douglas Gregor7ac6af72011-04-29 16:20:26 +00001834 __b = __move_and_check(_STD::next(__b), __b + __pos, __b, __vt);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001835 *__b = *__vt;
1836 }
1837 }
1838 else
1839 { // insert by shifting things forward
1840 if (__back_spare() == 0)
1841 __add_back_capacity();
1842 // __back_capacity >= 1
1843 size_type __de = __base::size() - __pos;
1844 if (__de == 0)
1845 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001846 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001847 ++__base::size();
1848 }
1849 else
1850 {
1851 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1852 iterator __e = __base::end();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001853 iterator __em1 = _STD::prev(__e);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001854 if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
1855 __vt = pointer_traits<const_pointer>::pointer_to(*__e);
Howard Hinnant2529d022011-02-02 17:36:20 +00001856 __alloc_traits::construct(__a, _STD::addressof(*__e), _STD::move(*__em1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001857 ++__base::size();
1858 if (__de > 1)
1859 __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
1860 *--__e = *__vt;
1861 }
1862 }
1863 return __base::begin() + __pos;
1864}
1865
Howard Hinnant73d21a42010-09-04 23:28:19 +00001866#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001867
1868template <class _Tp, class _Allocator>
1869typename deque<_Tp, _Allocator>::iterator
1870deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
1871{
1872 size_type __pos = __p - __base::begin();
1873 size_type __to_end = __base::size() - __pos;
1874 allocator_type& __a = __base::__alloc();
1875 if (__pos < __to_end)
1876 { // insert by shifting things backward
1877 if (__front_spare() == 0)
1878 __add_front_capacity();
1879 // __front_spare() >= 1
1880 if (__pos == 0)
1881 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001882 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001883 --__base::__start_;
1884 ++__base::size();
1885 }
1886 else
1887 {
1888 iterator __b = __base::begin();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001889 iterator __bm1 = _STD::prev(__b);
Howard Hinnant2529d022011-02-02 17:36:20 +00001890 __alloc_traits::construct(__a, _STD::addressof(*__bm1), _STD::move(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001891 --__base::__start_;
1892 ++__base::size();
1893 if (__pos > 1)
Douglas Gregor7ac6af72011-04-29 16:20:26 +00001894 __b = _STD::move(_STD::next(__b), __b + __pos, __b);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001895 *__b = _STD::move(__v);
1896 }
1897 }
1898 else
1899 { // insert by shifting things forward
1900 if (__back_spare() == 0)
1901 __add_back_capacity();
1902 // __back_capacity >= 1
1903 size_type __de = __base::size() - __pos;
1904 if (__de == 0)
1905 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001906 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001907 ++__base::size();
1908 }
1909 else
1910 {
1911 iterator __e = __base::end();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001912 iterator __em1 = _STD::prev(__e);
Howard Hinnant2529d022011-02-02 17:36:20 +00001913 __alloc_traits::construct(__a, _STD::addressof(*__e), _STD::move(*__em1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001914 ++__base::size();
1915 if (__de > 1)
1916 __e = _STD::move_backward(__e - __de, __em1, __e);
1917 *--__e = _STD::move(__v);
1918 }
1919 }
1920 return __base::begin() + __pos;
1921}
1922
Howard Hinnant73d21a42010-09-04 23:28:19 +00001923#ifndef _LIBCPP_HAS_NO_VARIADICS
1924
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001925template <class _Tp, class _Allocator>
1926template <class... _Args>
1927typename deque<_Tp, _Allocator>::iterator
1928deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
1929{
1930 size_type __pos = __p - __base::begin();
1931 size_type __to_end = __base::size() - __pos;
1932 allocator_type& __a = __base::__alloc();
1933 if (__pos < __to_end)
1934 { // insert by shifting things backward
1935 if (__front_spare() == 0)
1936 __add_front_capacity();
1937 // __front_spare() >= 1
1938 if (__pos == 0)
1939 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001940 __alloc_traits::construct(__a, _STD::addressof(*--__base::begin()), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001941 --__base::__start_;
1942 ++__base::size();
1943 }
1944 else
1945 {
1946 iterator __b = __base::begin();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001947 iterator __bm1 = _STD::prev(__b);
Howard Hinnant2529d022011-02-02 17:36:20 +00001948 __alloc_traits::construct(__a, _STD::addressof(*__bm1), _STD::move(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001949 --__base::__start_;
1950 ++__base::size();
1951 if (__pos > 1)
Douglas Gregor7ac6af72011-04-29 16:20:26 +00001952 __b = _STD::move(_STD::next(__b), __b + __pos, __b);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001953 *__b = value_type(_STD::forward<_Args>(__args)...);
1954 }
1955 }
1956 else
1957 { // insert by shifting things forward
1958 if (__back_spare() == 0)
1959 __add_back_capacity();
1960 // __back_capacity >= 1
1961 size_type __de = __base::size() - __pos;
1962 if (__de == 0)
1963 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001964 __alloc_traits::construct(__a, _STD::addressof(*__base::end()), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001965 ++__base::size();
1966 }
1967 else
1968 {
1969 iterator __e = __base::end();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001970 iterator __em1 = _STD::prev(__e);
Howard Hinnant2529d022011-02-02 17:36:20 +00001971 __alloc_traits::construct(__a, _STD::addressof(*__e), _STD::move(*__em1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001972 ++__base::size();
1973 if (__de > 1)
1974 __e = _STD::move_backward(__e - __de, __em1, __e);
1975 *--__e = value_type(_STD::forward<_Args>(__args)...);
1976 }
1977 }
1978 return __base::begin() + __pos;
1979}
1980
Howard Hinnant73d21a42010-09-04 23:28:19 +00001981#endif // _LIBCPP_HAS_NO_VARIADICS
1982#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001983
1984template <class _Tp, class _Allocator>
1985typename deque<_Tp, _Allocator>::iterator
1986deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
1987{
1988 size_type __pos = __p - __base::begin();
1989 size_type __to_end = __base::size() - __pos;
1990 allocator_type& __a = __base::__alloc();
1991 if (__pos < __to_end)
1992 { // insert by shifting things backward
1993 if (__n > __front_spare())
1994 __add_front_capacity(__n - __front_spare());
1995 // __n <= __front_spare()
1996 size_type __old_n = __n;
1997 iterator __old_begin = __base::begin();
1998 iterator __i = __old_begin;
1999 if (__n > __pos)
2000 {
2001 for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002002 __alloc_traits::construct(__a, _STD::addressof(*--__i), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002003 __n = __pos;
2004 }
2005 if (__n > 0)
2006 {
2007 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2008 iterator __obn = __old_begin + __n;
2009 __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
2010 if (__n < __pos)
2011 __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
2012 _STD::fill_n(__old_begin, __n, *__vt);
2013 }
2014 }
2015 else
2016 { // insert by shifting things forward
2017 size_type __back_capacity = __back_spare();
2018 if (__n > __back_capacity)
2019 __add_back_capacity(__n - __back_capacity);
2020 // __n <= __back_capacity
2021 size_type __old_n = __n;
2022 iterator __old_end = __base::end();
2023 iterator __i = __old_end;
2024 size_type __de = __base::size() - __pos;
2025 if (__n > __de)
2026 {
2027 for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002028 __alloc_traits::construct(__a, _STD::addressof(*__i), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002029 __n = __de;
2030 }
2031 if (__n > 0)
2032 {
2033 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
2034 iterator __oen = __old_end - __n;
2035 __move_construct_and_check(__oen, __old_end, __i, __vt);
2036 if (__n < __de)
2037 __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
2038 _STD::fill_n(__old_end - __n, __n, *__vt);
2039 }
2040 }
2041 return __base::begin() + __pos;
2042}
2043
2044template <class _Tp, class _Allocator>
2045template <class _InputIter>
2046typename deque<_Tp, _Allocator>::iterator
2047deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
2048 typename enable_if<__is_input_iterator<_InputIter>::value
2049 &&!__is_bidirectional_iterator<_InputIter>::value>::type*)
2050{
2051 __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
2052 __buf.__construct_at_end(__f, __l);
2053 typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
2054 return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
2055}
2056
2057template <class _Tp, class _Allocator>
2058template <class _BiIter>
2059typename deque<_Tp, _Allocator>::iterator
2060deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
2061 typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type*)
2062{
2063 size_type __n = _STD::distance(__f, __l);
2064 size_type __pos = __p - __base::begin();
2065 size_type __to_end = __base::size() - __pos;
2066 allocator_type& __a = __base::__alloc();
2067 if (__pos < __to_end)
2068 { // insert by shifting things backward
2069 if (__n > __front_spare())
2070 __add_front_capacity(__n - __front_spare());
2071 // __n <= __front_spare()
2072 size_type __old_n = __n;
2073 iterator __old_begin = __base::begin();
2074 iterator __i = __old_begin;
2075 _BiIter __m = __f;
2076 if (__n > __pos)
2077 {
2078 __m = __pos < __n / 2 ? _STD::prev(__l, __pos) : _STD::next(__f, __n - __pos);
2079 for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002080 __alloc_traits::construct(__a, _STD::addressof(*--__i), *--__j);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002081 __n = __pos;
2082 }
2083 if (__n > 0)
2084 {
2085 iterator __obn = __old_begin + __n;
2086 for (iterator __j = __obn; __j != __old_begin;)
2087 {
Howard Hinnant2529d022011-02-02 17:36:20 +00002088 __alloc_traits::construct(__a, _STD::addressof(*--__i), _STD::move(*--__j));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002089 --__base::__start_;
2090 ++__base::size();
2091 }
2092 if (__n < __pos)
2093 __old_begin = _STD::move(__obn, __old_begin + __pos, __old_begin);
2094 _STD::copy(__m, __l, __old_begin);
2095 }
2096 }
2097 else
2098 { // insert by shifting things forward
2099 size_type __back_capacity = __back_spare();
2100 if (__n > __back_capacity)
2101 __add_back_capacity(__n - __back_capacity);
2102 // __n <= __back_capacity
2103 size_type __old_n = __n;
2104 iterator __old_end = __base::end();
2105 iterator __i = __old_end;
2106 _BiIter __m = __l;
2107 size_type __de = __base::size() - __pos;
2108 if (__n > __de)
2109 {
2110 __m = __de < __n / 2 ? _STD::next(__f, __de) : _STD::prev(__l, __n - __de);
2111 for (_BiIter __j = __m; __j != __l; ++__i, ++__j, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002112 __alloc_traits::construct(__a, _STD::addressof(*__i), *__j);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002113 __n = __de;
2114 }
2115 if (__n > 0)
2116 {
2117 iterator __oen = __old_end - __n;
2118 for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002119 __alloc_traits::construct(__a, _STD::addressof(*__i), _STD::move(*__j));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002120 if (__n < __de)
2121 __old_end = _STD::move_backward(__old_end - __de, __oen, __old_end);
2122 _STD::copy_backward(__f, __m, __old_end);
2123 }
2124 }
2125 return __base::begin() + __pos;
2126}
2127
2128template <class _Tp, class _Allocator>
2129template <class _InpIter>
2130void
2131deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
2132 typename enable_if<__is_input_iterator<_InpIter>::value &&
2133 !__is_forward_iterator<_InpIter>::value>::type*)
2134{
2135 for (; __f != __l; ++__f)
2136 push_back(*__f);
2137}
2138
2139template <class _Tp, class _Allocator>
2140template <class _ForIter>
2141void
2142deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
2143 typename enable_if<__is_forward_iterator<_ForIter>::value>::type*)
2144{
2145 size_type __n = _STD::distance(__f, __l);
2146 allocator_type& __a = __base::__alloc();
2147 size_type __back_capacity = __back_spare();
2148 if (__n > __back_capacity)
2149 __add_back_capacity(__n - __back_capacity);
2150 // __n <= __back_capacity
2151 for (iterator __i = __base::end(); __f != __l; ++__i, ++__f, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002152 __alloc_traits::construct(__a, _STD::addressof(*__i), *__f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002153}
2154
2155template <class _Tp, class _Allocator>
2156void
2157deque<_Tp, _Allocator>::__append(size_type __n)
2158{
2159 allocator_type& __a = __base::__alloc();
2160 size_type __back_capacity = __back_spare();
2161 if (__n > __back_capacity)
2162 __add_back_capacity(__n - __back_capacity);
2163 // __n <= __back_capacity
2164 for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002165 __alloc_traits::construct(__a, _STD::addressof(*__i));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002166}
2167
2168template <class _Tp, class _Allocator>
2169void
2170deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
2171{
2172 allocator_type& __a = __base::__alloc();
2173 size_type __back_capacity = __back_spare();
2174 if (__n > __back_capacity)
2175 __add_back_capacity(__n - __back_capacity);
2176 // __n <= __back_capacity
2177 for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002178 __alloc_traits::construct(__a, _STD::addressof(*__i), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002179}
2180
2181// Create front capacity for one block of elements.
2182// Strong guarantee. Either do it or don't touch anything.
2183template <class _Tp, class _Allocator>
2184void
2185deque<_Tp, _Allocator>::__add_front_capacity()
2186{
2187 allocator_type& __a = __base::__alloc();
2188 if (__back_spare() >= __base::__block_size)
2189 {
2190 __base::__start_ += __base::__block_size;
2191 pointer __pt = __base::__map_.back();
2192 __base::__map_.pop_back();
2193 __base::__map_.push_front(__pt);
2194 }
2195 // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer
2196 else if (__base::__map_.size() < __base::__map_.capacity())
2197 { // we can put the new buffer into the map, but don't shift things around
2198 // until all buffers are allocated. If we throw, we don't need to fix
2199 // anything up (any added buffers are undetectible)
2200 if (__base::__map_.__front_spare() > 0)
2201 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2202 else
2203 {
2204 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2205 // Done allocating, reorder capacity
2206 pointer __pt = __base::__map_.back();
2207 __base::__map_.pop_back();
2208 __base::__map_.push_front(__pt);
2209 }
2210 __base::__start_ = __base::__map_.size() == 1 ?
2211 __base::__block_size / 2 :
2212 __base::__start_ + __base::__block_size;
2213 }
2214 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2215 else
2216 {
2217 __split_buffer<pointer, typename __base::__pointer_allocator&>
2218 __buf(max<size_type>(2 * __base::__map_.capacity(), 1),
2219 0, __base::__map_.__alloc());
2220#ifndef _LIBCPP_NO_EXCEPTIONS
2221 try
2222 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002223#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002224 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2225#ifndef _LIBCPP_NO_EXCEPTIONS
2226 }
2227 catch (...)
2228 {
2229 __alloc_traits::deallocate(__a, __buf.front(), __base::__block_size);
2230 throw;
2231 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002232#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002233 for (typename __base::__map_pointer __i = __base::__map_.begin();
2234 __i != __base::__map_.end(); ++__i)
2235 __buf.push_back(*__i);
2236 _STD::swap(__base::__map_.__first_, __buf.__first_);
2237 _STD::swap(__base::__map_.__begin_, __buf.__begin_);
2238 _STD::swap(__base::__map_.__end_, __buf.__end_);
2239 _STD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2240 __base::__start_ = __base::__map_.size() == 1 ?
2241 __base::__block_size / 2 :
2242 __base::__start_ + __base::__block_size;
2243 }
2244}
2245
2246// Create front capacity for __n elements.
2247// Strong guarantee. Either do it or don't touch anything.
2248template <class _Tp, class _Allocator>
2249void
2250deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
2251{
2252 allocator_type& __a = __base::__alloc();
2253 size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2254 // Number of unused blocks at back:
2255 size_type __back_capacity = __back_spare() / __base::__block_size;
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00002256 __back_capacity = _STD::min(__back_capacity, __nb); // don't take more than you need
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002257 __nb -= __back_capacity; // number of blocks need to allocate
2258 // If __nb == 0, then we have sufficient capacity.
2259 if (__nb == 0)
2260 {
2261 __base::__start_ += __base::__block_size * __back_capacity;
2262 for (; __back_capacity > 0; --__back_capacity)
2263 {
2264 pointer __pt = __base::__map_.back();
2265 __base::__map_.pop_back();
2266 __base::__map_.push_front(__pt);
2267 }
2268 }
2269 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2270 else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2271 { // we can put the new buffers into the map, but don't shift things around
2272 // until all buffers are allocated. If we throw, we don't need to fix
2273 // anything up (any added buffers are undetectible)
2274 for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))
2275 {
2276 if (__base::__map_.__front_spare() == 0)
2277 break;
2278 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2279 }
2280 for (; __nb > 0; --__nb, ++__back_capacity)
2281 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2282 // Done allocating, reorder capacity
2283 __base::__start_ += __back_capacity * __base::__block_size;
2284 for (; __back_capacity > 0; --__back_capacity)
2285 {
2286 pointer __pt = __base::__map_.back();
2287 __base::__map_.pop_back();
2288 __base::__map_.push_front(__pt);
2289 }
2290 }
2291 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2292 else
2293 {
2294 size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();
2295 __split_buffer<pointer, typename __base::__pointer_allocator&>
2296 __buf(max<size_type>(2* __base::__map_.capacity(),
2297 __nb + __base::__map_.size()),
2298 0, __base::__map_.__alloc());
2299#ifndef _LIBCPP_NO_EXCEPTIONS
2300 try
2301 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002302#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002303 for (; __nb > 0; --__nb)
2304 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2305#ifndef _LIBCPP_NO_EXCEPTIONS
2306 }
2307 catch (...)
2308 {
2309 for (typename __base::__map_pointer __i = __buf.begin();
2310 __i != __buf.end(); ++__i)
2311 __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2312 throw;
2313 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002314#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002315 for (; __back_capacity > 0; --__back_capacity)
2316 {
2317 __buf.push_back(__base::__map_.back());
2318 __base::__map_.pop_back();
2319 }
2320 for (typename __base::__map_pointer __i = __base::__map_.begin();
2321 __i != __base::__map_.end(); ++__i)
2322 __buf.push_back(*__i);
2323 _STD::swap(__base::__map_.__first_, __buf.__first_);
2324 _STD::swap(__base::__map_.__begin_, __buf.__begin_);
2325 _STD::swap(__base::__map_.__end_, __buf.__end_);
2326 _STD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2327 __base::__start_ += __ds;
2328 }
2329}
2330
2331// Create back capacity for one block of elements.
2332// Strong guarantee. Either do it or don't touch anything.
2333template <class _Tp, class _Allocator>
2334void
2335deque<_Tp, _Allocator>::__add_back_capacity()
2336{
2337 allocator_type& __a = __base::__alloc();
2338 if (__front_spare() >= __base::__block_size)
2339 {
2340 __base::__start_ -= __base::__block_size;
2341 pointer __pt = __base::__map_.front();
2342 __base::__map_.pop_front();
2343 __base::__map_.push_back(__pt);
2344 }
2345 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2346 else if (__base::__map_.size() < __base::__map_.capacity())
2347 { // we can put the new buffer into the map, but don't shift things around
2348 // until it is allocated. If we throw, we don't need to fix
2349 // anything up (any added buffers are undetectible)
2350 if (__base::__map_.__back_spare() != 0)
2351 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2352 else
2353 {
2354 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2355 // Done allocating, reorder capacity
2356 pointer __pt = __base::__map_.front();
2357 __base::__map_.pop_front();
2358 __base::__map_.push_back(__pt);
2359 }
2360 }
2361 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
2362 else
2363 {
2364 __split_buffer<pointer, typename __base::__pointer_allocator&>
2365 __buf(max<size_type>(2* __base::__map_.capacity(), 1),
2366 __base::__map_.size(),
2367 __base::__map_.__alloc());
2368#ifndef _LIBCPP_NO_EXCEPTIONS
2369 try
2370 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002371#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002372 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2373#ifndef _LIBCPP_NO_EXCEPTIONS
2374 }
2375 catch (...)
2376 {
2377 __alloc_traits::deallocate(__a, __buf.back(), __base::__block_size);
2378 throw;
2379 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002380#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002381 for (typename __base::__map_pointer __i = __base::__map_.end();
2382 __i != __base::__map_.begin();)
2383 __buf.push_front(*--__i);
2384 _STD::swap(__base::__map_.__first_, __buf.__first_);
2385 _STD::swap(__base::__map_.__begin_, __buf.__begin_);
2386 _STD::swap(__base::__map_.__end_, __buf.__end_);
2387 _STD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2388 }
2389}
2390
2391// Create back capacity for __n elements.
2392// Strong guarantee. Either do it or don't touch anything.
2393template <class _Tp, class _Allocator>
2394void
2395deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
2396{
2397 allocator_type& __a = __base::__alloc();
2398 size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
2399 // Number of unused blocks at front:
2400 size_type __front_capacity = __front_spare() / __base::__block_size;
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00002401 __front_capacity = _STD::min(__front_capacity, __nb); // don't take more than you need
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002402 __nb -= __front_capacity; // number of blocks need to allocate
2403 // If __nb == 0, then we have sufficient capacity.
2404 if (__nb == 0)
2405 {
2406 __base::__start_ -= __base::__block_size * __front_capacity;
2407 for (; __front_capacity > 0; --__front_capacity)
2408 {
2409 pointer __pt = __base::__map_.front();
2410 __base::__map_.pop_front();
2411 __base::__map_.push_back(__pt);
2412 }
2413 }
2414 // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
2415 else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
2416 { // we can put the new buffers into the map, but don't shift things around
2417 // until all buffers are allocated. If we throw, we don't need to fix
2418 // anything up (any added buffers are undetectible)
2419 for (; __nb > 0; --__nb)
2420 {
2421 if (__base::__map_.__back_spare() == 0)
2422 break;
2423 __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2424 }
2425 for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=
2426 __base::__block_size - (__base::__map_.size() == 1))
2427 __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
2428 // Done allocating, reorder capacity
2429 __base::__start_ -= __base::__block_size * __front_capacity;
2430 for (; __front_capacity > 0; --__front_capacity)
2431 {
2432 pointer __pt = __base::__map_.front();
2433 __base::__map_.pop_front();
2434 __base::__map_.push_back(__pt);
2435 }
2436 }
2437 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
2438 else
2439 {
2440 size_type __ds = __front_capacity * __base::__block_size;
2441 __split_buffer<pointer, typename __base::__pointer_allocator&>
2442 __buf(max<size_type>(2* __base::__map_.capacity(),
2443 __nb + __base::__map_.size()),
2444 __base::__map_.size() - __front_capacity,
2445 __base::__map_.__alloc());
2446#ifndef _LIBCPP_NO_EXCEPTIONS
2447 try
2448 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002449#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002450 for (; __nb > 0; --__nb)
2451 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
2452#ifndef _LIBCPP_NO_EXCEPTIONS
2453 }
2454 catch (...)
2455 {
2456 for (typename __base::__map_pointer __i = __buf.begin();
2457 __i != __buf.end(); ++__i)
2458 __alloc_traits::deallocate(__a, *__i, __base::__block_size);
2459 throw;
2460 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002461#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002462 for (; __front_capacity > 0; --__front_capacity)
2463 {
2464 __buf.push_back(__base::__map_.front());
2465 __base::__map_.pop_front();
2466 }
2467 for (typename __base::__map_pointer __i = __base::__map_.end();
2468 __i != __base::__map_.begin();)
2469 __buf.push_front(*--__i);
2470 _STD::swap(__base::__map_.__first_, __buf.__first_);
2471 _STD::swap(__base::__map_.__begin_, __buf.__begin_);
2472 _STD::swap(__base::__map_.__end_, __buf.__end_);
2473 _STD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
2474 __base::__start_ -= __ds;
2475 }
2476}
2477
2478template <class _Tp, class _Allocator>
2479void
2480deque<_Tp, _Allocator>::pop_front()
2481{
2482 allocator_type& __a = __base::__alloc();
2483 __alloc_traits::destroy(__a, *(__base::__map_.begin() +
2484 __base::__start_ / __base::__block_size) +
2485 __base::__start_ % __base::__block_size);
2486 --__base::size();
2487 if (++__base::__start_ >= 2 * __base::__block_size)
2488 {
2489 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2490 __base::__map_.pop_front();
2491 __base::__start_ -= __base::__block_size;
2492 }
2493}
2494
2495template <class _Tp, class _Allocator>
2496void
2497deque<_Tp, _Allocator>::pop_back()
2498{
2499 allocator_type& __a = __base::__alloc();
2500 size_type __p = __base::size() + __base::__start_ - 1;
2501 __alloc_traits::destroy(__a, *(__base::__map_.begin() +
2502 __p / __base::__block_size) +
2503 __p % __base::__block_size);
2504 --__base::size();
2505 if (__back_spare() >= 2 * __base::__block_size)
2506 {
2507 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2508 __base::__map_.pop_back();
2509 }
2510}
2511
2512// move assign [__f, __l) to [__r, __r + (__l-__f)).
2513// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
2514template <class _Tp, class _Allocator>
2515typename deque<_Tp, _Allocator>::iterator
2516deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
2517 const_pointer& __vt)
2518{
2519 // as if
2520 // for (; __f != __l; ++__f, ++__r)
2521 // *__r = _STD::move(*__f);
2522 difference_type __n = __l - __f;
2523 while (__n > 0)
2524 {
2525 pointer __fb = __f.__ptr_;
2526 pointer __fe = *__f.__m_iter_ + __base::__block_size;
2527 difference_type __bs = __fe - __fb;
2528 if (__bs > __n)
2529 {
2530 __bs = __n;
2531 __fe = __fb + __bs;
2532 }
2533 if (__fb <= __vt && __vt < __fe)
2534 __vt = (const_iterator(__f.__m_iter_, __vt) -= __f - __r).__ptr_;
2535 __r = _STD::move(__fb, __fe, __r);
2536 __n -= __bs;
2537 __f += __bs;
2538 }
2539 return __r;
2540}
2541
2542// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
2543// If __vt points into [__f, __l), then add (__r - __l) to __vt.
2544template <class _Tp, class _Allocator>
2545typename deque<_Tp, _Allocator>::iterator
2546deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
2547 const_pointer& __vt)
2548{
2549 // as if
2550 // while (__f != __l)
2551 // *--__r = _STD::move(*--__l);
2552 difference_type __n = __l - __f;
2553 while (__n > 0)
2554 {
2555 --__l;
2556 pointer __lb = *__l.__m_iter_;
2557 pointer __le = __l.__ptr_ + 1;
2558 difference_type __bs = __le - __lb;
2559 if (__bs > __n)
2560 {
2561 __bs = __n;
2562 __lb = __le - __bs;
2563 }
2564 if (__lb <= __vt && __vt < __le)
2565 __vt = (const_iterator(__l.__m_iter_, __vt) += __r - __l - 1).__ptr_;
2566 __r = _STD::move_backward(__lb, __le, __r);
2567 __n -= __bs;
2568 __l -= __bs - 1;
2569 }
2570 return __r;
2571}
2572
2573// move construct [__f, __l) to [__r, __r + (__l-__f)).
2574// If __vt points into [__f, __l), then add (__r - __f) to __vt.
2575template <class _Tp, class _Allocator>
2576void
2577deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
2578 iterator __r, const_pointer& __vt)
2579{
2580 allocator_type& __a = __base::__alloc();
2581 // as if
2582 // for (; __f != __l; ++__r, ++__f, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002583 // __alloc_traits::construct(__a, _STD::addressof(*__r), _STD::move(*__f));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002584 difference_type __n = __l - __f;
2585 while (__n > 0)
2586 {
2587 pointer __fb = __f.__ptr_;
2588 pointer __fe = *__f.__m_iter_ + __base::__block_size;
2589 difference_type __bs = __fe - __fb;
2590 if (__bs > __n)
2591 {
2592 __bs = __n;
2593 __fe = __fb + __bs;
2594 }
2595 if (__fb <= __vt && __vt < __fe)
2596 __vt = (const_iterator(__f.__m_iter_, __vt) += __r - __f).__ptr_;
2597 for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
Howard Hinnant2529d022011-02-02 17:36:20 +00002598 __alloc_traits::construct(__a, _STD::addressof(*__r), _STD::move(*__fb));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002599 __n -= __bs;
2600 __f += __bs;
2601 }
2602}
2603
2604// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
2605// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
2606template <class _Tp, class _Allocator>
2607void
2608deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
2609 iterator __r, const_pointer& __vt)
2610{
2611 allocator_type& __a = __base::__alloc();
2612 // as if
2613 // for (iterator __j = __l; __j != __f;)
2614 // {
Howard Hinnant2529d022011-02-02 17:36:20 +00002615 // __alloc_traitsconstruct(__a, _STD::addressof(*--__r), _STD::move(*--__j));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002616 // --__base::__start_;
2617 // ++__base::size();
2618 // }
2619 difference_type __n = __l - __f;
2620 while (__n > 0)
2621 {
2622 --__l;
2623 pointer __lb = *__l.__m_iter_;
2624 pointer __le = __l.__ptr_ + 1;
2625 difference_type __bs = __le - __lb;
2626 if (__bs > __n)
2627 {
2628 __bs = __n;
2629 __lb = __le - __bs;
2630 }
2631 if (__lb <= __vt && __vt < __le)
2632 __vt = (const_iterator(__l.__m_iter_, __vt) -= __l - __r + 1).__ptr_;
2633 while (__le != __lb)
2634 {
Howard Hinnant2529d022011-02-02 17:36:20 +00002635 __alloc_traits::construct(__a, _STD::addressof(*--__r), _STD::move(*--__le));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002636 --__base::__start_;
2637 ++__base::size();
2638 }
2639 __n -= __bs;
2640 __l -= __bs - 1;
2641 }
2642}
2643
2644template <class _Tp, class _Allocator>
2645typename deque<_Tp, _Allocator>::iterator
2646deque<_Tp, _Allocator>::erase(const_iterator __f)
2647{
2648 difference_type __n = 1;
2649 iterator __b = __base::begin();
2650 difference_type __pos = __f - __b;
2651 iterator __p = __b + __pos;
2652 allocator_type& __a = __base::__alloc();
2653 if (__pos < (__base::size() - 1) / 2)
2654 { // erase from front
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00002655 _STD::move_backward(__b, __p, _STD::next(__p));
Howard Hinnant2529d022011-02-02 17:36:20 +00002656 __alloc_traits::destroy(__a, _STD::addressof(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002657 --__base::size();
2658 ++__base::__start_;
2659 if (__front_spare() >= 2 * __base::__block_size)
2660 {
2661 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2662 __base::__map_.pop_front();
2663 __base::__start_ -= __base::__block_size;
2664 }
2665 }
2666 else
2667 { // erase from back
Douglas Gregor7ac6af72011-04-29 16:20:26 +00002668 iterator __i = _STD::move(_STD::next(__p), __base::end(), __p);
Howard Hinnant2529d022011-02-02 17:36:20 +00002669 __alloc_traits::destroy(__a, _STD::addressof(*__i));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002670 --__base::size();
2671 if (__back_spare() >= 2 * __base::__block_size)
2672 {
2673 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2674 __base::__map_.pop_back();
2675 }
2676 }
2677 return __base::begin() + __pos;
2678}
2679
2680template <class _Tp, class _Allocator>
2681typename deque<_Tp, _Allocator>::iterator
2682deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
2683{
2684 difference_type __n = __l - __f;
2685 iterator __b = __base::begin();
2686 difference_type __pos = __f - __b;
2687 iterator __p = __b + __pos;
2688 if (__n > 0)
2689 {
2690 allocator_type& __a = __base::__alloc();
2691 if (__pos < (__base::size() - __n) / 2)
2692 { // erase from front
2693 iterator __i = _STD::move_backward(__b, __p, __p + __n);
2694 for (; __b != __i; ++__b)
Howard Hinnant2529d022011-02-02 17:36:20 +00002695 __alloc_traits::destroy(__a, _STD::addressof(*__b));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002696 __base::size() -= __n;
2697 __base::__start_ += __n;
2698 while (__front_spare() >= 2 * __base::__block_size)
2699 {
2700 __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
2701 __base::__map_.pop_front();
2702 __base::__start_ -= __base::__block_size;
2703 }
2704 }
2705 else
2706 { // erase from back
2707 iterator __i = _STD::move(__p + __n, __base::end(), __p);
2708 for (iterator __e = __base::end(); __i != __e; ++__i)
Howard Hinnant2529d022011-02-02 17:36:20 +00002709 __alloc_traits::destroy(__a, _STD::addressof(*__i));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002710 __base::size() -= __n;
2711 while (__back_spare() >= 2 * __base::__block_size)
2712 {
2713 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2714 __base::__map_.pop_back();
2715 }
2716 }
2717 }
2718 return __base::begin() + __pos;
2719}
2720
2721template <class _Tp, class _Allocator>
2722void
2723deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
2724{
2725 iterator __e = __base::end();
2726 difference_type __n = __e - __f;
2727 if (__n > 0)
2728 {
2729 allocator_type& __a = __base::__alloc();
2730 iterator __b = __base::begin();
2731 difference_type __pos = __f - __b;
2732 for (iterator __p = __b + __pos; __p != __e; ++__p)
Howard Hinnant2529d022011-02-02 17:36:20 +00002733 __alloc_traits::destroy(__a, _STD::addressof(*__p));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002734 __base::size() -= __n;
2735 while (__back_spare() >= 2 * __base::__block_size)
2736 {
2737 __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
2738 __base::__map_.pop_back();
2739 }
2740 }
2741}
2742
2743template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00002744inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002745void
2746deque<_Tp, _Allocator>::swap(deque& __c)
Howard Hinnant0a612b02011-06-02 20:00:14 +00002747 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
2748 __is_nothrow_swappable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002749{
2750 __base::swap(__c);
2751}
2752
2753template <class _Tp, class _Allocator>
Howard Hinnant422a53f2010-09-21 21:28:23 +00002754inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002755void
Howard Hinnanta12beb32011-06-02 16:10:22 +00002756deque<_Tp, _Allocator>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002757{
2758 __base::clear();
2759}
2760
2761template <class _Tp, class _Allocator>
2762_LIBCPP_INLINE_VISIBILITY inline
2763bool
2764operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2765{
2766 const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
2767 return __sz == __y.size() && _STD::equal(__x.begin(), __x.end(), __y.begin());
2768}
2769
2770template <class _Tp, class _Allocator>
2771_LIBCPP_INLINE_VISIBILITY inline
2772bool
2773operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2774{
2775 return !(__x == __y);
2776}
2777
2778template <class _Tp, class _Allocator>
2779_LIBCPP_INLINE_VISIBILITY inline
2780bool
2781operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2782{
2783 return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
2784}
2785
2786template <class _Tp, class _Allocator>
2787_LIBCPP_INLINE_VISIBILITY inline
2788bool
2789operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2790{
2791 return __y < __x;
2792}
2793
2794template <class _Tp, class _Allocator>
2795_LIBCPP_INLINE_VISIBILITY inline
2796bool
2797operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2798{
2799 return !(__x < __y);
2800}
2801
2802template <class _Tp, class _Allocator>
2803_LIBCPP_INLINE_VISIBILITY inline
2804bool
2805operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
2806{
2807 return !(__y < __x);
2808}
2809
2810template <class _Tp, class _Allocator>
2811_LIBCPP_INLINE_VISIBILITY inline
2812void
2813swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
Howard Hinnant0a612b02011-06-02 20:00:14 +00002814 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002815{
2816 __x.swap(__y);
2817}
2818
2819_LIBCPP_END_NAMESPACE_STD
2820
2821#endif // _LIBCPP_DEQUE