Merge from mainline (168000:168310).
[official-gcc/graphite-test-results.git] / libstdc++-v3 / include / ext / slist
bloba34e36e310a8bf23da95d2a4b04485f37d99d658
1 // Singly-linked list implementation -*- C++ -*-
3 // Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008, 2009
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
27  * Copyright (c) 1997
28  * Silicon Graphics Computer Systems, Inc.
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.  Silicon Graphics 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  */
40 /** @file ext/slist
41  *  This file is a GNU extension to the Standard C++ Library (possibly
42  *  containing extensions from the HP/SGI STL subset). 
43  */
45 #ifndef _SLIST
46 #define _SLIST 1
48 #include <algorithm>
49 #include <bits/allocator.h>
50 #include <bits/stl_construct.h>
51 #include <bits/stl_uninitialized.h>
52 #include <bits/concept_check.h>
54 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
56   using std::size_t;
57   using std::ptrdiff_t;
58   using std::_Construct;
59   using std::_Destroy;
60   using std::allocator;
61   using std::__true_type;
62   using std::__false_type;
64   struct _Slist_node_base
65   {
66     _Slist_node_base* _M_next;
67   };
68   
69   inline _Slist_node_base*
70   __slist_make_link(_Slist_node_base* __prev_node,
71                     _Slist_node_base* __new_node)
72   {
73     __new_node->_M_next = __prev_node->_M_next;
74     __prev_node->_M_next = __new_node;
75     return __new_node;
76   }
78   inline _Slist_node_base*
79   __slist_previous(_Slist_node_base* __head,
80                    const _Slist_node_base* __node)
81   {
82     while (__head && __head->_M_next != __node)
83       __head = __head->_M_next;
84     return __head;
85   }
87   inline const _Slist_node_base*
88   __slist_previous(const _Slist_node_base* __head,
89                    const _Slist_node_base* __node)
90   {
91     while (__head && __head->_M_next != __node)
92       __head = __head->_M_next;
93     return __head;
94   }
96   inline void
97   __slist_splice_after(_Slist_node_base* __pos,
98                        _Slist_node_base* __before_first,
99                        _Slist_node_base* __before_last)
100   {
101     if (__pos != __before_first && __pos != __before_last)
102       {
103         _Slist_node_base* __first = __before_first->_M_next;
104         _Slist_node_base* __after = __pos->_M_next;
105         __before_first->_M_next = __before_last->_M_next;
106         __pos->_M_next = __first;
107         __before_last->_M_next = __after;
108       }
109   }
111   inline void
112   __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head)
113   {
114     _Slist_node_base* __before_last = __slist_previous(__head, 0);
115     if (__before_last != __head)
116       {
117         _Slist_node_base* __after = __pos->_M_next;
118         __pos->_M_next = __head->_M_next;
119         __head->_M_next = 0;
120         __before_last->_M_next = __after;
121       }
122   }
124   inline _Slist_node_base*
125   __slist_reverse(_Slist_node_base* __node)
126   {
127     _Slist_node_base* __result = __node;
128     __node = __node->_M_next;
129     __result->_M_next = 0;
130     while(__node)
131       {
132         _Slist_node_base* __next = __node->_M_next;
133         __node->_M_next = __result;
134         __result = __node;
135         __node = __next;
136       }
137     return __result;
138   }
140   inline size_t
141   __slist_size(_Slist_node_base* __node)
142   {
143     size_t __result = 0;
144     for (; __node != 0; __node = __node->_M_next)
145       ++__result;
146     return __result;
147   }
149   template <class _Tp>
150     struct _Slist_node : public _Slist_node_base
151     {
152       _Tp _M_data;
153     };
155   struct _Slist_iterator_base
156   {
157     typedef size_t                    size_type;
158     typedef ptrdiff_t                 difference_type;
159     typedef std::forward_iterator_tag iterator_category;
161     _Slist_node_base* _M_node;
162     
163     _Slist_iterator_base(_Slist_node_base* __x)
164     : _M_node(__x) {}
166     void
167     _M_incr()
168     { _M_node = _M_node->_M_next; }
170     bool
171     operator==(const _Slist_iterator_base& __x) const
172     { return _M_node == __x._M_node; }
174     bool
175     operator!=(const _Slist_iterator_base& __x) const
176     { return _M_node != __x._M_node; }
177   };
179   template <class _Tp, class _Ref, class _Ptr>
180     struct _Slist_iterator : public _Slist_iterator_base
181     {
182       typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
183       typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
184       typedef _Slist_iterator<_Tp, _Ref, _Ptr>             _Self;
186       typedef _Tp              value_type;
187       typedef _Ptr             pointer;
188       typedef _Ref             reference;
189       typedef _Slist_node<_Tp> _Node;
191       explicit
192       _Slist_iterator(_Node* __x)
193       : _Slist_iterator_base(__x) {}
195       _Slist_iterator()
196       : _Slist_iterator_base(0) {}
198       _Slist_iterator(const iterator& __x)
199       : _Slist_iterator_base(__x._M_node) {}
201       reference
202       operator*() const
203       { return ((_Node*) _M_node)->_M_data; }
205       pointer
206       operator->() const
207       { return &(operator*()); }
209       _Self&
210       operator++()
211       {
212         _M_incr();
213         return *this;
214       }
216       _Self
217       operator++(int)
218       {
219         _Self __tmp = *this;
220         _M_incr();
221         return __tmp;
222       }
223     };
225   template <class _Tp, class _Alloc>
226     struct _Slist_base
227     : public _Alloc::template rebind<_Slist_node<_Tp> >::other
228     {
229       typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other
230         _Node_alloc;
231       typedef _Alloc allocator_type;
233       allocator_type
234       get_allocator() const
235       { return *static_cast<const _Node_alloc*>(this); }
237       _Slist_base(const allocator_type& __a)
238       : _Node_alloc(__a)
239       { this->_M_head._M_next = 0; }
241       ~_Slist_base()
242       { _M_erase_after(&this->_M_head, 0); }
244     protected:
245       _Slist_node_base _M_head;
247       _Slist_node<_Tp>*
248       _M_get_node()
249       { return _Node_alloc::allocate(1); }
250   
251       void
252       _M_put_node(_Slist_node<_Tp>* __p)
253       { _Node_alloc::deallocate(__p, 1); }
255     protected:
256       _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
257       {
258         _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
259         _Slist_node_base* __next_next = __next->_M_next;
260         __pos->_M_next = __next_next;
261         get_allocator().destroy(&__next->_M_data);
262         _M_put_node(__next);
263         return __next_next;
264       }
265       _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
266     };
268   template <class _Tp, class _Alloc>
269     _Slist_node_base*
270     _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first,
271                                             _Slist_node_base* __last_node)
272     {
273       _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next);
274       while (__cur != __last_node)
275         {
276           _Slist_node<_Tp>* __tmp = __cur;
277           __cur = (_Slist_node<_Tp>*) __cur->_M_next;
278           get_allocator().destroy(&__tmp->_M_data);
279           _M_put_node(__tmp);
280         }
281       __before_first->_M_next = __last_node;
282       return __last_node;
283     }
285   /**
286    *  This is an SGI extension.
287    *  @ingroup SGIextensions
288    *  @doctodo
289    */
290   template <class _Tp, class _Alloc = allocator<_Tp> >
291     class slist : private _Slist_base<_Tp,_Alloc>
292     {
293       // concept requirements
294       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
295         
296     private:
297       typedef _Slist_base<_Tp,_Alloc> _Base;
299     public:
300       typedef _Tp               value_type;
301       typedef value_type*       pointer;
302       typedef const value_type* const_pointer;
303       typedef value_type&       reference;
304       typedef const value_type& const_reference;
305       typedef size_t            size_type;
306       typedef ptrdiff_t         difference_type;
307       
308       typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
309       typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
310       
311       typedef typename _Base::allocator_type allocator_type;
313       allocator_type
314       get_allocator() const
315       { return _Base::get_allocator(); }
317     private:
318       typedef _Slist_node<_Tp>      _Node;
319       typedef _Slist_node_base      _Node_base;
320       typedef _Slist_iterator_base  _Iterator_base;
321       
322       _Node*
323       _M_create_node(const value_type& __x)
324       {
325         _Node* __node = this->_M_get_node();
326         __try
327           {
328             get_allocator().construct(&__node->_M_data, __x);
329             __node->_M_next = 0;
330           }
331         __catch(...)
332           {
333             this->_M_put_node(__node);
334             __throw_exception_again;
335           }
336         return __node;
337       }
339       _Node*
340       _M_create_node()
341       {
342         _Node* __node = this->_M_get_node();
343         __try
344           {
345             get_allocator().construct(&__node->_M_data, value_type());
346             __node->_M_next = 0;
347           }
348         __catch(...)
349           {
350             this->_M_put_node(__node);
351             __throw_exception_again;
352           }
353         return __node;
354       }
356     public:
357       explicit
358       slist(const allocator_type& __a = allocator_type())
359       : _Base(__a) {}
361       slist(size_type __n, const value_type& __x,
362             const allocator_type& __a =  allocator_type())
363       : _Base(__a)
364       { _M_insert_after_fill(&this->_M_head, __n, __x); }
366       explicit
367       slist(size_type __n)
368       : _Base(allocator_type())
369       { _M_insert_after_fill(&this->_M_head, __n, value_type()); }
371       // We don't need any dispatching tricks here, because
372       // _M_insert_after_range already does them.
373       template <class _InputIterator>
374         slist(_InputIterator __first, _InputIterator __last,
375               const allocator_type& __a =  allocator_type())
376         : _Base(__a)
377         { _M_insert_after_range(&this->_M_head, __first, __last); }
379       slist(const slist& __x)
380       : _Base(__x.get_allocator())
381       { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); }
383       slist&
384       operator= (const slist& __x);
386       ~slist() {}
388     public:
389       // assign(), a generalized assignment member function.  Two
390       // versions: one that takes a count, and one that takes a range.
391       // The range version is a member template, so we dispatch on whether
392       // or not the type is an integer.
393       
394       void
395       assign(size_type __n, const _Tp& __val)
396       { _M_fill_assign(__n, __val); }
398       void
399       _M_fill_assign(size_type __n, const _Tp& __val);
401       template <class _InputIterator>
402         void
403         assign(_InputIterator __first, _InputIterator __last)
404         {
405           typedef typename std::__is_integer<_InputIterator>::__type _Integral;
406           _M_assign_dispatch(__first, __last, _Integral());
407         }
409       template <class _Integer>
410       void
411       _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
412       { _M_fill_assign((size_type) __n, (_Tp) __val); }
414       template <class _InputIterator>
415       void
416       _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
417                          __false_type);
419     public:
421       iterator
422       begin()
423       { return iterator((_Node*)this->_M_head._M_next); }
425       const_iterator
426       begin() const
427       { return const_iterator((_Node*)this->_M_head._M_next);}
429       iterator
430       end()
431       { return iterator(0); }
433       const_iterator
434       end() const
435       { return const_iterator(0); }
437       // Experimental new feature: before_begin() returns a
438       // non-dereferenceable iterator that, when incremented, yields
439       // begin().  This iterator may be used as the argument to
440       // insert_after, erase_after, etc.  Note that even for an empty
441       // slist, before_begin() is not the same iterator as end().  It
442       // is always necessary to increment before_begin() at least once to
443       // obtain end().
444       iterator
445       before_begin()
446       { return iterator((_Node*) &this->_M_head); }
448       const_iterator
449       before_begin() const
450       { return const_iterator((_Node*) &this->_M_head); }
452       size_type
453       size() const
454       { return __slist_size(this->_M_head._M_next); }
456       size_type
457       max_size() const
458       { return size_type(-1); }
460       bool
461       empty() const
462       { return this->_M_head._M_next == 0; }
464       void
465       swap(slist& __x)
466       { std::swap(this->_M_head._M_next, __x._M_head._M_next); }
468     public:
470       reference
471       front()
472       { return ((_Node*) this->_M_head._M_next)->_M_data; }
474       const_reference
475       front() const
476       { return ((_Node*) this->_M_head._M_next)->_M_data; }
478       void
479       push_front(const value_type& __x)
480       { __slist_make_link(&this->_M_head, _M_create_node(__x)); }
482       void
483       push_front()
484       { __slist_make_link(&this->_M_head, _M_create_node()); }
486       void
487       pop_front()
488       {
489         _Node* __node = (_Node*) this->_M_head._M_next;
490         this->_M_head._M_next = __node->_M_next;
491         get_allocator().destroy(&__node->_M_data);
492         this->_M_put_node(__node);
493       }
495       iterator
496       previous(const_iterator __pos)
497       { return iterator((_Node*) __slist_previous(&this->_M_head,
498                                                   __pos._M_node)); }
500       const_iterator
501       previous(const_iterator __pos) const
502       { return const_iterator((_Node*) __slist_previous(&this->_M_head,
503                                                         __pos._M_node)); }
505     private:
506       _Node*
507       _M_insert_after(_Node_base* __pos, const value_type& __x)
508       { return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); }
510       _Node*
511       _M_insert_after(_Node_base* __pos)
512       { return (_Node*) (__slist_make_link(__pos, _M_create_node())); }
514       void
515       _M_insert_after_fill(_Node_base* __pos,
516                            size_type __n, const value_type& __x)
517       {
518         for (size_type __i = 0; __i < __n; ++__i)
519           __pos = __slist_make_link(__pos, _M_create_node(__x));
520       }
522       // Check whether it's an integral type.  If so, it's not an iterator.
523       template <class _InIterator>
524         void
525         _M_insert_after_range(_Node_base* __pos,
526                               _InIterator __first, _InIterator __last)
527         {
528           typedef typename std::__is_integer<_InIterator>::__type _Integral;
529           _M_insert_after_range(__pos, __first, __last, _Integral());
530         }
532       template <class _Integer>
533         void
534         _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
535                               __true_type)
536         { _M_insert_after_fill(__pos, __n, __x); }
538       template <class _InIterator>
539         void
540         _M_insert_after_range(_Node_base* __pos,
541                               _InIterator __first, _InIterator __last,
542                               __false_type)
543         {
544           while (__first != __last)
545             {
546               __pos = __slist_make_link(__pos, _M_create_node(*__first));
547               ++__first;
548             }
549         }
551     public:
552       iterator
553       insert_after(iterator __pos, const value_type& __x)
554       { return iterator(_M_insert_after(__pos._M_node, __x)); }
556       iterator
557       insert_after(iterator __pos)
558       { return insert_after(__pos, value_type()); }
560       void
561       insert_after(iterator __pos, size_type __n, const value_type& __x)
562       { _M_insert_after_fill(__pos._M_node, __n, __x); }
564       // We don't need any dispatching tricks here, because
565       // _M_insert_after_range already does them.
566       template <class _InIterator>
567         void
568         insert_after(iterator __pos, _InIterator __first, _InIterator __last)
569         { _M_insert_after_range(__pos._M_node, __first, __last); }
571       iterator
572       insert(iterator __pos, const value_type& __x)
573       { return iterator(_M_insert_after(__slist_previous(&this->_M_head,
574                                                          __pos._M_node),
575                                         __x)); }
577       iterator
578       insert(iterator __pos)
579       { return iterator(_M_insert_after(__slist_previous(&this->_M_head,
580                                                          __pos._M_node),
581                                         value_type())); }
583       void
584       insert(iterator __pos, size_type __n, const value_type& __x)
585       { _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node),
586                              __n, __x); }
588       // We don't need any dispatching tricks here, because
589       // _M_insert_after_range already does them.
590       template <class _InIterator>
591         void
592         insert(iterator __pos, _InIterator __first, _InIterator __last)
593         { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node),
594                                 __first, __last); }
596     public:
597       iterator
598       erase_after(iterator __pos)
599       { return iterator((_Node*) this->_M_erase_after(__pos._M_node)); }
601       iterator
602       erase_after(iterator __before_first, iterator __last)
603       { 
604         return iterator((_Node*) this->_M_erase_after(__before_first._M_node,
605                                                       __last._M_node));
606       }
608       iterator
609       erase(iterator __pos)
610       { 
611         return iterator((_Node*) this->_M_erase_after
612                         (__slist_previous(&this->_M_head, __pos._M_node)));
613       }
615       iterator
616       erase(iterator __first, iterator __last)
617       { 
618         return iterator((_Node*) this->_M_erase_after
619                         (__slist_previous(&this->_M_head, __first._M_node),
620                          __last._M_node));
621       }
622       
623       void
624       resize(size_type new_size, const _Tp& __x);
626       void
627       resize(size_type new_size)
628       { resize(new_size, _Tp()); }
630       void
631       clear()
632       { this->_M_erase_after(&this->_M_head, 0); }
634     public:
635       // Moves the range [__before_first + 1, __before_last + 1) to *this,
636       //  inserting it immediately after __pos.  This is constant time.
637       void
638       splice_after(iterator __pos,
639                    iterator __before_first, iterator __before_last)
640       {
641         if (__before_first != __before_last)
642           __slist_splice_after(__pos._M_node, __before_first._M_node,
643                                __before_last._M_node);
644       }
646       // Moves the element that follows __prev to *this, inserting it
647       // immediately after __pos.  This is constant time.
648       void
649       splice_after(iterator __pos, iterator __prev)
650       { __slist_splice_after(__pos._M_node,
651                              __prev._M_node, __prev._M_node->_M_next); }
653       // Removes all of the elements from the list __x to *this, inserting
654       // them immediately after __pos.  __x must not be *this.  Complexity:
655       // linear in __x.size().
656       void
657       splice_after(iterator __pos, slist& __x)
658       { __slist_splice_after(__pos._M_node, &__x._M_head); }
660       // Linear in distance(begin(), __pos), and linear in __x.size().
661       void
662       splice(iterator __pos, slist& __x)
663       {
664         if (__x._M_head._M_next)
665           __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
666                                &__x._M_head,
667                                __slist_previous(&__x._M_head, 0)); }
669       // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
670       void
671       splice(iterator __pos, slist& __x, iterator __i)
672       { __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
673                              __slist_previous(&__x._M_head, __i._M_node),
674                              __i._M_node); }
676       // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
677       // and in distance(__first, __last).
678       void
679       splice(iterator __pos, slist& __x, iterator __first, iterator __last)
680       {
681         if (__first != __last)
682           __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
683                                __slist_previous(&__x._M_head, __first._M_node),
684                                __slist_previous(__first._M_node,
685                                                 __last._M_node));
686       }
688     public:
689       void
690       reverse()
691       {
692         if (this->_M_head._M_next)
693           this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
694       }
696       void
697       remove(const _Tp& __val);
699       void
700       unique();
701       
702       void
703       merge(slist& __x);
704       
705       void
706       sort();
708       template <class _Predicate>
709         void
710         remove_if(_Predicate __pred);
712       template <class _BinaryPredicate>
713         void
714         unique(_BinaryPredicate __pred);
716       template <class _StrictWeakOrdering>
717         void
718         merge(slist&, _StrictWeakOrdering);
720       template <class _StrictWeakOrdering>
721         void
722         sort(_StrictWeakOrdering __comp);
723     };
725   template <class _Tp, class _Alloc>
726     slist<_Tp, _Alloc>&
727     slist<_Tp, _Alloc>::operator=(const slist<_Tp, _Alloc>& __x)
728     {
729       if (&__x != this)
730         {
731           _Node_base* __p1 = &this->_M_head;
732           _Node* __n1 = (_Node*) this->_M_head._M_next;
733           const _Node* __n2 = (const _Node*) __x._M_head._M_next;
734           while (__n1 && __n2)
735             {
736               __n1->_M_data = __n2->_M_data;
737               __p1 = __n1;
738               __n1 = (_Node*) __n1->_M_next;
739               __n2 = (const _Node*) __n2->_M_next;
740             }
741           if (__n2 == 0)
742             this->_M_erase_after(__p1, 0);
743           else
744             _M_insert_after_range(__p1, const_iterator((_Node*)__n2),
745                                   const_iterator(0));
746         }
747       return *this;
748     }
750   template <class _Tp, class _Alloc>
751     void
752     slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val)
753     {
754       _Node_base* __prev = &this->_M_head;
755       _Node* __node = (_Node*) this->_M_head._M_next;
756       for (; __node != 0 && __n > 0; --__n)
757         {
758           __node->_M_data = __val;
759           __prev = __node;
760           __node = (_Node*) __node->_M_next;
761         }
762       if (__n > 0)
763         _M_insert_after_fill(__prev, __n, __val);
764       else
765         this->_M_erase_after(__prev, 0);
766     }
767   
768   template <class _Tp, class _Alloc>
769     template <class _InputIterator>
770       void
771       slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first,
772                                              _InputIterator __last,
773                                              __false_type)
774       {
775         _Node_base* __prev = &this->_M_head;
776         _Node* __node = (_Node*) this->_M_head._M_next;
777         while (__node != 0 && __first != __last)
778           {
779             __node->_M_data = *__first;
780             __prev = __node;
781             __node = (_Node*) __node->_M_next;
782             ++__first;
783           }
784         if (__first != __last)
785           _M_insert_after_range(__prev, __first, __last);
786         else
787           this->_M_erase_after(__prev, 0);
788       }
789   
790   template <class _Tp, class _Alloc>
791     inline bool
792     operator==(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
793     {
794       typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
795       const_iterator __end1 = _SL1.end();
796       const_iterator __end2 = _SL2.end();
797       
798       const_iterator __i1 = _SL1.begin();
799       const_iterator __i2 = _SL2.begin();
800       while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2)
801         {
802           ++__i1;
803           ++__i2;
804         }
805       return __i1 == __end1 && __i2 == __end2;
806     }
809   template <class _Tp, class _Alloc>
810     inline bool
811     operator<(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
812     { return std::lexicographical_compare(_SL1.begin(), _SL1.end(),
813                                           _SL2.begin(), _SL2.end()); }
815   template <class _Tp, class _Alloc>
816     inline bool
817     operator!=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
818     { return !(_SL1 == _SL2); }
820   template <class _Tp, class _Alloc>
821     inline bool
822     operator>(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
823     { return _SL2 < _SL1; }
825   template <class _Tp, class _Alloc>
826     inline bool
827     operator<=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
828     { return !(_SL2 < _SL1); }
830   template <class _Tp, class _Alloc>
831     inline bool
832     operator>=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
833     { return !(_SL1 < _SL2); }
835   template <class _Tp, class _Alloc>
836     inline void
837     swap(slist<_Tp, _Alloc>& __x, slist<_Tp, _Alloc>& __y)
838     { __x.swap(__y); }
840   template <class _Tp, class _Alloc>
841     void
842     slist<_Tp, _Alloc>::resize(size_type __len, const _Tp& __x)
843     {
844       _Node_base* __cur = &this->_M_head;
845       while (__cur->_M_next != 0 && __len > 0)
846         {
847           --__len;
848           __cur = __cur->_M_next;
849         }
850       if (__cur->_M_next)
851         this->_M_erase_after(__cur, 0);
852       else
853         _M_insert_after_fill(__cur, __len, __x);
854     }
856   template <class _Tp, class _Alloc>
857     void
858     slist<_Tp, _Alloc>::remove(const _Tp& __val)
859     { 
860       _Node_base* __cur = &this->_M_head;
861       while (__cur && __cur->_M_next)
862         {
863           if (((_Node*) __cur->_M_next)->_M_data == __val)
864             this->_M_erase_after(__cur);
865           else
866             __cur = __cur->_M_next;
867         }
868     }
870   template <class _Tp, class _Alloc>
871     void
872     slist<_Tp, _Alloc>::unique()
873     {
874       _Node_base* __cur = this->_M_head._M_next;
875       if (__cur)
876         {
877           while (__cur->_M_next)
878             {
879               if (((_Node*)__cur)->_M_data
880                   == ((_Node*)(__cur->_M_next))->_M_data)
881                 this->_M_erase_after(__cur);
882               else
883                 __cur = __cur->_M_next;
884             }
885         }
886     }
888   template <class _Tp, class _Alloc>
889     void
890     slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x)
891     {
892       _Node_base* __n1 = &this->_M_head;
893       while (__n1->_M_next && __x._M_head._M_next)
894         {
895           if (((_Node*) __x._M_head._M_next)->_M_data
896               < ((_Node*) __n1->_M_next)->_M_data)
897             __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
898           __n1 = __n1->_M_next;
899         }
900       if (__x._M_head._M_next)
901         {
902           __n1->_M_next = __x._M_head._M_next;
903           __x._M_head._M_next = 0;
904         }
905     }
907   template <class _Tp, class _Alloc>
908     void
909     slist<_Tp, _Alloc>::sort()
910     {
911       if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
912         {
913           slist __carry;
914           slist __counter[64];
915           int __fill = 0;
916           while (!empty())
917             {
918               __slist_splice_after(&__carry._M_head,
919                                    &this->_M_head, this->_M_head._M_next);
920               int __i = 0;
921               while (__i < __fill && !__counter[__i].empty())
922                 {
923                   __counter[__i].merge(__carry);
924                   __carry.swap(__counter[__i]);
925                   ++__i;
926                 }
927               __carry.swap(__counter[__i]);
928               if (__i == __fill)
929                 ++__fill;
930             }
931           
932           for (int __i = 1; __i < __fill; ++__i)
933             __counter[__i].merge(__counter[__i-1]);
934           this->swap(__counter[__fill-1]);
935         }
936     }
938   template <class _Tp, class _Alloc>
939     template <class _Predicate>
940       void slist<_Tp, _Alloc>::remove_if(_Predicate __pred)
941       {
942         _Node_base* __cur = &this->_M_head;
943         while (__cur->_M_next)
944           {
945             if (__pred(((_Node*) __cur->_M_next)->_M_data))
946               this->_M_erase_after(__cur);
947             else
948               __cur = __cur->_M_next;
949           }
950       }
952   template <class _Tp, class _Alloc>
953     template <class _BinaryPredicate>
954       void
955       slist<_Tp, _Alloc>::unique(_BinaryPredicate __pred)
956       {
957         _Node* __cur = (_Node*) this->_M_head._M_next;
958         if (__cur)
959           {
960             while (__cur->_M_next)
961               {
962                 if (__pred(((_Node*)__cur)->_M_data,
963                            ((_Node*)(__cur->_M_next))->_M_data))
964                   this->_M_erase_after(__cur);
965                 else
966                   __cur = (_Node*) __cur->_M_next;
967               }
968           }
969       }
971   template <class _Tp, class _Alloc>
972     template <class _StrictWeakOrdering>
973       void
974       slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x,
975                                _StrictWeakOrdering __comp)
976       {
977         _Node_base* __n1 = &this->_M_head;
978         while (__n1->_M_next && __x._M_head._M_next)
979           {
980             if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
981                        ((_Node*) __n1->_M_next)->_M_data))
982               __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
983             __n1 = __n1->_M_next;
984           }
985         if (__x._M_head._M_next)
986           {
987             __n1->_M_next = __x._M_head._M_next;
988             __x._M_head._M_next = 0;
989           }
990       }
992   template <class _Tp, class _Alloc>
993     template <class _StrictWeakOrdering>
994       void
995       slist<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
996       {
997         if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
998           {
999             slist __carry;
1000             slist __counter[64];
1001             int __fill = 0;
1002             while (!empty())
1003               {
1004                 __slist_splice_after(&__carry._M_head,
1005                                      &this->_M_head, this->_M_head._M_next);
1006                 int __i = 0;
1007                 while (__i < __fill && !__counter[__i].empty())
1008                   {
1009                     __counter[__i].merge(__carry, __comp);
1010                     __carry.swap(__counter[__i]);
1011                     ++__i;
1012                   }
1013                 __carry.swap(__counter[__i]);
1014                 if (__i == __fill)
1015                   ++__fill;
1016               }
1018             for (int __i = 1; __i < __fill; ++__i)
1019               __counter[__i].merge(__counter[__i-1], __comp);
1020             this->swap(__counter[__fill-1]);
1021           }
1022       }
1024 _GLIBCXX_END_NAMESPACE
1026 _GLIBCXX_BEGIN_NAMESPACE(std)
1028   // Specialization of insert_iterator so that insertions will be constant
1029   // time rather than linear time.
1030   template <class _Tp, class _Alloc>
1031     class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> >
1032     {
1033     protected:
1034       typedef __gnu_cxx::slist<_Tp, _Alloc> _Container;
1035       _Container* container;
1036       typename _Container::iterator iter;
1038     public:
1039       typedef _Container          container_type;
1040       typedef output_iterator_tag iterator_category;
1041       typedef void                value_type;
1042       typedef void                difference_type;
1043       typedef void                pointer;
1044       typedef void                reference;
1046       insert_iterator(_Container& __x, typename _Container::iterator __i)
1047       : container(&__x)
1048       {
1049         if (__i == __x.begin())
1050           iter = __x.before_begin();
1051         else
1052           iter = __x.previous(__i);
1053       }
1055       insert_iterator<_Container>&
1056       operator=(const typename _Container::value_type& __value)
1057       {
1058         iter = container->insert_after(iter, __value);
1059         return *this;
1060       }
1062       insert_iterator<_Container>&
1063       operator*()
1064       { return *this; }
1066       insert_iterator<_Container>&
1067       operator++()
1068       { return *this; }
1070       insert_iterator<_Container>&
1071       operator++(int)
1072       { return *this; }
1073     };
1075 _GLIBCXX_END_NAMESPACE
1077 #endif