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