blob: 0336c9fa38d7134620c07822a978b9ca7aa6b63b [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===---------------------------- list ------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_LIST
12#define _LIBCPP_LIST
13
14/*
15 list synopsis
16
17namespace std
18{
19
20template <class T, class Alloc = allocator<T> >
21class list
22{
23public:
24
25 // types:
26 typedef T value_type;
27 typedef Alloc allocator_type;
28 typedef typename allocator_type::reference reference;
29 typedef typename allocator_type::const_reference const_reference;
30 typedef typename allocator_type::pointer pointer;
31 typedef typename allocator_type::const_pointer const_pointer;
32 typedef implementation-defined iterator;
33 typedef implementation-defined const_iterator;
34 typedef implementation-defined size_type;
35 typedef implementation-defined difference_type;
36 typedef reverse_iterator<iterator> reverse_iterator;
37 typedef reverse_iterator<const_iterator> const_reverse_iterator;
38
39 list();
40 explicit list(const allocator_type& a);
41 explicit list(size_type n);
42 list(size_type n, const value_type& value);
43 list(size_type n, const value_type& value, const allocator_type& a);
44 template <class Iter>
45 list(Iter first, Iter last);
46 template <class Iter>
47 list(Iter first, Iter last, const allocator_type& a);
48 list(const list& x);
49 list(const list&, const allocator_type& a);
50 list(list&& x);
51 list(list&&, const allocator_type& a);
52 list(initializer_list<value_type>);
53 list(initializer_list<value_type>, const allocator_type& a);
54
55 ~list();
56
57 list& operator=(const list& x);
58 list& operator=(list&& x);
59 list& operator=(initializer_list<value_type>);
60 template <class Iter>
61 void assign(Iter first, Iter last);
62 void assign(size_type n, const value_type& t);
63 void assign(initializer_list<value_type>);
64
65 allocator_type get_allocator() const;
66
67 iterator begin();
68 const_iterator begin() const;
69 iterator end();
70 const_iterator end() const;
71 reverse_iterator rbegin();
72 const_reverse_iterator rbegin() const;
73 reverse_iterator rend();
74 const_reverse_iterator rend() const;
75 const_iterator cbegin() const;
76 const_iterator cend() const;
77 const_reverse_iterator crbegin() const;
78 const_reverse_iterator crend() const;
79
80 reference front();
81 const_reference front() const;
82 reference back();
83 const_reference back() const;
84
85 bool empty() const;
86 size_type size() const;
87 size_type max_size() const;
88
89 template <class... Args>
90 void emplace_front(Args&&... args);
91 void pop_front();
92 template <class... Args>
93 void emplace_back(Args&&... args);
94 void pop_back();
95 void push_front(const value_type& x);
96 void push_front(value_type&& x);
97 void push_back(const value_type& x);
98 void push_back(value_type&& x);
99 template <class... Args>
100 iterator emplace(const_iterator position, Args&&... args);
101 iterator insert(const_iterator position, const value_type& x);
102 iterator insert(const_iterator position, value_type&& x);
103 iterator insert(const_iterator position, size_type n, const value_type& x);
104 template <class Iter>
105 iterator insert(const_iterator position, Iter first, Iter last);
106 iterator insert(const_iterator position, initializer_list<value_type> il);
107
108 iterator erase(const_iterator position);
109 iterator erase(const_iterator position, const_iterator last);
110
111 void resize(size_type sz);
112 void resize(size_type sz, const value_type& c);
113
114 void swap(list<value_type,allocator_type>&);
115 void clear();
116
117 void splice(const_iterator position, list& x);
118 void splice(const_iterator position, list&& x);
119 void splice(const_iterator position, list& x, const_iterator i);
120 void splice(const_iterator position, list&& x, const_iterator i);
121 void splice(const_iterator position, list& x, const_iterator first,
122 const_iterator last);
123 void splice(const_iterator position, list&& x, const_iterator first,
124 const_iterator last);
125
126 void remove(const value_type& value);
127 template <class Pred> void remove_if(Pred pred);
128 void unique();
129 template <class BinaryPredicate>
130 void unique(BinaryPredicate binary_pred);
131 void merge(list& x);
132 void merge(list&& x);
133 template <class Compare>
134 void merge(list& x, Compare comp);
135 template <class Compare>
136 void merge(list&& x, Compare comp);
137 void sort();
138 template <class Compare>
139 void sort(Compare comp);
140 void reverse();
141};
142
143template <class T, class Alloc>
144 bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y);
145template <class T, class Alloc>
146 bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y);
147template <class T, class Alloc>
148 bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y);
149template <class T, class Alloc>
150 bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y);
151template <class T, class Alloc>
152 bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y);
153template <class T, class Alloc>
154 bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y);
155
156template <class T, class Alloc>
157 void swap(list<T,Alloc>& x, list<T,Alloc>& y);
158
159} // std
160
161*/
162
163#include <__config>
164
165#include <memory>
166#include <limits>
167#include <initializer_list>
168#include <iterator>
169#include <algorithm>
170
171#pragma GCC system_header
172
173_LIBCPP_BEGIN_NAMESPACE_STD
174
175template <class, class> struct __list_node;
176
177template <class _Tp, class _VoidPtr>
178struct __list_node_base
179{
180 typedef typename pointer_traits<_VoidPtr>::template
181#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
182 rebind<__list_node<_Tp, _VoidPtr> > pointer;
183#else
184 rebind<__list_node<_Tp, _VoidPtr> >::other pointer;
185#endif
186
187 pointer __prev_;
188 pointer __next_;
189
190 __list_node_base()
191 : __prev_(static_cast<pointer>(this)),
192 __next_(static_cast<pointer>(this))
193 {}
194};
195
196template <class _Tp, class _VoidPtr>
197struct __list_node
198 : public __list_node_base<_Tp, _VoidPtr>
199{
200 _Tp __value_;
201};
202
203template <class, class> class list;
204template <class, class> class __list_imp;
205template <class, class> class __list_const_iterator;
206
207template <class _Tp, class _VoidPtr>
208class __list_iterator
209{
210 typedef typename pointer_traits<_VoidPtr>::template
211#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
212 rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;
213#else
214 rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;
215#endif
216
217 __node_pointer __ptr_;
218
219 explicit __list_iterator(__node_pointer __p) : __ptr_(__p) {}
220
221 template<class, class> friend class list;
222 template<class, class> friend class __list_imp;
223 template<class, class> friend class __list_const_iterator;
224public:
225 typedef bidirectional_iterator_tag iterator_category;
226 typedef _Tp value_type;
227 typedef value_type& reference;
228 typedef typename pointer_traits<_VoidPtr>::template
229#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
230 rebind<value_type>
231#else
232 rebind<value_type>::other
233#endif
234 pointer;
235 typedef typename pointer_traits<pointer>::difference_type difference_type;
236
237 reference operator*() const {return __ptr_->__value_;}
238 pointer operator->() const {return &(operator*());}
239
240 __list_iterator& operator++() {__ptr_ = __ptr_->__next_; return *this;}
241 __list_iterator operator++(int) {__list_iterator __t(*this); ++(*this); return __t;}
242
243 __list_iterator& operator--() {__ptr_ = __ptr_->__prev_; return *this;}
244 __list_iterator operator--(int) {__list_iterator __t(*this); --(*this); return __t;}
245
246 friend bool operator==(const __list_iterator& __x, const __list_iterator& __y)
247 {return __x.__ptr_ == __y.__ptr_;}
248 friend bool operator!=(const __list_iterator& __x, const __list_iterator& __y)
249 {return !(__x == __y);}
250};
251
252template <class _Tp, class _VoidPtr>
253class __list_const_iterator
254{
255 typedef typename pointer_traits<_VoidPtr>::template
256#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
257 rebind<const __list_node<_Tp, _VoidPtr> > __node_pointer;
258#else
259 rebind<const __list_node<_Tp, _VoidPtr> >::other __node_pointer;
260#endif
261
262 __node_pointer __ptr_;
263
264 explicit __list_const_iterator(__node_pointer __p) : __ptr_(__p) {}
265
266 template<class, class> friend class list;
267 template<class, class> friend class __list_imp;
268public:
269 typedef bidirectional_iterator_tag iterator_category;
270 typedef _Tp value_type;
271 typedef const value_type& reference;
272 typedef typename pointer_traits<_VoidPtr>::template
273#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
274 rebind<const value_type>
275#else
276 rebind<const value_type>::other
277#endif
278 pointer;
279 typedef typename pointer_traits<pointer>::difference_type difference_type;
280
281 __list_const_iterator(__list_iterator<_Tp, _VoidPtr> __p) : __ptr_(__p.__ptr_) {}
282
283 reference operator*() const {return __ptr_->__value_;}
284 pointer operator->() const {return &(operator*());}
285
286 __list_const_iterator& operator++() {__ptr_ = __ptr_->__next_; return *this;}
287 __list_const_iterator operator++(int) {__list_const_iterator __t(*this); ++(*this); return __t;}
288
289 __list_const_iterator& operator--() {__ptr_ = __ptr_->__prev_; return *this;}
290 __list_const_iterator operator--(int) {__list_const_iterator __t(*this); --(*this); return __t;}
291
292 friend bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y)
293 {return __x.__ptr_ == __y.__ptr_;}
294 friend bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y)
295 {return !(__x == __y);}
296};
297
298template <class _Tp, class _Alloc>
299class __list_imp
300{
301 __list_imp(const __list_imp&);
302 __list_imp& operator=(const __list_imp&);
303protected:
304 typedef _Tp value_type;
305 typedef _Alloc allocator_type;
306 typedef allocator_traits<allocator_type> __alloc_traits;
307 typedef typename __alloc_traits::size_type size_type;
308 typedef typename __alloc_traits::void_pointer __void_pointer;
309 typedef __list_iterator<value_type, __void_pointer> iterator;
310 typedef __list_const_iterator<value_type, __void_pointer> const_iterator;
311 typedef __list_node_base<value_type, __void_pointer> __node_base;
312 typedef __list_node<value_type, __void_pointer> __node;
313 typedef typename __alloc_traits::template
314#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
315 rebind_alloc<__node>
316#else
317 rebind_alloc<__node>::other
318#endif
319 __node_allocator;
320 typedef allocator_traits<__node_allocator> __node_alloc_traits;
321 typedef typename __node_alloc_traits::pointer __node_pointer;
322 typedef typename __node_alloc_traits::const_pointer __node_const_pointer;
323 typedef typename __alloc_traits::pointer pointer;
324 typedef typename __alloc_traits::const_pointer const_pointer;
325 typedef typename __alloc_traits::difference_type difference_type;
326
327 __node_base __end_;
328 __compressed_pair<size_type, __node_allocator> __size_alloc_;
329
330 size_type& __sz() {return __size_alloc_.first();}
331 const size_type& __sz() const {return __size_alloc_.first();}
332 __node_allocator& __node_alloc() {return __size_alloc_.second();}
333 const __node_allocator& __node_alloc() const {return __size_alloc_.second();}
334
335 static void __unlink_nodes(__node_base& __f, __node_base& __l);
336
337 __list_imp();
338 __list_imp(const allocator_type& __a);
339 ~__list_imp();
340 void clear();
341 bool empty() const {return __sz() == 0;}
342
343 iterator begin() {return iterator(__end_.__next_);}
344 const_iterator begin() const {return const_iterator(__end_.__next_);}
345 iterator end() {return iterator(static_cast<__node_pointer> (&__end_));}
346 const_iterator end() const {return const_iterator(static_cast<__node_const_pointer>(&__end_));}
347
348 void swap(__list_imp& __c);
349
350 void __copy_assign_alloc(const __list_imp& __c)
351 {__copy_assign_alloc(__c, integral_constant<bool,
352 __node_alloc_traits::propagate_on_container_copy_assignment::value>());}
353
354 void __move_assign_alloc(__list_imp& __c)
355 {__move_assign_alloc(__c, integral_constant<bool,
356 __node_alloc_traits::propagate_on_container_move_assignment::value>());}
357
358private:
359 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
360 {__swap_alloc(__x, __y, integral_constant<bool,
361 __node_alloc_traits::propagate_on_container_swap::value>());}
362 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
363 {
364 using _STD::swap;
365 swap(__x, __y);
366 }
367 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
368 {}
369
370 void __copy_assign_alloc(const __list_imp& __c, true_type)
371 {
372 if (__node_alloc() != __c.__node_alloc())
373 clear();
374 __node_alloc() = __c.__node_alloc();
375 }
376
377 void __copy_assign_alloc(const __list_imp& __c, false_type)
378 {}
379
380 void __move_assign_alloc(const __list_imp& __c, true_type)
381 {
382 __node_alloc() = _STD::move(__c.__node_alloc());
383 }
384
385 void __move_assign_alloc(const __list_imp& __c, false_type)
386 {}
387};
388
389// Unlink nodes [__f, __l]
390template <class _Tp, class _Alloc>
391inline
392void
393__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_base& __f, __node_base& __l)
394{
395 __f.__prev_->__next_ = __l.__next_;
396 __l.__next_->__prev_ = __f.__prev_;
397}
398
399template <class _Tp, class _Alloc>
400inline
401__list_imp<_Tp, _Alloc>::__list_imp()
402 : __size_alloc_(0)
403{
404}
405
406template <class _Tp, class _Alloc>
407inline
408__list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a)
409 : __size_alloc_(0, __node_allocator(__a))
410{
411}
412
413template <class _Tp, class _Alloc>
414__list_imp<_Tp, _Alloc>::~__list_imp()
415{
416 clear();
417}
418
419template <class _Tp, class _Alloc>
420void
421__list_imp<_Tp, _Alloc>::clear()
422{
423 if (!empty())
424 {
425 __node_allocator& __na = __node_alloc();
426 iterator __f = begin();
427 iterator __l = end();
428 __unlink_nodes(*__f.__ptr_, *__l.__ptr_->__prev_);
429 __sz() = 0;
430 while (__f != __l)
431 {
432 __node& __n = *__f.__ptr_;
433 ++__f;
434 __node_alloc_traits::destroy(__na, addressof(__n.__value_));
435 __node_alloc_traits::deallocate(__na, addressof(__n), 1);
436 }
437 }
438}
439
440template <class _Tp, class _Alloc>
441void
442__list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
443{
444 using _STD::swap;
445 __swap_alloc(__node_alloc(), __c.__node_alloc());
446 swap(__sz(), __c.__sz());
447 swap(__end_, __c.__end_);
448 if (__sz() == 0)
449 __end_.__next_ = __end_.__prev_ = &static_cast<__node&>(__end_);
450 else
451 __end_.__prev_->__next_ = __end_.__next_->__prev_
452 = &static_cast<__node&>(__end_);
453 if (__c.__sz() == 0)
454 __c.__end_.__next_ = __c.__end_.__prev_
455 = &static_cast<__node&>(__c.__end_);
456 else
457 __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_
458 = &static_cast<__node&>(__c.__end_);
459}
460
461template <class _Tp, class _Alloc = allocator<_Tp> >
462class list
463 : private __list_imp<_Tp, _Alloc>
464{
465 typedef __list_imp<_Tp, _Alloc> base;
466 typedef typename base::__node __node;
467 typedef typename base::__node_allocator __node_allocator;
468 typedef typename base::__node_pointer __node_pointer;
469 typedef typename base::__node_alloc_traits __node_alloc_traits;
470
471public:
472 typedef _Tp value_type;
473 typedef _Alloc allocator_type;
474 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
475 "Invalid allocator::value_type");
476 typedef value_type& reference;
477 typedef const value_type& const_reference;
478 typedef typename base::pointer pointer;
479 typedef typename base::const_pointer const_pointer;
480 typedef typename base::size_type size_type;
481 typedef typename base::difference_type difference_type;
482 typedef typename base::iterator iterator;
483 typedef typename base::const_iterator const_iterator;
484 typedef _STD::reverse_iterator<iterator> reverse_iterator;
485 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
486
487 list() {}
488 list(const allocator_type& __a) : base(__a) {}
489 list(size_type __n);
490 list(size_type __n, const value_type& __x);
491 list(size_type __n, const value_type& __x, const allocator_type& __a);
492 template <class _InpIter>
493 list(_InpIter __f, _InpIter __l,
494 typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
495 template <class _InpIter>
496 list(_InpIter __f, _InpIter __l, const allocator_type& __a,
497 typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
498
499 list(const list& __c);
500 list(const list& __c, const allocator_type& __a);
501 list& operator=(const list& __c);
502 list(initializer_list<value_type> __il);
503 list(initializer_list<value_type> __il, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000504#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000505 list(list&& __c);
506 list(list&& __c, const allocator_type& __a);
507 list& operator=(list&& __c);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000508#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000509 list& operator=(initializer_list<value_type> __il)
510 {assign(__il.begin(), __il.end()); return *this;}
511
512 template <class _InpIter>
513 void assign(_InpIter __f, _InpIter __l,
514 typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
515 void assign(size_type __n, const value_type& __x);
516 void assign(initializer_list<value_type> __il)
517 {assign(__il.begin(), __il.end());}
518
519 allocator_type get_allocator() const;
520
521 size_type size() const {return base::__sz();}
522 bool empty() const {return base::empty();}
523 size_type max_size() const {return numeric_limits<difference_type>::max();}
524
525 iterator begin() {return base::begin();}
526 const_iterator begin() const {return base::begin();}
527 iterator end() {return base::end();}
528 const_iterator end() const {return base::end();}
529 const_iterator cbegin() const {return base::begin();}
530 const_iterator cend() const {return base::end();}
531
532 reverse_iterator rbegin() {return reverse_iterator(end());}
533 const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
534 reverse_iterator rend() {return reverse_iterator(begin());}
535 const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
536 const_reverse_iterator crbegin() const {return const_reverse_iterator(end());}
537 const_reverse_iterator crend() const {return const_reverse_iterator(begin());}
538
539 reference front() {return base::__end_.__next_->__value_;}
540 const_reference front() const {return base::__end_.__next_->__value_;}
541 reference back() {return base::__end_.__prev_->__value_;}
542 const_reference back() const {return base::__end_.__prev_->__value_;}
543
Howard Hinnant73d21a42010-09-04 23:28:19 +0000544#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000545 void push_front(value_type&& __x);
546 void push_back(value_type&& __x);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000547#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000548 template <class... _Args>
549 void emplace_front(_Args&&... __args);
550 template <class... _Args>
551 void emplace_back(_Args&&... __args);
552 template <class... _Args>
553 iterator emplace(const_iterator __p, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000554#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000555 iterator insert(const_iterator __p, value_type&& __x);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000556#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000557
558 void push_front(const value_type& __x);
559 void push_back(const value_type& __x);
560
561 iterator insert(const_iterator __p, const value_type& __x);
562 iterator insert(const_iterator __p, size_type __n, const value_type& __x);
563 template <class _InpIter>
564 iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,
565 typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
566 iterator insert(const_iterator __p, initializer_list<value_type> __il)
567 {return insert(__p, __il.begin(), __il.end());}
568
569 void swap(list& __c) {base::swap(__c);}
570 void clear() {base::clear();}
571
572 void pop_front();
573 void pop_back();
574
575 iterator erase(const_iterator __p);
576 iterator erase(const_iterator __f, const_iterator __l);
577
578 void resize(size_type __n);
579 void resize(size_type __n, const value_type& __x);
580
581 void splice(const_iterator __p, list& __c);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000582#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000583 void splice(const_iterator __p, list&& __c) {splice(__p, __c);}
584#endif
585 void splice(const_iterator __p, list& __c, const_iterator __i);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000586#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000587 void splice(const_iterator __p, list&& __c, const_iterator __i)
588 {splice(__p, __c, __i);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000589#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000590 void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000591#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000592 void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l)
593 {splice(__p, __c, __f, __l);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000594#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000595
596 void remove(const value_type& __x);
597 template <class _Pred> void remove_if(_Pred __pred);
598 void unique();
599 template <class _BinaryPred>
600 void unique(_BinaryPred __binary_pred);
601 void merge(list& __c);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000602#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000603 void merge(list&& __c) {merge(__c);}
604#endif
605 template <class _Comp>
606 void merge(list& __c, _Comp __comp);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000607#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000608 template <class _Comp>
609 void merge(list&& __c, _Comp __comp) {merge(__c, __comp);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000610#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000611 void sort();
612 template <class _Comp>
613 void sort(_Comp __comp);
614
615 void reverse();
616
617private:
618 static void __link_nodes(__node& __p, __node& __f, __node& __l);
619 iterator __iterator(size_type __n);
620 template <class _Comp>
621 static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
622
623 void __move_assign(list& __c, true_type);
624 void __move_assign(list& __c, false_type);
625};
626
627// Link in nodes [__f, __l] just prior to __p
628template <class _Tp, class _Alloc>
629inline
630void
631list<_Tp, _Alloc>::__link_nodes(__node& __p, __node& __f, __node& __l)
632{
633 __p.__prev_->__next_ = &__f;
634 __f.__prev_ = __p.__prev_;
635 __p.__prev_ = &__l;
636 __l.__next_ = &__p;
637}
638
639template <class _Tp, class _Alloc>
640inline
641typename list<_Tp, _Alloc>::iterator
642list<_Tp, _Alloc>::__iterator(size_type __n)
643{
644 return __n <= base::__sz() / 2 ? next(begin(), __n)
645 : prev(end(), base::__sz() - __n);
646}
647
648template <class _Tp, class _Alloc>
649list<_Tp, _Alloc>::list(size_type __n)
650{
651 for (; __n > 0; --__n)
Howard Hinnant73d21a42010-09-04 23:28:19 +0000652#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000653 emplace_back();
654#else
655 push_back(value_type());
656#endif
657}
658
659template <class _Tp, class _Alloc>
660list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
661{
662 for (; __n > 0; --__n)
663 push_back(__x);
664}
665
666template <class _Tp, class _Alloc>
667list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a)
668 : base(__a)
669{
670 for (; __n > 0; --__n)
671 push_back(__x);
672}
673
674template <class _Tp, class _Alloc>
675template <class _InpIter>
676list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
677 typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
678{
679 for (; __f != __l; ++__f)
680 push_back(*__f);
681}
682
683template <class _Tp, class _Alloc>
684template <class _InpIter>
685list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,
686 typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
687 : base(__a)
688{
689 for (; __f != __l; ++__f)
690 push_back(*__f);
691}
692
693template <class _Tp, class _Alloc>
694list<_Tp, _Alloc>::list(const list& __c)
695 : base(allocator_type(
696 __node_alloc_traits::select_on_container_copy_construction(
697 __c.__node_alloc())))
698{
699 for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
700 push_back(*__i);
701}
702
703template <class _Tp, class _Alloc>
704list<_Tp, _Alloc>::list(const list& __c, const allocator_type& __a)
705 : base(__a)
706{
707 for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
708 push_back(*__i);
709}
710
711template <class _Tp, class _Alloc>
712list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a)
713 : base(__a)
714{
715 for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
716 __e = __il.end(); __i != __e; ++__i)
717 push_back(*__i);
718}
719
720template <class _Tp, class _Alloc>
721list<_Tp, _Alloc>::list(initializer_list<value_type> __il)
722{
723 for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
724 __e = __il.end(); __i != __e; ++__i)
725 push_back(*__i);
726}
727
728template <class _Tp, class _Alloc>
729inline
730list<_Tp, _Alloc>&
731list<_Tp, _Alloc>::operator=(const list& __c)
732{
733 if (this != &__c)
734 {
735 base::__copy_assign_alloc(__c);
736 assign(__c.begin(), __c.end());
737 }
738 return *this;
739}
740
Howard Hinnant73d21a42010-09-04 23:28:19 +0000741#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000742
743template <class _Tp, class _Alloc>
744inline
745list<_Tp, _Alloc>::list(list&& __c)
746 : base(allocator_type(_STD::move(__c.__node_alloc())))
747{
748 splice(end(), __c);
749}
750
751template <class _Tp, class _Alloc>
752inline
753list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a)
754 : base(__a)
755{
756 if (__a == __c.get_allocator())
757 splice(end(), __c);
758 else
759 {
760 typedef move_iterator<iterator> _I;
761 assign(_I(__c.begin()), _I(__c.end()));
762 }
763}
764
765template <class _Tp, class _Alloc>
766inline
767list<_Tp, _Alloc>&
768list<_Tp, _Alloc>::operator=(list&& __c)
769{
770 __move_assign(__c, integral_constant<bool,
771 __node_alloc_traits::propagate_on_container_move_assignment::value>());
772 return *this;
773}
774
775template <class _Tp, class _Alloc>
776void
777list<_Tp, _Alloc>::__move_assign(list& __c, false_type)
778{
779 if (base::__node_alloc() != __c.__node_alloc())
780 {
781 typedef move_iterator<iterator> _I;
782 assign(_I(__c.begin()), _I(__c.end()));
783 }
784 else
785 __move_assign(__c, true_type());
786}
787
788template <class _Tp, class _Alloc>
789void
790list<_Tp, _Alloc>::__move_assign(list& __c, true_type)
791{
792 clear();
793 base::__move_assign_alloc(__c);
794 splice(end(), __c);
795}
796
Howard Hinnant73d21a42010-09-04 23:28:19 +0000797#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000798
799template <class _Tp, class _Alloc>
800template <class _InpIter>
801void
802list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l,
803 typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
804{
805 iterator __i = begin();
806 iterator __e = end();
807 for (; __f != __l && __i != __e; ++__f, ++__i)
808 *__i = *__f;
809 if (__i == __e)
810 insert(__e, __f, __l);
811 else
812 erase(__i, __e);
813}
814
815template <class _Tp, class _Alloc>
816void
817list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x)
818{
819 iterator __i = begin();
820 iterator __e = end();
821 for (; __n > 0 && __i != __e; --__n, ++__i)
822 *__i = __x;
823 if (__i == __e)
824 insert(__e, __n, __x);
825 else
826 erase(__i, __e);
827}
828
829template <class _Tp, class _Alloc>
830inline
831_Alloc
832list<_Tp, _Alloc>::get_allocator() const
833{
834 return allocator_type(base::__node_alloc());
835}
836
837template <class _Tp, class _Alloc>
838typename list<_Tp, _Alloc>::iterator
839list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x)
840{
841 __node_allocator& __na = base::__node_alloc();
842 typedef __allocator_destructor<__node_allocator> _D;
843 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
844 __hold->__prev_ = 0;
845 __node_alloc_traits::construct(__na, addressof(__hold->__value_), __x);
846 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
847 ++base::__sz();
848 return iterator(__hold.release());
849}
850
851template <class _Tp, class _Alloc>
852typename list<_Tp, _Alloc>::iterator
853list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x)
854{
855 iterator __r(const_cast<__node_pointer>(__p.__ptr_));
856 if (__n > 0)
857 {
858 size_type __ds = 0;
859 __node_allocator& __na = base::__node_alloc();
860 typedef __allocator_destructor<__node_allocator> _D;
861 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
862 __hold->__prev_ = 0;
863 __node_alloc_traits::construct(__na, addressof(__hold->__value_), __x);
864 ++__ds;
865 __r = iterator(__hold.get());
866 __hold.release();
867 iterator __e = __r;
868#ifndef _LIBCPP_NO_EXCEPTIONS
869 try
870 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000871#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000872 for (--__n; __n != 0; --__n, ++__e, ++__ds)
873 {
874 __hold.reset(__node_alloc_traits::allocate(__na, 1));
875 __node_alloc_traits::construct(__na, addressof(__hold->__value_), __x);
876 __e.__ptr_->__next_ = __hold.get();
877 __hold->__prev_ = __e.__ptr_;
878 __hold.release();
879 }
880#ifndef _LIBCPP_NO_EXCEPTIONS
881 }
882 catch (...)
883 {
884 while (true)
885 {
886 __node_alloc_traits::destroy(__na, addressof(*__e));
887 __node_pointer __prev = __e.__ptr_->__prev_;
888 __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
889 if (__prev == 0)
890 break;
891 __e = iterator(__prev);
892 }
893 throw;
894 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000895#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000896 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__r.__ptr_, *__e.__ptr_);
897 base::__sz() += __ds;
898 }
899 return __r;
900}
901
902template <class _Tp, class _Alloc>
903template <class _InpIter>
904typename list<_Tp, _Alloc>::iterator
905list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
906 typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
907{
908 iterator __r(const_cast<__node_pointer>(__p.__ptr_));
909 if (__f != __l)
910 {
911 size_type __ds = 0;
912 __node_allocator& __na = base::__node_alloc();
913 typedef __allocator_destructor<__node_allocator> _D;
914 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
915 __hold->__prev_ = 0;
916 __node_alloc_traits::construct(__na, addressof(__hold->__value_), *__f);
917 ++__ds;
918 __r = iterator(__hold.get());
919 __hold.release();
920 iterator __e = __r;
921#ifndef _LIBCPP_NO_EXCEPTIONS
922 try
923 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000924#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000925 for (++__f; __f != __l; ++__f, ++__e, ++__ds)
926 {
927 __hold.reset(__node_alloc_traits::allocate(__na, 1));
928 __node_alloc_traits::construct(__na, addressof(__hold->__value_), *__f);
929 __e.__ptr_->__next_ = __hold.get();
930 __hold->__prev_ = __e.__ptr_;
931 __hold.release();
932 }
933#ifndef _LIBCPP_NO_EXCEPTIONS
934 }
935 catch (...)
936 {
937 while (true)
938 {
939 __node_alloc_traits::destroy(__na, addressof(*__e));
940 __node_pointer __prev = __e.__ptr_->__prev_;
941 __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
942 if (__prev == 0)
943 break;
944 __e = iterator(__prev);
945 }
946 throw;
947 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000948#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000949 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__r.__ptr_, *__e.__ptr_);
950 base::__sz() += __ds;
951 }
952 return __r;
953}
954
955template <class _Tp, class _Alloc>
956void
957list<_Tp, _Alloc>::push_front(const value_type& __x)
958{
959 __node_allocator& __na = base::__node_alloc();
960 typedef __allocator_destructor<__node_allocator> _D;
961 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
962 __node_alloc_traits::construct(__na, addressof(__hold->__value_), __x);
963 __link_nodes(*base::__end_.__next_, *__hold, *__hold);
964 ++base::__sz();
965 __hold.release();
966}
967
968template <class _Tp, class _Alloc>
969void
970list<_Tp, _Alloc>::push_back(const value_type& __x)
971{
972 __node_allocator& __na = base::__node_alloc();
973 typedef __allocator_destructor<__node_allocator> _D;
974 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
975 __node_alloc_traits::construct(__na, addressof(__hold->__value_), __x);
976 __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
977 ++base::__sz();
978 __hold.release();
979}
980
Howard Hinnant73d21a42010-09-04 23:28:19 +0000981#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000982
983template <class _Tp, class _Alloc>
984void
985list<_Tp, _Alloc>::push_front(value_type&& __x)
986{
987 __node_allocator& __na = base::__node_alloc();
988 typedef __allocator_destructor<__node_allocator> _D;
989 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
990 __node_alloc_traits::construct(__na, addressof(__hold->__value_), _STD::move(__x));
991 __link_nodes(*base::__end_.__next_, *__hold, *__hold);
992 ++base::__sz();
993 __hold.release();
994}
995
996template <class _Tp, class _Alloc>
997void
998list<_Tp, _Alloc>::push_back(value_type&& __x)
999{
1000 __node_allocator& __na = base::__node_alloc();
1001 typedef __allocator_destructor<__node_allocator> _D;
1002 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1003 __node_alloc_traits::construct(__na, addressof(__hold->__value_), _STD::move(__x));
1004 __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
1005 ++base::__sz();
1006 __hold.release();
1007}
1008
Howard Hinnant73d21a42010-09-04 23:28:19 +00001009#ifndef _LIBCPP_HAS_NO_VARIADICS
1010
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001011template <class _Tp, class _Alloc>
1012template <class... _Args>
1013void
1014list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1015{
1016 __node_allocator& __na = base::__node_alloc();
1017 typedef __allocator_destructor<__node_allocator> _D;
1018 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1019 __node_alloc_traits::construct(__na, addressof(__hold->__value_), _STD::forward<_Args>(__args)...);
1020 __link_nodes(*base::__end_.__next_, *__hold, *__hold);
1021 ++base::__sz();
1022 __hold.release();
1023}
1024
1025template <class _Tp, class _Alloc>
1026template <class... _Args>
1027void
1028list<_Tp, _Alloc>::emplace_back(_Args&&... __args)
1029{
1030 __node_allocator& __na = base::__node_alloc();
1031 typedef __allocator_destructor<__node_allocator> _D;
1032 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1033 __node_alloc_traits::construct(__na, addressof(__hold->__value_), _STD::forward<_Args>(__args)...);
1034 __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
1035 ++base::__sz();
1036 __hold.release();
1037}
1038
1039template <class _Tp, class _Alloc>
1040template <class... _Args>
1041typename list<_Tp, _Alloc>::iterator
1042list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
1043{
1044 __node_allocator& __na = base::__node_alloc();
1045 typedef __allocator_destructor<__node_allocator> _D;
1046 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1047 __hold->__prev_ = 0;
1048 __node_alloc_traits::construct(__na, addressof(__hold->__value_), _STD::forward<_Args>(__args)...);
1049 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
1050 ++base::__sz();
1051 return iterator(__hold.release());
1052}
1053
Howard Hinnant73d21a42010-09-04 23:28:19 +00001054#endif // _LIBCPP_HAS_NO_VARIADICS
1055
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001056template <class _Tp, class _Alloc>
1057typename list<_Tp, _Alloc>::iterator
1058list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
1059{
1060 __node_allocator& __na = base::__node_alloc();
1061 typedef __allocator_destructor<__node_allocator> _D;
1062 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1063 __hold->__prev_ = 0;
1064 __node_alloc_traits::construct(__na, addressof(__hold->__value_), _STD::move(__x));
1065 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
1066 ++base::__sz();
1067 return iterator(__hold.release());
1068}
1069
Howard Hinnant73d21a42010-09-04 23:28:19 +00001070#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001071
1072template <class _Tp, class _Alloc>
1073void
1074list<_Tp, _Alloc>::pop_front()
1075{
1076 __node_allocator& __na = base::__node_alloc();
1077 __node& __n = *base::__end_.__next_;
1078 base::__unlink_nodes(__n, __n);
1079 --base::__sz();
1080 __node_alloc_traits::destroy(__na, addressof(__n.__value_));
1081 __node_alloc_traits::deallocate(__na, addressof(__n), 1);
1082}
1083
1084template <class _Tp, class _Alloc>
1085void
1086list<_Tp, _Alloc>::pop_back()
1087{
1088 __node_allocator& __na = base::__node_alloc();
1089 __node& __n = *base::__end_.__prev_;
1090 base::__unlink_nodes(__n, __n);
1091 --base::__sz();
1092 __node_alloc_traits::destroy(__na, addressof(__n.__value_));
1093 __node_alloc_traits::deallocate(__na, addressof(__n), 1);
1094}
1095
1096template <class _Tp, class _Alloc>
1097typename list<_Tp, _Alloc>::iterator
1098list<_Tp, _Alloc>::erase(const_iterator __p)
1099{
1100 __node_allocator& __na = base::__node_alloc();
1101 __node& __n = const_cast<__node&>(*__p.__ptr_);
1102 __node_pointer __r = __n.__next_;
1103 base::__unlink_nodes(__n, __n);
1104 --base::__sz();
1105 __node_alloc_traits::destroy(__na, addressof(__n.__value_));
1106 __node_alloc_traits::deallocate(__na, addressof(__n), 1);
1107 return iterator(__r);
1108}
1109
1110template <class _Tp, class _Alloc>
1111typename list<_Tp, _Alloc>::iterator
1112list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
1113{
1114 if (__f != __l)
1115 {
1116 __node_allocator& __na = base::__node_alloc();
1117 base::__unlink_nodes(const_cast<__node&>(*__f.__ptr_), *__l.__ptr_->__prev_);
1118 while (__f != __l)
1119 {
1120 __node& __n = const_cast<__node&>(*__f.__ptr_);
1121 ++__f;
1122 --base::__sz();
1123 __node_alloc_traits::destroy(__na, addressof(__n.__value_));
1124 __node_alloc_traits::deallocate(__na, addressof(__n), 1);
1125 }
1126 }
1127 return iterator(const_cast<__node_pointer>(__l.__ptr_));
1128}
1129
1130template <class _Tp, class _Alloc>
1131void
1132list<_Tp, _Alloc>::resize(size_type __n)
1133{
1134 if (__n < base::__sz())
1135 erase(__iterator(__n), end());
1136 else if (__n > base::__sz())
1137 {
1138 __n -= base::__sz();
1139 size_type __ds = 0;
1140 __node_allocator& __na = base::__node_alloc();
1141 typedef __allocator_destructor<__node_allocator> _D;
1142 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1143 __hold->__prev_ = 0;
1144 __node_alloc_traits::construct(__na, addressof(__hold->__value_));
1145 ++__ds;
1146 iterator __r = iterator(__hold.release());
1147 iterator __e = __r;
1148#ifndef _LIBCPP_NO_EXCEPTIONS
1149 try
1150 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001151#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001152 for (--__n; __n != 0; --__n, ++__e, ++__ds)
1153 {
1154 __hold.reset(__node_alloc_traits::allocate(__na, 1));
1155 __node_alloc_traits::construct(__na, addressof(__hold->__value_));
1156 __e.__ptr_->__next_ = __hold.get();
1157 __hold->__prev_ = __e.__ptr_;
1158 __hold.release();
1159 }
1160#ifndef _LIBCPP_NO_EXCEPTIONS
1161 }
1162 catch (...)
1163 {
1164 while (true)
1165 {
1166 __node_alloc_traits::destroy(__na, addressof(*__e));
1167 __node_pointer __prev = __e.__ptr_->__prev_;
1168 __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
1169 if (__prev == 0)
1170 break;
1171 __e = iterator(__prev);
1172 }
1173 throw;
1174 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001175#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001176 __link_nodes(static_cast<__node&>(base::__end_), *__r.__ptr_, *__e.__ptr_);
1177 base::__sz() += __ds;
1178 }
1179}
1180
1181template <class _Tp, class _Alloc>
1182void
1183list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
1184{
1185 if (__n < base::__sz())
1186 erase(__iterator(__n), end());
1187 else if (__n > base::__sz())
1188 {
1189 __n -= base::__sz();
1190 size_type __ds = 0;
1191 __node_allocator& __na = base::__node_alloc();
1192 typedef __allocator_destructor<__node_allocator> _D;
1193 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1194 __hold->__prev_ = 0;
1195 __node_alloc_traits::construct(__na, addressof(__hold->__value_), __x);
1196 ++__ds;
1197 iterator __r = iterator(__hold.release());
1198 iterator __e = __r;
1199#ifndef _LIBCPP_NO_EXCEPTIONS
1200 try
1201 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001202#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001203 for (--__n; __n != 0; --__n, ++__e, ++__ds)
1204 {
1205 __hold.reset(__node_alloc_traits::allocate(__na, 1));
1206 __node_alloc_traits::construct(__na, addressof(__hold->__value_), __x);
1207 __e.__ptr_->__next_ = __hold.get();
1208 __hold->__prev_ = __e.__ptr_;
1209 __hold.release();
1210 }
1211#ifndef _LIBCPP_NO_EXCEPTIONS
1212 }
1213 catch (...)
1214 {
1215 while (true)
1216 {
1217 __node_alloc_traits::destroy(__na, addressof(*__e));
1218 __node_pointer __prev = __e.__ptr_->__prev_;
1219 __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
1220 if (__prev == 0)
1221 break;
1222 __e = iterator(__prev);
1223 }
1224 throw;
1225 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001226#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001227 __link_nodes(static_cast<__node&>(base::__end_), *__r.__ptr_, *__e.__ptr_);
1228 base::__sz() += __ds;
Howard Hinnant324bb032010-08-22 00:02:43 +00001229 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001230}
1231
1232template <class _Tp, class _Alloc>
1233void
1234list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
1235{
1236 if (!__c.empty())
1237 {
1238 __node& __f = *__c.__end_.__next_;
1239 __node& __l = *__c.__end_.__prev_;
1240 base::__unlink_nodes(__f, __l);
1241 __link_nodes(const_cast<__node&>(*__p.__ptr_), __f, __l);
1242 base::__sz() += __c.__sz();
1243 __c.__sz() = 0;
1244 }
1245}
1246
1247template <class _Tp, class _Alloc>
1248void
1249list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
1250{
1251 if (__p != __i && __p != next(__i))
1252 {
1253 __node& __f = const_cast<__node&>(*__i.__ptr_);
1254 base::__unlink_nodes(__f, __f);
1255 __link_nodes(const_cast<__node&>(*__p.__ptr_), __f, __f);
1256 --__c.__sz();
1257 ++base::__sz();
1258 }
1259}
1260
1261template <class _Tp, class _Alloc>
1262void
1263list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l)
1264{
1265 if (__f != __l)
1266 {
1267 if (this != &__c)
1268 {
1269 size_type __s = _STD::distance(__f, __l);
1270 __c.__sz() -= __s;
1271 base::__sz() += __s;
1272 }
1273 __node& __first = const_cast<__node&>(*__f.__ptr_);
1274 --__l;
1275 __node& __last = const_cast<__node&>(*__l.__ptr_);
1276 base::__unlink_nodes(__first, __last);
1277 __link_nodes(const_cast<__node&>(*__p.__ptr_), __first, __last);
1278 }
1279}
1280
1281template <class _Tp, class _Alloc>
1282void
1283list<_Tp, _Alloc>::remove(const value_type& __x)
1284{
1285 for (iterator __i = begin(), __e = end(); __i != __e;)
1286 {
1287 if (*__i == __x)
1288 {
1289 iterator __j = next(__i);
1290 for (; __j != __e && *__j == __x; ++__j)
1291 ;
1292 __i = erase(__i, __j);
1293 }
1294 else
1295 ++__i;
1296 }
1297}
1298
1299template <class _Tp, class _Alloc>
1300template <class _Pred>
1301void
1302list<_Tp, _Alloc>::remove_if(_Pred __pred)
1303{
1304 for (iterator __i = begin(), __e = end(); __i != __e;)
1305 {
1306 if (__pred(*__i))
1307 {
1308 iterator __j = next(__i);
1309 for (; __j != __e && __pred(*__j); ++__j)
1310 ;
1311 __i = erase(__i, __j);
1312 }
1313 else
1314 ++__i;
1315 }
1316}
1317
1318template <class _Tp, class _Alloc>
1319inline
1320void
1321list<_Tp, _Alloc>::unique()
1322{
1323 unique(__equal_to<value_type>());
1324}
1325
1326template <class _Tp, class _Alloc>
1327template <class _BinaryPred>
1328void
1329list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred)
1330{
1331 for (iterator __i = begin(), __e = end(); __i != __e;)
1332 {
1333 iterator __j = next(__i);
1334 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1335 ;
1336 if (++__i != __j)
1337 __i = erase(__i, __j);
1338 }
1339}
1340
1341template <class _Tp, class _Alloc>
1342inline
1343void
1344list<_Tp, _Alloc>::merge(list& __c)
1345{
1346 merge(__c, __less<value_type>());
1347}
1348
1349template <class _Tp, class _Alloc>
1350template <class _Comp>
1351void
1352list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
1353{
1354 if (this != &__c)
1355 {
1356 iterator __f1 = begin();
1357 iterator __e1 = end();
1358 iterator __f2 = __c.begin();
1359 iterator __e2 = __c.end();
1360 while (__f1 != __e1 && __f2 != __e2)
1361 {
1362 if (__comp(*__f2, *__f1))
1363 {
1364 size_type __ds = 1;
1365 iterator __m2 = next(__f2);
1366 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2, ++__ds)
1367 ;
1368 base::__sz() += __ds;
1369 __c.__sz() -= __ds;
1370 __node& __f = *__f2.__ptr_;
1371 __node& __l = *__m2.__ptr_->__prev_;
1372 __f2 = __m2;
1373 base::__unlink_nodes(__f, __l);
1374 __m2 = next(__f1);
1375 __link_nodes(*__f1.__ptr_, __f, __l);
1376 __f1 = __m2;
1377 }
1378 else
1379 ++__f1;
1380 }
1381 splice(__e1, __c);
1382 }
1383}
1384
1385template <class _Tp, class _Alloc>
1386inline
1387void
1388list<_Tp, _Alloc>::sort()
1389{
1390 sort(__less<value_type>());
1391}
1392
1393template <class _Tp, class _Alloc>
1394template <class _Comp>
1395inline
1396void
1397list<_Tp, _Alloc>::sort(_Comp __comp)
1398{
1399 __sort(begin(), end(), base::__sz(), __comp);
1400}
1401
1402template <class _Tp, class _Alloc>
1403template <class _Comp>
1404inline
1405typename list<_Tp, _Alloc>::iterator
1406list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp)
1407{
1408 switch (__n)
1409 {
1410 case 0:
1411 case 1:
1412 return __f1;
1413 case 2:
1414 if (__comp(*--__e2, *__f1))
1415 {
1416 __node& __f = *__e2.__ptr_;
1417 base::__unlink_nodes(__f, __f);
1418 __link_nodes(*__f1.__ptr_, __f, __f);
1419 return __e2;
1420 }
1421 return __f1;
1422 }
1423 size_type __n2 = __n / 2;
1424 iterator __e1 = next(__f1, __n2);
1425 iterator __r = __f1 = __sort(__f1, __e1, __n2, __comp);
1426 iterator __f2 = __e1 = __sort(__e1, __e2, __n - __n2, __comp);
1427 if (__comp(*__f2, *__f1))
1428 {
1429 iterator __m2 = next(__f2);
1430 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
1431 ;
1432 __node& __f = *__f2.__ptr_;
1433 __node& __l = *__m2.__ptr_->__prev_;
1434 __r = __f2;
1435 __e1 = __f2 = __m2;
1436 base::__unlink_nodes(__f, __l);
1437 __m2 = next(__f1);
1438 __link_nodes(*__f1.__ptr_, __f, __l);
1439 __f1 = __m2;
1440 }
1441 else
1442 ++__f1;
1443 while (__f1 != __e1 && __f2 != __e2)
1444 {
1445 if (__comp(*__f2, *__f1))
1446 {
1447 iterator __m2 = next(__f2);
1448 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
1449 ;
1450 __node& __f = *__f2.__ptr_;
1451 __node& __l = *__m2.__ptr_->__prev_;
1452 if (__e1 == __f2)
1453 __e1 = __m2;
1454 __f2 = __m2;
1455 base::__unlink_nodes(__f, __l);
1456 __m2 = next(__f1);
1457 __link_nodes(*__f1.__ptr_, __f, __l);
1458 __f1 = __m2;
1459 }
1460 else
1461 ++__f1;
1462 }
1463 return __r;
1464}
1465
1466template <class _Tp, class _Alloc>
1467void
1468list<_Tp, _Alloc>::reverse()
1469{
1470 if (base::__sz() > 1)
1471 {
1472 iterator __e = end();
1473 for (iterator __i = begin(); __i != __e; --__i)
1474 _STD::swap(__i.__ptr_->__prev_, __i.__ptr_->__next_);
1475 _STD::swap(__e.__ptr_->__prev_, __e.__ptr_->__next_);
1476 }
1477}
1478
1479template <class _Tp, class _Alloc>
1480inline
1481bool
1482operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1483{
1484 return __x.size() == __y.size() && _STD::equal(__x.begin(), __x.end(), __y.begin());
1485}
1486
1487template <class _Tp, class _Alloc>
1488inline
1489bool
1490operator< (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1491{
1492 return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1493}
1494
1495template <class _Tp, class _Alloc>
1496inline
1497bool
1498operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1499{
1500 return !(__x == __y);
1501}
1502
1503template <class _Tp, class _Alloc>
1504inline
1505bool
1506operator> (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1507{
1508 return __y < __x;
1509}
1510
1511template <class _Tp, class _Alloc>
1512inline
1513bool
1514operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1515{
1516 return !(__x < __y);
1517}
1518
1519template <class _Tp, class _Alloc>
1520inline
1521bool
1522operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1523{
1524 return !(__y < __x);
1525}
1526
1527template <class _Tp, class _Alloc>
1528inline
1529void
1530swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
1531{
1532 __x.swap(__y);
1533}
1534
1535_LIBCPP_END_NAMESPACE_STD
1536
1537#endif // _LIBCPP_LIST