3 * Silicon Graphics Computer Systems, Inc.
5 * Permission to use, copy, modify, distribute and sell this software
6 * and its documentation for any purpose is hereby granted without fee,
7 * provided that the above copyright notice appear in all copies and
8 * that both that copyright notice and this permission notice appear
9 * in supporting documentation. Silicon Graphics makes no
10 * representations about the suitability of this software for any
11 * purpose. It is provided "as is" without express or implied warranty.
15 /* NOTE: This is an internal header file, included by other STL headers.
16 * You should not attempt to use it directly.
19 #ifndef __SGI_STL_INTERNAL_SLIST_H
20 #define __SGI_STL_INTERNAL_SLIST_H
22 #include <bits/concept_checks.h>
26 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
31 struct _Slist_node_base
33 _Slist_node_base* _M_next;
36 inline _Slist_node_base*
37 __slist_make_link(_Slist_node_base* __prev_node,
38 _Slist_node_base* __new_node)
40 __new_node->_M_next = __prev_node->_M_next;
41 __prev_node->_M_next = __new_node;
45 inline _Slist_node_base*
46 __slist_previous(_Slist_node_base* __head,
47 const _Slist_node_base* __node)
49 while (__head && __head->_M_next != __node)
50 __head = __head->_M_next;
54 inline const _Slist_node_base*
55 __slist_previous(const _Slist_node_base* __head,
56 const _Slist_node_base* __node)
58 while (__head && __head->_M_next != __node)
59 __head = __head->_M_next;
63 inline void __slist_splice_after(_Slist_node_base* __pos,
64 _Slist_node_base* __before_first,
65 _Slist_node_base* __before_last)
67 if (__pos != __before_first && __pos != __before_last) {
68 _Slist_node_base* __first = __before_first->_M_next;
69 _Slist_node_base* __after = __pos->_M_next;
70 __before_first->_M_next = __before_last->_M_next;
71 __pos->_M_next = __first;
72 __before_last->_M_next = __after;
77 __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head)
79 _Slist_node_base* __before_last = __slist_previous(__head, 0);
80 if (__before_last != __head) {
81 _Slist_node_base* __after = __pos->_M_next;
82 __pos->_M_next = __head->_M_next;
84 __before_last->_M_next = __after;
88 inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node)
90 _Slist_node_base* __result = __node;
91 __node = __node->_M_next;
92 __result->_M_next = 0;
94 _Slist_node_base* __next = __node->_M_next;
95 __node->_M_next = __result;
102 inline size_t __slist_size(_Slist_node_base* __node)
105 for ( ; __node != 0; __node = __node->_M_next)
111 struct _Slist_node : public _Slist_node_base
116 struct _Slist_iterator_base
118 typedef size_t size_type;
119 typedef ptrdiff_t difference_type;
120 typedef forward_iterator_tag iterator_category;
122 _Slist_node_base* _M_node;
124 _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {}
125 void _M_incr() { _M_node = _M_node->_M_next; }
127 bool operator==(const _Slist_iterator_base& __x) const {
128 return _M_node == __x._M_node;
130 bool operator!=(const _Slist_iterator_base& __x) const {
131 return _M_node != __x._M_node;
135 template <class _Tp, class _Ref, class _Ptr>
136 struct _Slist_iterator : public _Slist_iterator_base
138 typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator;
139 typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
140 typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self;
142 typedef _Tp value_type;
143 typedef _Ptr pointer;
144 typedef _Ref reference;
145 typedef _Slist_node<_Tp> _Node;
147 _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {}
148 _Slist_iterator() : _Slist_iterator_base(0) {}
149 _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {}
151 reference operator*() const { return ((_Node*) _M_node)->_M_data; }
152 #ifndef __SGI_STL_NO_ARROW_OPERATOR
153 pointer operator->() const { return &(operator*()); }
154 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
161 _Self operator++(int)
169 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
171 inline ptrdiff_t* distance_type(const _Slist_iterator_base&) {
175 inline forward_iterator_tag iterator_category(const _Slist_iterator_base&) {
176 return forward_iterator_tag();
179 template <class _Tp, class _Ref, class _Ptr>
180 inline _Tp* value_type(const _Slist_iterator<_Tp, _Ref, _Ptr>&) {
184 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
186 // Base class that encapsulates details of allocators. Three cases:
187 // an ordinary standard-conforming allocator, a standard-conforming
188 // allocator with no non-static data, and an SGI-style allocator.
189 // This complexity is necessary only because we're worrying about backward
190 // compatibility and because we want to avoid wasting storage on an
191 // allocator instance if it isn't necessary.
193 #ifdef __STL_USE_STD_ALLOCATORS
195 // Base for general standard-conforming allocators.
196 template <class _Tp, class _Allocator, bool _IsStatic>
197 class _Slist_alloc_base {
199 typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type
201 allocator_type get_allocator() const { return _M_node_allocator; }
203 _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {}
206 _Slist_node<_Tp>* _M_get_node()
207 { return _M_node_allocator.allocate(1); }
208 void _M_put_node(_Slist_node<_Tp>* __p)
209 { _M_node_allocator.deallocate(__p, 1); }
212 typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type
214 _Slist_node_base _M_head;
217 // Specialization for instanceless allocators.
218 template <class _Tp, class _Allocator>
219 class _Slist_alloc_base<_Tp,_Allocator, true> {
221 typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type
223 allocator_type get_allocator() const { return allocator_type(); }
225 _Slist_alloc_base(const allocator_type&) {}
228 typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type
230 _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
231 void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
234 _Slist_node_base _M_head;
238 template <class _Tp, class _Alloc>
240 : public _Slist_alloc_base<_Tp, _Alloc,
241 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
243 typedef _Slist_alloc_base<_Tp, _Alloc,
244 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
246 typedef typename _Base::allocator_type allocator_type;
248 _Slist_base(const allocator_type& __a)
249 : _Base(__a) { this->_M_head._M_next = 0; }
250 ~_Slist_base() { _M_erase_after(&this->_M_head, 0); }
254 _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
256 _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
257 _Slist_node_base* __next_next = __next->_M_next;
258 __pos->_M_next = __next_next;
259 destroy(&__next->_M_data);
263 _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
266 #else /* __STL_USE_STD_ALLOCATORS */
268 template <class _Tp, class _Alloc>
270 typedef _Alloc allocator_type;
271 allocator_type get_allocator() const { return allocator_type(); }
273 _Slist_base(const allocator_type&) { _M_head._M_next = 0; }
274 ~_Slist_base() { _M_erase_after(&_M_head, 0); }
277 typedef simple_alloc<_Slist_node<_Tp>, _Alloc> _Alloc_type;
278 _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
279 void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
281 _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
283 _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
284 _Slist_node_base* __next_next = __next->_M_next;
285 __pos->_M_next = __next_next;
286 destroy(&__next->_M_data);
290 _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
293 _Slist_node_base _M_head;
296 #endif /* __STL_USE_STD_ALLOCATORS */
298 template <class _Tp, class _Alloc>
300 _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first,
301 _Slist_node_base* __last_node) {
302 _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next);
303 while (__cur != __last_node) {
304 _Slist_node<_Tp>* __tmp = __cur;
305 __cur = (_Slist_node<_Tp>*) __cur->_M_next;
306 destroy(&__tmp->_M_data);
309 __before_first->_M_next = __last_node;
313 template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
314 class slist : private _Slist_base<_Tp,_Alloc>
318 __STL_CLASS_REQUIRES(_Tp, _Assignable);
321 typedef _Slist_base<_Tp,_Alloc> _Base;
323 typedef _Tp value_type;
324 typedef value_type* pointer;
325 typedef const value_type* const_pointer;
326 typedef value_type& reference;
327 typedef const value_type& const_reference;
328 typedef size_t size_type;
329 typedef ptrdiff_t difference_type;
331 typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator;
332 typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
334 typedef typename _Base::allocator_type allocator_type;
335 allocator_type get_allocator() const { return _Base::get_allocator(); }
338 typedef _Slist_node<_Tp> _Node;
339 typedef _Slist_node_base _Node_base;
340 typedef _Slist_iterator_base _Iterator_base;
342 _Node* _M_create_node(const value_type& __x) {
343 _Node* __node = this->_M_get_node();
345 construct(&__node->_M_data, __x);
348 __STL_UNWIND(this->_M_put_node(__node));
352 _Node* _M_create_node() {
353 _Node* __node = this->_M_get_node();
355 construct(&__node->_M_data);
358 __STL_UNWIND(this->_M_put_node(__node));
363 explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {}
365 slist(size_type __n, const value_type& __x,
366 const allocator_type& __a = allocator_type()) : _Base(__a)
367 { _M_insert_after_fill(&this->_M_head, __n, __x); }
369 explicit slist(size_type __n) : _Base(allocator_type())
370 { _M_insert_after_fill(&this->_M_head, __n, value_type()); }
372 #ifdef __STL_MEMBER_TEMPLATES
373 // We don't need any dispatching tricks here, because _M_insert_after_range
374 // already does them.
375 template <class _InputIterator>
376 slist(_InputIterator __first, _InputIterator __last,
377 const allocator_type& __a = allocator_type()) : _Base(__a)
378 { _M_insert_after_range(&this->_M_head, __first, __last); }
380 #else /* __STL_MEMBER_TEMPLATES */
381 slist(const_iterator __first, const_iterator __last,
382 const allocator_type& __a = allocator_type()) : _Base(__a)
383 { _M_insert_after_range(&this->_M_head, __first, __last); }
384 slist(const value_type* __first, const value_type* __last,
385 const allocator_type& __a = allocator_type()) : _Base(__a)
386 { _M_insert_after_range(&this->_M_head, __first, __last); }
387 #endif /* __STL_MEMBER_TEMPLATES */
389 slist(const slist& __x) : _Base(__x.get_allocator())
390 { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); }
392 slist& operator= (const slist& __x);
397 // assign(), a generalized assignment member function. Two
398 // versions: one that takes a count, and one that takes a range.
399 // The range version is a member template, so we dispatch on whether
400 // or not the type is an integer.
402 void assign(size_type __n, const _Tp& __val)
403 { _M_fill_assign(__n, __val); }
405 void _M_fill_assign(size_type __n, const _Tp& __val);
408 #ifdef __STL_MEMBER_TEMPLATES
410 template <class _InputIterator>
411 void assign(_InputIterator __first, _InputIterator __last) {
412 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
413 _M_assign_dispatch(__first, __last, _Integral());
416 template <class _Integer>
417 void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
418 { _M_fill_assign((size_type) __n, (_Tp) __val); }
420 template <class _InputIterator>
421 void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
424 #endif /* __STL_MEMBER_TEMPLATES */
428 iterator begin() { return iterator((_Node*)this->_M_head._M_next); }
429 const_iterator begin() const
430 { return const_iterator((_Node*)this->_M_head._M_next);}
432 iterator end() { return iterator(0); }
433 const_iterator end() const { return const_iterator(0); }
435 // Experimental new feature: before_begin() returns a
436 // non-dereferenceable iterator that, when incremented, yields
437 // begin(). This iterator may be used as the argument to
438 // insert_after, erase_after, etc. Note that even for an empty
439 // slist, before_begin() is not the same iterator as end(). It
440 // is always necessary to increment before_begin() at least once to
442 iterator before_begin() { return iterator((_Node*) &this->_M_head); }
443 const_iterator before_begin() const
444 { return const_iterator((_Node*) &this->_M_head); }
446 size_type size() const { return __slist_size(this->_M_head._M_next); }
448 size_type max_size() const { return size_type(-1); }
450 bool empty() const { return this->_M_head._M_next == 0; }
452 void swap(slist& __x)
453 { __STD::swap(this->_M_head._M_next, __x._M_head._M_next); }
457 reference front() { return ((_Node*) this->_M_head._M_next)->_M_data; }
458 const_reference front() const
459 { return ((_Node*) this->_M_head._M_next)->_M_data; }
460 void push_front(const value_type& __x) {
461 __slist_make_link(&this->_M_head, _M_create_node(__x));
463 void push_front() { __slist_make_link(&this->_M_head, _M_create_node()); }
465 _Node* __node = (_Node*) this->_M_head._M_next;
466 this->_M_head._M_next = __node->_M_next;
467 destroy(&__node->_M_data);
468 this->_M_put_node(__node);
471 iterator previous(const_iterator __pos) {
472 return iterator((_Node*) __slist_previous(&this->_M_head, __pos._M_node));
474 const_iterator previous(const_iterator __pos) const {
475 return const_iterator((_Node*) __slist_previous(&this->_M_head,
480 _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) {
481 return (_Node*) (__slist_make_link(__pos, _M_create_node(__x)));
484 _Node* _M_insert_after(_Node_base* __pos) {
485 return (_Node*) (__slist_make_link(__pos, _M_create_node()));
488 void _M_insert_after_fill(_Node_base* __pos,
489 size_type __n, const value_type& __x) {
490 for (size_type __i = 0; __i < __n; ++__i)
491 __pos = __slist_make_link(__pos, _M_create_node(__x));
494 #ifdef __STL_MEMBER_TEMPLATES
496 // Check whether it's an integral type. If so, it's not an iterator.
497 template <class _InIter>
498 void _M_insert_after_range(_Node_base* __pos,
499 _InIter __first, _InIter __last) {
500 typedef typename _Is_integer<_InIter>::_Integral _Integral;
501 _M_insert_after_range(__pos, __first, __last, _Integral());
504 template <class _Integer>
505 void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
507 _M_insert_after_fill(__pos, __n, __x);
510 template <class _InIter>
511 void _M_insert_after_range(_Node_base* __pos,
512 _InIter __first, _InIter __last,
514 while (__first != __last) {
515 __pos = __slist_make_link(__pos, _M_create_node(*__first));
520 #else /* __STL_MEMBER_TEMPLATES */
522 void _M_insert_after_range(_Node_base* __pos,
523 const_iterator __first, const_iterator __last) {
524 while (__first != __last) {
525 __pos = __slist_make_link(__pos, _M_create_node(*__first));
529 void _M_insert_after_range(_Node_base* __pos,
530 const value_type* __first,
531 const value_type* __last) {
532 while (__first != __last) {
533 __pos = __slist_make_link(__pos, _M_create_node(*__first));
538 #endif /* __STL_MEMBER_TEMPLATES */
542 iterator insert_after(iterator __pos, const value_type& __x) {
543 return iterator(_M_insert_after(__pos._M_node, __x));
546 iterator insert_after(iterator __pos) {
547 return insert_after(__pos, value_type());
550 void insert_after(iterator __pos, size_type __n, const value_type& __x) {
551 _M_insert_after_fill(__pos._M_node, __n, __x);
554 #ifdef __STL_MEMBER_TEMPLATES
556 // We don't need any dispatching tricks here, because _M_insert_after_range
557 // already does them.
558 template <class _InIter>
559 void insert_after(iterator __pos, _InIter __first, _InIter __last) {
560 _M_insert_after_range(__pos._M_node, __first, __last);
563 #else /* __STL_MEMBER_TEMPLATES */
565 void insert_after(iterator __pos,
566 const_iterator __first, const_iterator __last) {
567 _M_insert_after_range(__pos._M_node, __first, __last);
569 void insert_after(iterator __pos,
570 const value_type* __first, const value_type* __last) {
571 _M_insert_after_range(__pos._M_node, __first, __last);
574 #endif /* __STL_MEMBER_TEMPLATES */
576 iterator insert(iterator __pos, const value_type& __x) {
577 return iterator(_M_insert_after(__slist_previous(&this->_M_head,
582 iterator insert(iterator __pos) {
583 return iterator(_M_insert_after(__slist_previous(&this->_M_head,
588 void insert(iterator __pos, size_type __n, const value_type& __x) {
589 _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node),
593 #ifdef __STL_MEMBER_TEMPLATES
595 // We don't need any dispatching tricks here, because _M_insert_after_range
596 // already does them.
597 template <class _InIter>
598 void insert(iterator __pos, _InIter __first, _InIter __last) {
599 _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node),
603 #else /* __STL_MEMBER_TEMPLATES */
605 void insert(iterator __pos, const_iterator __first, const_iterator __last) {
606 _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node),
609 void insert(iterator __pos, const value_type* __first,
610 const value_type* __last) {
611 _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node),
615 #endif /* __STL_MEMBER_TEMPLATES */
619 iterator erase_after(iterator __pos) {
620 return iterator((_Node*) this->_M_erase_after(__pos._M_node));
622 iterator erase_after(iterator __before_first, iterator __last) {
623 return iterator((_Node*) this->_M_erase_after(__before_first._M_node,
627 iterator erase(iterator __pos) {
628 return (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head,
631 iterator erase(iterator __first, iterator __last) {
632 return (_Node*) this->_M_erase_after(
633 __slist_previous(&this->_M_head, __first._M_node), __last._M_node);
636 void resize(size_type new_size, const _Tp& __x);
637 void resize(size_type new_size) { resize(new_size, _Tp()); }
638 void clear() { this->_M_erase_after(&this->_M_head, 0); }
641 // Moves the range [__before_first + 1, __before_last + 1) to *this,
642 // inserting it immediately after __pos. This is constant time.
643 void splice_after(iterator __pos,
644 iterator __before_first, iterator __before_last)
646 if (__before_first != __before_last)
647 __slist_splice_after(__pos._M_node, __before_first._M_node,
648 __before_last._M_node);
651 // Moves the element that follows __prev to *this, inserting it immediately
652 // after __pos. This is constant time.
653 void splice_after(iterator __pos, iterator __prev)
655 __slist_splice_after(__pos._M_node,
656 __prev._M_node, __prev._M_node->_M_next);
660 // Removes all of the elements from the list __x to *this, inserting
661 // them immediately after __pos. __x must not be *this. Complexity:
662 // linear in __x.size().
663 void splice_after(iterator __pos, slist& __x)
665 __slist_splice_after(__pos._M_node, &__x._M_head);
668 // Linear in distance(begin(), __pos), and linear in __x.size().
669 void splice(iterator __pos, slist& __x) {
670 if (__x._M_head._M_next)
671 __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
672 &__x._M_head, __slist_previous(&__x._M_head, 0));
675 // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
676 void splice(iterator __pos, slist& __x, iterator __i) {
677 __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
678 __slist_previous(&__x._M_head, __i._M_node),
682 // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
683 // and in distance(__first, __last).
684 void splice(iterator __pos, slist& __x, iterator __first, iterator __last)
686 if (__first != __last)
687 __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
688 __slist_previous(&__x._M_head, __first._M_node),
689 __slist_previous(__first._M_node, __last._M_node));
694 if (this->_M_head._M_next)
695 this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
698 void remove(const _Tp& __val);
700 void merge(slist& __x);
703 #ifdef __STL_MEMBER_TEMPLATES
704 template <class _Predicate>
705 void remove_if(_Predicate __pred);
707 template <class _BinaryPredicate>
708 void unique(_BinaryPredicate __pred);
710 template <class _StrictWeakOrdering>
711 void merge(slist&, _StrictWeakOrdering);
713 template <class _StrictWeakOrdering>
714 void sort(_StrictWeakOrdering __comp);
715 #endif /* __STL_MEMBER_TEMPLATES */
718 template <class _Tp, class _Alloc>
719 slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x)
722 _Node_base* __p1 = &this->_M_head;
723 _Node* __n1 = (_Node*) this->_M_head._M_next;
724 const _Node* __n2 = (const _Node*) __x._M_head._M_next;
725 while (__n1 && __n2) {
726 __n1->_M_data = __n2->_M_data;
728 __n1 = (_Node*) __n1->_M_next;
729 __n2 = (const _Node*) __n2->_M_next;
732 this->_M_erase_after(__p1, 0);
734 _M_insert_after_range(__p1, const_iterator((_Node*)__n2),
740 template <class _Tp, class _Alloc>
741 void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
742 _Node_base* __prev = &this->_M_head;
743 _Node* __node = (_Node*) this->_M_head._M_next;
744 for ( ; __node != 0 && __n > 0 ; --__n) {
745 __node->_M_data = __val;
747 __node = (_Node*) __node->_M_next;
750 _M_insert_after_fill(__prev, __n, __val);
752 this->_M_erase_after(__prev, 0);
755 #ifdef __STL_MEMBER_TEMPLATES
757 template <class _Tp, class _Alloc> template <class _InputIter>
759 slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last,
762 _Node_base* __prev = &this->_M_head;
763 _Node* __node = (_Node*) this->_M_head._M_next;
764 while (__node != 0 && __first != __last) {
765 __node->_M_data = *__first;
767 __node = (_Node*) __node->_M_next;
770 if (__first != __last)
771 _M_insert_after_range(__prev, __first, __last);
773 this->_M_erase_after(__prev, 0);
776 #endif /* __STL_MEMBER_TEMPLATES */
778 template <class _Tp, class _Alloc>
780 operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2)
782 typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
783 const_iterator __end1 = _SL1.end();
784 const_iterator __end2 = _SL2.end();
786 const_iterator __i1 = _SL1.begin();
787 const_iterator __i2 = _SL2.begin();
788 while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
792 return __i1 == __end1 && __i2 == __end2;
796 template <class _Tp, class _Alloc>
798 operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2)
800 return lexicographical_compare(_SL1.begin(), _SL1.end(),
801 _SL2.begin(), _SL2.end());
804 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
806 template <class _Tp, class _Alloc>
808 operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
809 return !(_SL1 == _SL2);
812 template <class _Tp, class _Alloc>
814 operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
818 template <class _Tp, class _Alloc>
820 operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
821 return !(_SL2 < _SL1);
824 template <class _Tp, class _Alloc>
826 operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
827 return !(_SL1 < _SL2);
830 template <class _Tp, class _Alloc>
831 inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) {
835 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
838 template <class _Tp, class _Alloc>
839 void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x)
841 _Node_base* __cur = &this->_M_head;
842 while (__cur->_M_next != 0 && __len > 0) {
844 __cur = __cur->_M_next;
847 this->_M_erase_after(__cur, 0);
849 _M_insert_after_fill(__cur, __len, __x);
852 template <class _Tp, class _Alloc>
853 void slist<_Tp,_Alloc>::remove(const _Tp& __val)
855 _Node_base* __cur = &this->_M_head;
856 while (__cur && __cur->_M_next) {
857 if (((_Node*) __cur->_M_next)->_M_data == __val)
858 this->_M_erase_after(__cur);
860 __cur = __cur->_M_next;
864 template <class _Tp, class _Alloc>
865 void slist<_Tp,_Alloc>::unique()
867 _Node_base* __cur = this->_M_head._M_next;
869 while (__cur->_M_next) {
870 if (((_Node*)__cur)->_M_data ==
871 ((_Node*)(__cur->_M_next))->_M_data)
872 this->_M_erase_after(__cur);
874 __cur = __cur->_M_next;
879 template <class _Tp, class _Alloc>
880 void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x)
882 _Node_base* __n1 = &this->_M_head;
883 while (__n1->_M_next && __x._M_head._M_next) {
884 if (((_Node*) __x._M_head._M_next)->_M_data <
885 ((_Node*) __n1->_M_next)->_M_data)
886 __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
887 __n1 = __n1->_M_next;
889 if (__x._M_head._M_next) {
890 __n1->_M_next = __x._M_head._M_next;
891 __x._M_head._M_next = 0;
895 template <class _Tp, class _Alloc>
896 void slist<_Tp,_Alloc>::sort()
898 if (this->_M_head._M_next && this->_M_head._M_next->_M_next) {
903 __slist_splice_after(&__carry._M_head,
904 &this->_M_head, this->_M_head._M_next);
906 while (__i < __fill && !__counter[__i].empty()) {
907 __counter[__i].merge(__carry);
908 __carry.swap(__counter[__i]);
911 __carry.swap(__counter[__i]);
916 for (int __i = 1; __i < __fill; ++__i)
917 __counter[__i].merge(__counter[__i-1]);
918 this->swap(__counter[__fill-1]);
922 #ifdef __STL_MEMBER_TEMPLATES
924 template <class _Tp, class _Alloc>
925 template <class _Predicate>
926 void slist<_Tp,_Alloc>::remove_if(_Predicate __pred)
928 _Node_base* __cur = &this->_M_head;
929 while (__cur->_M_next) {
930 if (__pred(((_Node*) __cur->_M_next)->_M_data))
931 this->_M_erase_after(__cur);
933 __cur = __cur->_M_next;
937 template <class _Tp, class _Alloc> template <class _BinaryPredicate>
938 void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred)
940 _Node* __cur = (_Node*) this->_M_head._M_next;
942 while (__cur->_M_next) {
943 if (__pred(((_Node*)__cur)->_M_data,
944 ((_Node*)(__cur->_M_next))->_M_data))
945 this->_M_erase_after(__cur);
947 __cur = (_Node*) __cur->_M_next;
952 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
953 void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x,
954 _StrictWeakOrdering __comp)
956 _Node_base* __n1 = &this->_M_head;
957 while (__n1->_M_next && __x._M_head._M_next) {
958 if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
959 ((_Node*) __n1->_M_next)->_M_data))
960 __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
961 __n1 = __n1->_M_next;
963 if (__x._M_head._M_next) {
964 __n1->_M_next = __x._M_head._M_next;
965 __x._M_head._M_next = 0;
969 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
970 void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp)
972 if (this->_M_head._M_next && this->_M_head._M_next->_M_next) {
977 __slist_splice_after(&__carry._M_head,
978 &this->_M_head, this->_M_head._M_next);
980 while (__i < __fill && !__counter[__i].empty()) {
981 __counter[__i].merge(__carry, __comp);
982 __carry.swap(__counter[__i]);
985 __carry.swap(__counter[__i]);
990 for (int __i = 1; __i < __fill; ++__i)
991 __counter[__i].merge(__counter[__i-1], __comp);
992 this->swap(__counter[__fill-1]);
996 #endif /* __STL_MEMBER_TEMPLATES */
998 // Specialization of insert_iterator so that insertions will be constant
999 // time rather than linear time.
1001 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
1003 template <class _Tp, class _Alloc>
1004 class insert_iterator<slist<_Tp, _Alloc> > {
1006 typedef slist<_Tp, _Alloc> _Container;
1007 _Container* container;
1008 typename _Container::iterator iter;
1010 typedef _Container container_type;
1011 typedef output_iterator_tag iterator_category;
1012 typedef void value_type;
1013 typedef void difference_type;
1014 typedef void pointer;
1015 typedef void reference;
1017 insert_iterator(_Container& __x, typename _Container::iterator __i)
1019 if (__i == __x.begin())
1020 iter = __x.before_begin();
1022 iter = __x.previous(__i);
1025 insert_iterator<_Container>&
1026 operator=(const typename _Container::value_type& __value) {
1027 iter = container->insert_after(iter, __value);
1030 insert_iterator<_Container>& operator*() { return *this; }
1031 insert_iterator<_Container>& operator++() { return *this; }
1032 insert_iterator<_Container>& operator++(int) { return *this; }
1035 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
1037 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
1038 #pragma reset woff 1174
1039 #pragma reset woff 1375
1044 #endif /* __SGI_STL_INTERNAL_SLIST_H */