Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5134 serge 1
// Singly-linked list implementation -*- C++ -*-
2
 
3
// Copyright (C) 2001-2013 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 3, 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
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// .
24
 
25
/*
26
 * Copyright (c) 1997
27
 * Silicon Graphics Computer Systems, Inc.
28
 *
29
 * Permission to use, copy, modify, distribute and sell this software
30
 * and its documentation for any purpose is hereby granted without fee,
31
 * provided that the above copyright notice appear in all copies and
32
 * that both that copyright notice and this permission notice appear
33
 * in supporting documentation.  Silicon Graphics makes no
34
 * representations about the suitability of this software for any
35
 * purpose.  It is provided "as is" without express or implied warranty.
36
 *
37
 */
38
 
39
/** @file ext/slist
40
 *  This file is a GNU extension to the Standard C++ Library (possibly
41
 *  containing extensions from the HP/SGI STL subset).
42
 */
43
 
44
#ifndef _SLIST
45
#define _SLIST 1
46
 
47
#include 
48
#include 
49
#include 
50
#include 
51
#include 
52
 
53
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
54
{
55
_GLIBCXX_BEGIN_NAMESPACE_VERSION
56
 
57
  using std::size_t;
58
  using std::ptrdiff_t;
59
  using std::_Construct;
60
  using std::_Destroy;
61
  using std::allocator;
62
  using std::__true_type;
63
  using std::__false_type;
64
 
65
  struct _Slist_node_base
66
  {
67
    _Slist_node_base* _M_next;
68
  };
69
 
70
  inline _Slist_node_base*
71
  __slist_make_link(_Slist_node_base* __prev_node,
72
		    _Slist_node_base* __new_node)
73
  {
74
    __new_node->_M_next = __prev_node->_M_next;
75
    __prev_node->_M_next = __new_node;
76
    return __new_node;
77
  }
78
 
79
  inline _Slist_node_base*
80
  __slist_previous(_Slist_node_base* __head,
81
		   const _Slist_node_base* __node)
82
  {
83
    while (__head && __head->_M_next != __node)
84
      __head = __head->_M_next;
85
    return __head;
86
  }
87
 
88
  inline const _Slist_node_base*
89
  __slist_previous(const _Slist_node_base* __head,
90
		   const _Slist_node_base* __node)
91
  {
92
    while (__head && __head->_M_next != __node)
93
      __head = __head->_M_next;
94
    return __head;
95
  }
96
 
97
  inline void
98
  __slist_splice_after(_Slist_node_base* __pos,
99
		       _Slist_node_base* __before_first,
100
		       _Slist_node_base* __before_last)
101
  {
102
    if (__pos != __before_first && __pos != __before_last)
103
      {
104
	_Slist_node_base* __first = __before_first->_M_next;
105
	_Slist_node_base* __after = __pos->_M_next;
106
	__before_first->_M_next = __before_last->_M_next;
107
	__pos->_M_next = __first;
108
	__before_last->_M_next = __after;
109
      }
110
  }
111
 
112
  inline void
113
  __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head)
114
  {
115
    _Slist_node_base* __before_last = __slist_previous(__head, 0);
116
    if (__before_last != __head)
117
      {
118
	_Slist_node_base* __after = __pos->_M_next;
119
	__pos->_M_next = __head->_M_next;
120
	__head->_M_next = 0;
121
	__before_last->_M_next = __after;
122
      }
123
  }
124
 
125
  inline _Slist_node_base*
126
  __slist_reverse(_Slist_node_base* __node)
127
  {
128
    _Slist_node_base* __result = __node;
129
    __node = __node->_M_next;
130
    __result->_M_next = 0;
131
    while(__node)
132
      {
133
	_Slist_node_base* __next = __node->_M_next;
134
	__node->_M_next = __result;
135
	__result = __node;
136
	__node = __next;
137
      }
138
    return __result;
139
  }
140
 
141
  inline size_t
142
  __slist_size(_Slist_node_base* __node)
143
  {
144
    size_t __result = 0;
145
    for (; __node != 0; __node = __node->_M_next)
146
      ++__result;
147
    return __result;
148
  }
149
 
150
  template 
151
    struct _Slist_node : public _Slist_node_base
152
    {
153
      _Tp _M_data;
154
    };
155
 
156
  struct _Slist_iterator_base
157
  {
158
    typedef size_t                    size_type;
159
    typedef ptrdiff_t                 difference_type;
160
    typedef std::forward_iterator_tag iterator_category;
161
 
162
    _Slist_node_base* _M_node;
163
 
164
    _Slist_iterator_base(_Slist_node_base* __x)
165
    : _M_node(__x) {}
166
 
167
    void
168
    _M_incr()
169
    { _M_node = _M_node->_M_next; }
170
 
171
    bool
172
    operator==(const _Slist_iterator_base& __x) const
173
    { return _M_node == __x._M_node; }
174
 
175
    bool
176
    operator!=(const _Slist_iterator_base& __x) const
177
    { return _M_node != __x._M_node; }
178
  };
179
 
180
  template 
181
    struct _Slist_iterator : public _Slist_iterator_base
182
    {
183
      typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
184
      typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
185
      typedef _Slist_iterator<_Tp, _Ref, _Ptr>             _Self;
186
 
187
      typedef _Tp              value_type;
188
      typedef _Ptr             pointer;
189
      typedef _Ref             reference;
190
      typedef _Slist_node<_Tp> _Node;
191
 
192
      explicit
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 
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(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 
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  >
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 
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 
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 
411
      void
412
      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
413
      { _M_fill_assign((size_type) __n, (_Tp) __val); }
414
 
415
      template 
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 
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 
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 
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 
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 
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
      {
605
	return iterator((_Node*) this->_M_erase_after(__before_first._M_node,
606
						      __last._M_node));
607
      }
608
 
609
      iterator
610
      erase(iterator __pos)
611
      {
612
	return iterator((_Node*) this->_M_erase_after
613
			(__slist_previous(&this->_M_head, __pos._M_node)));
614
      }
615
 
616
      iterator
617
      erase(iterator __first, iterator __last)
618
      {
619
	return iterator((_Node*) this->_M_erase_after
620
			(__slist_previous(&this->_M_head, __first._M_node),
621
			 __last._M_node));
622
      }
623
 
624
      void
625
      resize(size_type new_size, const _Tp& __x);
626
 
627
      void
628
      resize(size_type new_size)
629
      { resize(new_size, _Tp()); }
630
 
631
      void
632
      clear()
633
      { this->_M_erase_after(&this->_M_head, 0); }
634
 
635
    public:
636
      // Moves the range [__before_first + 1, __before_last + 1) to *this,
637
      //  inserting it immediately after __pos.  This is constant time.
638
      void
639
      splice_after(iterator __pos,
640
		   iterator __before_first, iterator __before_last)
641
      {
642
	if (__before_first != __before_last)
643
	  __slist_splice_after(__pos._M_node, __before_first._M_node,
644
			       __before_last._M_node);
645
      }
646
 
647
      // Moves the element that follows __prev to *this, inserting it
648
      // immediately after __pos.  This is constant time.
649
      void
650
      splice_after(iterator __pos, iterator __prev)
651
      { __slist_splice_after(__pos._M_node,
652
			     __prev._M_node, __prev._M_node->_M_next); }
653
 
654
      // Removes all of the elements from the list __x to *this, inserting
655
      // them immediately after __pos.  __x must not be *this.  Complexity:
656
      // linear in __x.size().
657
      void
658
      splice_after(iterator __pos, slist& __x)
659
      { __slist_splice_after(__pos._M_node, &__x._M_head); }
660
 
661
      // Linear in distance(begin(), __pos), and linear in __x.size().
662
      void
663
      splice(iterator __pos, slist& __x)
664
      {
665
	if (__x._M_head._M_next)
666
	  __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
667
			       &__x._M_head,
668
			       __slist_previous(&__x._M_head, 0)); }
669
 
670
      // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
671
      void
672
      splice(iterator __pos, slist& __x, iterator __i)
673
      { __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
674
			     __slist_previous(&__x._M_head, __i._M_node),
675
			     __i._M_node); }
676
 
677
      // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
678
      // and in distance(__first, __last).
679
      void
680
      splice(iterator __pos, slist& __x, iterator __first, iterator __last)
681
      {
682
	if (__first != __last)
683
	  __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
684
			       __slist_previous(&__x._M_head, __first._M_node),
685
			       __slist_previous(__first._M_node,
686
						__last._M_node));
687
      }
688
 
689
    public:
690
      void
691
      reverse()
692
      {
693
	if (this->_M_head._M_next)
694
	  this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
695
      }
696
 
697
      void
698
      remove(const _Tp& __val);
699
 
700
      void
701
      unique();
702
 
703
      void
704
      merge(slist& __x);
705
 
706
      void
707
      sort();
708
 
709
      template 
710
        void
711
        remove_if(_Predicate __pred);
712
 
713
      template 
714
        void
715
        unique(_BinaryPredicate __pred);
716
 
717
      template 
718
        void
719
        merge(slist&, _StrictWeakOrdering);
720
 
721
      template 
722
        void
723
        sort(_StrictWeakOrdering __comp);
724
    };
725
 
726
  template 
727
    slist<_Tp, _Alloc>&
728
    slist<_Tp, _Alloc>::operator=(const slist<_Tp, _Alloc>& __x)
729
    {
730
      if (&__x != this)
731
	{
732
	  _Node_base* __p1 = &this->_M_head;
733
	  _Node* __n1 = (_Node*) this->_M_head._M_next;
734
	  const _Node* __n2 = (const _Node*) __x._M_head._M_next;
735
	  while (__n1 && __n2)
736
	    {
737
	      __n1->_M_data = __n2->_M_data;
738
	      __p1 = __n1;
739
	      __n1 = (_Node*) __n1->_M_next;
740
	      __n2 = (const _Node*) __n2->_M_next;
741
	    }
742
	  if (__n2 == 0)
743
	    this->_M_erase_after(__p1, 0);
744
	  else
745
	    _M_insert_after_range(__p1, const_iterator((_Node*)__n2),
746
                                  const_iterator(0));
747
	}
748
      return *this;
749
    }
750
 
751
  template 
752
    void
753
    slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val)
754
    {
755
      _Node_base* __prev = &this->_M_head;
756
      _Node* __node = (_Node*) this->_M_head._M_next;
757
      for (; __node != 0 && __n > 0; --__n)
758
	{
759
	  __node->_M_data = __val;
760
	  __prev = __node;
761
	  __node = (_Node*) __node->_M_next;
762
	}
763
      if (__n > 0)
764
	_M_insert_after_fill(__prev, __n, __val);
765
      else
766
	this->_M_erase_after(__prev, 0);
767
    }
768
 
769
  template 
770
    template 
771
      void
772
      slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first,
773
					     _InputIterator __last,
774
					     __false_type)
775
      {
776
	_Node_base* __prev = &this->_M_head;
777
	_Node* __node = (_Node*) this->_M_head._M_next;
778
	while (__node != 0 && __first != __last)
779
	  {
780
	    __node->_M_data = *__first;
781
	    __prev = __node;
782
	    __node = (_Node*) __node->_M_next;
783
	    ++__first;
784
	  }
785
	if (__first != __last)
786
	  _M_insert_after_range(__prev, __first, __last);
787
	else
788
	  this->_M_erase_after(__prev, 0);
789
      }
790
 
791
  template 
792
    inline bool
793
    operator==(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
794
    {
795
      typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
796
      const_iterator __end1 = _SL1.end();
797
      const_iterator __end2 = _SL2.end();
798
 
799
      const_iterator __i1 = _SL1.begin();
800
      const_iterator __i2 = _SL2.begin();
801
      while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2)
802
	{
803
	  ++__i1;
804
	  ++__i2;
805
	}
806
      return __i1 == __end1 && __i2 == __end2;
807
    }
808
 
809
 
810
  template 
811
    inline bool
