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