1
/*
2
 * Copyright (c) 1996,1997
3
 * Silicon Graphics Computer Systems, Inc.
4
 *
5
 * Copyright (c) 1997
6
 * Moscow Center for SPARC Technology
7
 *
8
 * Copyright (c) 1999
9
 * Boris Fomitchev
10
 *
11
 * Copyright (c) 2012
12
 * Petr Ovtchenkov
13
 *
14
 * This material is provided "as is", with absolutely no warranty expressed
15
 * or implied. Any use is at your own risk.
16
 *
17
 * Permission to use or copy this software for any purpose is hereby granted
18
 * without fee, provided the above notices are retained on all copies.
19
 * Permission to modify the code and to distribute modified code is granted,
20
 * provided the above notices are retained, and a notice that the code was
21
 * modified is included with the above copyright notice.
22
 *
23
 */
24
25
#ifndef _STLP_FORWARD_LIST
26
#define _STLP_FORWARD_LIST
27
28
#ifndef _STLP_OUTERMOST_HEADER_ID
29
#  define _STLP_OUTERMOST_HEADER_ID 0x58
30
#  include <stl/_prolog.h>
31
#endif
32
33
#include <utility>
34
35
#ifndef _STLP_INTERNAL_ALGOBASE_H
36
#  include <stl/_algobase.h>
37
#endif
38
39
#ifndef _STLP_INTERNAL_ALLOC_H
40
#  include <stl/_alloc.h>
41
#endif
42
43
#ifndef _STLP_INTERNAL_ITERATOR_H
44
#  include <stl/_iterator.h>
45
#endif
46
47
#ifndef _STLP_INTERNAL_FUNCTION_BASE_H
48
#  include <stl/_function_base.h>
49
#endif
50
51
#ifndef _STLP_CSTDDEF
52
#  include <cstddef>
53
#endif
54
55
_STLP_BEGIN_NAMESPACE
56
57
template <class _Tp, class _Alloc> class forward_list;
58
59
_STLP_MOVE_TO_PRIV_NAMESPACE
60
61
struct _Slist_node_base
62
{
63
    _Slist_node_base* _M_next;
64
};
65
66
template <class _Tp>
67
struct _Slist_node :
68
    public _Slist_node_base
