blob: 9d8fc726abf5000af93c96c60a4e8972af86c649 [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//
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_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
Howard Hinnantc5607272011-06-03 17:30:28 +000039 list()
40 noexcept(is_nothrow_default_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000041 explicit list(const allocator_type& a);
42 explicit list(size_type n);
43 list(size_type n, const value_type& value);
44 list(size_type n, const value_type& value, const allocator_type& a);
45 template <class Iter>
46 list(Iter first, Iter last);
47 template <class Iter>
48 list(Iter first, Iter last, const allocator_type& a);
49 list(const list& x);
50 list(const list&, const allocator_type& a);
Howard Hinnantc5607272011-06-03 17:30:28 +000051 list(list&& x)
52 noexcept(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000053 list(list&&, const allocator_type& a);
54 list(initializer_list<value_type>);
55 list(initializer_list<value_type>, const allocator_type& a);
56
57 ~list();
58
59 list& operator=(const list& x);
Howard Hinnantc5607272011-06-03 17:30:28 +000060 list& operator=(list&& x)
61 noexcept(
62 allocator_type::propagate_on_container_move_assignment::value &&
63 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000064 list& operator=(initializer_list<value_type>);
65 template <class Iter>
66 void assign(Iter first, Iter last);
67 void assign(size_type n, const value_type& t);
68 void assign(initializer_list<value_type>);
69
Howard Hinnantc5607272011-06-03 17:30:28 +000070 allocator_type get_allocator() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071
Howard Hinnantc5607272011-06-03 17:30:28 +000072 iterator begin() noexcept;
73 const_iterator begin() const noexcept;
74 iterator end() noexcept;
75 const_iterator end() const noexcept;
76 reverse_iterator rbegin() noexcept;
77 const_reverse_iterator rbegin() const noexcept;
78 reverse_iterator rend() noexcept;
79 const_reverse_iterator rend() const noexcept;
80 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 reference front();
86 const_reference front() const;
87 reference back();
88 const_reference back() const;
89
Howard Hinnantc5607272011-06-03 17:30:28 +000090 bool empty() const noexcept;
91 size_type size() const noexcept;
92 size_type max_size() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000093
94 template <class... Args>
95 void emplace_front(Args&&... args);
96 void pop_front();
97 template <class... Args>
98 void emplace_back(Args&&... args);
99 void pop_back();
100 void push_front(const value_type& x);
101 void push_front(value_type&& x);
102 void push_back(const value_type& x);
103 void push_back(value_type&& x);
104 template <class... Args>
105 iterator emplace(const_iterator position, Args&&... args);
106 iterator insert(const_iterator position, const value_type& x);
107 iterator insert(const_iterator position, value_type&& x);
108 iterator insert(const_iterator position, size_type n, const value_type& x);
109 template <class Iter>
110 iterator insert(const_iterator position, Iter first, Iter last);
111 iterator insert(const_iterator position, initializer_list<value_type> il);
112
113 iterator erase(const_iterator position);
114 iterator erase(const_iterator position, const_iterator last);
115
116 void resize(size_type sz);
117 void resize(size_type sz, const value_type& c);
118
Howard Hinnantc5607272011-06-03 17:30:28 +0000119 void swap(list&)
120 noexcept(!allocator_type::propagate_on_container_swap::value ||
121 __is_nothrow_swappable<allocator_type>::value);
122 void clear() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000123
124 void splice(const_iterator position, list& x);
125 void splice(const_iterator position, list&& x);
126 void splice(const_iterator position, list& x, const_iterator i);
127 void splice(const_iterator position, list&& x, const_iterator i);
128 void splice(const_iterator position, list& x, const_iterator first,
129 const_iterator last);
130 void splice(const_iterator position, list&& x, const_iterator first,
131 const_iterator last);
132
133 void remove(const value_type& value);
134 template <class Pred> void remove_if(Pred pred);
135 void unique();
136 template <class BinaryPredicate>
137 void unique(BinaryPredicate binary_pred);
138 void merge(list& x);
139 void merge(list&& x);
140 template <class Compare>
141 void merge(list& x, Compare comp);
142 template <class Compare>
143 void merge(list&& x, Compare comp);
144 void sort();
145 template <class Compare>
146 void sort(Compare comp);
Howard Hinnantc5607272011-06-03 17:30:28 +0000147 void reverse() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000148};
149
150template <class T, class Alloc>
151 bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y);
152template <class T, class Alloc>
153 bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y);
154template <class T, class Alloc>
155 bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y);
156template <class T, class Alloc>
157 bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y);
158template <class T, class Alloc>
159 bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y);
160template <class T, class Alloc>
161 bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y);
162
163template <class T, class Alloc>
Howard Hinnantc5607272011-06-03 17:30:28 +0000164 void swap(list<T,Alloc>& x, list<T,Alloc>& y)
165 noexcept(noexcept(x.swap(y)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000166
167} // std
168
169*/
170
171#include <__config>
172
173#include <memory>
174#include <limits>
175#include <initializer_list>
176#include <iterator>
177#include <algorithm>
178
179#pragma GCC system_header
180
181_LIBCPP_BEGIN_NAMESPACE_STD
182
183template <class, class> struct __list_node;
184
185template <class _Tp, class _VoidPtr>
186struct __list_node_base
187{
188 typedef typename pointer_traits<_VoidPtr>::template
189#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
190 rebind<__list_node<_Tp, _VoidPtr> > pointer;
191#else
192 rebind<__list_node<_Tp, _VoidPtr> >::other pointer;
193#endif
194
195 pointer __prev_;
196 pointer __next_;
197
Howard Hinnant82894812010-09-22 16:48:34 +0000198 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000199 __list_node_base()
200 : __prev_(static_cast<pointer>(this)),
201 __next_(static_cast<pointer>(this))
202 {}
203};
204
205template <class _Tp, class _VoidPtr>
206struct __list_node
207 : public __list_node_base<_Tp, _VoidPtr>
208{
209 _Tp __value_;
210};
211
212template <class, class> class list;
213template <class, class> class __list_imp;
214template <class, class> class __list_const_iterator;
215
216template <class _Tp, class _VoidPtr>
Howard Hinnant82894812010-09-22 16:48:34 +0000217class _LIBCPP_VISIBLE __list_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000218{
219 typedef typename pointer_traits<_VoidPtr>::template
220#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
221 rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;
222#else
223 rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;
224#endif
225
226 __node_pointer __ptr_;
227
Howard Hinnant82894812010-09-22 16:48:34 +0000228 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000229 explicit __list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000230
231 template<class, class> friend class list;
232 template<class, class> friend class __list_imp;
233 template<class, class> friend class __list_const_iterator;
234public:
235 typedef bidirectional_iterator_tag iterator_category;
236 typedef _Tp value_type;
237 typedef value_type& reference;
238 typedef typename pointer_traits<_VoidPtr>::template
239#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
240 rebind<value_type>
241#else
242 rebind<value_type>::other
243#endif
244 pointer;
245 typedef typename pointer_traits<pointer>::difference_type difference_type;
246
Howard Hinnant82894812010-09-22 16:48:34 +0000247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000248 __list_iterator() _NOEXCEPT {}
Howard Hinnant211f0ee2011-01-28 23:46:28 +0000249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000250 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000252 pointer operator->() const {return &(operator*());}
253
Howard Hinnant82894812010-09-22 16:48:34 +0000254 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000255 __list_iterator& operator++() {__ptr_ = __ptr_->__next_; return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000257 __list_iterator operator++(int) {__list_iterator __t(*this); ++(*this); return __t;}
258
Howard Hinnant82894812010-09-22 16:48:34 +0000259 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000260 __list_iterator& operator--() {__ptr_ = __ptr_->__prev_; return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000261 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000262 __list_iterator operator--(int) {__list_iterator __t(*this); --(*this); return __t;}
263
Howard Hinnant82894812010-09-22 16:48:34 +0000264 friend _LIBCPP_INLINE_VISIBILITY
265 bool operator==(const __list_iterator& __x, const __list_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000266 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000267 friend _LIBCPP_INLINE_VISIBILITY
268 bool operator!=(const __list_iterator& __x, const __list_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000269 {return !(__x == __y);}
270};
271
272template <class _Tp, class _VoidPtr>
Howard Hinnant82894812010-09-22 16:48:34 +0000273class _LIBCPP_VISIBLE __list_const_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000274{
275 typedef typename pointer_traits<_VoidPtr>::template
276#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
277 rebind<const __list_node<_Tp, _VoidPtr> > __node_pointer;
278#else
279 rebind<const __list_node<_Tp, _VoidPtr> >::other __node_pointer;
280#endif
281
282 __node_pointer __ptr_;
283
Howard Hinnant82894812010-09-22 16:48:34 +0000284 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000285 explicit __list_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000286
287 template<class, class> friend class list;
288 template<class, class> friend class __list_imp;
289public:
290 typedef bidirectional_iterator_tag iterator_category;
291 typedef _Tp value_type;
292 typedef const value_type& reference;
293 typedef typename pointer_traits<_VoidPtr>::template
294#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
295 rebind<const value_type>
296#else
297 rebind<const value_type>::other
298#endif
299 pointer;
300 typedef typename pointer_traits<pointer>::difference_type difference_type;
301
Howard Hinnant82894812010-09-22 16:48:34 +0000302 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000303 __list_const_iterator() _NOEXCEPT {}
Howard Hinnant211f0ee2011-01-28 23:46:28 +0000304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000305 __list_const_iterator(__list_iterator<_Tp, _VoidPtr> __p) _NOEXCEPT
306 : __ptr_(__p.__ptr_) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000307
Howard Hinnant82894812010-09-22 16:48:34 +0000308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000309 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000311 pointer operator->() const {return &(operator*());}
312
Howard Hinnant82894812010-09-22 16:48:34 +0000313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000314 __list_const_iterator& operator++() {__ptr_ = __ptr_->__next_; return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000316 __list_const_iterator operator++(int) {__list_const_iterator __t(*this); ++(*this); return __t;}
317
Howard Hinnant82894812010-09-22 16:48:34 +0000318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000319 __list_const_iterator& operator--() {__ptr_ = __ptr_->__prev_; return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000320 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000321 __list_const_iterator operator--(int) {__list_const_iterator __t(*this); --(*this); return __t;}
322
Howard Hinnant82894812010-09-22 16:48:34 +0000323 friend _LIBCPP_INLINE_VISIBILITY
324 bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000325 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000326 friend _LIBCPP_INLINE_VISIBILITY
327 bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000328 {return !(__x == __y);}
329};
330
331template <class _Tp, class _Alloc>
332class __list_imp
333{
334 __list_imp(const __list_imp&);
335 __list_imp& operator=(const __list_imp&);
336protected:
337 typedef _Tp value_type;
338 typedef _Alloc allocator_type;
339 typedef allocator_traits<allocator_type> __alloc_traits;
340 typedef typename __alloc_traits::size_type size_type;
341 typedef typename __alloc_traits::void_pointer __void_pointer;
342 typedef __list_iterator<value_type, __void_pointer> iterator;
343 typedef __list_const_iterator<value_type, __void_pointer> const_iterator;
344 typedef __list_node_base<value_type, __void_pointer> __node_base;
345 typedef __list_node<value_type, __void_pointer> __node;
346 typedef typename __alloc_traits::template
347#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
348 rebind_alloc<__node>
349#else
350 rebind_alloc<__node>::other
351#endif
352 __node_allocator;
353 typedef allocator_traits<__node_allocator> __node_alloc_traits;
354 typedef typename __node_alloc_traits::pointer __node_pointer;
355 typedef typename __node_alloc_traits::const_pointer __node_const_pointer;
356 typedef typename __alloc_traits::pointer pointer;
357 typedef typename __alloc_traits::const_pointer const_pointer;
358 typedef typename __alloc_traits::difference_type difference_type;
359
360 __node_base __end_;
361 __compressed_pair<size_type, __node_allocator> __size_alloc_;
362
Howard Hinnant82894812010-09-22 16:48:34 +0000363 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000364 size_type& __sz() _NOEXCEPT {return __size_alloc_.first();}
Howard Hinnant82894812010-09-22 16:48:34 +0000365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000366 const size_type& __sz() const _NOEXCEPT
367 {return __size_alloc_.first();}
Howard Hinnant82894812010-09-22 16:48:34 +0000368 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000369 __node_allocator& __node_alloc() _NOEXCEPT
370 {return __size_alloc_.second();}
Howard Hinnant82894812010-09-22 16:48:34 +0000371 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000372 const __node_allocator& __node_alloc() const _NOEXCEPT
373 {return __size_alloc_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000374
Howard Hinnantc5607272011-06-03 17:30:28 +0000375 static void __unlink_nodes(__node_base& __f, __node_base& __l) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000376
Howard Hinnantc5607272011-06-03 17:30:28 +0000377 __list_imp()
378 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000379 __list_imp(const allocator_type& __a);
380 ~__list_imp();
Howard Hinnantc5607272011-06-03 17:30:28 +0000381 void clear() _NOEXCEPT;
Howard Hinnant82894812010-09-22 16:48:34 +0000382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000383 bool empty() const _NOEXCEPT {return __sz() == 0;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000384
Howard Hinnant82894812010-09-22 16:48:34 +0000385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000386 iterator begin() _NOEXCEPT
387 {return iterator(__end_.__next_);}
Howard Hinnant82894812010-09-22 16:48:34 +0000388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000389 const_iterator begin() const _NOEXCEPT
390 {return const_iterator(__end_.__next_);}
Howard Hinnant82894812010-09-22 16:48:34 +0000391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000392 iterator end() _NOEXCEPT
393 {return iterator(static_cast<__node_pointer> (&__end_));}
Howard Hinnant82894812010-09-22 16:48:34 +0000394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000395 const_iterator end() const _NOEXCEPT
396 {return const_iterator(static_cast<__node_const_pointer>(&__end_));}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000397
Howard Hinnantc5607272011-06-03 17:30:28 +0000398 void swap(__list_imp& __c)
399 _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
400 __is_nothrow_swappable<__node_allocator>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000401
Howard Hinnant82894812010-09-22 16:48:34 +0000402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403 void __copy_assign_alloc(const __list_imp& __c)
404 {__copy_assign_alloc(__c, integral_constant<bool,
405 __node_alloc_traits::propagate_on_container_copy_assignment::value>());}
406
Howard Hinnant82894812010-09-22 16:48:34 +0000407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000408 void __move_assign_alloc(__list_imp& __c)
Howard Hinnantc5607272011-06-03 17:30:28 +0000409 _NOEXCEPT_(
410 !__node_alloc_traits::propagate_on_container_move_assignment::value ||
411 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000412 {__move_assign_alloc(__c, integral_constant<bool,
413 __node_alloc_traits::propagate_on_container_move_assignment::value>());}
414
415private:
Howard Hinnant82894812010-09-22 16:48:34 +0000416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000417 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
Howard Hinnantc5607272011-06-03 17:30:28 +0000418 _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
419 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000420 {__swap_alloc(__x, __y, integral_constant<bool,
421 __node_alloc_traits::propagate_on_container_swap::value>());}
Howard Hinnant82894812010-09-22 16:48:34 +0000422 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000423 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
Howard Hinnantc5607272011-06-03 17:30:28 +0000424 _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000425 {
426 using _STD::swap;
427 swap(__x, __y);
428 }
Howard Hinnant82894812010-09-22 16:48:34 +0000429 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000430 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
Howard Hinnantc5607272011-06-03 17:30:28 +0000431 _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000432 {}
433
Howard Hinnant82894812010-09-22 16:48:34 +0000434 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000435 void __copy_assign_alloc(const __list_imp& __c, true_type)
436 {
437 if (__node_alloc() != __c.__node_alloc())
438 clear();
439 __node_alloc() = __c.__node_alloc();
440 }
441
Howard Hinnant82894812010-09-22 16:48:34 +0000442 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000443 void __copy_assign_alloc(const __list_imp& __c, false_type)
444 {}
445
Howard Hinnant82894812010-09-22 16:48:34 +0000446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000447 void __move_assign_alloc(const __list_imp& __c, true_type)
Howard Hinnantc5607272011-06-03 17:30:28 +0000448 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000449 {
450 __node_alloc() = _STD::move(__c.__node_alloc());
451 }
452
Howard Hinnant82894812010-09-22 16:48:34 +0000453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000454 void __move_assign_alloc(const __list_imp& __c, false_type)
Howard Hinnantc5607272011-06-03 17:30:28 +0000455 _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000456 {}
457};
458
459// Unlink nodes [__f, __l]
460template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000461inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000462void
463__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_base& __f, __node_base& __l)
Howard Hinnantc5607272011-06-03 17:30:28 +0000464 _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000465{
466 __f.__prev_->__next_ = __l.__next_;
467 __l.__next_->__prev_ = __f.__prev_;
468}
469
470template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000471inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000472__list_imp<_Tp, _Alloc>::__list_imp()
Howard Hinnantc5607272011-06-03 17:30:28 +0000473 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000474 : __size_alloc_(0)
475{
476}
477
478template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000479inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000480__list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a)
481 : __size_alloc_(0, __node_allocator(__a))
482{
483}
484
485template <class _Tp, class _Alloc>
486__list_imp<_Tp, _Alloc>::~__list_imp()
487{
488 clear();
489}
490
491template <class _Tp, class _Alloc>
492void
Howard Hinnantc5607272011-06-03 17:30:28 +0000493__list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000494{
495 if (!empty())
496 {
497 __node_allocator& __na = __node_alloc();
498 iterator __f = begin();
499 iterator __l = end();
500 __unlink_nodes(*__f.__ptr_, *__l.__ptr_->__prev_);
501 __sz() = 0;
502 while (__f != __l)
503 {
504 __node& __n = *__f.__ptr_;
505 ++__f;
Howard Hinnant2529d022011-02-02 17:36:20 +0000506 __node_alloc_traits::destroy(__na, _STD::addressof(__n.__value_));
507 __node_alloc_traits::deallocate(__na, _STD::addressof(__n), 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000508 }
509 }
510}
511
512template <class _Tp, class _Alloc>
513void
514__list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
Howard Hinnantc5607272011-06-03 17:30:28 +0000515 _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
516 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000517{
518 using _STD::swap;
519 __swap_alloc(__node_alloc(), __c.__node_alloc());
520 swap(__sz(), __c.__sz());
521 swap(__end_, __c.__end_);
522 if (__sz() == 0)
523 __end_.__next_ = __end_.__prev_ = &static_cast<__node&>(__end_);
524 else
525 __end_.__prev_->__next_ = __end_.__next_->__prev_
526 = &static_cast<__node&>(__end_);
527 if (__c.__sz() == 0)
528 __c.__end_.__next_ = __c.__end_.__prev_
529 = &static_cast<__node&>(__c.__end_);
530 else
531 __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_
532 = &static_cast<__node&>(__c.__end_);
533}
534
535template <class _Tp, class _Alloc = allocator<_Tp> >
Howard Hinnant82894812010-09-22 16:48:34 +0000536class _LIBCPP_VISIBLE list
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000537 : private __list_imp<_Tp, _Alloc>
538{
539 typedef __list_imp<_Tp, _Alloc> base;
540 typedef typename base::__node __node;
541 typedef typename base::__node_allocator __node_allocator;
542 typedef typename base::__node_pointer __node_pointer;
543 typedef typename base::__node_alloc_traits __node_alloc_traits;
544
545public:
546 typedef _Tp value_type;
547 typedef _Alloc allocator_type;
548 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
549 "Invalid allocator::value_type");
550 typedef value_type& reference;
551 typedef const value_type& const_reference;
552 typedef typename base::pointer pointer;
553 typedef typename base::const_pointer const_pointer;
554 typedef typename base::size_type size_type;
555 typedef typename base::difference_type difference_type;
556 typedef typename base::iterator iterator;
557 typedef typename base::const_iterator const_iterator;
558 typedef _STD::reverse_iterator<iterator> reverse_iterator;
559 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
560
Howard Hinnant82894812010-09-22 16:48:34 +0000561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000562 list()
563 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
564 {}
Howard Hinnant82894812010-09-22 16:48:34 +0000565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000566 list(const allocator_type& __a) : base(__a) {}
567 list(size_type __n);
568 list(size_type __n, const value_type& __x);
569 list(size_type __n, const value_type& __x, const allocator_type& __a);
570 template <class _InpIter>
571 list(_InpIter __f, _InpIter __l,
572 typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
573 template <class _InpIter>
574 list(_InpIter __f, _InpIter __l, const allocator_type& __a,
575 typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
576
577 list(const list& __c);
578 list(const list& __c, const allocator_type& __a);
579 list& operator=(const list& __c);
580 list(initializer_list<value_type> __il);
581 list(initializer_list<value_type> __il, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000582#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc5607272011-06-03 17:30:28 +0000583 list(list&& __c)
584 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000585 list(list&& __c, const allocator_type& __a);
Howard Hinnantc5607272011-06-03 17:30:28 +0000586 list& operator=(list&& __c)
587 _NOEXCEPT_(
588 __node_alloc_traits::propagate_on_container_move_assignment::value &&
589 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000590#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant82894812010-09-22 16:48:34 +0000591 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000592 list& operator=(initializer_list<value_type> __il)
593 {assign(__il.begin(), __il.end()); return *this;}
594
595 template <class _InpIter>
596 void assign(_InpIter __f, _InpIter __l,
597 typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
598 void assign(size_type __n, const value_type& __x);
Howard Hinnant82894812010-09-22 16:48:34 +0000599 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000600 void assign(initializer_list<value_type> __il)
601 {assign(__il.begin(), __il.end());}
602
Howard Hinnantc5607272011-06-03 17:30:28 +0000603 allocator_type get_allocator() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000604
Howard Hinnant82894812010-09-22 16:48:34 +0000605 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000606 size_type size() const _NOEXCEPT {return base::__sz();}
Howard Hinnant82894812010-09-22 16:48:34 +0000607 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000608 bool empty() const _NOEXCEPT {return base::empty();}
Howard Hinnant82894812010-09-22 16:48:34 +0000609 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000610 size_type max_size() const _NOEXCEPT
611 {return numeric_limits<difference_type>::max();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000612
Howard Hinnant82894812010-09-22 16:48:34 +0000613 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000614 iterator begin() _NOEXCEPT {return base::begin();}
Howard Hinnant82894812010-09-22 16:48:34 +0000615 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000616 const_iterator begin() const _NOEXCEPT {return base::begin();}
Howard Hinnant82894812010-09-22 16:48:34 +0000617 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000618 iterator end() _NOEXCEPT {return base::end();}
Howard Hinnant82894812010-09-22 16:48:34 +0000619 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000620 const_iterator end() const _NOEXCEPT {return base::end();}
Howard Hinnant82894812010-09-22 16:48:34 +0000621 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000622 const_iterator cbegin() const _NOEXCEPT {return base::begin();}
Howard Hinnant82894812010-09-22 16:48:34 +0000623 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000624 const_iterator cend() const _NOEXCEPT {return base::end();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000625
Howard Hinnant82894812010-09-22 16:48:34 +0000626 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000627 reverse_iterator rbegin() _NOEXCEPT
628 {return reverse_iterator(end());}
Howard Hinnant82894812010-09-22 16:48:34 +0000629 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000630 const_reverse_iterator rbegin() const _NOEXCEPT
631 {return const_reverse_iterator(end());}
Howard Hinnant82894812010-09-22 16:48:34 +0000632 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000633 reverse_iterator rend() _NOEXCEPT
634 {return reverse_iterator(begin());}
Howard Hinnant82894812010-09-22 16:48:34 +0000635 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000636 const_reverse_iterator rend() const _NOEXCEPT
637 {return const_reverse_iterator(begin());}
Howard Hinnant82894812010-09-22 16:48:34 +0000638 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000639 const_reverse_iterator crbegin() const _NOEXCEPT
640 {return const_reverse_iterator(end());}
Howard Hinnant82894812010-09-22 16:48:34 +0000641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000642 const_reverse_iterator crend() const _NOEXCEPT
643 {return const_reverse_iterator(begin());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000644
Howard Hinnant82894812010-09-22 16:48:34 +0000645 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000646 reference front() {return base::__end_.__next_->__value_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000647 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000648 const_reference front() const {return base::__end_.__next_->__value_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000649 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000650 reference back() {return base::__end_.__prev_->__value_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000651 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000652 const_reference back() const {return base::__end_.__prev_->__value_;}
653
Howard Hinnant73d21a42010-09-04 23:28:19 +0000654#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000655 void push_front(value_type&& __x);
656 void push_back(value_type&& __x);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000657#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000658 template <class... _Args>
659 void emplace_front(_Args&&... __args);
660 template <class... _Args>
661 void emplace_back(_Args&&... __args);
662 template <class... _Args>
663 iterator emplace(const_iterator __p, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000664#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000665 iterator insert(const_iterator __p, value_type&& __x);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000666#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000667
668 void push_front(const value_type& __x);
669 void push_back(const value_type& __x);
670
671 iterator insert(const_iterator __p, const value_type& __x);
672 iterator insert(const_iterator __p, size_type __n, const value_type& __x);
673 template <class _InpIter>
674 iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,
675 typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
Howard Hinnant82894812010-09-22 16:48:34 +0000676 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000677 iterator insert(const_iterator __p, initializer_list<value_type> __il)
678 {return insert(__p, __il.begin(), __il.end());}
679
Howard Hinnant82894812010-09-22 16:48:34 +0000680 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000681 void swap(list& __c)
682 _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
683 __is_nothrow_swappable<__node_allocator>::value)
684 {base::swap(__c);}
Howard Hinnant82894812010-09-22 16:48:34 +0000685 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc5607272011-06-03 17:30:28 +0000686 void clear() _NOEXCEPT {base::clear();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000687
688 void pop_front();
689 void pop_back();
690
691 iterator erase(const_iterator __p);
692 iterator erase(const_iterator __f, const_iterator __l);
693
694 void resize(size_type __n);
695 void resize(size_type __n, const value_type& __x);
696
697 void splice(const_iterator __p, list& __c);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000698#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant82894812010-09-22 16:48:34 +0000699 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000700 void splice(const_iterator __p, list&& __c) {splice(__p, __c);}
701#endif
702 void splice(const_iterator __p, list& __c, const_iterator __i);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000703#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant82894812010-09-22 16:48:34 +0000704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000705 void splice(const_iterator __p, list&& __c, const_iterator __i)
706 {splice(__p, __c, __i);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000707#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000708 void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000709#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant82894812010-09-22 16:48:34 +0000710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000711 void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l)
712 {splice(__p, __c, __f, __l);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000713#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000714
715 void remove(const value_type& __x);
716 template <class _Pred> void remove_if(_Pred __pred);
717 void unique();
718 template <class _BinaryPred>
719 void unique(_BinaryPred __binary_pred);
720 void merge(list& __c);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000721#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant82894812010-09-22 16:48:34 +0000722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000723 void merge(list&& __c) {merge(__c);}
724#endif
725 template <class _Comp>
726 void merge(list& __c, _Comp __comp);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000727#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000728 template <class _Comp>
Howard Hinnant82894812010-09-22 16:48:34 +0000729 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000730 void merge(list&& __c, _Comp __comp) {merge(__c, __comp);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000731#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000732 void sort();
733 template <class _Comp>
734 void sort(_Comp __comp);
735
Howard Hinnantc5607272011-06-03 17:30:28 +0000736 void reverse() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000737
738private:
739 static void __link_nodes(__node& __p, __node& __f, __node& __l);
740 iterator __iterator(size_type __n);
741 template <class _Comp>
742 static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
743
Howard Hinnantc5607272011-06-03 17:30:28 +0000744 void __move_assign(list& __c, true_type)
745 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000746 void __move_assign(list& __c, false_type);
747};
748
749// Link in nodes [__f, __l] just prior to __p
750template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000751inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000752void
753list<_Tp, _Alloc>::__link_nodes(__node& __p, __node& __f, __node& __l)
754{
755 __p.__prev_->__next_ = &__f;
756 __f.__prev_ = __p.__prev_;
757 __p.__prev_ = &__l;
758 __l.__next_ = &__p;
759}
760
761template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000762inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000763typename list<_Tp, _Alloc>::iterator
764list<_Tp, _Alloc>::__iterator(size_type __n)
765{
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +0000766 return __n <= base::__sz() / 2 ? _STD::next(begin(), __n)
767 : _STD::prev(end(), base::__sz() - __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000768}
769
770template <class _Tp, class _Alloc>
771list<_Tp, _Alloc>::list(size_type __n)
772{
773 for (; __n > 0; --__n)
Howard Hinnant73d21a42010-09-04 23:28:19 +0000774#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000775 emplace_back();
776#else
777 push_back(value_type());
778#endif
779}
780
781template <class _Tp, class _Alloc>
782list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
783{
784 for (; __n > 0; --__n)
785 push_back(__x);
786}
787
788template <class _Tp, class _Alloc>
789list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a)
790 : base(__a)
791{
792 for (; __n > 0; --__n)
793 push_back(__x);
794}
795
796template <class _Tp, class _Alloc>
797template <class _InpIter>
798list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
799 typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
800{
801 for (; __f != __l; ++__f)
802 push_back(*__f);
803}
804
805template <class _Tp, class _Alloc>
806template <class _InpIter>
807list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,
808 typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
809 : base(__a)
810{
811 for (; __f != __l; ++__f)
812 push_back(*__f);
813}
814
815template <class _Tp, class _Alloc>
816list<_Tp, _Alloc>::list(const list& __c)
817 : base(allocator_type(
818 __node_alloc_traits::select_on_container_copy_construction(
819 __c.__node_alloc())))
820{
821 for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
822 push_back(*__i);
823}
824
825template <class _Tp, class _Alloc>
826list<_Tp, _Alloc>::list(const list& __c, const allocator_type& __a)
827 : base(__a)
828{
829 for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
830 push_back(*__i);
831}
832
833template <class _Tp, class _Alloc>
834list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a)
835 : base(__a)
836{
837 for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
838 __e = __il.end(); __i != __e; ++__i)
839 push_back(*__i);
840}
841
842template <class _Tp, class _Alloc>
843list<_Tp, _Alloc>::list(initializer_list<value_type> __il)
844{
845 for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
846 __e = __il.end(); __i != __e; ++__i)
847 push_back(*__i);
848}
849
850template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000851inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000852list<_Tp, _Alloc>&
853list<_Tp, _Alloc>::operator=(const list& __c)
854{
855 if (this != &__c)
856 {
857 base::__copy_assign_alloc(__c);
858 assign(__c.begin(), __c.end());
859 }
860 return *this;
861}
862
Howard Hinnant73d21a42010-09-04 23:28:19 +0000863#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000864
865template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000866inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000867list<_Tp, _Alloc>::list(list&& __c)
Howard Hinnantc5607272011-06-03 17:30:28 +0000868 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000869 : base(allocator_type(_STD::move(__c.__node_alloc())))
870{
871 splice(end(), __c);
872}
873
874template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000875inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000876list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a)
877 : base(__a)
878{
879 if (__a == __c.get_allocator())
880 splice(end(), __c);
881 else
882 {
883 typedef move_iterator<iterator> _I;
884 assign(_I(__c.begin()), _I(__c.end()));
885 }
886}
887
888template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000889inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000890list<_Tp, _Alloc>&
891list<_Tp, _Alloc>::operator=(list&& __c)
Howard Hinnantc5607272011-06-03 17:30:28 +0000892 _NOEXCEPT_(
893 __node_alloc_traits::propagate_on_container_move_assignment::value &&
894 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000895{
896 __move_assign(__c, integral_constant<bool,
897 __node_alloc_traits::propagate_on_container_move_assignment::value>());
898 return *this;
899}
900
901template <class _Tp, class _Alloc>
902void
903list<_Tp, _Alloc>::__move_assign(list& __c, false_type)
904{
905 if (base::__node_alloc() != __c.__node_alloc())
906 {
907 typedef move_iterator<iterator> _I;
908 assign(_I(__c.begin()), _I(__c.end()));
909 }
910 else
911 __move_assign(__c, true_type());
912}
913
914template <class _Tp, class _Alloc>
915void
916list<_Tp, _Alloc>::__move_assign(list& __c, true_type)
Howard Hinnantc5607272011-06-03 17:30:28 +0000917 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000918{
919 clear();
920 base::__move_assign_alloc(__c);
921 splice(end(), __c);
922}
923
Howard Hinnant73d21a42010-09-04 23:28:19 +0000924#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000925
926template <class _Tp, class _Alloc>
927template <class _InpIter>
928void
929list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l,
930 typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
931{
932 iterator __i = begin();
933 iterator __e = end();
934 for (; __f != __l && __i != __e; ++__f, ++__i)
935 *__i = *__f;
936 if (__i == __e)
937 insert(__e, __f, __l);
938 else
939 erase(__i, __e);
940}
941
942template <class _Tp, class _Alloc>
943void
944list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x)
945{
946 iterator __i = begin();
947 iterator __e = end();
948 for (; __n > 0 && __i != __e; --__n, ++__i)
949 *__i = __x;
950 if (__i == __e)
951 insert(__e, __n, __x);
952 else
953 erase(__i, __e);
954}
955
956template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +0000957inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000958_Alloc
Howard Hinnantc5607272011-06-03 17:30:28 +0000959list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000960{
961 return allocator_type(base::__node_alloc());
962}
963
964template <class _Tp, class _Alloc>
965typename list<_Tp, _Alloc>::iterator
966list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x)
967{
968 __node_allocator& __na = base::__node_alloc();
969 typedef __allocator_destructor<__node_allocator> _D;
970 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
971 __hold->__prev_ = 0;
Howard Hinnant2529d022011-02-02 17:36:20 +0000972 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), __x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000973 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
974 ++base::__sz();
975 return iterator(__hold.release());
976}
977
978template <class _Tp, class _Alloc>
979typename list<_Tp, _Alloc>::iterator
980list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x)
981{
982 iterator __r(const_cast<__node_pointer>(__p.__ptr_));
983 if (__n > 0)
984 {
985 size_type __ds = 0;
986 __node_allocator& __na = base::__node_alloc();
987 typedef __allocator_destructor<__node_allocator> _D;
988 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
989 __hold->__prev_ = 0;
Howard Hinnant2529d022011-02-02 17:36:20 +0000990 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), __x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000991 ++__ds;
992 __r = iterator(__hold.get());
993 __hold.release();
994 iterator __e = __r;
995#ifndef _LIBCPP_NO_EXCEPTIONS
996 try
997 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000998#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000999 for (--__n; __n != 0; --__n, ++__e, ++__ds)
1000 {
1001 __hold.reset(__node_alloc_traits::allocate(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001002 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), __x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001003 __e.__ptr_->__next_ = __hold.get();
1004 __hold->__prev_ = __e.__ptr_;
1005 __hold.release();
1006 }
1007#ifndef _LIBCPP_NO_EXCEPTIONS
1008 }
1009 catch (...)
1010 {
1011 while (true)
1012 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001013 __node_alloc_traits::destroy(__na, _STD::addressof(*__e));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001014 __node_pointer __prev = __e.__ptr_->__prev_;
1015 __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
1016 if (__prev == 0)
1017 break;
1018 __e = iterator(__prev);
1019 }
1020 throw;
1021 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001022#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001023 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__r.__ptr_, *__e.__ptr_);
1024 base::__sz() += __ds;
1025 }
1026 return __r;
1027}
1028
1029template <class _Tp, class _Alloc>
1030template <class _InpIter>
1031typename list<_Tp, _Alloc>::iterator
1032list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
1033 typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
1034{
1035 iterator __r(const_cast<__node_pointer>(__p.__ptr_));
1036 if (__f != __l)
1037 {
1038 size_type __ds = 0;
1039 __node_allocator& __na = base::__node_alloc();
1040 typedef __allocator_destructor<__node_allocator> _D;
1041 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1042 __hold->__prev_ = 0;
Howard Hinnant2529d022011-02-02 17:36:20 +00001043 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), *__f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001044 ++__ds;
1045 __r = iterator(__hold.get());
1046 __hold.release();
1047 iterator __e = __r;
1048#ifndef _LIBCPP_NO_EXCEPTIONS
1049 try
1050 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001051#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001052 for (++__f; __f != __l; ++__f, ++__e, ++__ds)
1053 {
1054 __hold.reset(__node_alloc_traits::allocate(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001055 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), *__f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001056 __e.__ptr_->__next_ = __hold.get();
1057 __hold->__prev_ = __e.__ptr_;
1058 __hold.release();
1059 }
1060#ifndef _LIBCPP_NO_EXCEPTIONS
1061 }
1062 catch (...)
1063 {
1064 while (true)
1065 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001066 __node_alloc_traits::destroy(__na, _STD::addressof(*__e));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001067 __node_pointer __prev = __e.__ptr_->__prev_;
1068 __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
1069 if (__prev == 0)
1070 break;
1071 __e = iterator(__prev);
1072 }
1073 throw;
1074 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001075#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001076 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__r.__ptr_, *__e.__ptr_);
1077 base::__sz() += __ds;
1078 }
1079 return __r;
1080}
1081
1082template <class _Tp, class _Alloc>
1083void
1084list<_Tp, _Alloc>::push_front(const value_type& __x)
1085{
1086 __node_allocator& __na = base::__node_alloc();
1087 typedef __allocator_destructor<__node_allocator> _D;
1088 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001089 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), __x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001090 __link_nodes(*base::__end_.__next_, *__hold, *__hold);
1091 ++base::__sz();
1092 __hold.release();
1093}
1094
1095template <class _Tp, class _Alloc>
1096void
1097list<_Tp, _Alloc>::push_back(const value_type& __x)
1098{
1099 __node_allocator& __na = base::__node_alloc();
1100 typedef __allocator_destructor<__node_allocator> _D;
1101 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001102 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), __x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001103 __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
1104 ++base::__sz();
1105 __hold.release();
1106}
1107
Howard Hinnant73d21a42010-09-04 23:28:19 +00001108#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001109
1110template <class _Tp, class _Alloc>
1111void
1112list<_Tp, _Alloc>::push_front(value_type&& __x)
1113{
1114 __node_allocator& __na = base::__node_alloc();
1115 typedef __allocator_destructor<__node_allocator> _D;
1116 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001117 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), _STD::move(__x));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001118 __link_nodes(*base::__end_.__next_, *__hold, *__hold);
1119 ++base::__sz();
1120 __hold.release();
1121}
1122
1123template <class _Tp, class _Alloc>
1124void
1125list<_Tp, _Alloc>::push_back(value_type&& __x)
1126{
1127 __node_allocator& __na = base::__node_alloc();
1128 typedef __allocator_destructor<__node_allocator> _D;
1129 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001130 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), _STD::move(__x));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001131 __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
1132 ++base::__sz();
1133 __hold.release();
1134}
1135
Howard Hinnant73d21a42010-09-04 23:28:19 +00001136#ifndef _LIBCPP_HAS_NO_VARIADICS
1137
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001138template <class _Tp, class _Alloc>
1139template <class... _Args>
1140void
1141list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1142{
1143 __node_allocator& __na = base::__node_alloc();
1144 typedef __allocator_destructor<__node_allocator> _D;
1145 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001146 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001147 __link_nodes(*base::__end_.__next_, *__hold, *__hold);
1148 ++base::__sz();
1149 __hold.release();
1150}
1151
1152template <class _Tp, class _Alloc>
1153template <class... _Args>
1154void
1155list<_Tp, _Alloc>::emplace_back(_Args&&... __args)
1156{
1157 __node_allocator& __na = base::__node_alloc();
1158 typedef __allocator_destructor<__node_allocator> _D;
1159 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001160 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001161 __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
1162 ++base::__sz();
1163 __hold.release();
1164}
1165
1166template <class _Tp, class _Alloc>
1167template <class... _Args>
1168typename list<_Tp, _Alloc>::iterator
1169list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
1170{
1171 __node_allocator& __na = base::__node_alloc();
1172 typedef __allocator_destructor<__node_allocator> _D;
1173 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1174 __hold->__prev_ = 0;
Howard Hinnant2529d022011-02-02 17:36:20 +00001175 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001176 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
1177 ++base::__sz();
1178 return iterator(__hold.release());
1179}
1180
Howard Hinnant73d21a42010-09-04 23:28:19 +00001181#endif // _LIBCPP_HAS_NO_VARIADICS
1182
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001183template <class _Tp, class _Alloc>
1184typename list<_Tp, _Alloc>::iterator
1185list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
1186{
1187 __node_allocator& __na = base::__node_alloc();
1188 typedef __allocator_destructor<__node_allocator> _D;
1189 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1190 __hold->__prev_ = 0;
Howard Hinnant2529d022011-02-02 17:36:20 +00001191 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), _STD::move(__x));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001192 __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
1193 ++base::__sz();
1194 return iterator(__hold.release());
1195}
1196
Howard Hinnant73d21a42010-09-04 23:28:19 +00001197#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001198
1199template <class _Tp, class _Alloc>
1200void
1201list<_Tp, _Alloc>::pop_front()
1202{
1203 __node_allocator& __na = base::__node_alloc();
1204 __node& __n = *base::__end_.__next_;
1205 base::__unlink_nodes(__n, __n);
1206 --base::__sz();
Howard Hinnant2529d022011-02-02 17:36:20 +00001207 __node_alloc_traits::destroy(__na, _STD::addressof(__n.__value_));
1208 __node_alloc_traits::deallocate(__na, _STD::addressof(__n), 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001209}
1210
1211template <class _Tp, class _Alloc>
1212void
1213list<_Tp, _Alloc>::pop_back()
1214{
1215 __node_allocator& __na = base::__node_alloc();
1216 __node& __n = *base::__end_.__prev_;
1217 base::__unlink_nodes(__n, __n);
1218 --base::__sz();
Howard Hinnant2529d022011-02-02 17:36:20 +00001219 __node_alloc_traits::destroy(__na, _STD::addressof(__n.__value_));
1220 __node_alloc_traits::deallocate(__na, _STD::addressof(__n), 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001221}
1222
1223template <class _Tp, class _Alloc>
1224typename list<_Tp, _Alloc>::iterator
1225list<_Tp, _Alloc>::erase(const_iterator __p)
1226{
1227 __node_allocator& __na = base::__node_alloc();
1228 __node& __n = const_cast<__node&>(*__p.__ptr_);
1229 __node_pointer __r = __n.__next_;
1230 base::__unlink_nodes(__n, __n);
1231 --base::__sz();
Howard Hinnant2529d022011-02-02 17:36:20 +00001232 __node_alloc_traits::destroy(__na, _STD::addressof(__n.__value_));
1233 __node_alloc_traits::deallocate(__na, _STD::addressof(__n), 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001234 return iterator(__r);
1235}
1236
1237template <class _Tp, class _Alloc>
1238typename list<_Tp, _Alloc>::iterator
1239list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
1240{
1241 if (__f != __l)
1242 {
1243 __node_allocator& __na = base::__node_alloc();
1244 base::__unlink_nodes(const_cast<__node&>(*__f.__ptr_), *__l.__ptr_->__prev_);
1245 while (__f != __l)
1246 {
1247 __node& __n = const_cast<__node&>(*__f.__ptr_);
1248 ++__f;
1249 --base::__sz();
Howard Hinnant2529d022011-02-02 17:36:20 +00001250 __node_alloc_traits::destroy(__na, _STD::addressof(__n.__value_));
1251 __node_alloc_traits::deallocate(__na, _STD::addressof(__n), 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001252 }
1253 }
1254 return iterator(const_cast<__node_pointer>(__l.__ptr_));
1255}
1256
1257template <class _Tp, class _Alloc>
1258void
1259list<_Tp, _Alloc>::resize(size_type __n)
1260{
1261 if (__n < base::__sz())
1262 erase(__iterator(__n), end());
1263 else if (__n > base::__sz())
1264 {
1265 __n -= base::__sz();
1266 size_type __ds = 0;
1267 __node_allocator& __na = base::__node_alloc();
1268 typedef __allocator_destructor<__node_allocator> _D;
1269 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1270 __hold->__prev_ = 0;
Howard Hinnant2529d022011-02-02 17:36:20 +00001271 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001272 ++__ds;
1273 iterator __r = iterator(__hold.release());
1274 iterator __e = __r;
1275#ifndef _LIBCPP_NO_EXCEPTIONS
1276 try
1277 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001278#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001279 for (--__n; __n != 0; --__n, ++__e, ++__ds)
1280 {
1281 __hold.reset(__node_alloc_traits::allocate(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001282 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001283 __e.__ptr_->__next_ = __hold.get();
1284 __hold->__prev_ = __e.__ptr_;
1285 __hold.release();
1286 }
1287#ifndef _LIBCPP_NO_EXCEPTIONS
1288 }
1289 catch (...)
1290 {
1291 while (true)
1292 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001293 __node_alloc_traits::destroy(__na, _STD::addressof(*__e));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001294 __node_pointer __prev = __e.__ptr_->__prev_;
1295 __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
1296 if (__prev == 0)
1297 break;
1298 __e = iterator(__prev);
1299 }
1300 throw;
1301 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001302#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001303 __link_nodes(static_cast<__node&>(base::__end_), *__r.__ptr_, *__e.__ptr_);
1304 base::__sz() += __ds;
1305 }
1306}
1307
1308template <class _Tp, class _Alloc>
1309void
1310list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
1311{
1312 if (__n < base::__sz())
1313 erase(__iterator(__n), end());
1314 else if (__n > base::__sz())
1315 {
1316 __n -= base::__sz();
1317 size_type __ds = 0;
1318 __node_allocator& __na = base::__node_alloc();
1319 typedef __allocator_destructor<__node_allocator> _D;
1320 unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1));
1321 __hold->__prev_ = 0;
Howard Hinnant2529d022011-02-02 17:36:20 +00001322 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), __x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001323 ++__ds;
1324 iterator __r = iterator(__hold.release());
1325 iterator __e = __r;
1326#ifndef _LIBCPP_NO_EXCEPTIONS
1327 try
1328 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001329#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001330 for (--__n; __n != 0; --__n, ++__e, ++__ds)
1331 {
1332 __hold.reset(__node_alloc_traits::allocate(__na, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001333 __node_alloc_traits::construct(__na, _STD::addressof(__hold->__value_), __x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001334 __e.__ptr_->__next_ = __hold.get();
1335 __hold->__prev_ = __e.__ptr_;
1336 __hold.release();
1337 }
1338#ifndef _LIBCPP_NO_EXCEPTIONS
1339 }
1340 catch (...)
1341 {
1342 while (true)
1343 {
Howard Hinnant2529d022011-02-02 17:36:20 +00001344 __node_alloc_traits::destroy(__na, _STD::addressof(*__e));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001345 __node_pointer __prev = __e.__ptr_->__prev_;
1346 __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
1347 if (__prev == 0)
1348 break;
1349 __e = iterator(__prev);
1350 }
1351 throw;
1352 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001353#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001354 __link_nodes(static_cast<__node&>(base::__end_), *__r.__ptr_, *__e.__ptr_);
1355 base::__sz() += __ds;
Howard Hinnant324bb032010-08-22 00:02:43 +00001356 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001357}
1358
1359template <class _Tp, class _Alloc>
1360void
1361list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
1362{
1363 if (!__c.empty())
1364 {
1365 __node& __f = *__c.__end_.__next_;
1366 __node& __l = *__c.__end_.__prev_;
1367 base::__unlink_nodes(__f, __l);
1368 __link_nodes(const_cast<__node&>(*__p.__ptr_), __f, __l);
1369 base::__sz() += __c.__sz();
1370 __c.__sz() = 0;
1371 }
1372}
1373
1374template <class _Tp, class _Alloc>
1375void
1376list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
1377{
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001378 if (__p != __i && __p != _STD::next(__i))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001379 {
1380 __node& __f = const_cast<__node&>(*__i.__ptr_);
1381 base::__unlink_nodes(__f, __f);
1382 __link_nodes(const_cast<__node&>(*__p.__ptr_), __f, __f);
1383 --__c.__sz();
1384 ++base::__sz();
1385 }
1386}
1387
1388template <class _Tp, class _Alloc>
1389void
1390list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l)
1391{
1392 if (__f != __l)
1393 {
1394 if (this != &__c)
1395 {
1396 size_type __s = _STD::distance(__f, __l);
1397 __c.__sz() -= __s;
1398 base::__sz() += __s;
1399 }
1400 __node& __first = const_cast<__node&>(*__f.__ptr_);
1401 --__l;
1402 __node& __last = const_cast<__node&>(*__l.__ptr_);
1403 base::__unlink_nodes(__first, __last);
1404 __link_nodes(const_cast<__node&>(*__p.__ptr_), __first, __last);
1405 }
1406}
1407
1408template <class _Tp, class _Alloc>
1409void
1410list<_Tp, _Alloc>::remove(const value_type& __x)
1411{
1412 for (iterator __i = begin(), __e = end(); __i != __e;)
1413 {
1414 if (*__i == __x)
1415 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001416 iterator __j = _STD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001417 for (; __j != __e && *__j == __x; ++__j)
1418 ;
1419 __i = erase(__i, __j);
1420 }
1421 else
1422 ++__i;
1423 }
1424}
1425
1426template <class _Tp, class _Alloc>
1427template <class _Pred>
1428void
1429list<_Tp, _Alloc>::remove_if(_Pred __pred)
1430{
1431 for (iterator __i = begin(), __e = end(); __i != __e;)
1432 {
1433 if (__pred(*__i))
1434 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001435 iterator __j = _STD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001436 for (; __j != __e && __pred(*__j); ++__j)
1437 ;
1438 __i = erase(__i, __j);
1439 }
1440 else
1441 ++__i;
1442 }
1443}
1444
1445template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001446inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001447void
1448list<_Tp, _Alloc>::unique()
1449{
1450 unique(__equal_to<value_type>());
1451}
1452
1453template <class _Tp, class _Alloc>
1454template <class _BinaryPred>
1455void
1456list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred)
1457{
1458 for (iterator __i = begin(), __e = end(); __i != __e;)
1459 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001460 iterator __j = _STD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001461 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1462 ;
1463 if (++__i != __j)
1464 __i = erase(__i, __j);
1465 }
1466}
1467
1468template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001469inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001470void
1471list<_Tp, _Alloc>::merge(list& __c)
1472{
1473 merge(__c, __less<value_type>());
1474}
1475
1476template <class _Tp, class _Alloc>
1477template <class _Comp>
1478void
1479list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
1480{
1481 if (this != &__c)
1482 {
1483 iterator __f1 = begin();
1484 iterator __e1 = end();
1485 iterator __f2 = __c.begin();
1486 iterator __e2 = __c.end();
1487 while (__f1 != __e1 && __f2 != __e2)
1488 {
1489 if (__comp(*__f2, *__f1))
1490 {
1491 size_type __ds = 1;
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001492 iterator __m2 = _STD::next(__f2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001493 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2, ++__ds)
1494 ;
1495 base::__sz() += __ds;
1496 __c.__sz() -= __ds;
1497 __node& __f = *__f2.__ptr_;
1498 __node& __l = *__m2.__ptr_->__prev_;
1499 __f2 = __m2;
1500 base::__unlink_nodes(__f, __l);
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001501 __m2 = _STD::next(__f1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001502 __link_nodes(*__f1.__ptr_, __f, __l);
1503 __f1 = __m2;
1504 }
1505 else
1506 ++__f1;
1507 }
1508 splice(__e1, __c);
1509 }
1510}
1511
1512template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001513inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001514void
1515list<_Tp, _Alloc>::sort()
1516{
1517 sort(__less<value_type>());
1518}
1519
1520template <class _Tp, class _Alloc>
1521template <class _Comp>
Howard Hinnant82894812010-09-22 16:48:34 +00001522inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001523void
1524list<_Tp, _Alloc>::sort(_Comp __comp)
1525{
1526 __sort(begin(), end(), base::__sz(), __comp);
1527}
1528
1529template <class _Tp, class _Alloc>
1530template <class _Comp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001531typename list<_Tp, _Alloc>::iterator
1532list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp)
1533{
1534 switch (__n)
1535 {
1536 case 0:
1537 case 1:
1538 return __f1;
1539 case 2:
1540 if (__comp(*--__e2, *__f1))
1541 {
1542 __node& __f = *__e2.__ptr_;
1543 base::__unlink_nodes(__f, __f);
1544 __link_nodes(*__f1.__ptr_, __f, __f);
1545 return __e2;
1546 }
1547 return __f1;
1548 }
1549 size_type __n2 = __n / 2;
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001550 iterator __e1 = _STD::next(__f1, __n2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001551 iterator __r = __f1 = __sort(__f1, __e1, __n2, __comp);
1552 iterator __f2 = __e1 = __sort(__e1, __e2, __n - __n2, __comp);
1553 if (__comp(*__f2, *__f1))
1554 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001555 iterator __m2 = _STD::next(__f2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001556 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
1557 ;
1558 __node& __f = *__f2.__ptr_;
1559 __node& __l = *__m2.__ptr_->__prev_;
1560 __r = __f2;
1561 __e1 = __f2 = __m2;
1562 base::__unlink_nodes(__f, __l);
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001563 __m2 = _STD::next(__f1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001564 __link_nodes(*__f1.__ptr_, __f, __l);
1565 __f1 = __m2;
1566 }
1567 else
1568 ++__f1;
1569 while (__f1 != __e1 && __f2 != __e2)
1570 {
1571 if (__comp(*__f2, *__f1))
1572 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001573 iterator __m2 = _STD::next(__f2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001574 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
1575 ;
1576 __node& __f = *__f2.__ptr_;
1577 __node& __l = *__m2.__ptr_->__prev_;
1578 if (__e1 == __f2)
1579 __e1 = __m2;
1580 __f2 = __m2;
1581 base::__unlink_nodes(__f, __l);
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001582 __m2 = _STD::next(__f1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001583 __link_nodes(*__f1.__ptr_, __f, __l);
1584 __f1 = __m2;
1585 }
1586 else
1587 ++__f1;
1588 }
1589 return __r;
1590}
1591
1592template <class _Tp, class _Alloc>
1593void
Howard Hinnantc5607272011-06-03 17:30:28 +00001594list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001595{
1596 if (base::__sz() > 1)
1597 {
1598 iterator __e = end();
1599 for (iterator __i = begin(); __i != __e; --__i)
1600 _STD::swap(__i.__ptr_->__prev_, __i.__ptr_->__next_);
1601 _STD::swap(__e.__ptr_->__prev_, __e.__ptr_->__next_);
1602 }
1603}
1604
1605template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001606inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001607bool
1608operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1609{
1610 return __x.size() == __y.size() && _STD::equal(__x.begin(), __x.end(), __y.begin());
1611}
1612
1613template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001614inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001615bool
1616operator< (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1617{
1618 return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1619}
1620
1621template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001622inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001623bool
1624operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1625{
1626 return !(__x == __y);
1627}
1628
1629template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001630inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001631bool
1632operator> (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1633{
1634 return __y < __x;
1635}
1636
1637template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001638inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001639bool
1640operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1641{
1642 return !(__x < __y);
1643}
1644
1645template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001646inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001647bool
1648operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1649{
1650 return !(__y < __x);
1651}
1652
1653template <class _Tp, class _Alloc>
Howard Hinnant82894812010-09-22 16:48:34 +00001654inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001655void
1656swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
Howard Hinnantc5607272011-06-03 17:30:28 +00001657 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001658{
1659 __x.swap(__y);
1660}
1661
1662_LIBCPP_END_NAMESPACE_STD
1663
1664#endif // _LIBCPP_LIST