1 // List implementation -*- C++ -*-
3 // Copyright (C) 2001 Free Software Foundation, Inc.
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)
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.
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,
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.
33 * Hewlett-Packard Company
35 * Permission to use, copy, modify, distribute and sell this software
36 * and its documentation for any purpose is hereby granted without fee,
37 * provided that the above copyright notice appear in all copies and
38 * that both that copyright notice and this permission notice appear
39 * in supporting documentation. Hewlett-Packard Company makes no
40 * representations about the suitability of this software for any
41 * purpose. It is provided "as is" without express or implied warranty.
44 * Copyright (c) 1996,1997
45 * Silicon Graphics Computer Systems, Inc.
47 * Permission to use, copy, modify, distribute and sell this software
48 * and its documentation for any purpose is hereby granted without fee,
49 * provided that the above copyright notice appear in all copies and
50 * that both that copyright notice and this permission notice appear
51 * in supporting documentation. Silicon Graphics makes no
52 * representations about the suitability of this software for any
53 * purpose. It is provided "as is" without express or implied warranty.
57 * This is an internal header file, included by other library headers.
58 * You should not attempt to use it directly.
61 #ifndef __SGI_STL_INTERNAL_LIST_H
62 #define __SGI_STL_INTERNAL_LIST_H
64 #include <bits/concept_check.h>
69 struct _List_node_base
{
70 _List_node_base
* _M_next
;
71 _List_node_base
* _M_prev
;
75 struct _List_node
: public _List_node_base
{
79 struct _List_iterator_base
{
80 typedef size_t size_type
;
81 typedef ptrdiff_t difference_type
;
82 typedef bidirectional_iterator_tag iterator_category
;
84 _List_node_base
* _M_node
;
86 _List_iterator_base(_List_node_base
* __x
) : _M_node(__x
) {}
87 _List_iterator_base() {}
89 void _M_incr() { _M_node
= _M_node
->_M_next
; }
90 void _M_decr() { _M_node
= _M_node
->_M_prev
; }
92 bool operator==(const _List_iterator_base
& __x
) const {
93 return _M_node
== __x
._M_node
;
95 bool operator!=(const _List_iterator_base
& __x
) const {
96 return _M_node
!= __x
._M_node
;
100 template<class _Tp
, class _Ref
, class _Ptr
>
101 struct _List_iterator
: public _List_iterator_base
{
102 typedef _List_iterator
<_Tp
,_Tp
&,_Tp
*> iterator
;
103 typedef _List_iterator
<_Tp
,const _Tp
&,const _Tp
*> const_iterator
;
104 typedef _List_iterator
<_Tp
,_Ref
,_Ptr
> _Self
;
106 typedef _Tp value_type
;
107 typedef _Ptr pointer
;
108 typedef _Ref reference
;
109 typedef _List_node
<_Tp
> _Node
;
111 _List_iterator(_Node
* __x
) : _List_iterator_base(__x
) {}
113 _List_iterator(const iterator
& __x
) : _List_iterator_base(__x
._M_node
) {}
115 reference
operator*() const { return ((_Node
*) _M_node
)->_M_data
; }
116 pointer
operator->() const { return &(operator*()); }
118 _Self
& operator++() {
122 _Self
operator++(int) {
127 _Self
& operator--() {
131 _Self
operator--(int) {
139 // Base class that encapsulates details of allocators. Three cases:
140 // an ordinary standard-conforming allocator, a standard-conforming
141 // allocator with no non-static data, and an SGI-style allocator.
142 // This complexity is necessary only because we're worrying about backward
143 // compatibility and because we want to avoid wasting storage on an
144 // allocator instance if it isn't necessary.
147 // Base for general standard-conforming allocators.
148 template <class _Tp
, class _Allocator
, bool _IsStatic
>
149 class _List_alloc_base
{
151 typedef typename _Alloc_traits
<_Tp
, _Allocator
>::allocator_type
153 allocator_type
get_allocator() const { return _Node_allocator
; }
155 _List_alloc_base(const allocator_type
& __a
) : _Node_allocator(__a
) {}
158 _List_node
<_Tp
>* _M_get_node()
159 { return _Node_allocator
.allocate(1); }
160 void _M_put_node(_List_node
<_Tp
>* __p
)
161 { _Node_allocator
.deallocate(__p
, 1); }
164 typename _Alloc_traits
<_List_node
<_Tp
>, _Allocator
>::allocator_type
166 _List_node
<_Tp
>* _M_node
;
169 // Specialization for instanceless allocators.
171 template <class _Tp
, class _Allocator
>
172 class _List_alloc_base
<_Tp
, _Allocator
, true> {
174 typedef typename _Alloc_traits
<_Tp
, _Allocator
>::allocator_type
176 allocator_type
get_allocator() const { return allocator_type(); }
178 _List_alloc_base(const allocator_type
&) {}
181 typedef typename _Alloc_traits
<_List_node
<_Tp
>, _Allocator
>::_Alloc_type
183 _List_node
<_Tp
>* _M_get_node() { return _Alloc_type::allocate(1); }
184 void _M_put_node(_List_node
<_Tp
>* __p
) { _Alloc_type::deallocate(__p
, 1); }
187 _List_node
<_Tp
>* _M_node
;
190 template <class _Tp
, class _Alloc
>
192 : public _List_alloc_base
<_Tp
, _Alloc
,
193 _Alloc_traits
<_Tp
, _Alloc
>::_S_instanceless
>
196 typedef _List_alloc_base
<_Tp
, _Alloc
,
197 _Alloc_traits
<_Tp
, _Alloc
>::_S_instanceless
>
199 typedef typename
_Base::allocator_type allocator_type
;
201 _List_base(const allocator_type
& __a
) : _Base(__a
) {
202 _M_node
= _M_get_node();
203 _M_node
->_M_next
= _M_node
;
204 _M_node
->_M_prev
= _M_node
;
208 _M_put_node(_M_node
);
215 template <class _Tp
, class _Alloc
>
217 _List_base
<_Tp
,_Alloc
>::clear()
219 _List_node
<_Tp
>* __cur
= (_List_node
<_Tp
>*) _M_node
->_M_next
;
220 while (__cur
!= _M_node
) {
221 _List_node
<_Tp
>* __tmp
= __cur
;
222 __cur
= (_List_node
<_Tp
>*) __cur
->_M_next
;
223 _Destroy(&__tmp
->_M_data
);
226 _M_node
->_M_next
= _M_node
;
227 _M_node
->_M_prev
= _M_node
;
230 template <class _Tp
, class _Alloc
= allocator
<_Tp
> >
231 class list
: protected _List_base
<_Tp
, _Alloc
>
233 // concept requirements
234 __glibcpp_class_requires(_Tp
, _SGIAssignableConcept
)
236 typedef _List_base
<_Tp
, _Alloc
> _Base
;
238 typedef void* _Void_pointer
;
241 typedef _Tp value_type
;
242 typedef value_type
* pointer
;
243 typedef const value_type
* const_pointer
;
244 typedef value_type
& reference
;
245 typedef const value_type
& const_reference
;
246 typedef _List_node
<_Tp
> _Node
;
247 typedef size_t size_type
;
248 typedef ptrdiff_t difference_type
;
250 typedef typename
_Base::allocator_type allocator_type
;
251 allocator_type
get_allocator() const { return _Base::get_allocator(); }
254 typedef _List_iterator
<_Tp
,_Tp
&,_Tp
*> iterator
;
255 typedef _List_iterator
<_Tp
,const _Tp
&,const _Tp
*> const_iterator
;
257 typedef reverse_iterator
<const_iterator
> const_reverse_iterator
;
258 typedef reverse_iterator
<iterator
> reverse_iterator
;
261 using _Base::_M_node
;
262 using _Base::_M_put_node
;
263 using _Base::_M_get_node
;
266 _Node
* _M_create_node(const _Tp
& __x
)
268 _Node
* __p
= _M_get_node();
270 _Construct(&__p
->_M_data
, __x
);
275 __throw_exception_again
;
280 _Node
* _M_create_node()
282 _Node
* __p
= _M_get_node();
284 _Construct(&__p
->_M_data
);
289 __throw_exception_again
;
295 explicit list(const allocator_type
& __a
= allocator_type()) : _Base(__a
) {}
297 iterator
begin() { return (_Node
*)(_M_node
->_M_next
); }
298 const_iterator
begin() const { return (_Node
*)(_M_node
->_M_next
); }
300 iterator
end() { return _M_node
; }
301 const_iterator
end() const { return _M_node
; }
303 reverse_iterator
rbegin()
304 { return reverse_iterator(end()); }
305 const_reverse_iterator
rbegin() const
306 { return const_reverse_iterator(end()); }
308 reverse_iterator
rend()
309 { return reverse_iterator(begin()); }
310 const_reverse_iterator
rend() const
311 { return const_reverse_iterator(begin()); }
313 bool empty() const { return _M_node
->_M_next
== _M_node
; }
314 size_type
size() const {
315 size_type __result
= 0;
316 distance(begin(), end(), __result
);
319 size_type
max_size() const { return size_type(-1); }
321 reference
front() { return *begin(); }
322 const_reference
front() const { return *begin(); }
323 reference
back() { return *(--end()); }
324 const_reference
back() const { return *(--end()); }
326 void swap(list
<_Tp
, _Alloc
>& __x
) { std::swap(_M_node
, __x
._M_node
); }
328 iterator
insert(iterator __position
, const _Tp
& __x
) {
329 _Node
* __tmp
= _M_create_node(__x
);
330 __tmp
->_M_next
= __position
._M_node
;
331 __tmp
->_M_prev
= __position
._M_node
->_M_prev
;
332 __position
._M_node
->_M_prev
->_M_next
= __tmp
;
333 __position
._M_node
->_M_prev
= __tmp
;
336 iterator
insert(iterator __position
) { return insert(__position
, _Tp()); }
338 // Check whether it's an integral type. If so, it's not an iterator.
339 template<class _Integer
>
340 void _M_insert_dispatch(iterator __pos
, _Integer __n
, _Integer __x
,
342 _M_fill_insert(__pos
, (size_type
) __n
, (_Tp
) __x
);
345 template <class _InputIterator
>
346 void _M_insert_dispatch(iterator __pos
,
347 _InputIterator __first
, _InputIterator __last
,
350 template <class _InputIterator
>
351 void insert(iterator __pos
, _InputIterator __first
, _InputIterator __last
) {
352 typedef typename _Is_integer
<_InputIterator
>::_Integral _Integral
;
353 _M_insert_dispatch(__pos
, __first
, __last
, _Integral());
356 void insert(iterator __pos
, size_type __n
, const _Tp
& __x
)
357 { _M_fill_insert(__pos
, __n
, __x
); }
358 void _M_fill_insert(iterator __pos
, size_type __n
, const _Tp
& __x
);
360 void push_front(const _Tp
& __x
) { insert(begin(), __x
); }
361 void push_front() {insert(begin());}
362 void push_back(const _Tp
& __x
) { insert(end(), __x
); }
363 void push_back() {insert(end());}
365 iterator
erase(iterator __position
) {
366 _List_node_base
* __next_node
= __position
._M_node
->_M_next
;
367 _List_node_base
* __prev_node
= __position
._M_node
->_M_prev
;
368 _Node
* __n
= (_Node
*) __position
._M_node
;
369 __prev_node
->_M_next
= __next_node
;
370 __next_node
->_M_prev
= __prev_node
;
371 _Destroy(&__n
->_M_data
);
373 return iterator((_Node
*) __next_node
);
375 iterator
erase(iterator __first
, iterator __last
);
376 void clear() { _Base::clear(); }
378 void resize(size_type __new_size
, const _Tp
& __x
);
379 void resize(size_type __new_size
) { this->resize(__new_size
, _Tp()); }
381 void pop_front() { erase(begin()); }
383 iterator __tmp
= end();
386 list(size_type __n
, const _Tp
& __value
,
387 const allocator_type
& __a
= allocator_type())
389 { insert(begin(), __n
, __value
); }
390 explicit list(size_type __n
)
391 : _Base(allocator_type())
392 { insert(begin(), __n
, _Tp()); }
394 // We don't need any dispatching tricks here, because insert does all of
396 template <class _InputIterator
>
397 list(_InputIterator __first
, _InputIterator __last
,
398 const allocator_type
& __a
= allocator_type())
400 { insert(begin(), __first
, __last
); }
402 list(const list
<_Tp
, _Alloc
>& __x
) : _Base(__x
.get_allocator())
403 { insert(begin(), __x
.begin(), __x
.end()); }
407 list
<_Tp
, _Alloc
>& operator=(const list
<_Tp
, _Alloc
>& __x
);
410 // assign(), a generalized assignment member function. Two
411 // versions: one that takes a count, and one that takes a range.
412 // The range version is a member template, so we dispatch on whether
413 // or not the type is an integer.
415 void assign(size_type __n
, const _Tp
& __val
) { _M_fill_assign(__n
, __val
); }
417 void _M_fill_assign(size_type __n
, const _Tp
& __val
);
419 template <class _InputIterator
>
420 void assign(_InputIterator __first
, _InputIterator __last
) {
421 typedef typename _Is_integer
<_InputIterator
>::_Integral _Integral
;
422 _M_assign_dispatch(__first
, __last
, _Integral());
425 template <class _Integer
>
426 void _M_assign_dispatch(_Integer __n
, _Integer __val
, __true_type
)
427 { _M_fill_assign((size_type
) __n
, (_Tp
) __val
); }
429 template <class _InputIterator
>
430 void _M_assign_dispatch(_InputIterator __first
, _InputIterator __last
,
434 void transfer(iterator __position
, iterator __first
, iterator __last
) {
435 if (__position
!= __last
) {
436 // Remove [first, last) from its old position.
437 __last
._M_node
->_M_prev
->_M_next
= __position
._M_node
;
438 __first
._M_node
->_M_prev
->_M_next
= __last
._M_node
;
439 __position
._M_node
->_M_prev
->_M_next
= __first
._M_node
;
441 // Splice [first, last) into its new position.
442 _List_node_base
* __tmp
= __position
._M_node
->_M_prev
;
443 __position
._M_node
->_M_prev
= __last
._M_node
->_M_prev
;
444 __last
._M_node
->_M_prev
= __first
._M_node
->_M_prev
;
445 __first
._M_node
->_M_prev
= __tmp
;
450 void splice(iterator __position
, list
& __x
) {
452 this->transfer(__position
, __x
.begin(), __x
.end());
454 void splice(iterator __position
, list
&, iterator __i
) {
457 if (__position
== __i
|| __position
== __j
) return;
458 this->transfer(__position
, __i
, __j
);
460 void splice(iterator __position
, list
&, iterator __first
, iterator __last
) {
461 if (__first
!= __last
)
462 this->transfer(__position
, __first
, __last
);
464 void remove(const _Tp
& __value
);
466 void merge(list
& __x
);
470 template <class _Predicate
> void remove_if(_Predicate
);
471 template <class _BinaryPredicate
> void unique(_BinaryPredicate
);
472 template <class _StrictWeakOrdering
> void merge(list
&, _StrictWeakOrdering
);
473 template <class _StrictWeakOrdering
> void sort(_StrictWeakOrdering
);
476 template <class _Tp
, class _Alloc
>
478 operator==(const list
<_Tp
,_Alloc
>& __x
, const list
<_Tp
,_Alloc
>& __y
)
480 typedef typename list
<_Tp
,_Alloc
>::const_iterator const_iterator
;
481 const_iterator __end1
= __x
.end();
482 const_iterator __end2
= __y
.end();
484 const_iterator __i1
= __x
.begin();
485 const_iterator __i2
= __y
.begin();
486 while (__i1
!= __end1
&& __i2
!= __end2
&& *__i1
== *__i2
) {
490 return __i1
== __end1
&& __i2
== __end2
;
493 template <class _Tp
, class _Alloc
>
494 inline bool operator<(const list
<_Tp
,_Alloc
>& __x
,
495 const list
<_Tp
,_Alloc
>& __y
)
497 return lexicographical_compare(__x
.begin(), __x
.end(),
498 __y
.begin(), __y
.end());
501 template <class _Tp
, class _Alloc
>
502 inline bool operator!=(const list
<_Tp
,_Alloc
>& __x
,
503 const list
<_Tp
,_Alloc
>& __y
) {
504 return !(__x
== __y
);
507 template <class _Tp
, class _Alloc
>
508 inline bool operator>(const list
<_Tp
,_Alloc
>& __x
,
509 const list
<_Tp
,_Alloc
>& __y
) {
513 template <class _Tp
, class _Alloc
>
514 inline bool operator<=(const list
<_Tp
,_Alloc
>& __x
,
515 const list
<_Tp
,_Alloc
>& __y
) {
519 template <class _Tp
, class _Alloc
>
520 inline bool operator>=(const list
<_Tp
,_Alloc
>& __x
,
521 const list
<_Tp
,_Alloc
>& __y
) {
525 template <class _Tp
, class _Alloc
>
527 swap(list
<_Tp
, _Alloc
>& __x
, list
<_Tp
, _Alloc
>& __y
)
532 template <class _Tp
, class _Alloc
> template <class _InputIter
>
534 list
<_Tp
, _Alloc
>::_M_insert_dispatch(iterator __position
,
535 _InputIter __first
, _InputIter __last
,
538 for ( ; __first
!= __last
; ++__first
)
539 insert(__position
, *__first
);
542 template <class _Tp
, class _Alloc
>
544 list
<_Tp
, _Alloc
>::_M_fill_insert(iterator __position
,
545 size_type __n
, const _Tp
& __x
)
547 for ( ; __n
> 0; --__n
)
548 insert(__position
, __x
);
551 template <class _Tp
, class _Alloc
>
552 typename list
<_Tp
,_Alloc
>::iterator list
<_Tp
, _Alloc
>::erase(iterator __first
,
555 while (__first
!= __last
)
560 template <class _Tp
, class _Alloc
>
561 void list
<_Tp
, _Alloc
>::resize(size_type __new_size
, const _Tp
& __x
)
563 iterator __i
= begin();
565 for ( ; __i
!= end() && __len
< __new_size
; ++__i
, ++__len
)
567 if (__len
== __new_size
)
570 insert(end(), __new_size
- __len
, __x
);
573 template <class _Tp
, class _Alloc
>
574 list
<_Tp
, _Alloc
>& list
<_Tp
, _Alloc
>::operator=(const list
<_Tp
, _Alloc
>& __x
)
577 iterator __first1
= begin();
578 iterator __last1
= end();
579 const_iterator __first2
= __x
.begin();
580 const_iterator __last2
= __x
.end();
581 while (__first1
!= __last1
&& __first2
!= __last2
)
582 *__first1
++ = *__first2
++;
583 if (__first2
== __last2
)
584 erase(__first1
, __last1
);
586 insert(__last1
, __first2
, __last2
);
591 template <class _Tp
, class _Alloc
>
592 void list
<_Tp
, _Alloc
>::_M_fill_assign(size_type __n
, const _Tp
& __val
) {
593 iterator __i
= begin();
594 for ( ; __i
!= end() && __n
> 0; ++__i
, --__n
)
597 insert(end(), __n
, __val
);
602 template <class _Tp
, class _Alloc
> template <class _InputIter
>
604 list
<_Tp
, _Alloc
>::_M_assign_dispatch(_InputIter __first2
, _InputIter __last2
,
607 iterator __first1
= begin();
608 iterator __last1
= end();
609 for ( ; __first1
!= __last1
&& __first2
!= __last2
; ++__first1
, ++__first2
)
610 *__first1
= *__first2
;
611 if (__first2
== __last2
)
612 erase(__first1
, __last1
);
614 insert(__last1
, __first2
, __last2
);
617 template <class _Tp
, class _Alloc
>
618 void list
<_Tp
, _Alloc
>::remove(const _Tp
& __value
)
620 iterator __first
= begin();
621 iterator __last
= end();
622 while (__first
!= __last
) {
623 iterator __next
= __first
;
625 if (*__first
== __value
) erase(__first
);
630 template <class _Tp
, class _Alloc
>
631 void list
<_Tp
, _Alloc
>::unique()
633 iterator __first
= begin();
634 iterator __last
= end();
635 if (__first
== __last
) return;
636 iterator __next
= __first
;
637 while (++__next
!= __last
) {
638 if (*__first
== *__next
)
646 template <class _Tp
, class _Alloc
>
647 void list
<_Tp
, _Alloc
>::merge(list
<_Tp
, _Alloc
>& __x
)
649 iterator __first1
= begin();
650 iterator __last1
= end();
651 iterator __first2
= __x
.begin();
652 iterator __last2
= __x
.end();
653 while (__first1
!= __last1
&& __first2
!= __last2
)
654 if (*__first2
< *__first1
) {
655 iterator __next
= __first2
;
656 transfer(__first1
, __first2
, ++__next
);
661 if (__first2
!= __last2
) transfer(__last1
, __first2
, __last2
);
664 inline void __List_base_reverse(_List_node_base
* __p
)
666 _List_node_base
* __tmp
= __p
;
668 std::swap(__tmp
->_M_next
, __tmp
->_M_prev
);
669 __tmp
= __tmp
->_M_prev
; // Old next node is now prev.
670 } while (__tmp
!= __p
);
673 template <class _Tp
, class _Alloc
>
674 inline void list
<_Tp
, _Alloc
>::reverse()
676 __List_base_reverse(this->_M_node
);
679 template <class _Tp
, class _Alloc
>
680 void list
<_Tp
, _Alloc
>::sort()
682 // Do nothing if the list has length 0 or 1.
683 if (_M_node
->_M_next
!= _M_node
&& _M_node
->_M_next
->_M_next
!= _M_node
) {
684 list
<_Tp
, _Alloc
> __carry
;
685 list
<_Tp
, _Alloc
> __counter
[64];
688 __carry
.splice(__carry
.begin(), *this, begin());
690 while(__i
< __fill
&& !__counter
[__i
].empty()) {
691 __counter
[__i
].merge(__carry
);
692 __carry
.swap(__counter
[__i
++]);
694 __carry
.swap(__counter
[__i
]);
695 if (__i
== __fill
) ++__fill
;
698 for (int __i
= 1; __i
< __fill
; ++__i
)
699 __counter
[__i
].merge(__counter
[__i
-1]);
700 swap(__counter
[__fill
-1]);
704 template <class _Tp
, class _Alloc
> template <class _Predicate
>
705 void list
<_Tp
, _Alloc
>::remove_if(_Predicate __pred
)
707 iterator __first
= begin();
708 iterator __last
= end();
709 while (__first
!= __last
) {
710 iterator __next
= __first
;
712 if (__pred(*__first
)) erase(__first
);
717 template <class _Tp
, class _Alloc
> template <class _BinaryPredicate
>
718 void list
<_Tp
, _Alloc
>::unique(_BinaryPredicate __binary_pred
)
720 iterator __first
= begin();
721 iterator __last
= end();
722 if (__first
== __last
) return;
723 iterator __next
= __first
;
724 while (++__next
!= __last
) {
725 if (__binary_pred(*__first
, *__next
))
733 template <class _Tp
, class _Alloc
> template <class _StrictWeakOrdering
>
734 void list
<_Tp
, _Alloc
>::merge(list
<_Tp
, _Alloc
>& __x
,
735 _StrictWeakOrdering __comp
)
737 iterator __first1
= begin();
738 iterator __last1
= end();
739 iterator __first2
= __x
.begin();
740 iterator __last2
= __x
.end();
741 while (__first1
!= __last1
&& __first2
!= __last2
)
742 if (__comp(*__first2
, *__first1
)) {
743 iterator __next
= __first2
;
744 transfer(__first1
, __first2
, ++__next
);
749 if (__first2
!= __last2
) transfer(__last1
, __first2
, __last2
);
752 template <class _Tp
, class _Alloc
> template <class _StrictWeakOrdering
>
753 void list
<_Tp
, _Alloc
>::sort(_StrictWeakOrdering __comp
)
755 // Do nothing if the list has length 0 or 1.
756 if (_M_node
->_M_next
!= _M_node
&& _M_node
->_M_next
->_M_next
!= _M_node
) {
757 list
<_Tp
, _Alloc
> __carry
;
758 list
<_Tp
, _Alloc
> __counter
[64];
761 __carry
.splice(__carry
.begin(), *this, begin());
763 while(__i
< __fill
&& !__counter
[__i
].empty()) {
764 __counter
[__i
].merge(__carry
, __comp
);
765 __carry
.swap(__counter
[__i
++]);
767 __carry
.swap(__counter
[__i
]);
768 if (__i
== __fill
) ++__fill
;
771 for (int __i
= 1; __i
< __fill
; ++__i
)
772 __counter
[__i
].merge(__counter
[__i
-1], __comp
);
773 swap(__counter
[__fill
-1]);
779 #endif /* __SGI_STL_INTERNAL_LIST_H */