69
{
70
    _Slist_node() = default;
71
    _Slist_node( const _Slist_node& ) = default;
72
    _Slist_node( _Slist_node&& ) = default;
73
    _Slist_node& operator =( const _Slist_node& ) = default;
74
    ~_Slist_node() = default;
75
76
    _Tp _M_data;
77
};
78
79
template <class _Tp> class _Slist_iterator;
80
template <class _Tp> class _Slist_iterator<_Tp const>;
81
82
template <class _Tp>
83
class _Slist_iterator
84
{
85
  public:
86
    typedef typename remove_const<_Tp>::type value_type;
87
    typedef value_type* pointer;
88
    typedef value_type& reference;
89
    typedef forward_iterator_tag iterator_category;
90
    typedef size_t size_type;
91
    typedef ptrdiff_t difference_type;
92
93
  private:
94
    typedef _Slist_iterator<value_type> _Self;
95
    typedef _Slist_node<value_type> _Node;
96
97
  public:
98
    _Slist_iterator() = default;
99
    _Slist_iterator(const _Slist_iterator&) = default;
100
    _Slist_iterator(_Slist_iterator&&) = default;
101
102
  private:
103
    explicit _Slist_iterator(_Slist_node_base* __x) :
104
        _M_node(static_cast<_Node*>(__x))
105
      { }
106
107
  public:
108
    _Slist_iterator& operator =( const _Slist_iterator& ) = default;
109
110
    reference operator *() const
111
      { return _M_node->_M_data; }
112
113
    const pointer operator ->() const
114
      { return &_M_node->_M_data; }
115
116
    _Self& operator ++()
117
      {
118
        _M_incr();
119
        return *this;
120
      }
121
    _Self operator ++(int)
122
      {
123
        _Self __tmp = *this;
124
        _M_incr();
125
        return __tmp;
126
      }
127
128
    bool operator ==(const _Self& __y ) const
129
      { return _M_node == __y._M_node; }
130
    bool operator ==(const _Slist_iterator<_Tp const>& __y ) const
131
      { return _M_node == reinterpret_cast<_Node*>(__y._M_node); }
132
    bool operator !=(const _Self& __y ) const
133
      { return _M_node != __y._M_node; }
134
    bool operator !=(const _Slist_iterator<_Tp const>& __y ) const
135
      { return _M_node != reinterpret_cast<_Node*>(__y._M_node); }
136
137
  private:
138
    void _M_incr()
139
      { _M_node = static_cast<_Node*>(_M_node->_M_next); }
140
    _Node* _M_node;
141
142
    template <class _TTp, class _Alloc>
143
    friend class _STLP_STD::forward_list;
144
145
    template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
146
    friend class hashtable;
147
148
    friend class _Slist_iterator<_Tp const>;
149
};
150
151
template <class _Tp>
152
class _Slist_iterator<_Tp const>
153
{
154
  public:
155
    typedef _Tp value_type;
156
    typedef value_type const* pointer;
157
    typedef value_type const& reference;
158
    typedef forward_iterator_tag iterator_category;
159
    typedef size_t size_type;
160
    typedef ptrdiff_t difference_type;
161
162
  private:
163
    typedef _Slist_iterator<value_type const> _Self;
164
    typedef _Slist_node<value_type const> _Node;
165
166
  public:
167
    _Slist_iterator() = default;
168
    _Slist_iterator(const _Slist_iterator&) = default;
169
    _Slist_iterator(_Slist_iterator&&) = default;
170
    _Slist_iterator(const _Slist_iterator<value_type>& x) :
171
        _M_node( reinterpret_cast<_Node*>(x._M_node) )
172
      { }
173
174
  private:
175
    explicit _Slist_iterator(_Slist_node_base* __x) :
176
        _M_node(static_cast<_Node*>(__x))
177
      { }
178
179
  public:
180
    _Slist_iterator& operator =( const _Slist_iterator& ) = default;
181
    _Slist_iterator& operator =( const _Slist_iterator<value_type>& x )
182
      {
183
        _M_node = reinterpret_cast<_Node*>(x._M_node);
184
        return *this;
185
      }
186
187
    reference operator *() const
188
      { return _M_node->_M_data; }
189
190
    const pointer operator ->() const
191
      { return &_M_node->_M_data; }
192
193
    _Self& operator++()
194
      {
195
        _M_incr();
196
        return *this;
197
      }
198
    _Self operator++(int)
199
      {
200
        _Self __tmp = *this;
201
        _M_incr();
202
        return __tmp;
203
      }
204
205
    bool operator ==(const _Self& __y ) const
206
      { return _M_node == __y._M_node; }
207
    bool operator ==(const _Slist_iterator<_Tp>& __y ) const
208
      { return _M_node == reinterpret_cast<_Node*>(__y._M_node); }
209
    bool operator !=(const _Self& __y ) const
210
      { return _M_node != __y._M_node; }
211
    bool operator !=(const _Slist_iterator<_Tp>& __y ) const
212
      { return _M_node != reinterpret_cast<_Node*>(__y._M_node); }
213
214
  private:
215
    void _M_incr()
216
      { _M_node = static_cast<_Node*>(_M_node->_M_next); }
217
218
    _Node* _M_node;
219
     
220
    template <class _TTp, class _Alloc>
221
    friend class _STLP_STD::forward_list;
222
223
    template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
224
    friend class hashtable;
225
226
    friend class _Slist_iterator<_Tp>;
227
};
228
229
#if defined (_STLP_USE_PTR_SPECIALIZATIONS)
230
#  define forward_list _STLP_PTR_IMPL_NAME(forward_list)
231
#elif defined (_STLP_DEBUG)
232
#  define forward_list _STLP_NON_DBG_NAME(forward_list)
233
#else
234
_STLP_MOVE_TO_STD_NAMESPACE
235
#endif
236
237
template <class _Tp, class _Alloc = allocator<_Tp>>
238
class forward_list
239
{
240
  private:
241
    typedef _STLP_PRIV _Slist_node<_Tp> _Node;
242
    typedef typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
243
    typedef _STLP_PRIV _Slist_node_base _Node_base;
244
245
    typedef _STLP_PRIV _STLP_alloc_proxy<_Node_base, _M_node_allocator_type> _AllocProxy;
246
    typedef forward_list<_Tp,_Alloc> _Self;
247
248
  public:
249
    typedef typename remove_const<_Tp>::type value_type;
250
    typedef value_type&       reference;
251
    typedef const value_type& const_reference;
252
    typedef _STLP_PRIV _Slist_iterator<typename remove_const<_Tp>::type> iterator;
253
    typedef _STLP_PRIV _Slist_iterator<typename add_const<_Tp>::type>  const_iterator;
254
    typedef size_t            size_type;
255
    typedef ptrdiff_t         difference_type;
256
257
    typedef _Alloc            allocator_type;
258
    typedef typename allocator_traits<allocator_type>::pointer pointer;
259
    typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
260
261
  private:
262
    _Node* __slist_make_link(_Node_base* __prev_node, _Node* __new_node)
263
      {
264
        __new_node->_M_next = __prev_node->_M_next;
265
        __prev_node->_M_next = __new_node;
266
        return __new_node;
267
      }
268
269
    _Node* _M_create_node(const value_type& __x)
270
      {
271
        _Node* __node = this->_M_head.allocate(1);
272
        _STLP_TRY {
273
          _Self::get_allocator().construct( &__node->_M_data, __x );
274
          __node->_M_next = 0;
275
        }
276
        _STLP_UNWIND(this->_M_head.deallocate(__node, 1))
277
          return __node;
278
      }
279
280
    _Node* _M_create_node(value_type&& __x)
281
      {
282
        _Node* __node = this->_M_head.allocate(1);
283
        _STLP_TRY {
284
          _Self::get_allocator().construct( &__node->_M_data, _STLP_STD::move(__x) );
285
          __node->_M_next = 0;
286
        }
287
        _STLP_UNWIND(this->_M_head.deallocate(__node, 1))
288
          return __node;
289
      }
290
291
  public:
292
    allocator_type get_allocator() const
293
      { return (const _M_node_allocator_type&)_M_head; }
294
295
    explicit forward_list(const allocator_type& __a = allocator_type()) :
296
        _M_head(__a)
297
      { _M_head._M_data._M_next = 0; }
298
299
    explicit forward_list(size_type __n) :
300
        _M_head(allocator_type())
301
      {
302
        _M_head._M_data._M_next = 0;
303
        _M_insert_after_fill(&this->_M_head._M_data, __n, _STLP_DEFAULT_CONSTRUCTED(_Tp));
304
      }
305
306
    forward_list(size_type __n, const value_type& __x, const allocator_type& __a =  allocator_type()) :
307
        _M_head(__a, _STLP_PRIV _Slist_node_base() )
308
      {
309
        _M_head._M_data._M_next = 0;
310
        _M_insert_after_fill(&this->_M_head._M_data, __n, __x);
311
      }
312
313
    // We don't need any dispatching tricks here, because _M_insert_after_range
314
    // already does them.
315
    template <class _InputIterator>
316
    forward_list(_InputIterator __first, _InputIterator __last,
317
                 const allocator_type& __a = allocator_type() ) :
318
        _M_head(__a, _STLP_PRIV _Slist_node_base() )
319
      {
320
        _M_head._M_data._M_next = 0;
321
        _M_insert_after_range(&this->_M_head._M_data, __first, __last);
322
      }
323
324
    forward_list(const _Self& __x) :
325
        _M_head(__x.get_allocator(), _STLP_PRIV _Slist_node_base() )
326
      {
327
        _M_head._M_data._M_next = 0;
328
        _M_insert_after_range(&this->_M_head._M_data, __x.begin(), __x.end());
329
      }
330
331
    forward_list(_Self&& __x) :
332
        _M_head(__x.get_allocator(), _STLP_PRIV _Slist_node_base() )
333
      {
334
        _M_head._M_data._M_next = __x._M_head._M_data._M_next;
335
        __x._M_head._M_data._M_next = 0;
336
      }
337
338
    forward_list(const _Self& __x, const allocator_type& __a) :
339
        _M_head(__a, _STLP_PRIV _Slist_node_base() )
340
      {
341
        _M_head._M_data._M_next = 0;
342
        _M_insert_after_range(&this->_M_head._M_data, __x.begin(), __x.end());
343
      }
344
345
    forward_list(_Self&& __x, const allocator_type& __a) :
346
        _M_head(__a, _STLP_PRIV _Slist_node_base() )
347
      {
348
        _M_head._M_data._M_next = __x._M_head._M_data._M_next;
349
        __x._M_head._M_data._M_next = 0;
350
      }
351
352
    _Self& operator =(const _Self& __x);
353
354
    ~forward_list()
355
      { _M_erase_after(&_M_head._M_data, 0); }
356
357
  private:
358
    template <class S>
359
    void _M_assign_dispatch( size_type __n, S __val, const true_type& )
360
      {
361
        _Node_base* __prev = &this->_M_head._M_data;
362
        _Node_base* __node = this->_M_head._M_data._M_next;
363
        for ( ; __node != 0 && __n > 0 ; --__n) {
364
          __STATIC_CAST(_Node*, __node)->_M_data = __val;
365
          __prev = __node;
366
          __node = __node->_M_next;
367
        }
368
        if (__n > 0) {
369
          _M_insert_after_fill(__prev, __n, __val);
370
        } else {
371
          this->_M_erase_after(__prev, 0);
372
        }
373
      }
374
375
    template <class _InputIterator>
376
    void _M_assign_dispatch( _InputIterator __first, _InputIterator __last, const false_type& )
377
      {
378
        _Node_base* __prev = &this->_M_head._M_data;
379
        _Node_base* __node = this->_M_head._M_data._M_next;
380
        while (__node != 0 && __first != __last) {
381
          __STATIC_CAST(_Node*, __node)->_M_data = *__first;
382
          __prev = __node;
383
          __node = __node->_M_next;
384
          ++__first;
385
        }
386
        if (__first != __last) {
387
          _M_insert_after_range(__prev, __first, __last);
388
        } else {
389
          this->_M_erase_after(__prev, 0);
390
        }
391
      }
392
393
  public:
394
    // assign(), a generalized assignment member function.  Two
395
    // versions: one that takes a count, and one that takes a range.
396
    // The range version is a member template, so we dispatch on whether
397
    // or not the type is an integer.
398
399
    template <class _InputIterator>
400
    void assign(_InputIterator __first, _InputIterator __last)
401
      { _Self::_M_assign_dispatch(__first, __last, typename is_convertible<_InputIterator,size_type>::type() ); }
402
403
    void assign(size_type __n, const _Tp& __val)
404
      { _Self::_M_assign_dispatch( __n, __val, true_type() ); }
405
406
    iterator before_begin()
407
      { return iterator(&this->_M_head._M_data); }
408
    const_iterator before_begin() const
409
      { return const_iterator(__CONST_CAST(_Node_base*, &this->_M_head._M_data)); }
410
411
    iterator begin()
412
      { return iterator(this->_M_head._M_data._M_next); }
413
    const_iterator begin() const
414
      { return const_iterator(this->_M_head._M_data._M_next);}
415
    const_iterator cbegin() const
416
      { return const_iterator(this->_M_head._M_data._M_next);}
417
418
    iterator end() { return iterator(0); }
419
    const_iterator end() const { return const_iterator(0); }
420
    const_iterator cend() const { return const_iterator(0); }
421
422
    size_type size() const
423
      {
424
        size_type __result = 0;
425
        for ( _Node_base* __node = this->_M_head._M_data._M_next; __node != 0; __node = __node->_M_next) {
426
          ++__result;
427
        }
428
        return __result;
429
      }
430
431
    size_type max_size() const { return size_type(-1); }
432
433
    bool empty() const { return this->_M_head._M_data._M_next == 0; }
434
435
    void swap(_Self& __x)
436
      { /* this->_M_head.swap(__x._M_head); */ _STLP_STD::swap(this->_M_head, __x._M_head); }
437
#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
438
    void _M_swap_workaround(_Self& __x) { swap(__x); }
439
#endif
440
441
    reference front()
442
      { return *begin(); }
443
    const_reference front() const
444
      { return *begin(); }
445
    void push_front(const value_type& __x)
446
      { _Self::__slist_make_link(&this->_M_head._M_data, _M_create_node(__x)); }
447
    void push_front(value_type&& __x)
448
      { _Self::__slist_make_link(&this->_M_head._M_data, _M_create_node(_STLP_STD::move(__x))); }
449
450
    void pop_front()
451
      {
452
        _Node* __node = __STATIC_CAST(_Node*, this->_M_head._M_data._M_next);
453
        this->_M_head._M_data._M_next = __node->_M_next;
454
        this->get_allocator().destroy( &__node->_M_data );
455
        this->_M_head.deallocate(__node, 1);
456
      }
457
458
  private:
459
    _Node* _M_insert_after(_Node_base* __pos, const value_type& __x)
460
      { return _Self::__slist_make_link(__pos, _M_create_node(__x)); }
461
462
    _Node* _M_insert_after(_Node_base* __pos, value_type&& __x)
463
      { return _Self::__slist_make_link(__pos, _M_create_node(_STLP_STD::move(__x))); }
464
465
    void _M_insert_after_fill(_Node_base* __pos, size_type __n, const value_type& __x)
466
      {
467
        for (size_type __i = 0; __i < __n; ++__i) {
468
          __pos = _Self::__slist_make_link(__pos, _M_create_node(__x));
469
        }
470
      }
471
472
    // Check whether it's an integral type.  If so, it's not an iterator.
473
    template <class _InIter>
474
    void _M_insert_after_range(_Node_base* __pos, _InIter __first, _InIter __last)
475
      {
476
        typedef typename is_integral<_InIter>::type _Integral;
477
        _M_insert_after_range(__pos, __first, __last, _Integral());
478
      }
479
480
    template <class _Integer>
481
    void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, const true_type&)
