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