STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stl_list.h
Go to the documentation of this file.
1 // List implementation -*- C++ -*-
2 
3 // Copyright (C) 2001-2013 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /*
26  *
27  * Copyright (c) 1994
28  * Hewlett-Packard Company
29  *
30  * Permission to use, copy, modify, distribute and sell this software
31  * and its documentation for any purpose is hereby granted without fee,
32  * provided that the above copyright notice appear in all copies and
33  * that both that copyright notice and this permission notice appear
34  * in supporting documentation. Hewlett-Packard Company makes no
35  * representations about the suitability of this software for any
36  * purpose. It is provided "as is" without express or implied warranty.
37  *
38  *
39  * Copyright (c) 1996,1997
40  * Silicon Graphics Computer Systems, Inc.
41  *
42  * Permission to use, copy, modify, distribute and sell this software
43  * and its documentation for any purpose is hereby granted without fee,
44  * provided that the above copyright notice appear in all copies and
45  * that both that copyright notice and this permission notice appear
46  * in supporting documentation. Silicon Graphics makes no
47  * representations about the suitability of this software for any
48  * purpose. It is provided "as is" without express or implied warranty.
49  */
50 
56 #ifndef _STL_LIST_H
57 #define _STL_LIST_H 1
58 
59 #include <bits/concept_check.h>
60 #if __cplusplus >= 201103L
61 #include <initializer_list>
62 #endif
63 
64 namespace std _GLIBCXX_VISIBILITY(default)
65 {
66  namespace __detail
67  {
68  _GLIBCXX_BEGIN_NAMESPACE_VERSION
69 
70  // Supporting structures are split into common and templated
71  // types; the latter publicly inherits from the former in an
72  // effort to reduce code duplication. This results in some
73  // "needless" static_cast'ing later on, but it's all safe
74  // downcasting.
75 
77  struct _List_node_base
78  {
79  _List_node_base* _M_next;
80  _List_node_base* _M_prev;
81 
82  static void
83  swap(_List_node_base& __x, _List_node_base& __y) _GLIBCXX_USE_NOEXCEPT;
84 
85  void
86  _M_transfer(_List_node_base* const __first,
87  _List_node_base* const __last) _GLIBCXX_USE_NOEXCEPT;
88 
89  void
90  _M_reverse() _GLIBCXX_USE_NOEXCEPT;
91 
92  void
93  _M_hook(_List_node_base* const __position) _GLIBCXX_USE_NOEXCEPT;
94 
95  void
96  _M_unhook() _GLIBCXX_USE_NOEXCEPT;
97  };
98 
99  _GLIBCXX_END_NAMESPACE_VERSION
100  } // namespace detail
101 
102 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
103 
105  template<typename _Tp>
106  struct _List_node : public __detail::_List_node_base
107  {
109  _Tp _M_data;
110 
111 #if __cplusplus >= 201103L
112  template<typename... _Args>
113  _List_node(_Args&&... __args)
114  : __detail::_List_node_base(), _M_data(std::forward<_Args>(__args)...)
115  { }
116 #endif
117  };
118 
124  template<typename _Tp>
125  struct _List_iterator
126  {
127  typedef _List_iterator<_Tp> _Self;
128  typedef _List_node<_Tp> _Node;
129 
130  typedef ptrdiff_t difference_type;
131  typedef std::bidirectional_iterator_tag iterator_category;
132  typedef _Tp value_type;
133  typedef _Tp* pointer;
134  typedef _Tp& reference;
135 
136  _List_iterator()
137  : _M_node() { }
138 
139  explicit
140  _List_iterator(__detail::_List_node_base* __x)
141  : _M_node(__x) { }
142 
143  // Must downcast from _List_node_base to _List_node to get to _M_data.
144  reference
145  operator*() const
146  { return static_cast<_Node*>(_M_node)->_M_data; }
147 
148  pointer
149  operator->() const
150  { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
151 
152  _Self&
153  operator++()
154  {
155  _M_node = _M_node->_M_next;
156  return *this;
157  }
158 
159  _Self
160  operator++(int)
161  {
162  _Self __tmp = *this;
163  _M_node = _M_node->_M_next;
164  return __tmp;
165  }
166 
167  _Self&
168  operator--()
169  {
170  _M_node = _M_node->_M_prev;
171  return *this;
172  }
173 
174  _Self
175  operator--(int)
176  {
177  _Self __tmp = *this;
178  _M_node = _M_node->_M_prev;
179  return __tmp;
180  }
181 
182  bool
183  operator==(const _Self& __x) const
184  { return _M_node == __x._M_node; }
185 
186  bool
187  operator!=(const _Self& __x) const
188  { return _M_node != __x._M_node; }
189 
190  // The only member points to the %list element.
191  __detail::_List_node_base* _M_node;
192  };
193 
199  template<typename _Tp>
200  struct _List_const_iterator
201  {
202  typedef _List_const_iterator<_Tp> _Self;
203  typedef const _List_node<_Tp> _Node;
204  typedef _List_iterator<_Tp> iterator;
205 
206  typedef ptrdiff_t difference_type;
207  typedef std::bidirectional_iterator_tag iterator_category;
208  typedef _Tp value_type;
209  typedef const _Tp* pointer;
210  typedef const _Tp& reference;
211 
212  _List_const_iterator()
213  : _M_node() { }
214 
215  explicit
216  _List_const_iterator(const __detail::_List_node_base* __x)
217  : _M_node(__x) { }
218 
219  _List_const_iterator(const iterator& __x)
220  : _M_node(__x._M_node) { }
221 
222  // Must downcast from List_node_base to _List_node to get to
223  // _M_data.
224  reference
225  operator*() const
226  { return static_cast<_Node*>(_M_node)->_M_data; }
227 
228  pointer
229  operator->() const
230  { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
231 
232  _Self&
233  operator++()
234  {
235  _M_node = _M_node->_M_next;
236  return *this;
237  }
238 
239  _Self
240  operator++(int)
241  {
242  _Self __tmp = *this;
243  _M_node = _M_node->_M_next;
244  return __tmp;
245  }
246 
247  _Self&
248  operator--()
249  {
250  _M_node = _M_node->_M_prev;
251  return *this;
252  }
253 
254  _Self
255  operator--(int)
256  {
257  _Self __tmp = *this;
258  _M_node = _M_node->_M_prev;
259  return __tmp;
260  }
261 
262  bool
263  operator==(const _Self& __x) const
264  { return _M_node == __x._M_node; }
265 
266  bool
267  operator!=(const _Self& __x) const
268  { return _M_node != __x._M_node; }
269 
270  // The only member points to the %list element.
271  const __detail::_List_node_base* _M_node;
272  };
273 
274  template<typename _Val>
275  inline bool
276  operator==(const _List_iterator<_Val>& __x,
277  const _List_const_iterator<_Val>& __y)
278  { return __x._M_node == __y._M_node; }
279 
280  template<typename _Val>
281  inline bool
282  operator!=(const _List_iterator<_Val>& __x,
283  const _List_const_iterator<_Val>& __y)
284  { return __x._M_node != __y._M_node; }
285 
286 
288  template<typename _Tp, typename _Alloc>
289  class _List_base
290  {
291  protected:
292  // NOTA BENE
293  // The stored instance is not actually of "allocator_type"'s
294  // type. Instead we rebind the type to
295  // Allocator<List_node<Tp>>, which according to [20.1.5]/4
296  // should probably be the same. List_node<Tp> is not the same
297  // size as Tp (it's two pointers larger), and specializations on
298  // Tp may go unused because List_node<Tp> is being bound
299  // instead.
300  //
301  // We put this to the test in the constructors and in
302  // get_allocator, where we use conversions between
303  // allocator_type and _Node_alloc_type. The conversion is
304  // required by table 32 in [20.1.5].
305  typedef typename _Alloc::template rebind<_List_node<_Tp> >::other
306  _Node_alloc_type;
307 
308  typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
309 
310  struct _List_impl
311  : public _Node_alloc_type
312  {
313  __detail::_List_node_base _M_node;
314 
315  _List_impl()
316  : _Node_alloc_type(), _M_node()
317  { }
318 
319  _List_impl(const _Node_alloc_type& __a)
320  : _Node_alloc_type(__a), _M_node()
321  { }
322 
323 #if __cplusplus >= 201103L
324  _List_impl(_Node_alloc_type&& __a)
325  : _Node_alloc_type(std::move(__a)), _M_node()
326  { }
327 #endif
328  };
329 
330  _List_impl _M_impl;
331 
332  _List_node<_Tp>*
333  _M_get_node()
334  { return _M_impl._Node_alloc_type::allocate(1); }
335 
336  void
337  _M_put_node(_List_node<_Tp>* __p)
338  { _M_impl._Node_alloc_type::deallocate(__p, 1); }
339 
340  public:
341  typedef _Alloc allocator_type;
342 
343  _Node_alloc_type&
344  _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
345  { return *static_cast<_Node_alloc_type*>(&_M_impl); }
346 
347  const _Node_alloc_type&
348  _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
349  { return *static_cast<const _Node_alloc_type*>(&_M_impl); }
350 
351  _Tp_alloc_type
352  _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT
353  { return _Tp_alloc_type(_M_get_Node_allocator()); }
354 
355  allocator_type
356  get_allocator() const _GLIBCXX_NOEXCEPT
357  { return allocator_type(_M_get_Node_allocator()); }
358 
359  _List_base()
360  : _M_impl()
361  { _M_init(); }
362 
363  _List_base(const _Node_alloc_type& __a)
364  : _M_impl(__a)
365  { _M_init(); }
366 
367 #if __cplusplus >= 201103L
368  _List_base(_List_base&& __x)
369  : _M_impl(std::move(__x._M_get_Node_allocator()))
370  {
371  _M_init();
372  __detail::_List_node_base::swap(_M_impl._M_node, __x._M_impl._M_node);
373  }
374 #endif
375 
376  // This is what actually destroys the list.
377  ~_List_base() _GLIBCXX_NOEXCEPT
378  { _M_clear(); }
379 
380  void
381  _M_clear();
382 
383  void
384  _M_init()
385  {
386  this->_M_impl._M_node._M_next = &this->_M_impl._M_node;
387  this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;
388  }
389  };
390 
437  template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
438  class list : protected _List_base<_Tp, _Alloc>
439  {
440  // concept requirements
441  typedef typename _Alloc::value_type _Alloc_value_type;
442  __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
443  __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
444 
445  typedef _List_base<_Tp, _Alloc> _Base;
446  typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
447  typedef typename _Base::_Node_alloc_type _Node_alloc_type;
448 
449  public:
450  typedef _Tp value_type;
451  typedef typename _Tp_alloc_type::pointer pointer;
452  typedef typename _Tp_alloc_type::const_pointer const_pointer;
453  typedef typename _Tp_alloc_type::reference reference;
454  typedef typename _Tp_alloc_type::const_reference const_reference;
455  typedef _List_iterator<_Tp> iterator;
456  typedef _List_const_iterator<_Tp> const_iterator;
457  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
458  typedef std::reverse_iterator<iterator> reverse_iterator;
459  typedef size_t size_type;
460  typedef ptrdiff_t difference_type;
461  typedef _Alloc allocator_type;
462 
463  protected:
464  // Note that pointers-to-_Node's can be ctor-converted to
465  // iterator types.
466  typedef _List_node<_Tp> _Node;
467 
468  using _Base::_M_impl;
469  using _Base::_M_put_node;
470  using _Base::_M_get_node;
471  using _Base::_M_get_Tp_allocator;
472  using _Base::_M_get_Node_allocator;
473 
480 #if __cplusplus < 201103L
481  _Node*
482  _M_create_node(const value_type& __x)
483  {
484  _Node* __p = this->_M_get_node();
485  __try
486  {
487  _M_get_Tp_allocator().construct
488  (std::__addressof(__p->_M_data), __x);
489  }
490  __catch(...)
491  {
492  _M_put_node(__p);
494  }
495  return __p;
496  }
497 #else
498  template<typename... _Args>
499  _Node*
500  _M_create_node(_Args&&... __args)
501  {
502  _Node* __p = this->_M_get_node();
503  __try
504  {
505  _M_get_Node_allocator().construct(__p,
506  std::forward<_Args>(__args)...);
507  }
508  __catch(...)
509  {
510  _M_put_node(__p);
512  }
513  return __p;
514  }
515 #endif
516 
517  public:
518  // [23.2.2.1] construct/copy/destroy
519  // (assign() and get_allocator() are also listed in this section)
523  list()
524  : _Base() { }
525 
530  explicit
531  list(const allocator_type& __a)
532  : _Base(_Node_alloc_type(__a)) { }
533 
534 #if __cplusplus >= 201103L
535 
542  explicit
543  list(size_type __n)
544  : _Base()
545  { _M_default_initialize(__n); }
546 
555  list(size_type __n, const value_type& __value,
556  const allocator_type& __a = allocator_type())
557  : _Base(_Node_alloc_type(__a))
558  { _M_fill_initialize(__n, __value); }
559 #else
560 
568  explicit
569  list(size_type __n, const value_type& __value = value_type(),
570  const allocator_type& __a = allocator_type())
571  : _Base(_Node_alloc_type(__a))
572  { _M_fill_initialize(__n, __value); }
573 #endif
574 
582  list(const list& __x)
583  : _Base(__x._M_get_Node_allocator())
584  { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); }
585 
586 #if __cplusplus >= 201103L
587 
594  list(list&& __x) noexcept
595  : _Base(std::move(__x)) { }
596 
605  list(initializer_list<value_type> __l,
606  const allocator_type& __a = allocator_type())
607  : _Base(_Node_alloc_type(__a))
608  { _M_initialize_dispatch(__l.begin(), __l.end(), __false_type()); }
609 #endif
610 
621 #if __cplusplus >= 201103L
622  template<typename _InputIterator,
623  typename = std::_RequireInputIter<_InputIterator>>
624  list(_InputIterator __first, _InputIterator __last,
625  const allocator_type& __a = allocator_type())
626  : _Base(_Node_alloc_type(__a))
627  { _M_initialize_dispatch(__first, __last, __false_type()); }
628 #else
629  template<typename _InputIterator>
630  list(_InputIterator __first, _InputIterator __last,
631  const allocator_type& __a = allocator_type())
632  : _Base(_Node_alloc_type(__a))
633  {
634  // Check whether it's an integral type. If so, it's not an iterator.
635  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
636  _M_initialize_dispatch(__first, __last, _Integral());
637  }
638 #endif
639 
655  list&
656  operator=(const list& __x);
657 
658 #if __cplusplus >= 201103L
659 
666  list&
667  operator=(list&& __x)
668  {
669  // NB: DR 1204.
670  // NB: DR 675.
671  this->clear();
672  this->swap(__x);
673  return *this;
674  }
675 
683  list&
684  operator=(initializer_list<value_type> __l)
685  {
686  this->assign(__l.begin(), __l.end());
687  return *this;
688  }
689 #endif
690 
701  void
702  assign(size_type __n, const value_type& __val)
703  { _M_fill_assign(__n, __val); }
704 
717 #if __cplusplus >= 201103L
718  template<typename _InputIterator,
719  typename = std::_RequireInputIter<_InputIterator>>
720  void
721  assign(_InputIterator __first, _InputIterator __last)
722  { _M_assign_dispatch(__first, __last, __false_type()); }
723 #else
724  template<typename _InputIterator>
725  void
726  assign(_InputIterator __first, _InputIterator __last)
727  {
728  // Check whether it's an integral type. If so, it's not an iterator.
729  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
730  _M_assign_dispatch(__first, __last, _Integral());
731  }
732 #endif
733 
734 #if __cplusplus >= 201103L
735 
742  void
743  assign(initializer_list<value_type> __l)
744  { this->assign(__l.begin(), __l.end()); }
745 #endif
746 
748  allocator_type
749  get_allocator() const _GLIBCXX_NOEXCEPT
750  { return _Base::get_allocator(); }
751 
752  // iterators
757  iterator
758  begin() _GLIBCXX_NOEXCEPT
759  { return iterator(this->_M_impl._M_node._M_next); }
760 
766  const_iterator
767  begin() const _GLIBCXX_NOEXCEPT
768  { return const_iterator(this->_M_impl._M_node._M_next); }
769 
775  iterator
776  end() _GLIBCXX_NOEXCEPT
777  { return iterator(&this->_M_impl._M_node); }
778 
784  const_iterator
785  end() const _GLIBCXX_NOEXCEPT
786  { return const_iterator(&this->_M_impl._M_node); }
787 
793  reverse_iterator
794  rbegin() _GLIBCXX_NOEXCEPT
795  { return reverse_iterator(end()); }
796 
802  const_reverse_iterator
803  rbegin() const _GLIBCXX_NOEXCEPT
804  { return const_reverse_iterator(end()); }
805 
811  reverse_iterator
812  rend() _GLIBCXX_NOEXCEPT
813  { return reverse_iterator(begin()); }
814 
820  const_reverse_iterator
821  rend() const _GLIBCXX_NOEXCEPT
822  { return const_reverse_iterator(begin()); }
823 
824 #if __cplusplus >= 201103L
825 
830  const_iterator
831  cbegin() const noexcept
832  { return const_iterator(this->_M_impl._M_node._M_next); }
833 
839  const_iterator
840  cend() const noexcept
841  { return const_iterator(&this->_M_impl._M_node); }
842 
848  const_reverse_iterator
849  crbegin() const noexcept
850  { return const_reverse_iterator(end()); }
851 
857  const_reverse_iterator
858  crend() const noexcept
859  { return const_reverse_iterator(begin()); }
860 #endif
861 
862  // [23.2.2.2] capacity
867  bool
868  empty() const _GLIBCXX_NOEXCEPT
869  { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; }
870 
872  size_type
873  size() const _GLIBCXX_NOEXCEPT
874  { return std::distance(begin(), end()); }
875 
877  size_type
878  max_size() const _GLIBCXX_NOEXCEPT
879  { return _M_get_Node_allocator().max_size(); }
880 
881 #if __cplusplus >= 201103L
882 
891  void
892  resize(size_type __new_size);
893 
904  void
905  resize(size_type __new_size, const value_type& __x);
906 #else
907 
917  void
918  resize(size_type __new_size, value_type __x = value_type());
919 #endif
920 
921  // element access
926  reference
927  front()
928  { return *begin(); }
929 
934  const_reference
935  front() const
936  { return *begin(); }
937 
942  reference
943  back()
944  {
945  iterator __tmp = end();
946  --__tmp;
947  return *__tmp;
948  }
949 
954  const_reference
955  back() const
956  {
957  const_iterator __tmp = end();
958  --__tmp;
959  return *__tmp;
960  }
961 
962  // [23.2.2.3] modifiers
973  void
974  push_front(const value_type& __x)
975  { this->_M_insert(begin(), __x); }
976 
977 #if __cplusplus >= 201103L
978  void
979  push_front(value_type&& __x)
980  { this->_M_insert(begin(), std::move(__x)); }
981 
982  template<typename... _Args>
983  void
984  emplace_front(_Args&&... __args)
985  { this->_M_insert(begin(), std::forward<_Args>(__args)...); }
986 #endif
987 
1000  void
1001  pop_front()
1002  { this->_M_erase(begin()); }
1003 
1014  void
1015  push_back(const value_type& __x)
1016  { this->_M_insert(end(), __x); }
1017 
1018 #if __cplusplus >= 201103L
1019  void
1020  push_back(value_type&& __x)
1021  { this->_M_insert(end(), std::move(__x)); }
1022 
1023  template<typename... _Args>
1024  void
1025  emplace_back(_Args&&... __args)
1026  { this->_M_insert(end(), std::forward<_Args>(__args)...); }
1027 #endif
1028 
1040  void
1041  pop_back()
1042  { this->_M_erase(iterator(this->_M_impl._M_node._M_prev)); }
1043 
1044 #if __cplusplus >= 201103L
1045 
1057  template<typename... _Args>
1058  iterator
1059  emplace(iterator __position, _Args&&... __args);
1060 #endif
1061 
1073  iterator
1074  insert(iterator __position, const value_type& __x);
1075 
1076 #if __cplusplus >= 201103L
1077 
1088  iterator
1089  insert(iterator __position, value_type&& __x)
1090  { return emplace(__position, std::move(__x)); }
1091 
1105  void
1106  insert(iterator __p, initializer_list<value_type> __l)
1107  { this->insert(__p, __l.begin(), __l.end()); }
1108 #endif
1109 
1122  void
1123  insert(iterator __position, size_type __n, const value_type& __x)
1124  {
1125  list __tmp(__n, __x, get_allocator());
1126  splice(__position, __tmp);
1127  }
1128 
1142 #if __cplusplus >= 201103L
1143  template<typename _InputIterator,
1144  typename = std::_RequireInputIter<_InputIterator>>
1145 #else
1146  template<typename _InputIterator>
1147 #endif
1148  void
1149  insert(iterator __position, _InputIterator __first,
1150  _InputIterator __last)
1151  {
1152  list __tmp(__first, __last, get_allocator());
1153  splice(__position, __tmp);
1154  }
1155 
1171  iterator
1172  erase(iterator __position);
1173 
1192  iterator
1193  erase(iterator __first, iterator __last)
1194  {
1195  while (__first != __last)
1196  __first = erase(__first);
1197  return __last;
1198  }
1199 
1209  void
1210  swap(list& __x)
1211  {
1212  __detail::_List_node_base::swap(this->_M_impl._M_node,
1213  __x._M_impl._M_node);
1214 
1215  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1216  // 431. Swapping containers with unequal allocators.
1217  std::__alloc_swap<typename _Base::_Node_alloc_type>::
1218  _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator());
1219  }
1220 
1227  void
1228  clear() _GLIBCXX_NOEXCEPT
1229  {
1230  _Base::_M_clear();
1231  _Base::_M_init();
1232  }
1233 
1234  // [23.2.2.4] list operations
1246  void
1247 #if __cplusplus >= 201103L
1248  splice(iterator __position, list&& __x)
1249 #else
1250  splice(iterator __position, list& __x)
1251 #endif
1252  {
1253  if (!__x.empty())
1254  {
1255  _M_check_equal_allocators(__x);
1256 
1257  this->_M_transfer(__position, __x.begin(), __x.end());
1258  }
1259  }
1260 
1261 #if __cplusplus >= 201103L
1262  void
1263  splice(iterator __position, list& __x)
1264  { splice(__position, std::move(__x)); }
1265 #endif
1266 
1276  void
1277 #if __cplusplus >= 201103L
1278  splice(iterator __position, list&& __x, iterator __i)
1279 #else
1280  splice(iterator __position, list& __x, iterator __i)
1281 #endif
1282  {
1283  iterator __j = __i;
1284  ++__j;
1285  if (__position == __i || __position == __j)
1286  return;
1287 
1288  if (this != &__x)
1289  _M_check_equal_allocators(__x);
1290 
1291  this->_M_transfer(__position, __i, __j);
1292  }
1293 
1294 #if __cplusplus >= 201103L
1295  void
1296  splice(iterator __position, list& __x, iterator __i)
1297  { splice(__position, std::move(__x), __i); }
1298 #endif
1299 
1312  void
1313 #if __cplusplus >= 201103L
1314  splice(iterator __position, list&& __x, iterator __first,
1315  iterator __last)
1316 #else
1317  splice(iterator __position, list& __x, iterator __first,
1318  iterator __last)
1319 #endif
1320  {
1321  if (__first != __last)
1322  {
1323  if (this != &__x)
1324  _M_check_equal_allocators(__x);
1325 
1326  this->_M_transfer(__position, __first, __last);
1327  }
1328  }
1329 
1330 #if __cplusplus >= 201103L
1331  void
1332  splice(iterator __position, list& __x, iterator __first, iterator __last)
1333  { splice(__position, std::move(__x), __first, __last); }
1334 #endif
1335 
1347  void
1348  remove(const _Tp& __value);
1349 
1361  template<typename _Predicate>
1362  void
1363  remove_if(_Predicate);
1364 
1375  void
1376  unique();
1377 
1390  template<typename _BinaryPredicate>
1391  void
1392  unique(_BinaryPredicate);
1393 
1403 #if __cplusplus >= 201103L
1404  void
1405  merge(list&& __x);
1406 
1407  void
1408  merge(list& __x)
1409  { merge(std::move(__x)); }
1410 #else
1411  void
1412  merge(list& __x);
1413 #endif
1414 
1428 #if __cplusplus >= 201103L
1429  template<typename _StrictWeakOrdering>
1430  void
1431  merge(list&& __x, _StrictWeakOrdering __comp);
1432 
1433  template<typename _StrictWeakOrdering>
1434  void
1435  merge(list& __x, _StrictWeakOrdering __comp)
1436  { merge(std::move(__x), __comp); }
1437 #else
1438  template<typename _StrictWeakOrdering>
1439  void
1440  merge(list& __x, _StrictWeakOrdering __comp);
1441 #endif
1442 
1448  void
1449  reverse() _GLIBCXX_NOEXCEPT
1450  { this->_M_impl._M_node._M_reverse(); }
1451 
1458  void
1459  sort();
1460 
1467  template<typename _StrictWeakOrdering>
1468  void
1469  sort(_StrictWeakOrdering);
1470 
1471  protected:
1472  // Internal constructor functions follow.
1473 
1474  // Called by the range constructor to implement [23.1.1]/9
1475 
1476  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1477  // 438. Ambiguity in the "do the right thing" clause
1478  template<typename _Integer>
1479  void
1480  _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
1481  { _M_fill_initialize(static_cast<size_type>(__n), __x); }
1482 
1483  // Called by the range constructor to implement [23.1.1]/9
1484  template<typename _InputIterator>
1485  void
1486  _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
1487  __false_type)
1488  {
1489  for (; __first != __last; ++__first)
1490 #if __cplusplus >= 201103L
1491  emplace_back(*__first);
1492 #else
1493  push_back(*__first);
1494 #endif
1495  }
1496 
1497  // Called by list(n,v,a), and the range constructor when it turns out
1498  // to be the same thing.
1499  void
1500  _M_fill_initialize(size_type __n, const value_type& __x)
1501  {
1502  for (; __n; --__n)
1503  push_back(__x);
1504  }
1505 
1506 #if __cplusplus >= 201103L
1507  // Called by list(n).
1508  void
1509  _M_default_initialize(size_type __n)
1510  {
1511  for (; __n; --__n)
1512  emplace_back();
1513  }
1514 
1515  // Called by resize(sz).
1516  void
1517  _M_default_append(size_type __n);
1518 #endif
1519 
1520  // Internal assign functions follow.
1521 
1522  // Called by the range assign to implement [23.1.1]/9
1523 
1524  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1525  // 438. Ambiguity in the "do the right thing" clause
1526  template<typename _Integer>
1527  void
1528  _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
1529  { _M_fill_assign(__n, __val); }
1530 
1531  // Called by the range assign to implement [23.1.1]/9
1532  template<typename _InputIterator>
1533  void
1534  _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
1535  __false_type);
1536 
1537  // Called by assign(n,t), and the range assign when it turns out
1538  // to be the same thing.
1539  void
1540  _M_fill_assign(size_type __n, const value_type& __val);
1541 
1542 
1543  // Moves the elements from [first,last) before position.
1544  void
1545  _M_transfer(iterator __position, iterator __first, iterator __last)
1546  { __position._M_node->_M_transfer(__first._M_node, __last._M_node); }
1547 
1548  // Inserts new element at position given and with value given.
1549 #if __cplusplus < 201103L
1550  void
1551  _M_insert(iterator __position, const value_type& __x)
1552  {
1553  _Node* __tmp = _M_create_node(__x);
1554  __tmp->_M_hook(__position._M_node);
1555  }
1556 #else
1557  template<typename... _Args>
1558  void
1559  _M_insert(iterator __position, _Args&&... __args)
1560  {
1561  _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
1562  __tmp->_M_hook(__position._M_node);
1563  }
1564 #endif
1565 
1566  // Erases element at position given.
1567  void
1568  _M_erase(iterator __position)
1569  {
1570  __position._M_node->_M_unhook();
1571  _Node* __n = static_cast<_Node*>(__position._M_node);
1572 #if __cplusplus >= 201103L
1573  _M_get_Node_allocator().destroy(__n);
1574 #else
1575  _M_get_Tp_allocator().destroy(std::__addressof(__n->_M_data));
1576 #endif
1577  _M_put_node(__n);
1578  }
1579 
1580  // To implement the splice (and merge) bits of N1599.
1581  void
1582  _M_check_equal_allocators(list& __x)
1583  {
1584  if (std::__alloc_neq<typename _Base::_Node_alloc_type>::
1585  _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator()))
1586  __throw_runtime_error(__N("list::_M_check_equal_allocators"));
1587  }
1588  };
1589 
1600  template<typename _Tp, typename _Alloc>
1601  inline bool
1602  operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1603  {
1604  typedef typename list<_Tp, _Alloc>::const_iterator const_iterator;
1605  const_iterator __end1 = __x.end();
1606  const_iterator __end2 = __y.end();
1607 
1608  const_iterator __i1 = __x.begin();
1609  const_iterator __i2 = __y.begin();
1610  while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2)
1611  {
1612  ++__i1;
1613  ++__i2;
1614  }
1615  return __i1 == __end1 && __i2 == __end2;
1616  }
1617 
1629  template<typename _Tp, typename _Alloc>
1630  inline bool
1631  operator<(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1632  { return std::lexicographical_compare(__x.begin(), __x.end(),
1633  __y.begin(), __y.end()); }
1634 
1636  template<typename _Tp, typename _Alloc>
1637  inline bool
1638  operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1639  { return !(__x == __y); }
1640 
1642  template<typename _Tp, typename _Alloc>
1643  inline bool
1644  operator>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1645  { return __y < __x; }
1646 
1648  template<typename _Tp, typename _Alloc>
1649  inline bool
1650  operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1651  { return !(__y < __x); }
1652 
1654  template<typename _Tp, typename _Alloc>
1655  inline bool
1656  operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
1657  { return !(__x < __y); }
1658 
1660  template<typename _Tp, typename _Alloc>
1661  inline void
1662  swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
1663  { __x.swap(__y); }
1664 
1665 _GLIBCXX_END_NAMESPACE_CONTAINER
1666 } // namespace std
1667 
1668 #endif /* _STL_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__))
namespace std _GLIBCXX_VISIBILITY(default)
Definition: stl_list.h:64
#define __try
Definition: exception_defines.h:35
#define __throw_exception_again
Definition: exception_defines.h:37
#define __glibcxx_class_requires(_a, _b)
Definition: concept_check.h:48
bool operator>(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:612
#define __glibcxx_class_requires2(_a, _b, _c)
Definition: concept_check.h:49
bool operator!=(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
#define __catch(X)
Definition: exception_defines.h:36
__PTRDIFF_TYPE__ ptrdiff_t
Definition: stddef.h:147
void swap(exception_ptr &__lhs, exception_ptr &__rhs)
Definition: exception_ptr.h:160