482
      { _M_insert_after_fill(__pos, __n, __x); }
483
484
    template <class _InIter>
485
    void _M_insert_after_range(_Node_base* __pos, _InIter __first, _InIter __last, const false_type&)
486
      {
487
        while (__first != __last) {
488
          __pos = _Self::__slist_make_link(__pos, _M_create_node(*__first));
489
          ++__first;
490
        }
491
      }
492
493
  public:
494
    iterator insert_after(const_iterator __pos, const value_type& __x)
495
      { return iterator(_M_insert_after(__pos._M_node, __x)); }
496
    iterator insert_after(const_iterator __pos, value_type&& __x)
497
      { return iterator(_M_insert_after(__pos._M_node, _STLP_STD::move(__x))); }
498
499
    void insert_after(const_iterator __pos, size_type __n, const value_type& __x)
500
      { _M_insert_after_fill(__pos._M_node, __n, __x); }
501
502
    // We don't need any dispatching tricks here, because _M_insert_after_range
503
    // already does them.
504
    template <class _InIter>
505
    void insert_after(const_iterator __pos, _InIter __first, _InIter __last)
506
      { _M_insert_after_range(__pos._M_node, __first, __last); }
507
508
    iterator erase_after(const_iterator __pos)
509
      { return iterator(this->_M_erase_after(__pos._M_node)); }
510
    iterator erase_after(const_iterator __before_first, const_iterator __last)
511
      { return iterator(this->_M_erase_after(__before_first._M_node, __last._M_node)); }
512
513
    void resize(size_type new_size, const value_type& __x);
514
515
    void resize(size_type new_size)
516
      { resize(new_size, value_type()); }
517
518
    void clear()
519
      { this->_M_erase_after(&this->_M_head._M_data, 0); }
520
521
    // Removes all of the elements from the list __x to *this, inserting
522
    // them immediately after __pos.  __x must not be *this.  Complexity:
523
    // linear in __x.size().
524
    void splice_after(const_iterator __pos, _Self& __x)
525
      {
526
        if ( !__x.empty() ) {
527
          if ( get_allocator() == __x.get_allocator() ) {
528
            _Node_base* tmp = __pos._M_node->_M_next;
529
            _Node_base* __node = __pos._M_node->_M_next = __x._M_head._M_data._M_next;
530
            while (__node->_M_next) {
531
              __node = __node->_M_next;
532
            }
533
            __node->_M_next = tmp;
534
            __x._M_head._M_data._M_next = 0;
535
          } else {
536
            insert_after(__pos, __x.begin(), __x.end() );
537
            __x.clear();
538
          }
539
        }
540
      }
541
542
    void splice_after(const_iterator __pos, _Self&& __x)
