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