1 /* 2 * 3 * Copyright (c) 1994 4 * Hewlett-Packard Company 5 * 6 * Permission to use, copy, modify, distribute and sell this software 7 * and its documentation for any purpose is hereby granted without fee, 8 * provided that the above copyright notice appear in all copies and 9 * that both that copyright notice and this permission notice appear 10 * in supporting documentation. Hewlett-Packard Company makes no 11 * representations about the suitability of this software for any 12 * purpose. It is provided "as is" without express or implied warranty. 13 * 14 * 15 * Copyright (c) 1996-1998 16 * Silicon Graphics Computer Systems, Inc. 17 * 18 * Permission to use, copy, modify, distribute and sell this software 19 * and its documentation for any purpose is hereby granted without fee, 20 * provided that the above copyright notice appear in all copies and 21 * that both that copyright notice and this permission notice appear 22 * in supporting documentation. Silicon Graphics makes no 23 * representations about the suitability of this software for any 24 * purpose. It is provided "as is" without express or implied warranty. 25 */ 26 27 /* NOTE: This is an internal header file, included by other STL headers. 28 * You should not attempt to use it directly. 29 */ 30 31 #ifndef __SGI_STL_INTERNAL_ITERATOR_H 32 #define __SGI_STL_INTERNAL_ITERATOR_H 33 34 __STL_BEGIN_NAMESPACE 35 36 struct input_iterator_tag {}; 37 struct output_iterator_tag {}; 38 struct forward_iterator_tag : public input_iterator_tag {}; 39 struct bidirectional_iterator_tag : public forward_iterator_tag {}; 40 struct random_access_iterator_tag : public bidirectional_iterator_tag {}; 41 42 // The base classes input_iterator, output_iterator, forward_iterator, 43 // bidirectional_iterator, and random_access_iterator are not part of 44 // the C++ standard. (they have been replaced by struct iterator.) 45 // They are included for backward compatibility with the HP STL. 46 47 template <class _Tp, class _Distance> struct input_iterator { 48 typedef input_iterator_tag iterator_category; 49 typedef _Tp value_type; 50 typedef _Distance difference_type; 51 typedef _Tp* pointer; 52 typedef _Tp& reference; 53 }; 54 55 struct output_iterator { 56 typedef output_iterator_tag iterator_category; 57 typedef void value_type; 58 typedef void difference_type; 59 typedef void pointer; 60 typedef void reference; 61 }; 62 63 template <class _Tp, class _Distance> struct forward_iterator { 64 typedef forward_iterator_tag iterator_category; 65 typedef _Tp value_type; 66 typedef _Distance difference_type; 67 typedef _Tp* pointer; 68 typedef _Tp& reference; 69 }; 70 71 72 template <class _Tp, class _Distance> struct bidirectional_iterator { 73 typedef bidirectional_iterator_tag iterator_category; 74 typedef _Tp value_type; 75 typedef _Distance difference_type; 76 typedef _Tp* pointer; 77 typedef _Tp& reference; 78 }; 79 80 template <class _Tp, class _Distance> struct random_access_iterator { 81 typedef random_access_iterator_tag iterator_category; 82 typedef _Tp value_type; 83 typedef _Distance difference_type; 84 typedef _Tp* pointer; 85 typedef _Tp& reference; 86 }; 87 88 #ifdef __STL_USE_NAMESPACES 89 template <class _Category, class _Tp, class _Distance = ptrdiff_t, 90 class _Pointer = _Tp*, class _Reference = _Tp&> 91 struct iterator { 92 typedef _Category iterator_category; 93 typedef _Tp value_type; 94 typedef _Distance difference_type; 95 typedef _Pointer pointer; 96 typedef _Reference reference; 97 }; 98 #endif /* __STL_USE_NAMESPACES */ 99 100 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 101 102 template <class _Iterator> 103 struct iterator_traits { 104 typedef typename _Iterator::iterator_category iterator_category; 105 typedef typename _Iterator::value_type value_type; 106 typedef typename _Iterator::difference_type difference_type; 107 typedef typename _Iterator::pointer pointer; 108 typedef typename _Iterator::reference reference; 109 }; 110 111 template <class _Tp> 112 struct iterator_traits<_Tp*> { 113 typedef random_access_iterator_tag iterator_category; 114 typedef _Tp value_type; 115 typedef ptrdiff_t difference_type; 116 typedef _Tp* pointer; 117 typedef _Tp& reference; 118 }; 119 120 template <class _Tp> 121 struct iterator_traits<const _Tp*> { 122 typedef random_access_iterator_tag iterator_category; 123 typedef _Tp value_type; 124 typedef ptrdiff_t difference_type; 125 typedef const _Tp* pointer; 126 typedef const _Tp& reference; 127 }; 128 129 // The overloaded functions iterator_category, distance_type, and 130 // value_type are not part of the C++ standard. (They have been 131 // replaced by struct iterator_traits.) They are included for 132 // backward compatibility with the HP STL. 133 134 // We introduce internal names for these functions. 135 136 template <class _Iter> 137 inline typename iterator_traits<_Iter>::iterator_category 138 __iterator_category(const _Iter&) 139 { 140 typedef typename iterator_traits<_Iter>::iterator_category _Category; 141 return _Category(); 142 } 143 144 template <class _Iter> 145 inline typename iterator_traits<_Iter>::difference_type* 146 __distance_type(const _Iter&) 147 { 148 return static_cast<typename iterator_traits<_Iter>::difference_type*>(0); 149 } 150 151 template <class _Iter> 152 inline typename iterator_traits<_Iter>::value_type* 153 __value_type(const _Iter&) 154 { 155 return static_cast<typename iterator_traits<_Iter>::value_type*>(0); 156 } 157 158 template <class _Iter> 159 inline typename iterator_traits<_Iter>::iterator_category 160 iterator_category(const _Iter& __i) { return __iterator_category(__i); } 161 162 163 template <class _Iter> 164 inline typename iterator_traits<_Iter>::difference_type* 165 distance_type(const _Iter& __i) { return __distance_type(__i); } 166 167 template <class _Iter> 168 inline typename iterator_traits<_Iter>::value_type* 169 value_type(const _Iter& __i) { return __value_type(__i); } 170 171 #define __ITERATOR_CATEGORY(__i) __iterator_category(__i) 172 #define __DISTANCE_TYPE(__i) __distance_type(__i) 173 #define __VALUE_TYPE(__i) __value_type(__i) 174 175 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 176 177 template <class _Tp, class _Distance> 178 inline input_iterator_tag 179 iterator_category(const input_iterator<_Tp, _Distance>&) 180 { return input_iterator_tag(); } 181 182 inline output_iterator_tag iterator_category(const output_iterator&) 183 { return output_iterator_tag(); } 184 185 template <class _Tp, class _Distance> 186 inline forward_iterator_tag 187 iterator_category(const forward_iterator<_Tp, _Distance>&) 188 { return forward_iterator_tag(); } 189 190 template <class _Tp, class _Distance> 191 inline bidirectional_iterator_tag 192 iterator_category(const bidirectional_iterator<_Tp, _Distance>&) 193 { return bidirectional_iterator_tag(); } 194 195 template <class _Tp, class _Distance> 196 inline random_access_iterator_tag 197 iterator_category(const random_access_iterator<_Tp, _Distance>&) 198 { return random_access_iterator_tag(); } 199 200 template <class _Tp> 201 inline random_access_iterator_tag iterator_category(const _Tp*) 202 { return random_access_iterator_tag(); } 203 204 template <class _Tp, class _Distance> 205 inline _Tp* value_type(const input_iterator<_Tp, _Distance>&) 206 { return (_Tp*)(0); } 207 208 template <class _Tp, class _Distance> 209 inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&) 210 { return (_Tp*)(0); } 211 212 template <class _Tp, class _Distance> 213 inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&) 214 { return (_Tp*)(0); } 215 216 template <class _Tp, class _Distance> 217 inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&) 218 { return (_Tp*)(0); } 219 220 template <class _Tp> 221 inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); } 222 223 template <class _Tp, class _Distance> 224 inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&) 225 { 226 return (_Distance*)(0); 227 } 228 229 template <class _Tp, class _Distance> 230 inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&) 231 { 232 return (_Distance*)(0); 233 } 234 235 template <class _Tp, class _Distance> 236 inline _Distance* 237 distance_type(const bidirectional_iterator<_Tp, _Distance>&) 238 { 239 return (_Distance*)(0); 240 } 241 242 template <class _Tp, class _Distance> 243 inline _Distance* 244 distance_type(const random_access_iterator<_Tp, _Distance>&) 245 { 246 return (_Distance*)(0); 247 } 248 249 template <class _Tp> 250 inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); } 251 252 // Without partial specialization we can't use iterator_traits, so 253 // we must keep the old iterator query functions around. 254 255 #define __ITERATOR_CATEGORY(__i) iterator_category(__i) 256 #define __DISTANCE_TYPE(__i) distance_type(__i) 257 #define __VALUE_TYPE(__i) value_type(__i) 258 259 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 260 261 template <class _InputIterator, class _Distance> 262 inline void __distance(_InputIterator __first, _InputIterator __last, 263 _Distance& __n, input_iterator_tag) 264 { 265 while (__first != __last) { ++__first; ++__n; } 266 } 267 268 template <class _RandomAccessIterator, class _Distance> 269 inline void __distance(_RandomAccessIterator __first, 270 _RandomAccessIterator __last, 271 _Distance& __n, random_access_iterator_tag) 272 { 273 __n += __last - __first; 274 } 275 276 template <class _InputIterator, class _Distance> 277 inline void distance(_InputIterator __first, 278 _InputIterator __last, _Distance& __n) 279 { 280 __distance(__first, __last, __n, iterator_category(__first)); 281 } 282 283 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 284 285 template <class _InputIterator> 286 inline typename iterator_traits<_InputIterator>::difference_type 287 __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) 288 { 289 typename iterator_traits<_InputIterator>::difference_type __n = 0; 290 while (__first != __last) { 291 ++__first; ++__n; 292 } 293 return __n; 294 } 295 296 template <class _RandomAccessIterator> 297 inline typename iterator_traits<_RandomAccessIterator>::difference_type 298 __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, 299 random_access_iterator_tag) { 300 return __last - __first; 301 } 302 303 template <class _InputIterator> 304 inline typename iterator_traits<_InputIterator>::difference_type 305 distance(_InputIterator __first, _InputIterator __last) { 306 typedef typename iterator_traits<_InputIterator>::iterator_category 307 _Category; 308 return __distance(__first, __last, _Category()); 309 } 310 311 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 312 313 template <class _InputIter, class _Distance> 314 inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) { 315 while (__n--) ++__i; 316 } 317 318 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 319 #pragma set woff 1183 320 #endif 321 322 template <class _BidirectionalIterator, class _Distance> 323 inline void __advance(_BidirectionalIterator& __i, _Distance __n, 324 bidirectional_iterator_tag) { 325 if (__n >= 0) 326 while (__n--) ++__i; 327 else 328 while (__n++) --__i; 329 } 330 331 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 332 #pragma reset woff 1183 333 #endif 334 335 template <class _RandomAccessIterator, class _Distance> 336 inline void __advance(_RandomAccessIterator& __i, _Distance __n, 337 random_access_iterator_tag) { 338 __i += __n; 339 } 340 341 template <class _InputIterator, class _Distance> 342 inline void advance(_InputIterator& __i, _Distance __n) { 343 __advance(__i, __n, iterator_category(__i)); 344 } 345 346 template <class _Container> 347 class back_insert_iterator { 348 protected: 349 _Container* container; 350 public: 351 typedef _Container container_type; 352 typedef output_iterator_tag iterator_category; 353 typedef void value_type; 354 typedef void difference_type; 355 typedef void pointer; 356 typedef void reference; 357 358 explicit back_insert_iterator(_Container& __x) : container(&__x) {} 359 back_insert_iterator<_Container>& 360 operator=(const typename _Container::value_type& __value) { 361 container->push_back(__value); 362 return *this; 363 } 364 back_insert_iterator<_Container>& operator*() { return *this; } 365 back_insert_iterator<_Container>& operator++() { return *this; } 366 back_insert_iterator<_Container>& operator++(int) { return *this; } 367 }; 368 369 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 370 371 template <class _Container> 372 inline output_iterator_tag 373 iterator_category(const back_insert_iterator<_Container>&) 374 { 375 return output_iterator_tag(); 376 } 377 378 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 379 380 template <class _Container> 381 inline back_insert_iterator<_Container> back_inserter(_Container& __x) { 382 return back_insert_iterator<_Container>(__x); 383 } 384 385 template <class _Container> 386 class front_insert_iterator { 387 protected: 388 _Container* container; 389 public: 390 typedef _Container container_type; 391 typedef output_iterator_tag iterator_category; 392 typedef void value_type; 393 typedef void difference_type; 394 typedef void pointer; 395 typedef void reference; 396 397 explicit front_insert_iterator(_Container& __x) : container(&__x) {} 398 front_insert_iterator<_Container>& 399 operator=(const typename _Container::value_type& __value) { 400 container->push_front(__value); 401 return *this; 402 } 403 front_insert_iterator<_Container>& operator*() { return *this; } 404 front_insert_iterator<_Container>& operator++() { return *this; } 405 front_insert_iterator<_Container>& operator++(int) { return *this; } 406 }; 407 408 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 409 410 template <class _Container> 411 inline output_iterator_tag 412 iterator_category(const front_insert_iterator<_Container>&) 413 { 414 return output_iterator_tag(); 415 } 416 417 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 418 419 template <class _Container> 420 inline front_insert_iterator<_Container> front_inserter(_Container& __x) { 421 return front_insert_iterator<_Container>(__x); 422 } 423 424 template <class _Container> 425 class insert_iterator { 426 protected: 427 _Container* container; 428 typename _Container::iterator iter; 429 public: 430 typedef _Container container_type; 431 typedef output_iterator_tag iterator_category; 432 typedef void value_type; 433 typedef void difference_type; 434 typedef void pointer; 435 typedef void reference; 436 437 insert_iterator(_Container& __x, typename _Container::iterator __i) 438 : container(&__x), iter(__i) {} 439 insert_iterator<_Container>& 440 operator=(const typename _Container::value_type& __value) { 441 iter = container->insert(iter, __value); 442 ++iter; 443 return *this; 444 } 445 insert_iterator<_Container>& operator*() { return *this; } 446 insert_iterator<_Container>& operator++() { return *this; } 447 insert_iterator<_Container>& operator++(int) { return *this; } 448 }; 449 450 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 451 452 template <class _Container> 453 inline output_iterator_tag 454 iterator_category(const insert_iterator<_Container>&) 455 { 456 return output_iterator_tag(); 457 } 458 459 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 460 461 template <class _Container, class _Iterator> 462 inline 463 insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) 464 { 465 typedef typename _Container::iterator __iter; 466 return insert_iterator<_Container>(__x, __iter(__i)); 467 } 468 469 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 470 template <class _BidirectionalIterator, class _Tp, class _Reference = _Tp&, 471 class _Distance = ptrdiff_t> 472 #else 473 template <class _BidirectionalIterator, class _Tp, class _Reference, 474 class _Distance> 475 #endif 476 class reverse_bidirectional_iterator { 477 typedef reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, 478 _Reference, _Distance> _Self; 479 protected: 480 _BidirectionalIterator current; 481 public: 482 typedef bidirectional_iterator_tag iterator_category; 483 typedef _Tp value_type; 484 typedef _Distance difference_type; 485 typedef _Tp* pointer; 486 typedef _Reference reference; 487 488 reverse_bidirectional_iterator() {} 489 explicit reverse_bidirectional_iterator(_BidirectionalIterator __x) 490 : current(__x) {} 491 _BidirectionalIterator base() const { return current; } 492 _Reference operator*() const { 493 _BidirectionalIterator __tmp = current; 494 return *--__tmp; 495 } 496 #ifndef __SGI_STL_NO_ARROW_OPERATOR 497 pointer operator->() const { return &(operator*()); } 498 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 499 _Self& operator++() { 500 --current; 501 return *this; 502 } 503 _Self operator++(int) { 504 _Self __tmp = *this; 505 --current; 506 return __tmp; 507 } 508 _Self& operator--() { 509 ++current; 510 return *this; 511 } 512 _Self operator--(int) { 513 _Self __tmp = *this; 514 ++current; 515 return __tmp; 516 } 517 }; 518 519 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 520 521 template <class _BidirectionalIterator, class _Tp, class _Reference, 522 class _Distance> 523 inline bidirectional_iterator_tag 524 iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator, 525 _Tp, _Reference, 526 _Distance>&) 527 { 528 return bidirectional_iterator_tag(); 529 } 530 531 template <class _BidirectionalIterator, class _Tp, class _Reference, 532 class _Distance> 533 inline _Tp* 534 value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, 535 _Reference, _Distance>&) 536 { 537 return (_Tp*) 0; 538 } 539 540 template <class _BidirectionalIterator, class _Tp, class _Reference, 541 class _Distance> 542 inline _Distance* 543 distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, 544 _Tp, 545 _Reference, _Distance>&) 546 { 547 return (_Distance*) 0; 548 } 549 550 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 551 552 template <class _BiIter, class _Tp, class _Ref, 553 class _Distance> 554 inline bool operator==( 555 const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, 556 const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y) 557 { 558 return __x.base() == __y.base(); 559 } 560 561 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 562 563 // This is the new version of reverse_iterator, as defined in the 564 // draft C++ standard. It relies on the iterator_traits template, 565 // which in turn relies on partial specialization. The class 566 // reverse_bidirectional_iterator is no longer part of the draft 567 // standard, but it is retained for backward compatibility. 568 569 template <class _Iterator> 570 class reverse_iterator 571 { 572 protected: 573 _Iterator current; 574 public: 575 typedef typename iterator_traits<_Iterator>::iterator_category 576 iterator_category; 577 typedef typename iterator_traits<_Iterator>::value_type 578 value_type; 579 typedef typename iterator_traits<_Iterator>::difference_type 580 difference_type; 581 typedef typename iterator_traits<_Iterator>::pointer 582 pointer; 583 typedef typename iterator_traits<_Iterator>::reference 584 reference; 585 586 typedef _Iterator iterator_type; 587 typedef reverse_iterator<_Iterator> _Self; 588 589 public: 590 reverse_iterator() {} 591 explicit reverse_iterator(iterator_type __x) : current(__x) {} 592 593 reverse_iterator(const _Self& __x) : current(__x.current) {} 594 #ifdef __STL_MEMBER_TEMPLATES 595 template <class _Iter> 596 reverse_iterator(const reverse_iterator<_Iter>& __x) 597 : current(__x.base()) {} 598 #endif /* __STL_MEMBER_TEMPLATES */ 599 600 iterator_type base() const { return current; } 601 reference operator*() const { 602 _Iterator __tmp = current; 603 return *--__tmp; 604 } 605 #ifndef __SGI_STL_NO_ARROW_OPERATOR 606 pointer operator->() const { return &(operator*()); } 607 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 608 609 _Self& operator++() { 610 --current; 611 return *this; 612 } 613 _Self operator++(int) { 614 _Self __tmp = *this; 615 --current; 616 return __tmp; 617 } 618 _Self& operator--() { 619 ++current; 620 return *this; 621 } 622 _Self operator--(int) { 623 _Self __tmp = *this; 624 ++current; 625 return __tmp; 626 } 627 628 _Self operator+(difference_type __n) const { 629 return _Self(current - __n); 630 } 631 _Self& operator+=(difference_type __n) { 632 current -= __n; 633 return *this; 634 } 635 _Self operator-(difference_type __n) const { 636 return _Self(current + __n); 637 } 638 _Self& operator-=(difference_type __n) { 639 current += __n; 640 return *this; 641 } 642 reference operator[](difference_type __n) const { return *(*this + __n); } 643 }; 644 645 template <class _Iterator> 646 inline bool operator==(const reverse_iterator<_Iterator>& __x, 647 const reverse_iterator<_Iterator>& __y) { 648 return __x.base() == __y.base(); 649 } 650 651 template <class _Iterator> 652 inline bool operator<(const reverse_iterator<_Iterator>& __x, 653 const reverse_iterator<_Iterator>& __y) { 654 return __y.base() < __x.base(); 655 } 656 657 template <class _Iterator> 658 inline typename reverse_iterator<_Iterator>::difference_type 659 operator-(const reverse_iterator<_Iterator>& __x, 660 const reverse_iterator<_Iterator>& __y) { 661 return __y.base() - __x.base(); 662 } 663 664 template <class _Iterator> 665 inline reverse_iterator<_Iterator> 666 operator+(typename reverse_iterator<_Iterator>::difference_type __n, 667 const reverse_iterator<_Iterator>& __x) { 668 return reverse_iterator<_Iterator>(__x.base() - __n); 669 } 670 671 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 672 673 // This is the old version of reverse_iterator, as found in the original 674 // HP STL. It does not use partial specialization. 675 676 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 677 template <class _RandomAccessIterator, class _Tp, class _Reference = _Tp&, 678 class _Distance = ptrdiff_t> 679 #else 680 template <class _RandomAccessIterator, class _Tp, class _Reference, 681 class _Distance> 682 #endif 683 class reverse_iterator { 684 typedef reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance> 685 _Self; 686 protected: 687 _RandomAccessIterator current; 688 public: 689 typedef random_access_iterator_tag iterator_category; 690 typedef _Tp value_type; 691 typedef _Distance difference_type; 692 typedef _Tp* pointer; 693 typedef _Reference reference; 694 695 reverse_iterator() {} 696 explicit reverse_iterator(_RandomAccessIterator __x) : current(__x) {} 697 _RandomAccessIterator base() const { return current; } 698 _Reference operator*() const { return *(current - 1); } 699 #ifndef __SGI_STL_NO_ARROW_OPERATOR 700 pointer operator->() const { return &(operator*()); } 701 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 702 _Self& operator++() { 703 --current; 704 return *this; 705 } 706 _Self operator++(int) { 707 _Self __tmp = *this; 708 --current; 709 return __tmp; 710 } 711 _Self& operator--() { 712 ++current; 713 return *this; 714 } 715 _Self operator--(int) { 716 _Self __tmp = *this; 717 ++current; 718 return __tmp; 719 } 720 _Self operator+(_Distance __n) const { 721 return _Self(current - __n); 722 } 723 _Self& operator+=(_Distance __n) { 724 current -= __n; 725 return *this; 726 } 727 _Self operator-(_Distance __n) const { 728 return _Self(current + __n); 729 } 730 _Self& operator-=(_Distance __n) { 731 current += __n; 732 return *this; 733 } 734 _Reference operator[](_Distance __n) const { return *(*this + __n); } 735 }; 736 737 template <class _RandomAccessIterator, class _Tp, 738 class _Reference, class _Distance> 739 inline random_access_iterator_tag 740 iterator_category(const reverse_iterator<_RandomAccessIterator, _Tp, 741 _Reference, _Distance>&) 742 { 743 return random_access_iterator_tag(); 744 } 745 746 template <class _RandomAccessIterator, class _Tp, 747 class _Reference, class _Distance> 748 inline _Tp* value_type(const reverse_iterator<_RandomAccessIterator, _Tp, 749 _Reference, _Distance>&) 750 { 751 return (_Tp*) 0; 752 } 753 754 template <class _RandomAccessIterator, class _Tp, 755 class _Reference, class _Distance> 756 inline _Distance* 757 distance_type(const reverse_iterator<_RandomAccessIterator, 758 _Tp, _Reference, _Distance>&) 759 { 760 return (_Distance*) 0; 761 } 762 763 764 template <class _RandomAccessIterator, class _Tp, 765 class _Reference, class _Distance> 766 inline bool 767 operator==(const reverse_iterator<_RandomAccessIterator, _Tp, 768 _Reference, _Distance>& __x, 769 const reverse_iterator<_RandomAccessIterator, _Tp, 770 _Reference, _Distance>& __y) 771 { 772 return __x.base() == __y.base(); 773 } 774 775 template <class _RandomAccessIterator, class _Tp, 776 class _Reference, class _Distance> 777 inline bool 778 operator<(const reverse_iterator<_RandomAccessIterator, _Tp, 779 _Reference, _Distance>& __x, 780 const reverse_iterator<_RandomAccessIterator, _Tp, 781 _Reference, _Distance>& __y) 782 { 783 return __y.base() < __x.base(); 784 } 785 786 template <class _RandomAccessIterator, class _Tp, 787 class _Reference, class _Distance> 788 inline _Distance 789 operator-(const reverse_iterator<_RandomAccessIterator, _Tp, 790 _Reference, _Distance>& __x, 791 const reverse_iterator<_RandomAccessIterator, _Tp, 792 _Reference, _Distance>& __y) 793 { 794 return __y.base() - __x.base(); 795 } 796 797 template <class _RandAccIter, class _Tp, class _Ref, class _Dist> 798 inline reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist> 799 operator+(_Dist __n, 800 const reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>& __x) 801 { 802 return reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>(__x.base() - __n); 803 } 804 805 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 806 807 // When we have templatized iostreams, istream_iterator and ostream_iterator 808 // must be rewritten. 809 810 template <class _Tp, class _Dist = ptrdiff_t> 811 class istream_iterator { 812 friend bool operator== __STL_NULL_TMPL_ARGS (const istream_iterator&, 813 const istream_iterator&); 814 protected: 815 istream* _M_stream; 816 _Tp _M_value; 817 bool _M_end_marker; 818 void _M_read() { 819 _M_end_marker = (*_M_stream) ? true : false; 820 if (_M_end_marker) *_M_stream >> _M_value; 821 _M_end_marker = (*_M_stream) ? true : false; 822 } 823 public: 824 typedef input_iterator_tag iterator_category; 825 typedef _Tp value_type; 826 typedef _Dist difference_type; 827 typedef const _Tp* pointer; 828 typedef const _Tp& reference; 829 830 istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} 831 istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); } 832 reference operator*() const { return _M_value; } 833 #ifndef __SGI_STL_NO_ARROW_OPERATOR 834 pointer operator->() const { return &(operator*()); } 835 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 836 istream_iterator<_Tp, _Dist>& operator++() { 837 _M_read(); 838 return *this; 839 } 840 istream_iterator<_Tp, _Dist> operator++(int) { 841 istream_iterator<_Tp, _Dist> __tmp = *this; 842 _M_read(); 843 return __tmp; 844 } 845 }; 846 847 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 848 849 template <class _Tp, class _Dist> 850 inline input_iterator_tag 851 iterator_category(const istream_iterator<_Tp, _Dist>&) 852 { 853 return input_iterator_tag(); 854 } 855 856 template <class _Tp, class _Dist> 857 inline _Tp* 858 value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; } 859 860 template <class _Tp, class _Dist> 861 inline _Dist* 862 distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; } 863 864 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 865 866 template <class _Tp, class _Distance> 867 inline bool operator==(const istream_iterator<_Tp, _Distance>& __x, 868 const istream_iterator<_Tp, _Distance>& __y) { 869 return (__x._M_stream == __y._M_stream && 870 __x._M_end_marker == __y._M_end_marker) || 871 __x._M_end_marker == false && __y._M_end_marker == false; 872 } 873 874 template <class _Tp> 875 class ostream_iterator { 876 protected: 877 ostream* _M_stream; 878 const char* _M_string; 879 public: 880 typedef output_iterator_tag iterator_category; 881 typedef void value_type; 882 typedef void difference_type; 883 typedef void pointer; 884 typedef void reference; 885 886 ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {} 887 ostream_iterator(ostream& __s, const char* __c) 888 : _M_stream(&__s), _M_string(__c) {} 889 ostream_iterator<_Tp>& operator=(const _Tp& __value) { 890 *_M_stream << __value; 891 if (_M_string) *_M_stream << _M_string; 892 return *this; 893 } 894 ostream_iterator<_Tp>& operator*() { return *this; } 895 ostream_iterator<_Tp>& operator++() { return *this; } 896 ostream_iterator<_Tp>& operator++(int) { return *this; } 897 }; 898 899 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 900 901 template <class _Tp> 902 inline output_iterator_tag 903 iterator_category(const ostream_iterator<_Tp>&) { 904 return output_iterator_tag(); 905 } 906 907 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 908 909 __STL_END_NAMESPACE 910 911 #endif /* __SGI_STL_INTERNAL_ITERATOR_H */ 912 913 // Local Variables: 914 // mode:C++ 915 // End: 916