543
      {
544
        if ( !__x.empty() ) {
545
          if ( get_allocator() == __x.get_allocator() ) {
546
            _Node_base* tmp = __pos._M_node->_M_next;
547
            _Node_base* __node = __pos._M_node->_M_next = __x._M_head._M_data._M_next;
548
            while (__node->_M_next) {
549
              __node = __node->_M_next;
550
            }
551
            __node->_M_next = tmp;
552
            __x._M_head._M_data._M_next = 0;
553
          } else {
554
            insert_after(__pos, __x.begin(), __x.end() );
555
            __x.clear();
556
          }
557
        }
558
      }
559
560
    // Moves the range (first, last) to *this,
561
    // inserting it immediately after __pos.  This is O(distance(first,last)) time.
562
    void splice_after(const_iterator __pos, _Self& __x, const_iterator first, const_iterator last)
563
      {
564
        if ( first._M_node->_M_next == last._M_node ) {
565
          return;
566
        }
567
568
        if ( get_allocator() == __x.get_allocator() ) {
569
          _Node_base* tmp = __pos._M_node->_M_next;
570
          _Node_base* __node = __pos._M_node->_M_next = first._M_node->_M_next;
571
          while ( __node->_M_next != last._M_node ) {
572
            __node = __node->_M_next;
573
          }
574
          __node->_M_next = tmp;
575
          first._M_node->_M_next = last._M_node;
576
        } else {
577
          const_iterator tmp = first++;
578
          insert_after(__pos, first, last);
579
          __x.erase_after(tmp, last);
580
       }
581
      }
582
583
    void splice_after(const_iterator __pos, _Self&& __x, const_iterator first, const_iterator last)
584
      {
585
        if ( first._M_node->_M_next == last._M_node ) {
586
          return;
587
        }
588
589
        if ( get_allocator() == __x.get_allocator() ) {
590
          _Node_base* tmp = __pos._M_node->_M_next;
591
          _Node_base* __node = __pos._M_node->_M_next = first._M_node->_M_next;
592
          while ( __node->_M_next != last._M_node ) {
593
            __node = __node->_M_next;
594
          }
595
          __node->_M_next = tmp;
596
          first._M_node->_M_next = last._M_node;
597
        } else {
598
          const_iterator tmp = first++;
599
          insert_after(__pos, first, last);
600
          __x.erase_after(tmp, last);
601
        }
602
      }
603
604
    // Moves the element that follows __prev to *this, inserting it immediately
605
    //  after __pos.  This is constant time.
606
    void splice_after(const_iterator __pos, _Self& __x, const_iterator __prev)
607
      {
608
        if ( (__pos != __prev) && (__pos._M_node !=  __prev._M_node->_M_next) ) {
609
          if ( get_allocator() == __x.get_allocator() ) {
610
            _Node_base* tmp = __pos._M_node->_M_next;
611
            __pos._M_node->_M_next = __prev._M_node->_M_next;
612
            __prev._M_node->_M_next = __prev._M_node->_M_next->_M_next;
613
            __pos._M_node->_M_next->_M_next = tmp;
614
          } else {
615
            const_iterator tmp = __prev++;
616
            insert_after(__pos, *__prev);
617
            __x.erase_after(tmp);
618
          }
619
        }
620
      }
