2001-10-23 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / libstdc++-v3 / include / ext / slist
blobcc6b6dfa6d212b1025d0153886e1bf5ba8b6b27d
1 // Singly-linked list implementation -*- C++ -*-
3 // Copyright (C) 2001 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 2, or (at your option)
9 // any later version.
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.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
31  * Copyright (c) 1997
32  * Silicon Graphics Computer Systems, Inc.
33  *
34  * Permission to use, copy, modify, distribute and sell this software
35  * and its documentation for any purpose is hereby granted without fee,
36  * provided that the above copyright notice appear in all copies and
37  * that both that copyright notice and this permission notice appear
38  * in supporting documentation.  Silicon Graphics makes no
39  * representations about the suitability of this software for any
40  * purpose.  It is provided "as is" without express or implied warranty.
41  *
42  */
44 /* NOTE: This is an internal header file, included by other STL headers.
45  *   You should not attempt to use it directly.
46  */
48 #ifndef __SGI_STL_INTERNAL_SLIST_H
49 #define __SGI_STL_INTERNAL_SLIST_H
51 #include <bits/stl_algobase.h>
52 #include <bits/stl_alloc.h>
53 #include <bits/stl_construct.h>
54 #include <bits/stl_uninitialized.h>
55 #include <bits/concept_check.h>
57 namespace std
58
60 struct _Slist_node_base
62   _Slist_node_base* _M_next;
65 inline _Slist_node_base*
66 __slist_make_link(_Slist_node_base* __prev_node,
67                   _Slist_node_base* __new_node)
69   __new_node->_M_next = __prev_node->_M_next;
70   __prev_node->_M_next = __new_node;
71   return __new_node;
74 inline _Slist_node_base* 
75 __slist_previous(_Slist_node_base* __head,
76                  const _Slist_node_base* __node)
78   while (__head && __head->_M_next != __node)
79     __head = __head->_M_next;
80   return __head;
83 inline const _Slist_node_base* 
84 __slist_previous(const _Slist_node_base* __head,
85                  const _Slist_node_base* __node)
87   while (__head && __head->_M_next != __node)
88     __head = __head->_M_next;
89   return __head;
92 inline void __slist_splice_after(_Slist_node_base* __pos,
93                                  _Slist_node_base* __before_first,
94                                  _Slist_node_base* __before_last)
96   if (__pos != __before_first && __pos != __before_last) {
97     _Slist_node_base* __first = __before_first->_M_next;
98     _Slist_node_base* __after = __pos->_M_next;
99     __before_first->_M_next = __before_last->_M_next;
100     __pos->_M_next = __first;
101     __before_last->_M_next = __after;
102   }
105 inline void
106 __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head)
108   _Slist_node_base* __before_last = __slist_previous(__head, 0);
109   if (__before_last != __head) {
110     _Slist_node_base* __after = __pos->_M_next;
111     __pos->_M_next = __head->_M_next;
112     __head->_M_next = 0;
113     __before_last->_M_next = __after;
114   }
117 inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node)
119   _Slist_node_base* __result = __node;
120   __node = __node->_M_next;
121   __result->_M_next = 0;
122   while(__node) {
123     _Slist_node_base* __next = __node->_M_next;
124     __node->_M_next = __result;
125     __result = __node;
126     __node = __next;
127   }
128   return __result;
131 inline size_t __slist_size(_Slist_node_base* __node)
133   size_t __result = 0;
134   for ( ; __node != 0; __node = __node->_M_next)
135     ++__result;
136   return __result;
139 template <class _Tp>
140 struct _Slist_node : public _Slist_node_base
142   _Tp _M_data;
145 struct _Slist_iterator_base
147   typedef size_t               size_type;
148   typedef ptrdiff_t            difference_type;
149   typedef forward_iterator_tag iterator_category;
151   _Slist_node_base* _M_node;
153   _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {}
154   void _M_incr() { _M_node = _M_node->_M_next; }
156   bool operator==(const _Slist_iterator_base& __x) const {
157     return _M_node == __x._M_node;
158   }
159   bool operator!=(const _Slist_iterator_base& __x) const {
160     return _M_node != __x._M_node;
161   }
164 template <class _Tp, class _Ref, class _Ptr>
165 struct _Slist_iterator : public _Slist_iterator_base
167   typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
168   typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
169   typedef _Slist_iterator<_Tp, _Ref, _Ptr>             _Self;
171   typedef _Tp              value_type;
172   typedef _Ptr             pointer;
173   typedef _Ref             reference;
174   typedef _Slist_node<_Tp> _Node;
176   _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {}
177   _Slist_iterator() : _Slist_iterator_base(0) {}
178   _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {}
180   reference operator*() const { return ((_Node*) _M_node)->_M_data; }
181   pointer operator->() const { return &(operator*()); }
183   _Self& operator++()
184   {
185     _M_incr();
186     return *this;
187   }
188   _Self operator++(int)
189   {
190     _Self __tmp = *this;
191     _M_incr();
192     return __tmp;
193   }
197 // Base class that encapsulates details of allocators.  Three cases:
198 // an ordinary standard-conforming allocator, a standard-conforming
199 // allocator with no non-static data, and an SGI-style allocator.
200 // This complexity is necessary only because we're worrying about backward
201 // compatibility and because we want to avoid wasting storage on an 
202 // allocator instance if it isn't necessary.
204 // Base for general standard-conforming allocators.
205 template <class _Tp, class _Allocator, bool _IsStatic>
206 class _Slist_alloc_base {
207 public:
208   typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type
209           allocator_type;
210   allocator_type get_allocator() const { return _M_node_allocator; }
212   _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {}
214 protected:
215   _Slist_node<_Tp>* _M_get_node() 
216     { return _M_node_allocator.allocate(1); }
217   void _M_put_node(_Slist_node<_Tp>* __p) 
218     { _M_node_allocator.deallocate(__p, 1); }
220 protected:
221   typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type
222            _M_node_allocator;
223   _Slist_node_base _M_head;
226 // Specialization for instanceless allocators.
227 template <class _Tp, class _Allocator>
228 class _Slist_alloc_base<_Tp,_Allocator, true> {
229 public:
230   typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type
231           allocator_type;
232   allocator_type get_allocator() const { return allocator_type(); }
234   _Slist_alloc_base(const allocator_type&) {}
236 protected:
237   typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type
238           _Alloc_type;
239   _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
240   void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
242 protected:
243   _Slist_node_base _M_head;
247 template <class _Tp, class _Alloc>
248 struct _Slist_base
249   : public _Slist_alloc_base<_Tp, _Alloc,
250                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
252   typedef _Slist_alloc_base<_Tp, _Alloc,
253                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
254           _Base;
255   typedef typename _Base::allocator_type allocator_type;
257   _Slist_base(const allocator_type& __a)
258     : _Base(__a) { this->_M_head._M_next = 0; }
259   ~_Slist_base() { _M_erase_after(&this->_M_head, 0); }
261 protected:
263   _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
264   {
265     _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
266     _Slist_node_base* __next_next = __next->_M_next;
267     __pos->_M_next = __next_next;
268     _Destroy(&__next->_M_data);
269     _M_put_node(__next);
270     return __next_next;
271   }
272   _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
275 template <class _Tp, class _Alloc> 
276 _Slist_node_base*
277 _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first,
278                                         _Slist_node_base* __last_node) {
279   _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next);
280   while (__cur != __last_node) {
281     _Slist_node<_Tp>* __tmp = __cur;
282     __cur = (_Slist_node<_Tp>*) __cur->_M_next;
283     _Destroy(&__tmp->_M_data);
284     _M_put_node(__tmp);
285   }
286   __before_first->_M_next = __last_node;
287   return __last_node;
290 template <class _Tp, class _Alloc = allocator<_Tp> >
291 class slist : private _Slist_base<_Tp,_Alloc>
293   // concept requirements
294   __glibcpp_class_requires(_Tp, _SGIAssignableConcept);
296 private:
297   typedef _Slist_base<_Tp,_Alloc> _Base;
298 public:
299   typedef _Tp                value_type;
300   typedef value_type*       pointer;
301   typedef const value_type* const_pointer;
302   typedef value_type&       reference;
303   typedef const value_type& const_reference;
304   typedef size_t            size_type;
305   typedef ptrdiff_t         difference_type;
307   typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
308   typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
310   typedef typename _Base::allocator_type allocator_type;
311   allocator_type get_allocator() const { return _Base::get_allocator(); }
313 private:
314   typedef _Slist_node<_Tp>      _Node;
315   typedef _Slist_node_base      _Node_base;
316   typedef _Slist_iterator_base  _Iterator_base;
318   _Node* _M_create_node(const value_type& __x) {
319     _Node* __node = this->_M_get_node();
320     try {
321       _Construct(&__node->_M_data, __x);
322       __node->_M_next = 0;
323     }
324     catch(...)
325       {
326         this->_M_put_node(__node);
327         __throw_exception_again;
328       }
329     return __node;
330   }
331   
332   _Node* _M_create_node() {
333     _Node* __node = this->_M_get_node();
334     try {
335       _Construct(&__node->_M_data);
336       __node->_M_next = 0;
337     }
338     catch(...)
339       {
340         this->_M_put_node(__node);
341         __throw_exception_again;
342       }
343     return __node;
344   }
346 public:
347   explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {}
349   slist(size_type __n, const value_type& __x,
350         const allocator_type& __a =  allocator_type()) : _Base(__a)
351     { _M_insert_after_fill(&this->_M_head, __n, __x); }
353   explicit slist(size_type __n) : _Base(allocator_type())
354     { _M_insert_after_fill(&this->_M_head, __n, value_type()); }
356   // We don't need any dispatching tricks here, because _M_insert_after_range
357   // already does them.
358   template <class _InputIterator>
359   slist(_InputIterator __first, _InputIterator __last,
360         const allocator_type& __a =  allocator_type()) : _Base(__a)
361     { _M_insert_after_range(&this->_M_head, __first, __last); }
363   slist(const slist& __x) : _Base(__x.get_allocator())
364     { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); }
366   slist& operator= (const slist& __x);
368   ~slist() {}
370 public:
371   // assign(), a generalized assignment member function.  Two
372   // versions: one that takes a count, and one that takes a range.
373   // The range version is a member template, so we dispatch on whether
374   // or not the type is an integer.
376   void assign(size_type __n, const _Tp& __val)
377     { _M_fill_assign(__n, __val); }
379   void _M_fill_assign(size_type __n, const _Tp& __val);
381   template <class _InputIterator>
382   void assign(_InputIterator __first, _InputIterator __last) {
383     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
384     _M_assign_dispatch(__first, __last, _Integral());
385   }
387   template <class _Integer>
388   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
389     { _M_fill_assign((size_type) __n, (_Tp) __val); }
391   template <class _InputIterator>
392   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
393                           __false_type);
395 public:
397   iterator begin() { return iterator((_Node*)this->_M_head._M_next); }
398   const_iterator begin() const 
399     { return const_iterator((_Node*)this->_M_head._M_next);}
401   iterator end() { return iterator(0); }
402   const_iterator end() const { return const_iterator(0); }
404   // Experimental new feature: before_begin() returns a
405   // non-dereferenceable iterator that, when incremented, yields
406   // begin().  This iterator may be used as the argument to
407   // insert_after, erase_after, etc.  Note that even for an empty 
408   // slist, before_begin() is not the same iterator as end().  It 
409   // is always necessary to increment before_begin() at least once to
410   // obtain end().
411   iterator before_begin() { return iterator((_Node*) &this->_M_head); }
412   const_iterator before_begin() const
413     { return const_iterator((_Node*) &this->_M_head); }
415   size_type size() const { return __slist_size(this->_M_head._M_next); }
416   
417   size_type max_size() const { return size_type(-1); }
419   bool empty() const { return this->_M_head._M_next == 0; }
421   void swap(slist& __x)
422     { std::swap(this->_M_head._M_next, __x._M_head._M_next); }
424 public:
426   reference front() { return ((_Node*) this->_M_head._M_next)->_M_data; }
427   const_reference front() const 
428     { return ((_Node*) this->_M_head._M_next)->_M_data; }
429   void push_front(const value_type& __x)   {
430     __slist_make_link(&this->_M_head, _M_create_node(__x));
431   }
432   void push_front() { __slist_make_link(&this->_M_head, _M_create_node()); }
433   void pop_front() {
434     _Node* __node = (_Node*) this->_M_head._M_next;
435     this->_M_head._M_next = __node->_M_next;
436     _Destroy(&__node->_M_data);
437     this->_M_put_node(__node);
438   }
440   iterator previous(const_iterator __pos) {
441     return iterator((_Node*) __slist_previous(&this->_M_head, __pos._M_node));
442   }
443   const_iterator previous(const_iterator __pos) const {
444     return const_iterator((_Node*) __slist_previous(&this->_M_head,
445                                                     __pos._M_node));
446   }
448 private:
449   _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) {
450     return (_Node*) (__slist_make_link(__pos, _M_create_node(__x)));
451   }
453   _Node* _M_insert_after(_Node_base* __pos) {
454     return (_Node*) (__slist_make_link(__pos, _M_create_node()));
455   }
457   void _M_insert_after_fill(_Node_base* __pos,
458                             size_type __n, const value_type& __x) {
459     for (size_type __i = 0; __i < __n; ++__i)
460       __pos = __slist_make_link(__pos, _M_create_node(__x));
461   }
463   // Check whether it's an integral type.  If so, it's not an iterator.
464   template <class _InIter>
465   void _M_insert_after_range(_Node_base* __pos, 
466                              _InIter __first, _InIter __last) {
467     typedef typename _Is_integer<_InIter>::_Integral _Integral;
468     _M_insert_after_range(__pos, __first, __last, _Integral());
469   }
471   template <class _Integer>
472   void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
473                              __true_type) {
474     _M_insert_after_fill(__pos, __n, __x);
475   }
477   template <class _InIter>
478   void _M_insert_after_range(_Node_base* __pos,
479                              _InIter __first, _InIter __last,
480                              __false_type) {
481     while (__first != __last) {
482       __pos = __slist_make_link(__pos, _M_create_node(*__first));
483       ++__first;
484     }
485   }
487 public:
489   iterator insert_after(iterator __pos, const value_type& __x) {
490     return iterator(_M_insert_after(__pos._M_node, __x));
491   }
493   iterator insert_after(iterator __pos) {
494     return insert_after(__pos, value_type());
495   }
497   void insert_after(iterator __pos, size_type __n, const value_type& __x) {
498     _M_insert_after_fill(__pos._M_node, __n, __x);
499   }
501   // We don't need any dispatching tricks here, because _M_insert_after_range
502   // already does them.
503   template <class _InIter>
504   void insert_after(iterator __pos, _InIter __first, _InIter __last) {
505     _M_insert_after_range(__pos._M_node, __first, __last);
506   }
508   iterator insert(iterator __pos, const value_type& __x) {
509     return iterator(_M_insert_after(__slist_previous(&this->_M_head,
510                                                      __pos._M_node),
511                     __x));
512   }
514   iterator insert(iterator __pos) {
515     return iterator(_M_insert_after(__slist_previous(&this->_M_head,
516                                                      __pos._M_node),
517                                     value_type()));
518   }
520   void insert(iterator __pos, size_type __n, const value_type& __x) {
521     _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node),
522                          __n, __x);
523   } 
524     
525   // We don't need any dispatching tricks here, because _M_insert_after_range
526   // already does them.
527   template <class _InIter>
528   void insert(iterator __pos, _InIter __first, _InIter __last) {
529     _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), 
530                           __first, __last);
531   }
533 public:
534   iterator erase_after(iterator __pos) {
535     return iterator((_Node*) this->_M_erase_after(__pos._M_node));
536   }
537   iterator erase_after(iterator __before_first, iterator __last) {
538     return iterator((_Node*) this->_M_erase_after(__before_first._M_node, 
539                                                   __last._M_node));
540   } 
542   iterator erase(iterator __pos) {
543     return (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head, 
544                                                           __pos._M_node));
545   }
546   iterator erase(iterator __first, iterator __last) {
547     return (_Node*) this->_M_erase_after(
548       __slist_previous(&this->_M_head, __first._M_node), __last._M_node);
549   }
551   void resize(size_type new_size, const _Tp& __x);
552   void resize(size_type new_size) { resize(new_size, _Tp()); }
553   void clear() { this->_M_erase_after(&this->_M_head, 0); }
555 public:
556   // Moves the range [__before_first + 1, __before_last + 1) to *this,
557   //  inserting it immediately after __pos.  This is constant time.
558   void splice_after(iterator __pos, 
559                     iterator __before_first, iterator __before_last)
560   {
561     if (__before_first != __before_last) 
562       __slist_splice_after(__pos._M_node, __before_first._M_node, 
563                            __before_last._M_node);
564   }
566   // Moves the element that follows __prev to *this, inserting it immediately
567   //  after __pos.  This is constant time.
568   void splice_after(iterator __pos, iterator __prev)
569   {
570     __slist_splice_after(__pos._M_node,
571                          __prev._M_node, __prev._M_node->_M_next);
572   }
575   // Removes all of the elements from the list __x to *this, inserting
576   // them immediately after __pos.  __x must not be *this.  Complexity:
577   // linear in __x.size().
578   void splice_after(iterator __pos, slist& __x)
579   {
580     __slist_splice_after(__pos._M_node, &__x._M_head);
581   }
583   // Linear in distance(begin(), __pos), and linear in __x.size().
584   void splice(iterator __pos, slist& __x) {
585     if (__x._M_head._M_next)
586       __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
587                            &__x._M_head, __slist_previous(&__x._M_head, 0));
588   }
590   // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
591   void splice(iterator __pos, slist& __x, iterator __i) {
592     __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
593                          __slist_previous(&__x._M_head, __i._M_node),
594                          __i._M_node);
595   }
597   // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
598   // and in distance(__first, __last).
599   void splice(iterator __pos, slist& __x, iterator __first, iterator __last)
600   {
601     if (__first != __last)
602       __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
603                            __slist_previous(&__x._M_head, __first._M_node),
604                            __slist_previous(__first._M_node, __last._M_node));
605   }
607 public:
608   void reverse() { 
609     if (this->_M_head._M_next)
610       this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
611   }
613   void remove(const _Tp& __val); 
614   void unique(); 
615   void merge(slist& __x);
616   void sort();     
618   template <class _Predicate> 
619   void remove_if(_Predicate __pred);
621   template <class _BinaryPredicate> 
622   void unique(_BinaryPredicate __pred); 
624   template <class _StrictWeakOrdering> 
625   void merge(slist&, _StrictWeakOrdering);
627   template <class _StrictWeakOrdering> 
628   void sort(_StrictWeakOrdering __comp); 
631 template <class _Tp, class _Alloc>
632 slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x)
634   if (&__x != this) {
635     _Node_base* __p1 = &this->_M_head;
636     _Node* __n1 = (_Node*) this->_M_head._M_next;
637     const _Node* __n2 = (const _Node*) __x._M_head._M_next;
638     while (__n1 && __n2) {
639       __n1->_M_data = __n2->_M_data;
640       __p1 = __n1;
641       __n1 = (_Node*) __n1->_M_next;
642       __n2 = (const _Node*) __n2->_M_next;
643     }
644     if (__n2 == 0)
645       this->_M_erase_after(__p1, 0);
646     else
647       _M_insert_after_range(__p1, const_iterator((_Node*)__n2), 
648                                   const_iterator(0));
649   }
650   return *this;
653 template <class _Tp, class _Alloc>
654 void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
655   _Node_base* __prev = &this->_M_head;
656   _Node* __node = (_Node*) this->_M_head._M_next;
657   for ( ; __node != 0 && __n > 0 ; --__n) {
658     __node->_M_data = __val;
659     __prev = __node;
660     __node = (_Node*) __node->_M_next;
661   }
662   if (__n > 0)
663     _M_insert_after_fill(__prev, __n, __val);
664   else
665     this->_M_erase_after(__prev, 0);
668 template <class _Tp, class _Alloc> template <class _InputIter>
669 void
670 slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last,
671                                        __false_type)
673   _Node_base* __prev = &this->_M_head;
674   _Node* __node = (_Node*) this->_M_head._M_next;
675   while (__node != 0 && __first != __last) {
676     __node->_M_data = *__first;
677     __prev = __node;
678     __node = (_Node*) __node->_M_next;
679     ++__first;
680   }
681   if (__first != __last)
682     _M_insert_after_range(__prev, __first, __last);
683   else
684     this->_M_erase_after(__prev, 0);
687 template <class _Tp, class _Alloc>
688 inline bool 
689 operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2)
691   typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
692   const_iterator __end1 = _SL1.end();
693   const_iterator __end2 = _SL2.end();
695   const_iterator __i1 = _SL1.begin();
696   const_iterator __i2 = _SL2.begin();
697   while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
698     ++__i1;
699     ++__i2;
700   }
701   return __i1 == __end1 && __i2 == __end2;
705 template <class _Tp, class _Alloc>
706 inline bool
707 operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2)
709   return lexicographical_compare(_SL1.begin(), _SL1.end(), 
710                                  _SL2.begin(), _SL2.end());
713 template <class _Tp, class _Alloc>
714 inline bool 
715 operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
716   return !(_SL1 == _SL2);
719 template <class _Tp, class _Alloc>
720 inline bool 
721 operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
722   return _SL2 < _SL1;
725 template <class _Tp, class _Alloc>
726 inline bool 
727 operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
728   return !(_SL2 < _SL1);
731 template <class _Tp, class _Alloc>
732 inline bool 
733 operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
734   return !(_SL1 < _SL2);
737 template <class _Tp, class _Alloc>
738 inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) {
739   __x.swap(__y);
743 template <class _Tp, class _Alloc>
744 void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x)
746   _Node_base* __cur = &this->_M_head;
747   while (__cur->_M_next != 0 && __len > 0) {
748     --__len;
749     __cur = __cur->_M_next;
750   }
751   if (__cur->_M_next) 
752     this->_M_erase_after(__cur, 0);
753   else
754     _M_insert_after_fill(__cur, __len, __x);
757 template <class _Tp, class _Alloc>
758 void slist<_Tp,_Alloc>::remove(const _Tp& __val)
760   _Node_base* __cur = &this->_M_head;
761   while (__cur && __cur->_M_next) {
762     if (((_Node*) __cur->_M_next)->_M_data == __val)
763       this->_M_erase_after(__cur);
764     else
765       __cur = __cur->_M_next;
766   }
769 template <class _Tp, class _Alloc> 
770 void slist<_Tp,_Alloc>::unique()
772   _Node_base* __cur = this->_M_head._M_next;
773   if (__cur) {
774     while (__cur->_M_next) {
775       if (((_Node*)__cur)->_M_data == 
776           ((_Node*)(__cur->_M_next))->_M_data)
777         this->_M_erase_after(__cur);
778       else
779         __cur = __cur->_M_next;
780     }
781   }
784 template <class _Tp, class _Alloc>
785 void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x)
787   _Node_base* __n1 = &this->_M_head;
788   while (__n1->_M_next && __x._M_head._M_next) {
789     if (((_Node*) __x._M_head._M_next)->_M_data < 
790         ((_Node*)       __n1->_M_next)->_M_data) 
791       __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
792     __n1 = __n1->_M_next;
793   }
794   if (__x._M_head._M_next) {
795     __n1->_M_next = __x._M_head._M_next;
796     __x._M_head._M_next = 0;
797   }
800 template <class _Tp, class _Alloc>
801 void slist<_Tp,_Alloc>::sort()
803   if (this->_M_head._M_next && this->_M_head._M_next->_M_next) {
804     slist __carry;
805     slist __counter[64];
806     int __fill = 0;
807     while (!empty()) {
808       __slist_splice_after(&__carry._M_head,
809                            &this->_M_head, this->_M_head._M_next);
810       int __i = 0;
811       while (__i < __fill && !__counter[__i].empty()) {
812         __counter[__i].merge(__carry);
813         __carry.swap(__counter[__i]);
814         ++__i;
815       }
816       __carry.swap(__counter[__i]);
817       if (__i == __fill)
818         ++__fill;
819     }
821     for (int __i = 1; __i < __fill; ++__i)
822       __counter[__i].merge(__counter[__i-1]);
823     this->swap(__counter[__fill-1]);
824   }
827 template <class _Tp, class _Alloc> 
828 template <class _Predicate>
829 void slist<_Tp,_Alloc>::remove_if(_Predicate __pred)
831   _Node_base* __cur = &this->_M_head;
832   while (__cur->_M_next) {
833     if (__pred(((_Node*) __cur->_M_next)->_M_data))
834       this->_M_erase_after(__cur);
835     else
836       __cur = __cur->_M_next;
837   }
840 template <class _Tp, class _Alloc> template <class _BinaryPredicate> 
841 void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred)
843   _Node* __cur = (_Node*) this->_M_head._M_next;
844   if (__cur) {
845     while (__cur->_M_next) {
846       if (__pred(((_Node*)__cur)->_M_data, 
847                  ((_Node*)(__cur->_M_next))->_M_data))
848         this->_M_erase_after(__cur);
849       else
850         __cur = (_Node*) __cur->_M_next;
851     }
852   }
855 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
856 void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x,
857                               _StrictWeakOrdering __comp)
859   _Node_base* __n1 = &this->_M_head;
860   while (__n1->_M_next && __x._M_head._M_next) {
861     if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
862                ((_Node*)       __n1->_M_next)->_M_data))
863       __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
864     __n1 = __n1->_M_next;
865   }
866   if (__x._M_head._M_next) {
867     __n1->_M_next = __x._M_head._M_next;
868     __x._M_head._M_next = 0;
869   }
872 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> 
873 void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp)
875   if (this->_M_head._M_next && this->_M_head._M_next->_M_next) {
876     slist __carry;
877     slist __counter[64];
878     int __fill = 0;
879     while (!empty()) {
880       __slist_splice_after(&__carry._M_head,
881                            &this->_M_head, this->_M_head._M_next);
882       int __i = 0;
883       while (__i < __fill && !__counter[__i].empty()) {
884         __counter[__i].merge(__carry, __comp);
885         __carry.swap(__counter[__i]);
886         ++__i;
887       }
888       __carry.swap(__counter[__i]);
889       if (__i == __fill)
890         ++__fill;
891     }
893     for (int __i = 1; __i < __fill; ++__i)
894       __counter[__i].merge(__counter[__i-1], __comp);
895     this->swap(__counter[__fill-1]);
896   }
899 // Specialization of insert_iterator so that insertions will be constant
900 // time rather than linear time.
902 template <class _Tp, class _Alloc>
903 class insert_iterator<slist<_Tp, _Alloc> > {
904 protected:
905   typedef slist<_Tp, _Alloc> _Container;
906   _Container* container;
907   typename _Container::iterator iter;
908 public:
909   typedef _Container          container_type;
910   typedef output_iterator_tag iterator_category;
911   typedef void                value_type;
912   typedef void                difference_type;
913   typedef void                pointer;
914   typedef void                reference;
916   insert_iterator(_Container& __x, typename _Container::iterator __i) 
917     : container(&__x) {
918     if (__i == __x.begin())
919       iter = __x.before_begin();
920     else
921       iter = __x.previous(__i);
922   }
924   insert_iterator<_Container>&
925   operator=(const typename _Container::value_type& __value) { 
926     iter = container->insert_after(iter, __value);
927     return *this;
928   }
929   insert_iterator<_Container>& operator*() { return *this; }
930   insert_iterator<_Container>& operator++() { return *this; }
931   insert_iterator<_Container>& operator++(int) { return *this; }
934 } // namespace std 
936 #endif /* __SGI_STL_INTERNAL_SLIST_H */
938 // Local Variables:
939 // mode:C++
940 // End: