30 #ifndef _FORWARD_LIST_H
31 #define _FORWARD_LIST_H 1
33 #pragma GCC system_header
36 #if __cplusplus >= 201103L
42 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
49 struct _Fwd_list_node_base
51 _Fwd_list_node_base() =
default;
53 _Fwd_list_node_base* _M_next =
nullptr;
56 _M_transfer_after(_Fwd_list_node_base* __begin,
57 _Fwd_list_node_base* __end)
59 _Fwd_list_node_base* __keep = __begin->_M_next;
62 __begin->_M_next = __end->_M_next;
63 __end->_M_next = _M_next;
72 _M_reverse_after() noexcept
74 _Fwd_list_node_base* __tail = _M_next;
77 while (_Fwd_list_node_base* __temp = __tail->_M_next)
79 _Fwd_list_node_base* __keep = _M_next;
81 __tail->_M_next = __temp->_M_next;
82 _M_next->_M_next = __keep;
93 template<
typename _Tp>
95 :
public _Fwd_list_node_base
97 _Fwd_list_node() =
default;
99 typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
105 return static_cast<_Tp*
>(
static_cast<void*
>(&_M_storage));
109 _M_valptr()
const noexcept
111 return static_cast<const _Tp*
>(
static_cast<const void*
>(&_M_storage));
120 template<
typename _Tp>
121 struct _Fwd_list_iterator
123 typedef _Fwd_list_iterator<_Tp> _Self;
124 typedef _Fwd_list_node<_Tp> _Node;
126 typedef _Tp value_type;
127 typedef _Tp* pointer;
128 typedef _Tp& reference;
130 typedef std::forward_iterator_tag iterator_category;
136 _Fwd_list_iterator(_Fwd_list_node_base* __n)
141 {
return *
static_cast<_Node*
>(this->_M_node)->_M_valptr(); }
145 {
return static_cast<_Node*
>(this->_M_node)->_M_valptr(); }
150 _M_node = _M_node->_M_next;
158 _M_node = _M_node->_M_next;
164 {
return _M_node == __x._M_node; }
168 {
return _M_node != __x._M_node; }
174 return _Fwd_list_iterator(_M_node->_M_next);
176 return _Fwd_list_iterator(0);
179 _Fwd_list_node_base* _M_node;
187 template<
typename _Tp>
188 struct _Fwd_list_const_iterator
190 typedef _Fwd_list_const_iterator<_Tp> _Self;
191 typedef const _Fwd_list_node<_Tp> _Node;
192 typedef _Fwd_list_iterator<_Tp> iterator;
194 typedef _Tp value_type;
195 typedef const _Tp* pointer;
196 typedef const _Tp& reference;
198 typedef std::forward_iterator_tag iterator_category;
200 _Fwd_list_const_iterator()
204 _Fwd_list_const_iterator(
const _Fwd_list_node_base* __n)
207 _Fwd_list_const_iterator(
const iterator& __iter)
208 : _M_node(__iter._M_node) { }
212 {
return *
static_cast<_Node*
>(this->_M_node)->_M_valptr(); }
216 {
return static_cast<_Node*
>(this->_M_node)->_M_valptr(); }
221 _M_node = _M_node->_M_next;
229 _M_node = _M_node->_M_next;
235 {
return _M_node == __x._M_node; }
239 {
return _M_node != __x._M_node; }
245 return _Fwd_list_const_iterator(_M_node->_M_next);
247 return _Fwd_list_const_iterator(0);
250 const _Fwd_list_node_base* _M_node;
256 template<
typename _Tp>
258 operator==(
const _Fwd_list_iterator<_Tp>& __x,
259 const _Fwd_list_const_iterator<_Tp>& __y)
260 {
return __x._M_node == __y._M_node; }
265 template<
typename _Tp>
267 operator!=(
const _Fwd_list_iterator<_Tp>& __x,
268 const _Fwd_list_const_iterator<_Tp>& __y)
269 {
return __x._M_node != __y._M_node; }
274 template<
typename _Tp,
typename _Alloc>
275 struct _Fwd_list_base
278 typedef typename __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits;
279 typedef typename _Alloc_traits::template rebind<_Tp>::other
282 typedef typename _Alloc_traits::template
283 rebind<_Fwd_list_node<_Tp>>::other _Node_alloc_type;
285 typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
287 struct _Fwd_list_impl
288 :
public _Node_alloc_type
290 _Fwd_list_node_base _M_head;
293 : _Node_alloc_type(), _M_head()
296 _Fwd_list_impl(
const _Node_alloc_type& __a)
297 : _Node_alloc_type(__a), _M_head()
300 _Fwd_list_impl(_Node_alloc_type&& __a)
301 : _Node_alloc_type(std::move(__a)), _M_head()
305 _Fwd_list_impl _M_impl;
308 typedef _Fwd_list_iterator<_Tp> iterator;
309 typedef _Fwd_list_const_iterator<_Tp> const_iterator;
310 typedef _Fwd_list_node<_Tp> _Node;
313 _M_get_Node_allocator() noexcept
314 {
return *
static_cast<_Node_alloc_type*
>(&this->_M_impl); }
316 const _Node_alloc_type&
317 _M_get_Node_allocator()
const noexcept
318 {
return *
static_cast<const _Node_alloc_type*
>(&this->_M_impl); }
323 _Fwd_list_base(
const _Node_alloc_type& __a)
326 _Fwd_list_base(_Fwd_list_base&& __lst,
const _Node_alloc_type& __a);
328 _Fwd_list_base(_Fwd_list_base&& __lst)
329 : _M_impl(std::move(__lst._M_get_Node_allocator()))
331 this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
332 __lst._M_impl._M_head._M_next = 0;
336 { _M_erase_after(&_M_impl._M_head, 0); }
342 {
return _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1); }
344 template<
typename... _Args>
346 _M_create_node(_Args&&... __args)
348 _Node* __node = this->_M_get_node();
351 _Tp_alloc_type __a(_M_get_Node_allocator());
352 typedef allocator_traits<_Tp_alloc_type> _Alloc_traits;
353 ::new ((
void*)__node) _Node();
354 _Alloc_traits::construct(__a, __node->_M_valptr(),
355 std::forward<_Args>(__args)...);
359 this->_M_put_node(__node);
365 template<
typename... _Args>
367 _M_insert_after(const_iterator __pos, _Args&&... __args);
370 _M_put_node(_Node* __p)
371 { _Node_alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
374 _M_erase_after(_Fwd_list_node_base* __pos);
377 _M_erase_after(_Fwd_list_node_base* __pos,
378 _Fwd_list_node_base* __last);
407 template<
typename _Tp,
typename _Alloc = allocator<_Tp> >
408 class forward_list :
private _Fwd_list_base<_Tp, _Alloc>
411 typedef _Fwd_list_base<_Tp, _Alloc> _Base;
412 typedef _Fwd_list_node<_Tp> _Node;
413 typedef _Fwd_list_node_base _Node_base;
414 typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
415 typedef typename _Base::_Node_alloc_type _Node_alloc_type;
416 typedef typename _Base::_Node_alloc_traits _Node_alloc_traits;
417 typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
421 typedef _Tp value_type;
422 typedef typename _Alloc_traits::pointer pointer;
423 typedef typename _Alloc_traits::const_pointer const_pointer;
424 typedef typename _Alloc_traits::reference reference;
425 typedef typename _Alloc_traits::const_reference const_reference;
427 typedef _Fwd_list_iterator<_Tp> iterator;
428 typedef _Fwd_list_const_iterator<_Tp> const_iterator;
431 typedef _Alloc allocator_type;
440 forward_list(
const _Alloc& __al = _Alloc())
441 : _Base(_Node_alloc_type(__al))
449 forward_list(
const forward_list& __list,
const _Alloc& __al)
450 : _Base(_Node_alloc_type(__al))
451 { _M_range_initialize(__list.begin(), __list.end()); }
458 forward_list(forward_list&& __list,
const _Alloc& __al)
459 noexcept(_Node_alloc_traits::_S_always_equal())
460 : _Base(std::move(__list), _Node_alloc_type(__al))
471 forward_list(size_type __n,
const _Alloc& __al = _Alloc())
472 : _Base(_Node_alloc_type(__al))
473 { _M_default_initialize(__n); }
484 forward_list(size_type __n,
const _Tp& __value,
485 const _Alloc& __al = _Alloc())
486 : _Base(_Node_alloc_type(__al))
487 { _M_fill_initialize(__n, __value); }
499 template<
typename _InputIterator,
500 typename = std::_RequireInputIter<_InputIterator>>
501 forward_list(_InputIterator __first, _InputIterator __last,
502 const _Alloc& __al = _Alloc())
503 : _Base(_Node_alloc_type(__al))
504 { _M_range_initialize(__first, __last); }
511 forward_list(
const forward_list& __list)
512 : _Base(_Node_alloc_traits::_S_select_on_copy(
513 __list._M_get_Node_allocator()))
514 { _M_range_initialize(__list.begin(), __list.end()); }
525 forward_list(forward_list&& __list) noexcept
526 : _Base(std::move(__list)) { }
536 forward_list(std::initializer_list<_Tp> __il,
537 const _Alloc& __al = _Alloc())
538 : _Base(_Node_alloc_type(__al))
539 { _M_range_initialize(__il.begin(), __il.end()); }
544 ~forward_list() noexcept
556 operator=(
const forward_list& __list);
568 operator=(forward_list&& __list)
569 noexcept(_Node_alloc_traits::_S_nothrow_move())
571 constexpr
bool __move_storage =
572 _Node_alloc_traits::_S_propagate_on_move_assign()
573 || _Node_alloc_traits::_S_always_equal();
574 _M_move_assign(std::move(__list),
575 integral_constant<bool, __move_storage>());
588 operator=(std::initializer_list<_Tp> __il)
606 template<
typename _InputIterator,
607 typename = std::_RequireInputIter<_InputIterator>>
609 assign(_InputIterator __first, _InputIterator __last)
611 typedef is_assignable<_Tp, decltype(*__first)> __assignable;
612 _M_assign(__first, __last, __assignable());
626 assign(size_type __n,
const _Tp& __val)
627 { _M_assign_n(__n, __val, is_copy_assignable<_Tp>()); }
638 assign(std::initializer_list<_Tp> __il)
639 { assign(__il.begin(), __il.end()); }
643 get_allocator()
const noexcept
644 {
return allocator_type(this->_M_get_Node_allocator()); }
653 before_begin() noexcept
654 {
return iterator(&this->_M_impl._M_head); }
662 before_begin()
const noexcept
663 {
return const_iterator(&this->_M_impl._M_head); }
671 {
return iterator(this->_M_impl._M_head._M_next); }
679 begin()
const noexcept
680 {
return const_iterator(this->_M_impl._M_head._M_next); }
689 {
return iterator(0); }
698 {
return const_iterator(0); }
706 cbegin()
const noexcept
707 {
return const_iterator(this->_M_impl._M_head._M_next); }
715 cbefore_begin()
const noexcept
716 {
return const_iterator(&this->_M_impl._M_head); }
724 cend()
const noexcept
725 {
return const_iterator(0); }
732 empty()
const noexcept
733 {
return this->_M_impl._M_head._M_next == 0; }
739 max_size()
const noexcept
740 {
return _Node_alloc_traits::max_size(this->_M_get_Node_allocator()); }
751 _Node* __front =
static_cast<_Node*
>(this->_M_impl._M_head._M_next);
752 return *__front->_M_valptr();
762 _Node* __front =
static_cast<_Node*
>(this->_M_impl._M_head._M_next);
763 return *__front->_M_valptr();
779 template<
typename... _Args>
781 emplace_front(_Args&&... __args)
782 { this->_M_insert_after(cbefore_begin(),
783 std::forward<_Args>(__args)...); }
796 push_front(
const _Tp& __val)
797 { this->_M_insert_after(cbefore_begin(), __val); }
803 push_front(_Tp&& __val)
804 { this->_M_insert_after(cbefore_begin(), std::move(__val)); }
820 { this->_M_erase_after(&this->_M_impl._M_head); }
835 template<
typename... _Args>
837 emplace_after(const_iterator __pos, _Args&&... __args)
838 {
return iterator(this->_M_insert_after(__pos,
839 std::forward<_Args>(__args)...)); }
854 insert_after(const_iterator __pos,
const _Tp& __val)
855 {
return iterator(this->_M_insert_after(__pos, __val)); }
861 insert_after(const_iterator __pos, _Tp&& __val)
862 {
return iterator(this->_M_insert_after(__pos, std::move(__val))); }
880 insert_after(const_iterator __pos, size_type __n,
const _Tp& __val);
897 template<
typename _InputIterator,
898 typename = std::_RequireInputIter<_InputIterator>>
900 insert_after(const_iterator __pos,
901 _InputIterator __first, _InputIterator __last);
919 insert_after(const_iterator __pos, std::initializer_list<_Tp> __il)
920 {
return insert_after(__pos, __il.begin(), __il.end()); }
940 erase_after(const_iterator __pos)
941 {
return iterator(this->_M_erase_after(const_cast<_Node_base*>
963 erase_after(const_iterator __pos, const_iterator __last)
964 {
return iterator(this->_M_erase_after(const_cast<_Node_base*>
966 const_cast<_Node_base*>
967 (__last._M_node))); }
980 swap(forward_list& __list)
981 noexcept(_Node_alloc_traits::_S_nothrow_swap())
984 __list._M_impl._M_head._M_next);
985 _Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(),
986 __list._M_get_Node_allocator());
1001 resize(size_type __sz);
1016 resize(size_type __sz,
const value_type& __val);
1028 { this->_M_erase_after(&this->_M_impl._M_head, 0); }
1044 splice_after(const_iterator __pos, forward_list&& __list)
1046 if (!__list.empty())
1047 _M_splice_after(__pos, __list.before_begin(), __list.end());
1051 splice_after(const_iterator __pos, forward_list& __list)
1052 { splice_after(__pos, std::move(__list)); }
1065 splice_after(const_iterator __pos, forward_list&& __list,
1066 const_iterator __i);
1069 splice_after(const_iterator __pos, forward_list& __list,
1071 { splice_after(__pos, std::move(__list), __i); }
1087 splice_after(const_iterator __pos, forward_list&&,
1088 const_iterator __before, const_iterator __last)
1089 { _M_splice_after(__pos, __before, __last); }
1092 splice_after(const_iterator __pos, forward_list&,
1093 const_iterator __before, const_iterator __last)
1094 { _M_splice_after(__pos, __before, __last); }
1108 remove(
const _Tp& __val);
1121 template<
typename _Pred>
1123 remove_if(_Pred __pred);
1137 { unique(std::equal_to<_Tp>()); }
1151 template<
typename _BinPred>
1153 unique(_BinPred __binary_pred);
1165 merge(forward_list&& __list)
1166 { merge(std::move(__list), std::less<_Tp>()); }
1169 merge(forward_list& __list)
1170 { merge(std::move(__list)); }
1183 template<
typename _Comp>
1185 merge(forward_list&& __list, _Comp __comp);
1187 template<
typename _Comp>
1189 merge(forward_list& __list, _Comp __comp)
1190 { merge(std::move(__list), __comp); }
1200 { sort(std::less<_Tp>()); }
1208 template<
typename _Comp>
1219 { this->_M_impl._M_head._M_reverse_after(); }
1223 template<
typename _InputIterator>
1225 _M_range_initialize(_InputIterator __first, _InputIterator __last);
1230 _M_fill_initialize(size_type __n,
const value_type& __value);
1234 _M_splice_after(const_iterator __pos, const_iterator __before,
1235 const_iterator __last);
1239 _M_default_initialize(size_type __n);
1243 _M_default_insert_after(const_iterator __pos, size_type __n);
1250 std::swap(this->_M_impl._M_head._M_next,
1251 __list._M_impl._M_head._M_next);
1252 std::__alloc_on_move(this->_M_get_Node_allocator(),
1253 __list._M_get_Node_allocator());
1260 if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator())
1265 this->assign(std::__make_move_if_noexcept_iterator(__list.begin()),
1266 std::__make_move_if_noexcept_iterator(__list.end()));
1271 template<
typename _InputIterator>
1273 _M_assign(_InputIterator __first, _InputIterator __last,
true_type)
1275 auto __prev = before_begin();
1276 auto __curr = begin();
1278 while (__curr != __end && __first != __last)
1285 if (__first != __last)
1286 insert_after(__prev, __first, __last);
1287 else if (__curr != __end)
1288 erase_after(__prev, __end);
1293 template<
typename _InputIterator>
1295 _M_assign(_InputIterator __first, _InputIterator __last,
false_type)
1298 insert_after(cbefore_begin(), __first, __last);
1303 _M_assign_n(size_type __n,
const _Tp& __val,
true_type)
1305 auto __prev = before_begin();
1306 auto __curr = begin();
1308 while (__curr != __end && __n > 0)
1316 insert_after(__prev, __n, __val);
1317 else if (__curr != __end)
1318 erase_after(__prev, __end);
1323 _M_assign_n(size_type __n,
const _Tp& __val,
false_type)
1326 insert_after(cbefore_begin(), __n, __val);
1340 template<
typename _Tp,
typename _Alloc>
1342 operator==(
const forward_list<_Tp, _Alloc>& __lx,
1343 const forward_list<_Tp, _Alloc>& __ly);
1357 template<
typename _Tp,
typename _Alloc>
1359 operator<(const forward_list<_Tp, _Alloc>& __lx,
1360 const forward_list<_Tp, _Alloc>& __ly)
1361 {
return std::lexicographical_compare(__lx.cbegin(), __lx.cend(),
1362 __ly.cbegin(), __ly.cend()); }
1365 template<
typename _Tp,
typename _Alloc>
1367 operator!=(
const forward_list<_Tp, _Alloc>& __lx,
1368 const forward_list<_Tp, _Alloc>& __ly)
1369 {
return !(__lx == __ly); }
1372 template<
typename _Tp,
typename _Alloc>
1374 operator>(
const forward_list<_Tp, _Alloc>& __lx,
1375 const forward_list<_Tp, _Alloc>& __ly)
1376 {
return (__ly < __lx); }
1379 template<
typename _Tp,
typename _Alloc>
1381 operator>=(
const forward_list<_Tp, _Alloc>& __lx,
1382 const forward_list<_Tp, _Alloc>& __ly)
1383 {
return !(__lx < __ly); }
1386 template<
typename _Tp,
typename _Alloc>
1388 operator<=(const forward_list<_Tp, _Alloc>& __lx,
1389 const forward_list<_Tp, _Alloc>& __ly)
1390 {
return !(__ly < __lx); }
1393 template<
typename _Tp,
typename _Alloc>
1395 swap(forward_list<_Tp, _Alloc>& __lx,
1396 forward_list<_Tp, _Alloc>& __ly)
1397 { __lx.swap(__ly); }
1399 _GLIBCXX_END_NAMESPACE_CONTAINER
1402 #endif // _FORWARD_LIST_H
bool operator>=(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:644
bool operator==(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
#define __try
Definition: exception_defines.h:35
#define __throw_exception_again
Definition: exception_defines.h:37
bool operator>(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:612
bool operator!=(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
__SIZE_TYPE__ size_t
Definition: stddef.h:212
std::tr1::integral_constant< int, 1 > true_type
Definition: type_utils.hpp:70
#define __catch(X)
Definition: exception_defines.h:36
__PTRDIFF_TYPE__ ptrdiff_t
Definition: stddef.h:147
namespace std _GLIBCXX_VISIBILITY(default)
Definition: forward_list.h:40
void swap(exception_ptr &__lhs, exception_ptr &__rhs)
Definition: exception_ptr.h:160
std::tr1::integral_constant< int, 0 > false_type
Definition: type_utils.hpp:71