621
622
    void splice_after(const_iterator __pos, _Self&& __x, const_iterator __prev)
623
      {
624
        if ( (__pos != __prev) && (__pos._M_node !=  __prev._M_node->_M_next) ) {
625
          if ( get_allocator() == __x.get_allocator() ) {
626
            _Node_base* tmp = __pos._M_node->_M_next;
627
            __pos._M_node->_M_next = __prev._M_node->_M_next;
628
            __prev._M_node->_M_next = __prev._M_node->_M_next->_M_next;
629
            __pos._M_node->_M_next->_M_next = tmp;
630
          } else {
631
            const_iterator tmp = __prev++;
632
            insert_after(__pos, *__prev);
633
            __x.erase_after(tmp);
634
          }
635
        }
636
      }
637
638
    void reverse()
639
      {
640
        if (this->_M_head._M_data._M_next) {
641
          _Node_base* __cur = this->_M_head._M_data._M_next;
642
          _Node_base* __prev = __cur;
643
          _Node_base* __next;
644
          __cur = __cur->_M_next;
645
          __prev->_M_next = 0;
646
          while ( __cur ) {
647
            __next = __cur->_M_next;
648
            __cur->_M_next = __prev;
649
            __prev = __cur;
650
            __cur = __next;
651
          }
652
          this->_M_head._M_data._M_next = __prev;
653
        }
654
      }
655
656
    void remove(const value_type& __val);
657
658
    void unique()
659
      { this->unique( equal_to<value_type>() ); }
660
    void merge(_Self& __x)
661
      { this->merge( __x, less<value_type>() ); }
662
    void sort()
663
      { this->sort( less<value_type>() ); }
664
665
    template <class _Predicate>
666
    void remove_if(_Predicate __pred)
667
      {
668
        _Node_base* __cur = &this->_M_head._M_data;
669
        while (__cur->_M_next) {
670
          if (__pred(__STATIC_CAST(_Node*, __cur->_M_next)->_M_data)) {
671
            this->_M_erase_after(__cur);
672
          } else {
673
            __cur = __cur->_M_next;
674
          }
675
        }
676
      }
677
678
    template <class _BinaryPredicate>
679
    void unique(_BinaryPredicate __pred)
680
      {
681
        /*
682
          iterator i2 = begin();
683
          if ( i1 != end() ) {
684
            iterator i1 = i2++;
685
            if ( i2 != end() ) {
686
              if ( *i1 == *i2 ) {
687
                erase_after( i1 );
688
              }
689
            }
690
          }
691
         */
692
693
        iterator __ite = this->begin();
694
        if (__ite != this->end()) {
695
          while (__ite._M_node->_M_next) {
696
            if ( __pred( *__ite, static_cast<_Node*>(__ite._M_node->_M_next)->_M_data ) ) {
697
              this->erase_after(__ite);
698
            } else {
699
              ++__ite;
700
            }
701
          }
702
        }
703
      }
704
705
    template <class _StrictWeakOrdering>
706
    void merge(_Self& __x, _StrictWeakOrdering __comp);
707
708
    template <class _StrictWeakOrdering>
709
    void sort(_StrictWeakOrdering __comp);
710
711
  private:
712
    _Node_base* _M_erase_after(_Node_base* __pos)
713
      {
714
        _Node* __next = __STATIC_CAST(_Node*, __pos->_M_next);
715
        _Node_base* __next_next = __next->_M_next;
716
        __pos->_M_next = __next_next;
717
        this->get_allocator().destroy( &__next->_M_data );
718
        _M_head.deallocate(__next,1);
719
        return __next_next;
720
      }
