stl_iterator.h

Go to the documentation of this file.
00001 // Iterators -*- C++ -*- 00002 00003 // Copyright (C) 2001, 2002 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 2, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 /* 00031 * 00032 * Copyright (c) 1994 00033 * Hewlett-Packard Company 00034 * 00035 * Permission to use, copy, modify, distribute and sell this software 00036 * and its documentation for any purpose is hereby granted without fee, 00037 * provided that the above copyright notice appear in all copies and 00038 * that both that copyright notice and this permission notice appear 00039 * in supporting documentation. Hewlett-Packard Company makes no 00040 * representations about the suitability of this software for any 00041 * purpose. It is provided "as is" without express or implied warranty. 00042 * 00043 * 00044 * Copyright (c) 1996-1998 00045 * Silicon Graphics Computer Systems, Inc. 00046 * 00047 * Permission to use, copy, modify, distribute and sell this software 00048 * and its documentation for any purpose is hereby granted without fee, 00049 * provided that the above copyright notice appear in all copies and 00050 * that both that copyright notice and this permission notice appear 00051 * in supporting documentation. Silicon Graphics makes no 00052 * representations about the suitability of this software for any 00053 * purpose. It is provided "as is" without express or implied warranty. 00054 */ 00055 00056 /** @file stl_iterator.h 00057 * This is an internal header file, included by other library headers. 00058 * You should not attempt to use it directly. 00059 * 00060 * This file implements reverse_iterator, back_insert_iterator, 00061 * front_insert_iterator, insert_iterator, __normal_iterator, and their 00062 * supporting functions and overloaded operators. 00063 */ 00064 00065 #ifndef __GLIBCPP_INTERNAL_ITERATOR_H 00066 #define __GLIBCPP_INTERNAL_ITERATOR_H 00067 00068 namespace std 00069 { 00070 // 24.4.1 Reverse iterators 00071 /** 00072 * "Bidirectional and random access iterators have corresponding reverse 00073 * %iterator adaptors that iterate through the data structure in the 00074 * opposite direction. They have the same signatures as the corresponding 00075 * iterators. The fundamental relation between a reverse %iterator and its 00076 * corresponding %iterator @c i is established by the identity: 00077 * @code 00078 * &*(reverse_iterator(i)) == &*(i - 1) 00079 * @endcode 00080 * 00081 * This mapping is dictated by the fact that while there is always a 00082 * pointer past the end of an array, there might not be a valid pointer 00083 * before the beginning of an array." [24.4.1]/1,2 00084 * 00085 * Reverse iterators can be tricky and surprising at first. Their 00086 * semantics make sense, however, and the trickiness is a side effect of 00087 * the requirement that the iterators must be safe. 00088 */ 00089 template<typename _Iterator> 00090 class reverse_iterator 00091 : public iterator<typename iterator_traits<_Iterator>::iterator_category, 00092 typename iterator_traits<_Iterator>::value_type, 00093 typename iterator_traits<_Iterator>::difference_type, 00094 typename iterator_traits<_Iterator>::pointer, 00095 typename iterator_traits<_Iterator>::reference> 00096 { 00097 protected: 00098 _Iterator current; 00099 00100 public: 00101 typedef _Iterator iterator_type; 00102 typedef typename iterator_traits<_Iterator>::difference_type 00103 difference_type; 00104 typedef typename iterator_traits<_Iterator>::reference reference; 00105 typedef typename iterator_traits<_Iterator>::pointer pointer; 00106 00107 public: 00108 /** 00109 * The default constructor default-initializes member @p current. 00110 * If it is a pointer, that means it is zero-initialized. 00111 */ 00112 // _GLIBCPP_RESOLVE_LIB_DEFECTS 00113 // 235 No specification of default ctor for reverse_iterator 00114 reverse_iterator() : current() { } 00115 00116 /** 00117 * This %iterator will move in the opposite direction that @p x does. 00118 */ 00119 explicit 00120 reverse_iterator(iterator_type __x) : current(__x) { } 00121 00122 /** 00123 * The copy constructor is normal. 00124 */ 00125 reverse_iterator(const reverse_iterator& __x) 00126 : current(__x.current) { } 00127 00128 /** 00129 * A reverse_iterator across other types can be copied in the normal 00130 * fashion. 00131 */ 00132 template<typename _Iter> 00133 reverse_iterator(const reverse_iterator<_Iter>& __x) 00134 : current(__x.base()) { } 00135 00136 /** 00137 * @return @c current, the %iterator used for underlying work. 00138 */ 00139 iterator_type 00140 base() const { return current; } 00141 00142 /** 00143 * @return TODO 00144 * 00145 * @doctodo 00146 */ 00147 reference 00148 operator*() const 00149 { 00150 _Iterator __tmp = current; 00151 return *--__tmp; 00152 } 00153 00154 /** 00155 * @return TODO 00156 * 00157 * @doctodo 00158 */ 00159 pointer 00160 operator->() const { return &(operator*()); } 00161 00162 /** 00163 * @return TODO 00164 * 00165 * @doctodo 00166 */ 00167 reverse_iterator& 00168 operator++() 00169 { 00170 --current; 00171 return *this; 00172 } 00173 00174 /** 00175 * @return TODO 00176 * 00177 * @doctodo 00178 */ 00179 reverse_iterator 00180 operator++(int) 00181 { 00182 reverse_iterator __tmp = *this; 00183 --current; 00184 return __tmp; 00185 } 00186 00187 /** 00188 * @return TODO 00189 * 00190 * @doctodo 00191 */ 00192 reverse_iterator& 00193 operator--() 00194 { 00195 ++current; 00196 return *this; 00197 } 00198 00199 /** 00200 * @return TODO 00201 * 00202 * @doctodo 00203 */ 00204 reverse_iterator operator--(int) 00205 { 00206 reverse_iterator __tmp = *this; 00207 ++current; 00208 return __tmp; 00209 } 00210 00211 /** 00212 * @return TODO 00213 * 00214 * @doctodo 00215 */ 00216 reverse_iterator 00217 operator+(difference_type __n) const 00218 { return reverse_iterator(current - __n); } 00219 00220 /** 00221 * @return TODO 00222 * 00223 * @doctodo 00224 */ 00225 reverse_iterator& 00226 operator+=(difference_type __n) 00227 { 00228 current -= __n; 00229 return *this; 00230 } 00231 00232 /** 00233 * @return TODO 00234 * 00235 * @doctodo 00236 */ 00237 reverse_iterator 00238 operator-(difference_type __n) const 00239 { return reverse_iterator(current + __n); } 00240 00241 /** 00242 * @return TODO 00243 * 00244 * @doctodo 00245 */ 00246 reverse_iterator& 00247 operator-=(difference_type __n) 00248 { 00249 current += __n; 00250 return *this; 00251 } 00252 00253 /** 00254 * @return TODO 00255 * 00256 * @doctodo 00257 */ 00258 reference 00259 operator[](difference_type __n) const { return *(*this + __n); } 00260 }; 00261 00262 //@{ 00263 /** 00264 * @param x A %reverse_iterator. 00265 * @param y A %reverse_iterator. 00266 * @return A simple bool. 00267 * 00268 * Reverse iterators forward many operations to their underlying base() 00269 * iterators. Others are implemented in terms of one another. 00270 * 00271 */ 00272 template<typename _Iterator> 00273 inline bool 00274 operator==(const reverse_iterator<_Iterator>& __x, 00275 const reverse_iterator<_Iterator>& __y) 00276 { return __x.base() == __y.base(); } 00277 00278 template<typename _Iterator> 00279 inline bool 00280 operator<(const reverse_iterator<_Iterator>& __x, 00281 const reverse_iterator<_Iterator>& __y) 00282 { return __y.base() < __x.base(); } 00283 00284 template<typename _Iterator> 00285 inline bool 00286 operator!=(const reverse_iterator<_Iterator>& __x, 00287 const reverse_iterator<_Iterator>& __y) 00288 { return !(__x == __y); } 00289 00290 template<typename _Iterator> 00291 inline bool 00292 operator>(const reverse_iterator<_Iterator>& __x, 00293 const reverse_iterator<_Iterator>& __y) 00294 { return __y < __x; } 00295 00296 template<typename _Iterator> 00297 inline bool 00298 operator<=(const reverse_iterator<_Iterator>& __x, 00299 const reverse_iterator<_Iterator>& __y) 00300 { return !(__y < __x); } 00301 00302 template<typename _Iterator> 00303 inline bool 00304 operator>=(const reverse_iterator<_Iterator>& __x, 00305 const reverse_iterator<_Iterator>& __y) 00306 { return !(__x < __y); } 00307 00308 template<typename _Iterator> 00309 inline typename reverse_iterator<_Iterator>::difference_type 00310 operator-(const reverse_iterator<_Iterator>& __x, 00311 const reverse_iterator<_Iterator>& __y) 00312 { return __y.base() - __x.base(); } 00313 00314 template<typename _Iterator> 00315 inline reverse_iterator<_Iterator> 00316 operator+(typename reverse_iterator<_Iterator>::difference_type __n, 00317 const reverse_iterator<_Iterator>& __x) 00318 { return reverse_iterator<_Iterator>(__x.base() - __n); } 00319 //@} 00320 00321 // 24.4.2.2.1 back_insert_iterator 00322 /** 00323 * @brief Turns assignment into insertion. 00324 * 00325 * These are output iterators, constructed from a container-of-T. 00326 * Assigning a T to the iterator appends it to the container using 00327 * push_back. 00328 * 00329 * Tip: Using the back_inserter function to create these iterators can 00330 * save typing. 00331 */ 00332 template<typename _Container> 00333 class back_insert_iterator 00334 : public iterator<output_iterator_tag, void, void, void, void> 00335 { 00336 protected: 00337 _Container* container; 00338 00339 public: 00340 /// A nested typedef for the type of whatever container you used. 00341 typedef _Container container_type; 00342 00343 /// The only way to create this %iterator is with a container. 00344 explicit 00345 back_insert_iterator(_Container& __x) : container(&__x) { } 00346 00347 /** 00348 * @param value An instance of whatever type 00349 * container_type::const_reference is; presumably a 00350 * reference-to-const T for container<T>. 00351 * @return This %iterator, for chained operations. 00352 * 00353 * This kind of %iterator doesn't really have a "position" in the 00354 * container (you can think of the position as being permanently at 00355 * the end, if you like). Assigning a value to the %iterator will 00356 * always append the value to the end of the container. 00357 */ 00358 back_insert_iterator& 00359 operator=(typename _Container::const_reference __value) 00360 { 00361 container->push_back(__value); 00362 return *this; 00363 } 00364 00365 /// Simply returns *this. 00366 back_insert_iterator& 00367 operator*() { return *this; } 00368 00369 /// Simply returns *this. (This %iterator does not "move".) 00370 back_insert_iterator& 00371 operator++() { return *this; } 00372 00373 /// Simply returns *this. (This %iterator does not "move".) 00374 back_insert_iterator 00375 operator++(int) { return *this; } 00376 }; 00377 00378 /** 00379 * @param x A container of arbitrary type. 00380 * @return An instance of back_insert_iterator working on @p x. 00381 * 00382 * This wrapper function helps in creating back_insert_iterator instances. 00383 * Typing the name of the %iterator requires knowing the precise full 00384 * type of the container, which can be tedious and impedes generic 00385 * programming. Using this function lets you take advantage of automatic 00386 * template parameter deduction, making the compiler match the correct 00387 * types for you. 00388 */ 00389 template<typename _Container> 00390 inline back_insert_iterator<_Container> 00391 back_inserter(_Container& __x) 00392 { return back_insert_iterator<_Container>(__x); } 00393 00394 /** 00395 * @brief Turns assignment into insertion. 00396 * 00397 * These are output iterators, constructed from a container-of-T. 00398 * Assigning a T to the iterator prepends it to the container using 00399 * push_front. 00400 * 00401 * Tip: Using the front_inserter function to create these iterators can 00402 * save typing. 00403 */ 00404 template<typename _Container> 00405 class front_insert_iterator 00406 : public iterator<output_iterator_tag, void, void, void, void> 00407 { 00408 protected: 00409 _Container* container; 00410 00411 public: 00412 /// A nested typedef for the type of whatever container you used. 00413 typedef _Container container_type; 00414 00415 /// The only way to create this %iterator is with a container. 00416 explicit front_insert_iterator(_Container& __x) : container(&__x) { } 00417 00418 /** 00419 * @param value An instance of whatever type 00420 * container_type::const_reference is; presumably a 00421 * reference-to-const T for container<T>. 00422 * @return This %iterator, for chained operations. 00423 * 00424 * This kind of %iterator doesn't really have a "position" in the 00425 * container (you can think of the position as being permanently at 00426 * the front, if you like). Assigning a value to the %iterator will 00427 * always prepend the value to the front of the container. 00428 */ 00429 front_insert_iterator& 00430 operator=(typename _Container::const_reference __value) 00431 { 00432 container->push_front(__value); 00433 return *this; 00434 } 00435 00436 /// Simply returns *this. 00437 front_insert_iterator& 00438 operator*() { return *this; } 00439 00440 /// Simply returns *this. (This %iterator does not "move".) 00441 front_insert_iterator& 00442 operator++() { return *this; } 00443 00444 /// Simply returns *this. (This %iterator does not "move".) 00445 front_insert_iterator 00446 operator++(int) { return *this; } 00447 }; 00448 00449 /** 00450 * @param x A container of arbitrary type. 00451 * @return An instance of front_insert_iterator working on @p x. 00452 * 00453 * This wrapper function helps in creating front_insert_iterator instances. 00454 * Typing the name of the %iterator requires knowing the precise full 00455 * type of the container, which can be tedious and impedes generic 00456 * programming. Using this function lets you take advantage of automatic 00457 * template parameter deduction, making the compiler match the correct 00458 * types for you. 00459 */ 00460 template<typename _Container> 00461 inline front_insert_iterator<_Container> 00462 front_inserter(_Container& __x) 00463 { return front_insert_iterator<_Container>(__x); } 00464 00465 /** 00466 * @brief Turns assignment into insertion. 00467 * 00468 * These are output iterators, constructed from a container-of-T. 00469 * Assigning a T to the iterator inserts it in the container at the 00470 * %iterator's position, rather than overwriting the value at that 00471 * position. 00472 * 00473 * (Sequences will actually insert a @e copy of the value before the 00474 * %iterator's position.) 00475 * 00476 * Tip: Using the inserter function to create these iterators can 00477 * save typing. 00478 */ 00479 template<typename _Container> 00480 class insert_iterator 00481 : public iterator<output_iterator_tag, void, void, void, void> 00482 { 00483 protected: 00484 _Container* container; 00485 typename _Container::iterator iter; 00486 00487 public: 00488 /// A nested typedef for the type of whatever container you used. 00489 typedef _Container container_type; 00490 00491 /** 00492 * The only way to create this %iterator is with a container and an 00493 * initial position (a normal %iterator into the container). 00494 */ 00495 insert_iterator(_Container& __x, typename _Container::iterator __i) 00496 : container(&__x), iter(__i) {} 00497 00498 /** 00499 * @param value An instance of whatever type 00500 * container_type::const_reference is; presumably a 00501 * reference-to-const T for container<T>. 00502 * @return This %iterator, for chained operations. 00503 * 00504 * This kind of %iterator maintains its own position in the 00505 * container. Assigning a value to the %iterator will insert the 00506 * value into the container at the place before the %iterator. 00507 * 00508 * The position is maintained such that subsequent assignments will 00509 * insert values immediately after one another. For example, 00510 * @code 00511 * // vector v contains A and Z 00512 * 00513 * insert_iterator i (v, ++v.begin()); 00514 * i = 1; 00515 * i = 2; 00516 * i = 3; 00517 * 00518 * // vector v contains A, 1, 2, 3, and Z 00519 * @endcode 00520 */ 00521 insert_iterator& 00522 operator=(const typename _Container::const_reference __value) 00523 { 00524 iter = container->insert(iter, __value); 00525 ++iter; 00526 return *this; 00527 } 00528 00529 /// Simply returns *this. 00530 insert_iterator& 00531 operator*() { return *this; } 00532 00533 /// Simply returns *this. (This %iterator does not "move".) 00534 insert_iterator& 00535 operator++() { return *this; } 00536 00537 /// Simply returns *this. (This %iterator does not "move".) 00538 insert_iterator& 00539 operator++(int) { return *this; } 00540 }; 00541 00542 /** 00543 * @param x A container of arbitrary type. 00544 * @return An instance of insert_iterator working on @p x. 00545 * 00546 * This wrapper function helps in creating insert_iterator instances. 00547 * Typing the name of the %iterator requires knowing the precise full 00548 * type of the container, which can be tedious and impedes generic 00549 * programming. Using this function lets you take advantage of automatic 00550 * template parameter deduction, making the compiler match the correct 00551 * types for you. 00552 */ 00553 template<typename _Container, typename _Iterator> 00554 inline insert_iterator<_Container> 00555 inserter(_Container& __x, _Iterator __i) 00556 { 00557 return insert_iterator<_Container>(__x, 00558 typename _Container::iterator(__i)); 00559 } 00560 } // namespace std 00561 00562 namespace __gnu_cxx 00563 { 00564 // This iterator adapter is 'normal' in the sense that it does not 00565 // change the semantics of any of the operators of its iterator 00566 // parameter. Its primary purpose is to convert an iterator that is 00567 // not a class, e.g. a pointer, into an iterator that is a class. 00568 // The _Container parameter exists solely so that different containers 00569 // using this template can instantiate different types, even if the 00570 // _Iterator parameter is the same. 00571 using std::iterator_traits; 00572 using std::iterator; 00573 template<typename _Iterator, typename _Container> 00574 class __normal_iterator 00575 : public iterator<typename iterator_traits<_Iterator>::iterator_category, 00576 typename iterator_traits<_Iterator>::value_type, 00577 typename iterator_traits<_Iterator>::difference_type, 00578 typename iterator_traits<_Iterator>::pointer, 00579 typename iterator_traits<_Iterator>::reference> 00580 { 00581 protected: 00582 _Iterator _M_current; 00583 00584 public: 00585 typedef typename iterator_traits<_Iterator>::difference_type 00586 difference_type; 00587 typedef typename iterator_traits<_Iterator>::reference reference; 00588 typedef typename iterator_traits<_Iterator>::pointer pointer; 00589 00590 __normal_iterator() : _M_current(_Iterator()) { } 00591 00592 explicit 00593 __normal_iterator(const _Iterator& __i) : _M_current(__i) { } 00594 00595 // Allow iterator to const_iterator conversion 00596 template<typename _Iter> 00597 inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i) 00598 : _M_current(__i.base()) { } 00599 00600 // Forward iterator requirements 00601 reference 00602 operator*() const { return *_M_current; } 00603 00604 pointer 00605 operator->() const { return _M_current; } 00606 00607 __normal_iterator& 00608 operator++() { ++_M_current; return *this; } 00609 00610 __normal_iterator 00611 operator++(int) { return __normal_iterator(_M_current++); } 00612 00613 // Bidirectional iterator requirements 00614 __normal_iterator& 00615 operator--() { --_M_current; return *this; } 00616 00617 __normal_iterator 00618 operator--(int) { return __normal_iterator(_M_current--); } 00619 00620 // Random access iterator requirements 00621 reference 00622 operator[](const difference_type& __n) const 00623 { return _M_current[__n]; } 00624 00625 __normal_iterator& 00626 operator+=(const difference_type& __n) 00627 { _M_current += __n; return *this; } 00628 00629 __normal_iterator 00630 operator+(const difference_type& __n) const 00631 { return __normal_iterator(_M_current + __n); } 00632 00633 __normal_iterator& 00634 operator-=(const difference_type& __n) 00635 { _M_current -= __n; return *this; } 00636 00637 __normal_iterator 00638 operator-(const difference_type& __n) const 00639 { return __normal_iterator(_M_current - __n); } 00640 00641 const _Iterator& 00642 base() const { return _M_current; } 00643 }; 00644 00645 // Note: In what follows, the left- and right-hand-side iterators are 00646 // allowed to vary in types (conceptually in cv-qualification) so that 00647 // comparaison between cv-qualified and non-cv-qualified iterators be 00648 // valid. However, the greedy and unfriendly operators in std::rel_ops 00649 // will make overload resolution ambiguous (when in scope) if we don't 00650 // provide overloads whose operands are of the same type. Can someone 00651 // remind me what generic programming is about? -- Gaby 00652 00653 // Forward iterator requirements 00654 template<typename _IteratorL, typename _IteratorR, typename _Container> 00655 inline bool 00656 operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, 00657 const __normal_iterator<_IteratorR, _Container>& __rhs) 00658 { return __lhs.base() == __rhs.base(); } 00659 00660 template<typename _Iterator, typename _Container> 00661 inline bool 00662 operator==(const __normal_iterator<_Iterator, _Container>& __lhs, 00663 const __normal_iterator<_Iterator, _Container>& __rhs) 00664 { return __lhs.base() == __rhs.base(); } 00665 00666 template<typename _IteratorL, typename _IteratorR, typename _Container> 00667 inline bool 00668 operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, 00669 const __normal_iterator<_IteratorR, _Container>& __rhs) 00670 { return __lhs.base() != __rhs.base(); } 00671 00672 template<typename _Iterator, typename _Container> 00673 inline bool 00674 operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, 00675 const __normal_iterator<_Iterator, _Container>& __rhs) 00676 { return __lhs.base() != __rhs.base(); } 00677 00678 // Random access iterator requirements 00679 template<typename _IteratorL, typename _IteratorR, typename _Container> 00680 inline bool 00681 operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, 00682 const __normal_iterator<_IteratorR, _Container>& __rhs) 00683 { return __lhs.base() < __rhs.base(); } 00684 00685 template<typename _Iterator, typename _Container> 00686 inline bool 00687 operator<(const __normal_iterator<_Iterator, _Container>& __lhs, 00688 const __normal_iterator<_Iterator, _Container>& __rhs) 00689 { return __lhs.base() < __rhs.base(); } 00690 00691 template<typename _IteratorL, typename _IteratorR, typename _Container> 00692 inline bool 00693 operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, 00694 const __normal_iterator<_IteratorR, _Container>& __rhs) 00695 { return __lhs.base() > __rhs.base(); } 00696 00697 template<typename _Iterator, typename _Container> 00698 inline bool 00699 operator>(const __normal_iterator<_Iterator, _Container>& __lhs, 00700 const __normal_iterator<_Iterator, _Container>& __rhs) 00701 { return __lhs.base() > __rhs.base(); } 00702 00703 template<typename _IteratorL, typename _IteratorR, typename _Container> 00704 inline bool 00705 operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, 00706 const __normal_iterator<_IteratorR, _Container>& __rhs) 00707 { return __lhs.base() <= __rhs.base(); } 00708 00709 template<typename _Iterator, typename _Container> 00710 inline bool 00711 operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, 00712 const __normal_iterator<_Iterator, _Container>& __rhs) 00713 { return __lhs.base() <= __rhs.base(); } 00714 00715 template<typename _IteratorL, typename _IteratorR, typename _Container> 00716 inline bool 00717 operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, 00718 const __normal_iterator<_IteratorR, _Container>& __rhs) 00719 { return __lhs.base() >= __rhs.base(); } 00720 00721 template<typename _Iterator, typename _Container> 00722 inline bool 00723 operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, 00724 const __normal_iterator<_Iterator, _Container>& __rhs) 00725 { return __lhs.base() >= __rhs.base(); } 00726 00727 // _GLIBCPP_RESOLVE_LIB_DEFECTS 00728 // According to the resolution of DR179 not only the various comparison 00729 // operators but also operator- must accept mixed iterator/const_iterator 00730 // parameters. 00731 template<typename _IteratorL, typename _IteratorR, typename _Container> 00732 inline typename __normal_iterator<_IteratorL, _Container>::difference_type 00733 operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, 00734 const __normal_iterator<_IteratorR, _Container>& __rhs) 00735 { return __lhs.base() - __rhs.base(); } 00736 00737 template<typename _Iterator, typename _Container> 00738 inline __normal_iterator<_Iterator, _Container> 00739 operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n, 00740 const __normal_iterator<_Iterator, _Container>& __i) 00741 { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } 00742 } // namespace __gnu_cxx 00743 00744 #endif 00745 00746 // Local Variables: 00747 // mode:C++ 00748 // End:

Generated on Sun Sep 19 16:34:00 2004 for libstdc++-v3 Source by doxygen 1.3.8