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