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