812
    operator<(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
813
    { return std::lexicographical_compare(_SL1.begin(), _SL1.end(),
814
					  _SL2.begin(), _SL2.end()); }
815
 
816
  template 
817
    inline bool
818
    operator!=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
819
    { return !(_SL1 == _SL2); }
820
 
821
  template 
822
    inline bool
823
    operator>(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
824
    { return _SL2 < _SL1; }
825
 
826
  template 
827
    inline bool
828
    operator<=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
829
    { return !(_SL2 < _SL1); }
830
 
831
  template 
832
    inline bool
833
    operator>=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
834
    { return !(_SL1 < _SL2); }
835
 
836
  template 
837
    inline void
838
    swap(slist<_Tp, _Alloc>& __x, slist<_Tp, _Alloc>& __y)
839
    { __x.swap(__y); }
840
 
841
  template 
842
    void
843
    slist<_Tp, _Alloc>::resize(size_type __len, const _Tp& __x)
844
    {
845
      _Node_base* __cur = &this->_M_head;
846
      while (__cur->_M_next != 0 && __len > 0)
847
	{
848
	  --__len;
849
	  __cur = __cur->_M_next;
850
	}
851
      if (__cur->_M_next)
852
	this->_M_erase_after(__cur, 0);
853
      else
854
	_M_insert_after_fill(__cur, __len, __x);
855
    }
856
 
857
  template 
858
    void
859
    slist<_Tp, _Alloc>::remove(const _Tp& __val)
860
    {
861
      _Node_base* __cur = &this->_M_head;
862
      while (__cur && __cur->_M_next)
863
	{
864
	  if (((_Node*) __cur->_M_next)->_M_data == __val)
865
	    this->_M_erase_after(__cur);
866
	  else
867
	    __cur = __cur->_M_next;
868
	}
869
    }
870
 
871
  template 
872
    void
873
    slist<_Tp, _Alloc>::unique()
874
    {
875
      _Node_base* __cur = this->_M_head._M_next;
876
      if (__cur)
877
	{
878
	  while (__cur->_M_next)
879
	    {
880
	      if (((_Node*)__cur)->_M_data
881
		  == ((_Node*)(__cur->_M_next))->_M_data)
882
		this->_M_erase_after(__cur);
883
	      else
884
		__cur = __cur->_M_next;
885
	    }
886
	}
887
    }
888
 
889
  template 
890
    void
891
    slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x)
892
    {
893
      _Node_base* __n1 = &this->_M_head;
894
      while (__n1->_M_next && __x._M_head._M_next)
895
	{
896
	  if (((_Node*) __x._M_head._M_next)->_M_data
897
	      < ((_Node*) __n1->_M_next)->_M_data)
898
	    __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
899
	  __n1 = __n1->_M_next;
900
	}
901
      if (__x._M_head._M_next)
902
	{
903
	  __n1->_M_next = __x._M_head._M_next;
904
	  __x._M_head._M_next = 0;
905
	}
906
    }
907
 
908
  template 
909
    void
910
    slist<_Tp, _Alloc>::sort()
911
    {
912
      if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
913
	{
914
	  slist __carry;
915
	  slist __counter[64];
916
	  int __fill = 0;
917
	  while (!empty())
918
	    {
919
	      __slist_splice_after(&__carry._M_head,
920
				   &this->_M_head, this->_M_head._M_next);
921
	      int __i = 0;
922
	      while (__i < __fill && !__counter[__i].empty())
923
		{
924
		  __counter[__i].merge(__carry);
925
		  __carry.swap(__counter[__i]);
926
		  ++__i;
927
		}
928
	      __carry.swap(__counter[__i]);
929
	      if (__i == __fill)
930
		++__fill;
931
	    }
932
 
933
	  for (int __i = 1; __i < __fill; ++__i)
934
	    __counter[__i].merge(__counter[__i-1]);
935
	  this->swap(__counter[__fill-1]);
936
	}
937
    }
938
 
939
  template 
940
    template 
941
      void slist<_Tp, _Alloc>::remove_if(_Predicate __pred)
942
      {
943
	_Node_base* __cur = &this->_M_head;
944
	while (__cur->_M_next)
945
	  {
946
	    if (__pred(((_Node*) __cur->_M_next)->_M_data))
947
	      this->_M_erase_after(__cur);
948
	    else
949
	      __cur = __cur->_M_next;
950
	  }
951
      }
952
 
953
  template 
954
    template 
955
      void
956
      slist<_Tp, _Alloc>::unique(_BinaryPredicate __pred)
957
      {
958
	_Node* __cur = (_Node*) this->_M_head._M_next;
959
	if (__cur)
960
	  {
961
	    while (__cur->_M_next)
962
	      {
963
		if (__pred(((_Node*)__cur)->_M_data,
964
			   ((_Node*)(__cur->_M_next))->_M_data))
965
		  this->_M_erase_after(__cur);
966
		else
967
		  __cur = (_Node*) __cur->_M_next;
968
	      }
969
	  }
970
      }
971
 
972
  template 
973
    template 
974
      void
975
      slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x,
976
			       _StrictWeakOrdering __comp)
977
      {
978
	_Node_base* __n1 = &this->_M_head;
979
	while (__n1->_M_next && __x._M_head._M_next)
980
	  {
981
	    if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
982
		       ((_Node*) __n1->_M_next)->_M_data))
983
	      __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
984
	    __n1 = __n1->_M_next;
985
	  }
986
	if (__x._M_head._M_next)
987
	  {
988
	    __n1->_M_next = __x._M_head._M_next;
989
	    __x._M_head._M_next = 0;
990
	  }
991
      }
992
 
993
  template 
994
    template 
995
      void
996
      slist<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
997
      {
998
	if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
999
	  {
1000
	    slist __carry;
1001
	    slist __counter[64];
1002
	    int __fill = 0;
1003
	    while (!empty())
1004
	      {
1005
		__slist_splice_after(&__carry._M_head,
1006
				     &this->_M_head, this->_M_head._M_next);
1007
		int __i = 0;
1008
		while (__i < __fill && !__counter[__i].empty())
1009
		  {
1010
		    __counter[__i].merge(__carry, __comp);
1011
		    __carry.swap(__counter[__i]);
1012
		    ++__i;
1013
		  }
1014
		__carry.swap(__counter[__i]);
1015
		if (__i == __fill)
1016
		  ++__fill;
1017
	      }
1018
 
1019
	    for (int __i = 1; __i < __fill; ++__i)
1020
	      __counter[__i].merge(__counter[__i-1], __comp);
1021
	    this->swap(__counter[__fill-1]);
1022
	  }
1023
      }
1024
 
1025
_GLIBCXX_END_NAMESPACE_VERSION
1026
} // namespace
1027
 
1028
namespace std _GLIBCXX_VISIBILITY(default)
1029
{
1030
_GLIBCXX_BEGIN_NAMESPACE_VERSION
1031
 
1032
  // Specialization of insert_iterator so that insertions will be constant
1033
  // time rather than linear time.
1034
  template 
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_VERSION
1080
} // namespace
1081
 
1082
#endif