1 // Iterators -*- C++ -*- 2 3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, 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 // You should have received a copy of the GNU General Public License along 18 // with this library; see the file COPYING. If not, write to the Free 19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 // USA. 21 22 // As a special exception, you may use this file as part of a free software 23 // library without restriction. Specifically, if other files instantiate 24 // templates or use macros or inline functions from this file, or you compile 25 // this file and link it with other files to produce an executable, this 26 // file does not by itself cause the resulting executable to be covered by 27 // the GNU General Public License. This exception does not however 28 // invalidate any other reasons why the executable file might be covered by 29 // the GNU General Public License. 30 31 /* 32 * 33 * Copyright (c) 1994 34 * Hewlett-Packard Company 35 * 36 * Permission to use, copy, modify, distribute and sell this software 37 * and its documentation for any purpose is hereby granted without fee, 38 * provided that the above copyright notice appear in all copies and 39 * that both that copyright notice and this permission notice appear 40 * in supporting documentation. Hewlett-Packard Company makes no 41 * representations about the suitability of this software for any 42 * purpose. It is provided "as is" without express or implied warranty. 43 * 44 * 45 * Copyright (c) 1996-1998 46 * Silicon Graphics Computer Systems, Inc. 47 * 48 * Permission to use, copy, modify, distribute and sell this software 49 * and its documentation for any purpose is hereby granted without fee, 50 * provided that the above copyright notice appear in all copies and 51 * that both that copyright notice and this permission notice appear 52 * in supporting documentation. Silicon Graphics makes no 53 * representations about the suitability of this software for any 54 * purpose. It is provided "as is" without express or implied warranty. 55 */ 56 57 /** @file stl_iterator.h 58 * This is an internal header file, included by other library headers. 59 * You should not attempt to use it directly. 60 * 61 * This file implements reverse_iterator, back_insert_iterator, 62 * front_insert_iterator, insert_iterator, __normal_iterator, and their 63 * supporting functions and overloaded operators. 64 */ 65 66 #ifndef _ITERATOR_H 67 #define _ITERATOR_H 1 68 69 #include <bits/cpp_type_traits.h> 70 #include <ext/type_traits.h> 71 72 _GLIBCXX_BEGIN_NAMESPACE(std) 73 74 // 24.4.1 Reverse iterators 75 /** 76 * "Bidirectional and random access iterators have corresponding reverse 77 * %iterator adaptors that iterate through the data structure in the 78 * opposite direction. They have the same signatures as the corresponding 79 * iterators. The fundamental relation between a reverse %iterator and its 80 * corresponding %iterator @c i is established by the identity: 81 * @code 82 * &*(reverse_iterator(i)) == &*(i - 1) 83 * @endcode 84 * 85 * This mapping is dictated by the fact that while there is always a 86 * pointer past the end of an array, there might not be a valid pointer 87 * before the beginning of an array." [24.4.1]/1,2 88 * 89 * Reverse iterators can be tricky and surprising at first. Their 90 * semantics make sense, however, and the trickiness is a side effect of 91 * the requirement that the iterators must be safe. 92 */ 93 template<typename _Iterator> 94 class reverse_iterator 95 : public iterator<typename iterator_traits<_Iterator>::iterator_category, 96 typename iterator_traits<_Iterator>::value_type, 97 typename iterator_traits<_Iterator>::difference_type, 98 typename iterator_traits<_Iterator>::pointer, 99 typename iterator_traits<_Iterator>::reference> 100 { 101 protected: 102 _Iterator current; 103 104 public: 105 typedef _Iterator iterator_type; 106 typedef typename iterator_traits<_Iterator>::difference_type 107 difference_type; 108 typedef typename iterator_traits<_Iterator>::reference reference; 109 typedef typename iterator_traits<_Iterator>::pointer pointer; 110 111 public: 112 /** 113 * The default constructor default-initializes member @p current. 114 * If it is a pointer, that means it is zero-initialized. 115 */ 116 // _GLIBCXX_RESOLVE_LIB_DEFECTS 117 // 235 No specification of default ctor for reverse_iterator 118 reverse_iterator() : current() { } 119 120 /** 121 * This %iterator will move in the opposite direction that @p x does. 122 */ 123 explicit 124 reverse_iterator(iterator_type __x) : current(__x) { } 125 126 /** 127 * The copy constructor is normal. 128 */ 129 reverse_iterator(const reverse_iterator& __x) 130 : current(__x.current) { } 131 132 /** 133 * A reverse_iterator across other types can be copied in the normal 134 * fashion. 135 */ 136 template<typename _Iter> 137 reverse_iterator(const reverse_iterator<_Iter>& __x) 138 : current(__x.base()) { } 139 140 /** 141 * @return @c current, the %iterator used for underlying work. 142 */ 143 iterator_type 144 base() const 145 { return current; } 146 147 /** 148 * @return TODO 149 * 150 * @doctodo 151 */ 152 reference 153 operator*() const 154 { 155 _Iterator __tmp = current; 156 return *--__tmp; 157 } 158 159 /** 160 * @return TODO 161 * 162 * @doctodo 163 */ 164 pointer 165 operator->() const 166 { return &(operator*()); } 167 168 /** 169 * @return TODO 170 * 171 * @doctodo 172 */ 173 reverse_iterator& 174 operator++() 175 { 176 --current; 177 return *this; 178 } 179 180 /** 181 * @return TODO 182 * 183 * @doctodo 184 */ 185 reverse_iterator 186 operator++(int) 187 { 188 reverse_iterator __tmp = *this; 189 --current; 190 return __tmp; 191 } 192 193 /** 194 * @return TODO 195 * 196 * @doctodo 197 */ 198 reverse_iterator& 199 operator--() 200 { 201 ++current; 202 return *this; 203 } 204 205 /** 206 * @return TODO 207 * 208 * @doctodo 209 */ 210 reverse_iterator 211 operator--(int) 212 { 213 reverse_iterator __tmp = *this; 214 ++current; 215 return __tmp; 216 } 217 218 /** 219 * @return TODO 220 * 221 * @doctodo 222 */ 223 reverse_iterator 224 operator+(difference_type __n) const 225 { return reverse_iterator(current - __n); } 226 227 /** 228 * @return TODO 229 * 230 * @doctodo 231 */ 232 reverse_iterator& 233 operator+=(difference_type __n) 234 { 235 current -= __n; 236 return *this; 237 } 238 239 /** 240 * @return TODO 241 * 242 * @doctodo 243 */ 244 reverse_iterator 245 operator-(difference_type __n) const 246 { return reverse_iterator(current + __n); } 247 248 /** 249 * @return TODO 250 * 251 * @doctodo 252 */ 253 reverse_iterator& 254 operator-=(difference_type __n) 255 { 256 current += __n; 257 return *this; 258 } 259 260 /** 261 * @return TODO 262 * 263 * @doctodo 264 */ 265 reference 266 operator[](difference_type __n) const 267 { return *(*this + __n); } 268 }; 269 270 //@{ 271 /** 272 * @param x A %reverse_iterator. 273 * @param y A %reverse_iterator. 274 * @return A simple bool. 275 * 276 * Reverse iterators forward many operations to their underlying base() 277 * iterators. Others are implemented in terms of one another. 278 * 279 */ 280 template<typename _Iterator> 281 inline bool 282 operator==(const reverse_iterator<_Iterator>& __x, 283 const reverse_iterator<_Iterator>& __y) 284 { return __x.base() == __y.base(); } 285 286 template<typename _Iterator> 287 inline bool 288 operator<(const reverse_iterator<_Iterator>& __x, 289 const reverse_iterator<_Iterator>& __y) 290 { return __y.base() < __x.base(); } 291 292 template<typename _Iterator> 293 inline bool 294 operator!=(const reverse_iterator<_Iterator>& __x, 295 const reverse_iterator<_Iterator>& __y) 296 { return !(__x == __y); } 297 298 template<typename _Iterator> 299 inline bool 300 operator>(const reverse_iterator<_Iterator>& __x, 301 const reverse_iterator<_Iterator>& __y) 302 { return __y < __x; } 303 304 template<typename _Iterator> 305 inline bool 306 operator<=(const reverse_iterator<_Iterator>& __x, 307 const reverse_iterator<_Iterator>& __y) 308 { return !(__y < __x); } 309 310 template<typename _Iterator> 311 inline bool 312 operator>=(const reverse_iterator<_Iterator>& __x, 313 const reverse_iterator<_Iterator>& __y) 314 { return !(__x < __y); } 315 316 template<typename _Iterator> 317 inline typename reverse_iterator<_Iterator>::difference_type 318 operator-(const reverse_iterator<_Iterator>& __x, 319 const reverse_iterator<_Iterator>& __y) 320 { return __y.base() - __x.base(); } 321 322 template<typename _Iterator> 323 inline reverse_iterator<_Iterator> 324 operator+(typename reverse_iterator<_Iterator>::difference_type __n, 325 const reverse_iterator<_Iterator>& __x) 326 { return reverse_iterator<_Iterator>(__x.base() - __n); } 327 328 // _GLIBCXX_RESOLVE_LIB_DEFECTS 329 // DR 280. Comparison of reverse_iterator to const reverse_iterator. 330 template<typename _IteratorL, typename _IteratorR> 331 inline bool 332 operator==(const reverse_iterator<_IteratorL>& __x, 333 const reverse_iterator<_IteratorR>& __y) 334 { return __x.base() == __y.base(); } 335 336 template<typename _IteratorL, typename _IteratorR> 337 inline bool 338 operator<(const reverse_iterator<_IteratorL>& __x, 339 const reverse_iterator<_IteratorR>& __y) 340 { return __y.base() < __x.base(); } 341 342 template<typename _IteratorL, typename _IteratorR> 343 inline bool 344 operator!=(const reverse_iterator<_IteratorL>& __x, 345 const reverse_iterator<_IteratorR>& __y) 346 { return !(__x == __y); } 347 348 template<typename _IteratorL, typename _IteratorR> 349 inline bool 350 operator>(const reverse_iterator<_IteratorL>& __x, 351 const reverse_iterator<_IteratorR>& __y) 352 { return __y < __x; } 353 354 template<typename _IteratorL, typename _IteratorR> 355 inline bool 356 operator<=(const reverse_iterator<_IteratorL>& __x, 357 const reverse_iterator<_IteratorR>& __y) 358 { return !(__y < __x); } 359 360 template<typename _IteratorL, typename _IteratorR> 361 inline bool 362 operator>=(const reverse_iterator<_IteratorL>& __x, 363 const reverse_iterator<_IteratorR>& __y) 364 { return !(__x < __y); } 365 366 template<typename _IteratorL, typename _IteratorR> 367 inline typename reverse_iterator<_IteratorL>::difference_type 368 operator-(const reverse_iterator<_IteratorL>& __x, 369 const reverse_iterator<_IteratorR>& __y) 370 { return __y.base() - __x.base(); } 371 //@} 372 373 // 24.4.2.2.1 back_insert_iterator 374 /** 375 * @brief Turns assignment into insertion. 376 * 377 * These are output iterators, constructed from a container-of-T. 378 * Assigning a T to the iterator appends it to the container using 379 * push_back. 380 * 381 * Tip: Using the back_inserter function to create these iterators can 382 * save typing. 383 */ 384 template<typename _Container> 385 class back_insert_iterator 386 : public iterator<output_iterator_tag, void, void, void, void> 387 { 388 protected: 389 _Container* container; 390 391 public: 392 /// A nested typedef for the type of whatever container you used. 393 typedef _Container container_type; 394 395 /// The only way to create this %iterator is with a container. 396 explicit 397 back_insert_iterator(_Container& __x) : container(&__x) { } 398 399 /** 400 * @param value An instance of whatever type 401 * container_type::const_reference is; presumably a 402 * reference-to-const T for container<T>. 403 * @return This %iterator, for chained operations. 404 * 405 * This kind of %iterator doesn't really have a "position" in the 406 * container (you can think of the position as being permanently at 407 * the end, if you like). Assigning a value to the %iterator will 408 * always append the value to the end of the container. 409 */ 410 back_insert_iterator& 411 operator=(typename _Container::const_reference __value) 412 { 413 container->push_back(__value); 414 return *this; 415 } 416 417 /// Simply returns *this. 418 back_insert_iterator& 419 operator*() 420 { return *this; } 421 422 /// Simply returns *this. (This %iterator does not "move".) 423 back_insert_iterator& 424 operator++() 425 { return *this; } 426 427 /// Simply returns *this. (This %iterator does not "move".) 428 back_insert_iterator 429 operator++(int) 430 { return *this; } 431 }; 432 433 /** 434 * @param x A container of arbitrary type. 435 * @return An instance of back_insert_iterator working on @p x. 436 * 437 * This wrapper function helps in creating back_insert_iterator instances. 438 * Typing the name of the %iterator requires knowing the precise full 439 * type of the container, which can be tedious and impedes generic 440 * programming. Using this function lets you take advantage of automatic 441 * template parameter deduction, making the compiler match the correct 442 * types for you. 443 */ 444 template<typename _Container> 445 inline back_insert_iterator<_Container> 446 back_inserter(_Container& __x) 447 { return back_insert_iterator<_Container>(__x); } 448 449 /** 450 * @brief Turns assignment into insertion. 451 * 452 * These are output iterators, constructed from a container-of-T. 453 * Assigning a T to the iterator prepends it to the container using 454 * push_front. 455 * 456 * Tip: Using the front_inserter function to create these iterators can 457 * save typing. 458 */ 459 template<typename _Container> 460 class front_insert_iterator 461 : public iterator<output_iterator_tag, void, void, void, void> 462 { 463 protected: 464 _Container* container; 465 466 public: 467 /// A nested typedef for the type of whatever container you used. 468 typedef _Container container_type; 469 470 /// The only way to create this %iterator is with a container. 471 explicit front_insert_iterator(_Container& __x) : container(&__x) { } 472 473 /** 474 * @param value An instance of whatever type 475 * container_type::const_reference is; presumably a 476 * reference-to-const T for container<T>. 477 * @return This %iterator, for chained operations. 478 * 479 * This kind of %iterator doesn't really have a "position" in the 480 * container (you can think of the position as being permanently at 481 * the front, if you like). Assigning a value to the %iterator will 482 * always prepend the value to the front of the container. 483 */ 484 front_insert_iterator& 485 operator=(typename _Container::const_reference __value) 486 { 487 container->push_front(__value); 488 return *this; 489 } 490 491 /// Simply returns *this. 492 front_insert_iterator& 493 operator*() 494 { return *this; } 495 496 /// Simply returns *this. (This %iterator does not "move".) 497 front_insert_iterator& 498 operator++() 499 { return *this; } 500 501 /// Simply returns *this. (This %iterator does not "move".) 502 front_insert_iterator 503 operator++(int) 504 { return *this; } 505 }; 506 507 /** 508 * @param x A container of arbitrary type. 509 * @return An instance of front_insert_iterator working on @p x. 510 * 511 * This wrapper function helps in creating front_insert_iterator instances. 512 * Typing the name of the %iterator requires knowing the precise full 513 * type of the container, which can be tedious and impedes generic 514 * programming. Using this function lets you take advantage of automatic 515 * template parameter deduction, making the compiler match the correct 516 * types for you. 517 */ 518 template<typename _Container> 519 inline front_insert_iterator<_Container> 520 front_inserter(_Container& __x) 521 { return front_insert_iterator<_Container>(__x); } 522 523 /** 524 * @brief Turns assignment into insertion. 525 * 526 * These are output iterators, constructed from a container-of-T. 527 * Assigning a T to the iterator inserts it in the container at the 528 * %iterator's position, rather than overwriting the value at that 529 * position. 530 * 531 * (Sequences will actually insert a @e copy of the value before the 532 * %iterator's position.) 533 * 534 * Tip: Using the inserter function to create these iterators can 535 * save typing. 536 */ 537 template<typename _Container> 538 class insert_iterator 539 : public iterator<output_iterator_tag, void, void, void, void> 540 { 541 protected: 542 _Container* container; 543 typename _Container::iterator iter; 544 545 public: 546 /// A nested typedef for the type of whatever container you used. 547 typedef _Container container_type; 548 549 /** 550 * The only way to create this %iterator is with a container and an 551 * initial position (a normal %iterator into the container). 552 */ 553 insert_iterator(_Container& __x, typename _Container::iterator __i) 554 : container(&__x), iter(__i) {} 555 556 /** 557 * @param value An instance of whatever type 558 * container_type::const_reference is; presumably a 559 * reference-to-const T for container<T>. 560 * @return This %iterator, for chained operations. 561 * 562 * This kind of %iterator maintains its own position in the 563 * container. Assigning a value to the %iterator will insert the 564 * value into the container at the place before the %iterator. 565 * 566 * The position is maintained such that subsequent assignments will 567 * insert values immediately after one another. For example, 568 * @code 569 * // vector v contains A and Z 570 * 571 * insert_iterator i (v, ++v.begin()); 572 * i = 1; 573 * i = 2; 574 * i = 3; 575 * 576 * // vector v contains A, 1, 2, 3, and Z 577 * @endcode 578 */ 579 insert_iterator& 580 operator=(const typename _Container::const_reference __value) 581 { 582 iter = container->insert(iter, __value); 583 ++iter; 584 return *this; 585 } 586 587 /// Simply returns *this. 588 insert_iterator& 589 operator*() 590 { return *this; } 591 592 /// Simply returns *this. (This %iterator does not "move".) 593 insert_iterator& 594 operator++() 595 { return *this; } 596 597 /// Simply returns *this. (This %iterator does not "move".) 598 insert_iterator& 599 operator++(int) 600 { return *this; } 601 }; 602 603 /** 604 * @param x A container of arbitrary type. 605 * @return An instance of insert_iterator working on @p x. 606 * 607 * This wrapper function helps in creating insert_iterator instances. 608 * Typing the name of the %iterator requires knowing the precise full 609 * type of the container, which can be tedious and impedes generic 610 * programming. Using this function lets you take advantage of automatic 611 * template parameter deduction, making the compiler match the correct 612 * types for you. 613 */ 614 template<typename _Container, typename _Iterator> 615 inline insert_iterator<_Container> 616 inserter(_Container& __x, _Iterator __i) 617 { 618 return insert_iterator<_Container>(__x, 619 typename _Container::iterator(__i)); 620 } 621 622 _GLIBCXX_END_NAMESPACE 623 624 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 625 626 // This iterator adapter is 'normal' in the sense that it does not 627 // change the semantics of any of the operators of its iterator 628 // parameter. Its primary purpose is to convert an iterator that is 629 // not a class, e.g. a pointer, into an iterator that is a class. 630 // The _Container parameter exists solely so that different containers 631 // using this template can instantiate different types, even if the 632 // _Iterator parameter is the same. 633 using std::iterator_traits; 634 using std::iterator; 635 template<typename _Iterator, typename _Container> 636 class __normal_iterator 637 { 638 protected: 639 _Iterator _M_current; 640 641 public: 642 typedef typename iterator_traits<_Iterator>::iterator_category 643 iterator_category; 644 typedef typename iterator_traits<_Iterator>::value_type value_type; 645 typedef typename iterator_traits<_Iterator>::difference_type 646 difference_type; 647 typedef typename iterator_traits<_Iterator>::reference reference; 648 typedef typename iterator_traits<_Iterator>::pointer pointer; 649 650 __normal_iterator() : _M_current(_Iterator()) { } 651 652 explicit 653 __normal_iterator(const _Iterator& __i) : _M_current(__i) { } 654 655 // Allow iterator to const_iterator conversion 656 template<typename _Iter> 657 __normal_iterator(const __normal_iterator<_Iter, 658 typename __enable_if< 659 (std::__are_same<_Iter, typename _Container::pointer>::__value), 660 _Container>::__type>& __i) 661 : _M_current(__i.base()) { } 662 663 // Forward iterator requirements 664 reference 665 operator*() const 666 { return *_M_current; } 667 668 pointer 669 operator->() const 670 { return _M_current; } 671 672 __normal_iterator& 673 operator++() 674 { 675 ++_M_current; 676 return *this; 677 } 678 679 __normal_iterator 680 operator++(int) 681 { return __normal_iterator(_M_current++); } 682 683 // Bidirectional iterator requirements 684 __normal_iterator& 685 operator--() 686 { 687 --_M_current; 688 return *this; 689 } 690 691 __normal_iterator 692 operator--(int) 693 { return __normal_iterator(_M_current--); } 694 695 // Random access iterator requirements 696 reference 697 operator[](const difference_type& __n) const 698 { return _M_current[__n]; } 699 700 __normal_iterator& 701 operator+=(const difference_type& __n) 702 { _M_current += __n; return *this; } 703 704 __normal_iterator 705 operator+(const difference_type& __n) const 706 { return __normal_iterator(_M_current + __n); } 707 708 __normal_iterator& 709 operator-=(const difference_type& __n) 710 { _M_current -= __n; return *this; } 711 712 __normal_iterator 713 operator-(const difference_type& __n) const 714 { return __normal_iterator(_M_current - __n); } 715 716 const _Iterator& 717 base() const 718 { return _M_current; } 719 }; 720 721 // Note: In what follows, the left- and right-hand-side iterators are 722 // allowed to vary in types (conceptually in cv-qualification) so that 723 // comparaison between cv-qualified and non-cv-qualified iterators be 724 // valid. However, the greedy and unfriendly operators in std::rel_ops 725 // will make overload resolution ambiguous (when in scope) if we don't 726 // provide overloads whose operands are of the same type. Can someone 727 // remind me what generic programming is about? -- Gaby 728 729 // Forward iterator requirements 730 template<typename _IteratorL, typename _IteratorR, typename _Container> 731 inline bool 732 operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, 733 const __normal_iterator<_IteratorR, _Container>& __rhs) 734 { return __lhs.base() == __rhs.base(); } 735 736 template<typename _Iterator, typename _Container> 737 inline bool 738 operator==(const __normal_iterator<_Iterator, _Container>& __lhs, 739 const __normal_iterator<_Iterator, _Container>& __rhs) 740 { return __lhs.base() == __rhs.base(); } 741 742 template<typename _IteratorL, typename _IteratorR, typename _Container> 743 inline bool 744 operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, 745 const __normal_iterator<_IteratorR, _Container>& __rhs) 746 { return __lhs.base() != __rhs.base(); } 747 748 template<typename _Iterator, typename _Container> 749 inline bool 750 operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, 751 const __normal_iterator<_Iterator, _Container>& __rhs) 752 { return __lhs.base() != __rhs.base(); } 753 754 // Random access iterator requirements 755 template<typename _IteratorL, typename _IteratorR, typename _Container> 756 inline bool 757 operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, 758 const __normal_iterator<_IteratorR, _Container>& __rhs) 759 { return __lhs.base() < __rhs.base(); } 760 761 template<typename _Iterator, typename _Container> 762 inline bool 763 operator<(const __normal_iterator<_Iterator, _Container>& __lhs, 764 const __normal_iterator<_Iterator, _Container>& __rhs) 765 { return __lhs.base() < __rhs.base(); } 766 767 template<typename _IteratorL, typename _IteratorR, typename _Container> 768 inline bool 769 operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, 770 const __normal_iterator<_IteratorR, _Container>& __rhs) 771 { return __lhs.base() > __rhs.base(); } 772 773 template<typename _Iterator, typename _Container> 774 inline bool 775 operator>(const __normal_iterator<_Iterator, _Container>& __lhs, 776 const __normal_iterator<_Iterator, _Container>& __rhs) 777 { return __lhs.base() > __rhs.base(); } 778 779 template<typename _IteratorL, typename _IteratorR, typename _Container> 780 inline bool 781 operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, 782 const __normal_iterator<_IteratorR, _Container>& __rhs) 783 { return __lhs.base() <= __rhs.base(); } 784 785 template<typename _Iterator, typename _Container> 786 inline bool 787 operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, 788 const __normal_iterator<_Iterator, _Container>& __rhs) 789 { return __lhs.base() <= __rhs.base(); } 790 791 template<typename _IteratorL, typename _IteratorR, typename _Container> 792 inline bool 793 operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, 794 const __normal_iterator<_IteratorR, _Container>& __rhs) 795 { return __lhs.base() >= __rhs.base(); } 796 797 template<typename _Iterator, typename _Container> 798 inline bool 799 operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, 800 const __normal_iterator<_Iterator, _Container>& __rhs) 801 { return __lhs.base() >= __rhs.base(); } 802 803 // _GLIBCXX_RESOLVE_LIB_DEFECTS 804 // According to the resolution of DR179 not only the various comparison 805 // operators but also operator- must accept mixed iterator/const_iterator 806 // parameters. 807 template<typename _IteratorL, typename _IteratorR, typename _Container> 808 inline typename __normal_iterator<_IteratorL, _Container>::difference_type 809 operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, 810 const __normal_iterator<_IteratorR, _Container>& __rhs) 811 { return __lhs.base() - __rhs.base(); } 812 813 template<typename _Iterator, typename _Container> 814 inline typename __normal_iterator<_Iterator, _Container>::difference_type 815 operator-(const __normal_iterator<_Iterator, _Container>& __lhs, 816 const __normal_iterator<_Iterator, _Container>& __rhs) 817 { return __lhs.base() - __rhs.base(); } 818 819 template<typename _Iterator, typename _Container> 820 inline __normal_iterator<_Iterator, _Container> 821 operator+(typename __normal_iterator<_Iterator, _Container>::difference_type 822 __n, const __normal_iterator<_Iterator, _Container>& __i) 823 { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } 824 825 _GLIBCXX_END_NAMESPACE 826 827 #endif 828