721
    _Node_base* _M_erase_after(_Node_base*, _Node_base*);
722
723
    _AllocProxy _M_head;
724
};
725
726
#if defined (forward_list)
727
_STLP_MOVE_TO_STD_NAMESPACE
728
#  undef forward_list
729
#endif // forward_list
730
731
_STLP_END_NAMESPACE
732
733
#include <stl/_forward_list.c>
734
735
#if defined (_STLP_USE_PTR_SPECIALIZATIONS)
736
#  include <stl/pointers/_forward_list.h>
737
#endif
738
739
#if defined (_STLP_DEBUG)
740
#  include <stl/debug/_forward_list.h>
741
#endif
742
743
_STLP_BEGIN_NAMESPACE
744
745
template <class _Tp1, class _Alloc1, class _Tp2, class _Alloc2>
746
inline
747
bool _STLP_CALL operator ==(const forward_list<_Tp1,_Alloc1>& _SL1, const forward_list<_Tp2,_Alloc2>& _SL2)
748
{
749
  typedef typename forward_list<_Tp1,_Alloc1>::const_iterator const_iterator1;
750
  typedef typename forward_list<_Tp2,_Alloc2>::const_iterator const_iterator2;
751
  const_iterator1 __end1 = _SL1.end();
752
  const_iterator2 __end2 = _SL2.end();
753
754
  const_iterator1 __i1 = _SL1.begin();
755
  const_iterator2 __i2 = _SL2.begin();
756
  while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
757
    ++__i1;
758
    ++__i2;
759
  }
760
  return __i1 == __end1 && __i2 == __end2;
761
}
762
763
template <class _Tp1, class _Alloc1, class _Tp2, class _Alloc2>
764
inline
765
bool  _STLP_CALL operator <(const forward_list<_Tp1,_Alloc1>& x, const forward_list<_Tp2,_Alloc2>& y)
766
{ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
767
768
template <class _Tp, class _Alloc>
769
inline void _STLP_CALL swap( forward_list<_Tp,_Alloc>& x, forward_list<_Tp,_Alloc>& y )
770
{ x.swap( y ); }
771
772
#if 0
773
#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
774
775
// Specialization of insert_iterator so that insertions will be constant
776
// time rather than linear time.
777
template <class _Tp, class _Alloc>
778
class insert_iterator<forward_list<_Tp, _Alloc> >
779
{
780
  protected:
781
    typedef forward_list<_Tp, _Alloc> _Container;
782
    _Container* _M_container;
783
    typename _Container::iterator _M_iter;
784
  public:
785
    typedef _Container          container_type;
786
    typedef output_iterator_tag iterator_category;
787
    typedef void                value_type;
788
    typedef void                difference_type;
789
    typedef void                pointer;
790
    typedef void                reference;
791
792
    insert_iterator(_Container& __x, typename _Container::iterator __i) :
793
        _M_container(&__x),
794
        _M_iter( __i == __x.begin() ? __x.before_begin() : __x.previous(__i) ) // ups, prev!?...
795
      { }
796
797
    insert_iterator<_Container>&
798
    operator = (const typename _Container::value_type& __val)
799
      {
800
        _M_iter = _M_container->insert_after(_M_iter, __val);
801
        return *this;
802
      }
803
804
  insert_iterator<_Container>& operator*() { return *this; }
805
  insert_iterator<_Container>& operator++() { return *this; }
806
  insert_iterator<_Container>& operator++(int) { return *this; }
807
};
808
#endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
809
#endif // 0
810
811
_STLP_END_NAMESPACE
812
813
#if (_STLP_OUTERMOST_HEADER_ID == 0x58)
814
#  include <stl/_epilog.h>
815
#  undef _STLP_OUTERMOST_HEADER_ID
816
#endif
817
818
#endif /* _STLP_FORWARD_LIST */
819
820
// Local Variables:
821
// mode:C++
822
// End: