100db7afdSDavid E. O'Brien // Iterators -*- C++ -*-
200db7afdSDavid E. O'Brien 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
4*f8a1b7d9SAlexander Kabaev // Free Software Foundation, Inc.
500db7afdSDavid E. O'Brien //
600db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library.  This library is free
700db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
800db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
900db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
1000db7afdSDavid E. O'Brien // any later version.
1100db7afdSDavid E. O'Brien 
1200db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1300db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1400db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1500db7afdSDavid E. O'Brien // GNU General Public License for more details.
1600db7afdSDavid E. O'Brien 
1700db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1800db7afdSDavid E. O'Brien // with this library; see the file COPYING.  If not, write to the Free
19*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2000db7afdSDavid E. O'Brien // USA.
2100db7afdSDavid E. O'Brien 
2200db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2300db7afdSDavid E. O'Brien // library without restriction.  Specifically, if other files instantiate
2400db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2500db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2600db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2700db7afdSDavid E. O'Brien // the GNU General Public License.  This exception does not however
2800db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2900db7afdSDavid E. O'Brien // the GNU General Public License.
3000db7afdSDavid E. O'Brien 
3100db7afdSDavid E. O'Brien /*
3200db7afdSDavid E. O'Brien  *
3300db7afdSDavid E. O'Brien  * Copyright (c) 1994
3400db7afdSDavid E. O'Brien  * Hewlett-Packard Company
3500db7afdSDavid E. O'Brien  *
3600db7afdSDavid E. O'Brien  * Permission to use, copy, modify, distribute and sell this software
3700db7afdSDavid E. O'Brien  * and its documentation for any purpose is hereby granted without fee,
3800db7afdSDavid E. O'Brien  * provided that the above copyright notice appear in all copies and
3900db7afdSDavid E. O'Brien  * that both that copyright notice and this permission notice appear
4000db7afdSDavid E. O'Brien  * in supporting documentation.  Hewlett-Packard Company makes no
4100db7afdSDavid E. O'Brien  * representations about the suitability of this software for any
4200db7afdSDavid E. O'Brien  * purpose.  It is provided "as is" without express or implied warranty.
4300db7afdSDavid E. O'Brien  *
4400db7afdSDavid E. O'Brien  *
4500db7afdSDavid E. O'Brien  * Copyright (c) 1996-1998
4600db7afdSDavid E. O'Brien  * Silicon Graphics Computer Systems, Inc.
4700db7afdSDavid E. O'Brien  *
4800db7afdSDavid E. O'Brien  * Permission to use, copy, modify, distribute and sell this software
4900db7afdSDavid E. O'Brien  * and its documentation for any purpose is hereby granted without fee,
5000db7afdSDavid E. O'Brien  * provided that the above copyright notice appear in all copies and
5100db7afdSDavid E. O'Brien  * that both that copyright notice and this permission notice appear
5200db7afdSDavid E. O'Brien  * in supporting documentation.  Silicon Graphics makes no
5300db7afdSDavid E. O'Brien  * representations about the suitability of this software for any
5400db7afdSDavid E. O'Brien  * purpose.  It is provided "as is" without express or implied warranty.
5500db7afdSDavid E. O'Brien  */
5600db7afdSDavid E. O'Brien 
5700db7afdSDavid E. O'Brien /** @file stl_iterator.h
5800db7afdSDavid E. O'Brien  *  This is an internal header file, included by other library headers.
5900db7afdSDavid E. O'Brien  *  You should not attempt to use it directly.
6000db7afdSDavid E. O'Brien  *
6100db7afdSDavid E. O'Brien  *  This file implements reverse_iterator, back_insert_iterator,
6200db7afdSDavid E. O'Brien  *  front_insert_iterator, insert_iterator, __normal_iterator, and their
6300db7afdSDavid E. O'Brien  *  supporting functions and overloaded operators.
6400db7afdSDavid E. O'Brien  */
6500db7afdSDavid E. O'Brien 
66ffeaf689SAlexander Kabaev #ifndef _ITERATOR_H
67ffeaf689SAlexander Kabaev #define _ITERATOR_H 1
6800db7afdSDavid E. O'Brien 
69*f8a1b7d9SAlexander Kabaev #include <bits/cpp_type_traits.h>
70*f8a1b7d9SAlexander Kabaev #include <ext/type_traits.h>
71*f8a1b7d9SAlexander Kabaev 
_GLIBCXX_BEGIN_NAMESPACE(std)72*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
73*f8a1b7d9SAlexander Kabaev 
7400db7afdSDavid E. O'Brien   // 24.4.1 Reverse iterators
7500db7afdSDavid E. O'Brien   /**
7600db7afdSDavid E. O'Brien    *  "Bidirectional and random access iterators have corresponding reverse
7700db7afdSDavid E. O'Brien    *  %iterator adaptors that iterate through the data structure in the
7800db7afdSDavid E. O'Brien    *  opposite direction.  They have the same signatures as the corresponding
7900db7afdSDavid E. O'Brien    *  iterators.  The fundamental relation between a reverse %iterator and its
8000db7afdSDavid E. O'Brien    *  corresponding %iterator @c i is established by the identity:
8100db7afdSDavid E. O'Brien    *  @code
8200db7afdSDavid E. O'Brien    *      &*(reverse_iterator(i)) == &*(i - 1)
8300db7afdSDavid E. O'Brien    *  @endcode
8400db7afdSDavid E. O'Brien    *
8500db7afdSDavid E. O'Brien    *  This mapping is dictated by the fact that while there is always a
8600db7afdSDavid E. O'Brien    *  pointer past the end of an array, there might not be a valid pointer
8700db7afdSDavid E. O'Brien    *  before the beginning of an array." [24.4.1]/1,2
8800db7afdSDavid E. O'Brien    *
8900db7afdSDavid E. O'Brien    *  Reverse iterators can be tricky and surprising at first.  Their
9000db7afdSDavid E. O'Brien    *  semantics make sense, however, and the trickiness is a side effect of
9100db7afdSDavid E. O'Brien    *  the requirement that the iterators must be safe.
9200db7afdSDavid E. O'Brien   */
9300db7afdSDavid E. O'Brien   template<typename _Iterator>
9400db7afdSDavid E. O'Brien     class reverse_iterator
9500db7afdSDavid E. O'Brien     : public iterator<typename iterator_traits<_Iterator>::iterator_category,
9600db7afdSDavid E. O'Brien 		      typename iterator_traits<_Iterator>::value_type,
9700db7afdSDavid E. O'Brien 		      typename iterator_traits<_Iterator>::difference_type,
9800db7afdSDavid E. O'Brien 		      typename iterator_traits<_Iterator>::pointer,
9900db7afdSDavid E. O'Brien                       typename iterator_traits<_Iterator>::reference>
10000db7afdSDavid E. O'Brien     {
10100db7afdSDavid E. O'Brien     protected:
10200db7afdSDavid E. O'Brien       _Iterator current;
10300db7afdSDavid E. O'Brien 
10400db7afdSDavid E. O'Brien     public:
10500db7afdSDavid E. O'Brien       typedef _Iterator					       iterator_type;
10600db7afdSDavid E. O'Brien       typedef typename iterator_traits<_Iterator>::difference_type
10700db7afdSDavid E. O'Brien 							       difference_type;
10800db7afdSDavid E. O'Brien       typedef typename iterator_traits<_Iterator>::reference   reference;
10900db7afdSDavid E. O'Brien       typedef typename iterator_traits<_Iterator>::pointer     pointer;
11000db7afdSDavid E. O'Brien 
11100db7afdSDavid E. O'Brien     public:
11200db7afdSDavid E. O'Brien       /**
1131b86b14eSAlexander Kabaev        *  The default constructor default-initializes member @p current.
1141b86b14eSAlexander Kabaev        *  If it is a pointer, that means it is zero-initialized.
11500db7afdSDavid E. O'Brien       */
116ffeaf689SAlexander Kabaev       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1171b86b14eSAlexander Kabaev       // 235 No specification of default ctor for reverse_iterator
1181b86b14eSAlexander Kabaev       reverse_iterator() : current() { }
11900db7afdSDavid E. O'Brien 
12000db7afdSDavid E. O'Brien       /**
12100db7afdSDavid E. O'Brien        *  This %iterator will move in the opposite direction that @p x does.
12200db7afdSDavid E. O'Brien       */
12300db7afdSDavid E. O'Brien       explicit
12400db7afdSDavid E. O'Brien       reverse_iterator(iterator_type __x) : current(__x) { }
12500db7afdSDavid E. O'Brien 
12600db7afdSDavid E. O'Brien       /**
12700db7afdSDavid E. O'Brien        *  The copy constructor is normal.
12800db7afdSDavid E. O'Brien       */
12900db7afdSDavid E. O'Brien       reverse_iterator(const reverse_iterator& __x)
13000db7afdSDavid E. O'Brien       : current(__x.current) { }
13100db7afdSDavid E. O'Brien 
13200db7afdSDavid E. O'Brien       /**
13300db7afdSDavid E. O'Brien        *  A reverse_iterator across other types can be copied in the normal
13400db7afdSDavid E. O'Brien        *  fashion.
13500db7afdSDavid E. O'Brien       */
13600db7afdSDavid E. O'Brien       template<typename _Iter>
13700db7afdSDavid E. O'Brien         reverse_iterator(const reverse_iterator<_Iter>& __x)
13800db7afdSDavid E. O'Brien 	: current(__x.base()) { }
13900db7afdSDavid E. O'Brien 
14000db7afdSDavid E. O'Brien       /**
14100db7afdSDavid E. O'Brien        *  @return  @c current, the %iterator used for underlying work.
14200db7afdSDavid E. O'Brien       */
14300db7afdSDavid E. O'Brien       iterator_type
144ffeaf689SAlexander Kabaev       base() const
145ffeaf689SAlexander Kabaev       { return current; }
14600db7afdSDavid E. O'Brien 
14700db7afdSDavid E. O'Brien       /**
14800db7afdSDavid E. O'Brien        *  @return  TODO
14900db7afdSDavid E. O'Brien        *
15000db7afdSDavid E. O'Brien        *  @doctodo
15100db7afdSDavid E. O'Brien       */
15200db7afdSDavid E. O'Brien       reference
15300db7afdSDavid E. O'Brien       operator*() const
15400db7afdSDavid E. O'Brien       {
15500db7afdSDavid E. O'Brien 	_Iterator __tmp = current;
15600db7afdSDavid E. O'Brien 	return *--__tmp;
15700db7afdSDavid E. O'Brien       }
15800db7afdSDavid E. O'Brien 
15900db7afdSDavid E. O'Brien       /**
16000db7afdSDavid E. O'Brien        *  @return  TODO
16100db7afdSDavid E. O'Brien        *
16200db7afdSDavid E. O'Brien        *  @doctodo
16300db7afdSDavid E. O'Brien       */
16400db7afdSDavid E. O'Brien       pointer
165ffeaf689SAlexander Kabaev       operator->() const
166ffeaf689SAlexander Kabaev       { return &(operator*()); }
16700db7afdSDavid E. O'Brien 
16800db7afdSDavid E. O'Brien       /**
16900db7afdSDavid E. O'Brien        *  @return  TODO
17000db7afdSDavid E. O'Brien        *
17100db7afdSDavid E. O'Brien        *  @doctodo
17200db7afdSDavid E. O'Brien       */
17300db7afdSDavid E. O'Brien       reverse_iterator&
17400db7afdSDavid E. O'Brien       operator++()
17500db7afdSDavid E. O'Brien       {
17600db7afdSDavid E. O'Brien 	--current;
17700db7afdSDavid E. O'Brien 	return *this;
17800db7afdSDavid E. O'Brien       }
17900db7afdSDavid E. O'Brien 
18000db7afdSDavid E. O'Brien       /**
18100db7afdSDavid E. O'Brien        *  @return  TODO
18200db7afdSDavid E. O'Brien        *
18300db7afdSDavid E. O'Brien        *  @doctodo
18400db7afdSDavid E. O'Brien       */
18500db7afdSDavid E. O'Brien       reverse_iterator
18600db7afdSDavid E. O'Brien       operator++(int)
18700db7afdSDavid E. O'Brien       {
18800db7afdSDavid E. O'Brien 	reverse_iterator __tmp = *this;
18900db7afdSDavid E. O'Brien 	--current;
19000db7afdSDavid E. O'Brien 	return __tmp;
19100db7afdSDavid E. O'Brien       }
19200db7afdSDavid E. O'Brien 
19300db7afdSDavid E. O'Brien       /**
19400db7afdSDavid E. O'Brien        *  @return  TODO
19500db7afdSDavid E. O'Brien        *
19600db7afdSDavid E. O'Brien        *  @doctodo
19700db7afdSDavid E. O'Brien       */
19800db7afdSDavid E. O'Brien       reverse_iterator&
19900db7afdSDavid E. O'Brien       operator--()
20000db7afdSDavid E. O'Brien       {
20100db7afdSDavid E. O'Brien 	++current;
20200db7afdSDavid E. O'Brien 	return *this;
20300db7afdSDavid E. O'Brien       }
20400db7afdSDavid E. O'Brien 
20500db7afdSDavid E. O'Brien       /**
20600db7afdSDavid E. O'Brien        *  @return  TODO
20700db7afdSDavid E. O'Brien        *
20800db7afdSDavid E. O'Brien        *  @doctodo
20900db7afdSDavid E. O'Brien       */
210*f8a1b7d9SAlexander Kabaev       reverse_iterator
211*f8a1b7d9SAlexander Kabaev       operator--(int)
21200db7afdSDavid E. O'Brien       {
21300db7afdSDavid E. O'Brien 	reverse_iterator __tmp = *this;
21400db7afdSDavid E. O'Brien 	++current;
21500db7afdSDavid E. O'Brien 	return __tmp;
21600db7afdSDavid E. O'Brien       }
21700db7afdSDavid E. O'Brien 
21800db7afdSDavid E. O'Brien       /**
21900db7afdSDavid E. O'Brien        *  @return  TODO
22000db7afdSDavid E. O'Brien        *
22100db7afdSDavid E. O'Brien        *  @doctodo
22200db7afdSDavid E. O'Brien       */
22300db7afdSDavid E. O'Brien       reverse_iterator
22400db7afdSDavid E. O'Brien       operator+(difference_type __n) const
22500db7afdSDavid E. O'Brien       { return reverse_iterator(current - __n); }
22600db7afdSDavid E. O'Brien 
22700db7afdSDavid E. O'Brien       /**
22800db7afdSDavid E. O'Brien        *  @return  TODO
22900db7afdSDavid E. O'Brien        *
23000db7afdSDavid E. O'Brien        *  @doctodo
23100db7afdSDavid E. O'Brien       */
23200db7afdSDavid E. O'Brien       reverse_iterator&
23300db7afdSDavid E. O'Brien       operator+=(difference_type __n)
23400db7afdSDavid E. O'Brien       {
23500db7afdSDavid E. O'Brien 	current -= __n;
23600db7afdSDavid E. O'Brien 	return *this;
23700db7afdSDavid E. O'Brien       }
23800db7afdSDavid E. O'Brien 
23900db7afdSDavid E. O'Brien       /**
24000db7afdSDavid E. O'Brien        *  @return  TODO
24100db7afdSDavid E. O'Brien        *
24200db7afdSDavid E. O'Brien        *  @doctodo
24300db7afdSDavid E. O'Brien       */
24400db7afdSDavid E. O'Brien       reverse_iterator
24500db7afdSDavid E. O'Brien       operator-(difference_type __n) const
24600db7afdSDavid E. O'Brien       { return reverse_iterator(current + __n); }
24700db7afdSDavid E. O'Brien 
24800db7afdSDavid E. O'Brien       /**
24900db7afdSDavid E. O'Brien        *  @return  TODO
25000db7afdSDavid E. O'Brien        *
25100db7afdSDavid E. O'Brien        *  @doctodo
25200db7afdSDavid E. O'Brien       */
25300db7afdSDavid E. O'Brien       reverse_iterator&
25400db7afdSDavid E. O'Brien       operator-=(difference_type __n)
25500db7afdSDavid E. O'Brien       {
25600db7afdSDavid E. O'Brien 	current += __n;
25700db7afdSDavid E. O'Brien 	return *this;
25800db7afdSDavid E. O'Brien       }
25900db7afdSDavid E. O'Brien 
26000db7afdSDavid E. O'Brien       /**
26100db7afdSDavid E. O'Brien        *  @return  TODO
26200db7afdSDavid E. O'Brien        *
26300db7afdSDavid E. O'Brien        *  @doctodo
26400db7afdSDavid E. O'Brien       */
26500db7afdSDavid E. O'Brien       reference
266ffeaf689SAlexander Kabaev       operator[](difference_type __n) const
267ffeaf689SAlexander Kabaev       { return *(*this + __n); }
26800db7afdSDavid E. O'Brien     };
26900db7afdSDavid E. O'Brien 
27000db7afdSDavid E. O'Brien   //@{
27100db7afdSDavid E. O'Brien   /**
27200db7afdSDavid E. O'Brien    *  @param  x  A %reverse_iterator.
27300db7afdSDavid E. O'Brien    *  @param  y  A %reverse_iterator.
27400db7afdSDavid E. O'Brien    *  @return  A simple bool.
27500db7afdSDavid E. O'Brien    *
27600db7afdSDavid E. O'Brien    *  Reverse iterators forward many operations to their underlying base()
27700db7afdSDavid E. O'Brien    *  iterators.  Others are implemented in terms of one another.
27800db7afdSDavid E. O'Brien    *
27900db7afdSDavid E. O'Brien   */
28000db7afdSDavid E. O'Brien   template<typename _Iterator>
28100db7afdSDavid E. O'Brien     inline bool
28200db7afdSDavid E. O'Brien     operator==(const reverse_iterator<_Iterator>& __x,
28300db7afdSDavid E. O'Brien 	       const reverse_iterator<_Iterator>& __y)
28400db7afdSDavid E. O'Brien     { return __x.base() == __y.base(); }
28500db7afdSDavid E. O'Brien 
28600db7afdSDavid E. O'Brien   template<typename _Iterator>
28700db7afdSDavid E. O'Brien     inline bool
28800db7afdSDavid E. O'Brien     operator<(const reverse_iterator<_Iterator>& __x,
28900db7afdSDavid E. O'Brien 	      const reverse_iterator<_Iterator>& __y)
29000db7afdSDavid E. O'Brien     { return __y.base() < __x.base(); }
29100db7afdSDavid E. O'Brien 
29200db7afdSDavid E. O'Brien   template<typename _Iterator>
29300db7afdSDavid E. O'Brien     inline bool
29400db7afdSDavid E. O'Brien     operator!=(const reverse_iterator<_Iterator>& __x,
29500db7afdSDavid E. O'Brien 	       const reverse_iterator<_Iterator>& __y)
29600db7afdSDavid E. O'Brien     { return !(__x == __y); }
29700db7afdSDavid E. O'Brien 
29800db7afdSDavid E. O'Brien   template<typename _Iterator>
29900db7afdSDavid E. O'Brien     inline bool
30000db7afdSDavid E. O'Brien     operator>(const reverse_iterator<_Iterator>& __x,
30100db7afdSDavid E. O'Brien 	      const reverse_iterator<_Iterator>& __y)
30200db7afdSDavid E. O'Brien     { return __y < __x; }
30300db7afdSDavid E. O'Brien 
30400db7afdSDavid E. O'Brien   template<typename _Iterator>
30500db7afdSDavid E. O'Brien     inline bool
30600db7afdSDavid E. O'Brien     operator<=(const reverse_iterator<_Iterator>& __x,
30700db7afdSDavid E. O'Brien 	       const reverse_iterator<_Iterator>& __y)
30800db7afdSDavid E. O'Brien     { return !(__y < __x); }
30900db7afdSDavid E. O'Brien 
31000db7afdSDavid E. O'Brien   template<typename _Iterator>
31100db7afdSDavid E. O'Brien     inline bool
31200db7afdSDavid E. O'Brien     operator>=(const reverse_iterator<_Iterator>& __x,
31300db7afdSDavid E. O'Brien 	       const reverse_iterator<_Iterator>& __y)
31400db7afdSDavid E. O'Brien     { return !(__x < __y); }
31500db7afdSDavid E. O'Brien 
31600db7afdSDavid E. O'Brien   template<typename _Iterator>
31700db7afdSDavid E. O'Brien     inline typename reverse_iterator<_Iterator>::difference_type
31800db7afdSDavid E. O'Brien     operator-(const reverse_iterator<_Iterator>& __x,
31900db7afdSDavid E. O'Brien 	      const reverse_iterator<_Iterator>& __y)
32000db7afdSDavid E. O'Brien     { return __y.base() - __x.base(); }
32100db7afdSDavid E. O'Brien 
32200db7afdSDavid E. O'Brien   template<typename _Iterator>
32300db7afdSDavid E. O'Brien     inline reverse_iterator<_Iterator>
32400db7afdSDavid E. O'Brien     operator+(typename reverse_iterator<_Iterator>::difference_type __n,
32500db7afdSDavid E. O'Brien 	      const reverse_iterator<_Iterator>& __x)
32600db7afdSDavid E. O'Brien     { return reverse_iterator<_Iterator>(__x.base() - __n); }
327*f8a1b7d9SAlexander Kabaev 
328*f8a1b7d9SAlexander Kabaev   // _GLIBCXX_RESOLVE_LIB_DEFECTS
329*f8a1b7d9SAlexander Kabaev   // DR 280. Comparison of reverse_iterator to const reverse_iterator.
330*f8a1b7d9SAlexander Kabaev   template<typename _IteratorL, typename _IteratorR>
331*f8a1b7d9SAlexander Kabaev     inline bool
332*f8a1b7d9SAlexander Kabaev     operator==(const reverse_iterator<_IteratorL>& __x,
333*f8a1b7d9SAlexander Kabaev 	       const reverse_iterator<_IteratorR>& __y)
334*f8a1b7d9SAlexander Kabaev     { return __x.base() == __y.base(); }
335*f8a1b7d9SAlexander Kabaev 
336*f8a1b7d9SAlexander Kabaev   template<typename _IteratorL, typename _IteratorR>
337*f8a1b7d9SAlexander Kabaev     inline bool
338*f8a1b7d9SAlexander Kabaev     operator<(const reverse_iterator<_IteratorL>& __x,
339*f8a1b7d9SAlexander Kabaev 	      const reverse_iterator<_IteratorR>& __y)
340*f8a1b7d9SAlexander Kabaev     { return __y.base() < __x.base(); }
341*f8a1b7d9SAlexander Kabaev 
342*f8a1b7d9SAlexander Kabaev   template<typename _IteratorL, typename _IteratorR>
343*f8a1b7d9SAlexander Kabaev     inline bool
344*f8a1b7d9SAlexander Kabaev     operator!=(const reverse_iterator<_IteratorL>& __x,
345*f8a1b7d9SAlexander Kabaev 	       const reverse_iterator<_IteratorR>& __y)
346*f8a1b7d9SAlexander Kabaev     { return !(__x == __y); }
347*f8a1b7d9SAlexander Kabaev 
348*f8a1b7d9SAlexander Kabaev   template<typename _IteratorL, typename _IteratorR>
349*f8a1b7d9SAlexander Kabaev     inline bool
350*f8a1b7d9SAlexander Kabaev     operator>(const reverse_iterator<_IteratorL>& __x,
351*f8a1b7d9SAlexander Kabaev 	      const reverse_iterator<_IteratorR>& __y)
352*f8a1b7d9SAlexander Kabaev     { return __y < __x; }
353*f8a1b7d9SAlexander Kabaev 
354*f8a1b7d9SAlexander Kabaev   template<typename _IteratorL, typename _IteratorR>
355*f8a1b7d9SAlexander Kabaev     inline bool
356*f8a1b7d9SAlexander Kabaev     operator<=(const reverse_iterator<_IteratorL>& __x,
357*f8a1b7d9SAlexander Kabaev 	       const reverse_iterator<_IteratorR>& __y)
358*f8a1b7d9SAlexander Kabaev     { return !(__y < __x); }
359*f8a1b7d9SAlexander Kabaev 
360*f8a1b7d9SAlexander Kabaev   template<typename _IteratorL, typename _IteratorR>
361*f8a1b7d9SAlexander Kabaev     inline bool
362*f8a1b7d9SAlexander Kabaev     operator>=(const reverse_iterator<_IteratorL>& __x,
363*f8a1b7d9SAlexander Kabaev 	       const reverse_iterator<_IteratorR>& __y)
364*f8a1b7d9SAlexander Kabaev     { return !(__x < __y); }
365*f8a1b7d9SAlexander Kabaev 
366*f8a1b7d9SAlexander Kabaev   template<typename _IteratorL, typename _IteratorR>
367*f8a1b7d9SAlexander Kabaev     inline typename reverse_iterator<_IteratorL>::difference_type
368*f8a1b7d9SAlexander Kabaev     operator-(const reverse_iterator<_IteratorL>& __x,
369*f8a1b7d9SAlexander Kabaev 	      const reverse_iterator<_IteratorR>& __y)
370*f8a1b7d9SAlexander Kabaev     { return __y.base() - __x.base(); }
37100db7afdSDavid E. O'Brien   //@}
37200db7afdSDavid E. O'Brien 
37300db7afdSDavid E. O'Brien   // 24.4.2.2.1 back_insert_iterator
37400db7afdSDavid E. O'Brien   /**
3751b86b14eSAlexander Kabaev    *  @brief  Turns assignment into insertion.
3761b86b14eSAlexander Kabaev    *
37700db7afdSDavid E. O'Brien    *  These are output iterators, constructed from a container-of-T.
37800db7afdSDavid E. O'Brien    *  Assigning a T to the iterator appends it to the container using
37900db7afdSDavid E. O'Brien    *  push_back.
38000db7afdSDavid E. O'Brien    *
38100db7afdSDavid E. O'Brien    *  Tip:  Using the back_inserter function to create these iterators can
38200db7afdSDavid E. O'Brien    *  save typing.
38300db7afdSDavid E. O'Brien   */
38400db7afdSDavid E. O'Brien   template<typename _Container>
38500db7afdSDavid E. O'Brien     class back_insert_iterator
38600db7afdSDavid E. O'Brien     : public iterator<output_iterator_tag, void, void, void, void>
38700db7afdSDavid E. O'Brien     {
38800db7afdSDavid E. O'Brien     protected:
38900db7afdSDavid E. O'Brien       _Container* container;
39000db7afdSDavid E. O'Brien 
39100db7afdSDavid E. O'Brien     public:
39200db7afdSDavid E. O'Brien       /// A nested typedef for the type of whatever container you used.
39300db7afdSDavid E. O'Brien       typedef _Container          container_type;
39400db7afdSDavid E. O'Brien 
39500db7afdSDavid E. O'Brien       /// The only way to create this %iterator is with a container.
39600db7afdSDavid E. O'Brien       explicit
back_insert_iterator(_Container & __x)39700db7afdSDavid E. O'Brien       back_insert_iterator(_Container& __x) : container(&__x) { }
39800db7afdSDavid E. O'Brien 
39900db7afdSDavid E. O'Brien       /**
40000db7afdSDavid E. O'Brien        *  @param  value  An instance of whatever type
40100db7afdSDavid E. O'Brien        *                 container_type::const_reference is; presumably a
40200db7afdSDavid E. O'Brien        *                 reference-to-const T for container<T>.
40300db7afdSDavid E. O'Brien        *  @return  This %iterator, for chained operations.
40400db7afdSDavid E. O'Brien        *
40500db7afdSDavid E. O'Brien        *  This kind of %iterator doesn't really have a "position" in the
40600db7afdSDavid E. O'Brien        *  container (you can think of the position as being permanently at
40700db7afdSDavid E. O'Brien        *  the end, if you like).  Assigning a value to the %iterator will
40800db7afdSDavid E. O'Brien        *  always append the value to the end of the container.
40900db7afdSDavid E. O'Brien       */
41000db7afdSDavid E. O'Brien       back_insert_iterator&
41100db7afdSDavid E. O'Brien       operator=(typename _Container::const_reference __value)
41200db7afdSDavid E. O'Brien       {
41300db7afdSDavid E. O'Brien 	container->push_back(__value);
41400db7afdSDavid E. O'Brien 	return *this;
41500db7afdSDavid E. O'Brien       }
41600db7afdSDavid E. O'Brien 
41700db7afdSDavid E. O'Brien       /// Simply returns *this.
41800db7afdSDavid E. O'Brien       back_insert_iterator&
419ffeaf689SAlexander Kabaev       operator*()
420ffeaf689SAlexander Kabaev       { return *this; }
42100db7afdSDavid E. O'Brien 
42200db7afdSDavid E. O'Brien       /// Simply returns *this.  (This %iterator does not "move".)
42300db7afdSDavid E. O'Brien       back_insert_iterator&
424ffeaf689SAlexander Kabaev       operator++()
425ffeaf689SAlexander Kabaev       { return *this; }
42600db7afdSDavid E. O'Brien 
42700db7afdSDavid E. O'Brien       /// Simply returns *this.  (This %iterator does not "move".)
42800db7afdSDavid E. O'Brien       back_insert_iterator
429ffeaf689SAlexander Kabaev       operator++(int)
430ffeaf689SAlexander Kabaev       { return *this; }
43100db7afdSDavid E. O'Brien     };
43200db7afdSDavid E. O'Brien 
43300db7afdSDavid E. O'Brien   /**
43400db7afdSDavid E. O'Brien    *  @param  x  A container of arbitrary type.
43500db7afdSDavid E. O'Brien    *  @return  An instance of back_insert_iterator working on @p x.
43600db7afdSDavid E. O'Brien    *
43700db7afdSDavid E. O'Brien    *  This wrapper function helps in creating back_insert_iterator instances.
43800db7afdSDavid E. O'Brien    *  Typing the name of the %iterator requires knowing the precise full
43900db7afdSDavid E. O'Brien    *  type of the container, which can be tedious and impedes generic
44000db7afdSDavid E. O'Brien    *  programming.  Using this function lets you take advantage of automatic
44100db7afdSDavid E. O'Brien    *  template parameter deduction, making the compiler match the correct
44200db7afdSDavid E. O'Brien    *  types for you.
44300db7afdSDavid E. O'Brien   */
44400db7afdSDavid E. O'Brien   template<typename _Container>
44500db7afdSDavid E. O'Brien     inline back_insert_iterator<_Container>
back_inserter(_Container & __x)44600db7afdSDavid E. O'Brien     back_inserter(_Container& __x)
44700db7afdSDavid E. O'Brien     { return back_insert_iterator<_Container>(__x); }
44800db7afdSDavid E. O'Brien 
44900db7afdSDavid E. O'Brien   /**
4501b86b14eSAlexander Kabaev    *  @brief  Turns assignment into insertion.
4511b86b14eSAlexander Kabaev    *
45200db7afdSDavid E. O'Brien    *  These are output iterators, constructed from a container-of-T.
45300db7afdSDavid E. O'Brien    *  Assigning a T to the iterator prepends it to the container using
45400db7afdSDavid E. O'Brien    *  push_front.
45500db7afdSDavid E. O'Brien    *
45600db7afdSDavid E. O'Brien    *  Tip:  Using the front_inserter function to create these iterators can
45700db7afdSDavid E. O'Brien    *  save typing.
45800db7afdSDavid E. O'Brien   */
45900db7afdSDavid E. O'Brien   template<typename _Container>
46000db7afdSDavid E. O'Brien     class front_insert_iterator
46100db7afdSDavid E. O'Brien     : public iterator<output_iterator_tag, void, void, void, void>
46200db7afdSDavid E. O'Brien     {
46300db7afdSDavid E. O'Brien     protected:
46400db7afdSDavid E. O'Brien       _Container* container;
46500db7afdSDavid E. O'Brien 
46600db7afdSDavid E. O'Brien     public:
46700db7afdSDavid E. O'Brien       /// A nested typedef for the type of whatever container you used.
46800db7afdSDavid E. O'Brien       typedef _Container          container_type;
46900db7afdSDavid E. O'Brien 
47000db7afdSDavid E. O'Brien       /// The only way to create this %iterator is with a container.
front_insert_iterator(_Container & __x)47100db7afdSDavid E. O'Brien       explicit front_insert_iterator(_Container& __x) : container(&__x) { }
47200db7afdSDavid E. O'Brien 
47300db7afdSDavid E. O'Brien       /**
47400db7afdSDavid E. O'Brien        *  @param  value  An instance of whatever type
47500db7afdSDavid E. O'Brien        *                 container_type::const_reference is; presumably a
47600db7afdSDavid E. O'Brien        *                 reference-to-const T for container<T>.
47700db7afdSDavid E. O'Brien        *  @return  This %iterator, for chained operations.
47800db7afdSDavid E. O'Brien        *
47900db7afdSDavid E. O'Brien        *  This kind of %iterator doesn't really have a "position" in the
48000db7afdSDavid E. O'Brien        *  container (you can think of the position as being permanently at
48100db7afdSDavid E. O'Brien        *  the front, if you like).  Assigning a value to the %iterator will
48200db7afdSDavid E. O'Brien        *  always prepend the value to the front of the container.
48300db7afdSDavid E. O'Brien       */
48400db7afdSDavid E. O'Brien       front_insert_iterator&
48500db7afdSDavid E. O'Brien       operator=(typename _Container::const_reference __value)
48600db7afdSDavid E. O'Brien       {
48700db7afdSDavid E. O'Brien 	container->push_front(__value);
48800db7afdSDavid E. O'Brien 	return *this;
48900db7afdSDavid E. O'Brien       }
49000db7afdSDavid E. O'Brien 
49100db7afdSDavid E. O'Brien       /// Simply returns *this.
49200db7afdSDavid E. O'Brien       front_insert_iterator&
493ffeaf689SAlexander Kabaev       operator*()
494ffeaf689SAlexander Kabaev       { return *this; }
49500db7afdSDavid E. O'Brien 
49600db7afdSDavid E. O'Brien       /// Simply returns *this.  (This %iterator does not "move".)
49700db7afdSDavid E. O'Brien       front_insert_iterator&
498ffeaf689SAlexander Kabaev       operator++()
499ffeaf689SAlexander Kabaev       { return *this; }
50000db7afdSDavid E. O'Brien 
50100db7afdSDavid E. O'Brien       /// Simply returns *this.  (This %iterator does not "move".)
50200db7afdSDavid E. O'Brien       front_insert_iterator
503ffeaf689SAlexander Kabaev       operator++(int)
504ffeaf689SAlexander Kabaev       { return *this; }
50500db7afdSDavid E. O'Brien     };
50600db7afdSDavid E. O'Brien 
50700db7afdSDavid E. O'Brien   /**
50800db7afdSDavid E. O'Brien    *  @param  x  A container of arbitrary type.
50900db7afdSDavid E. O'Brien    *  @return  An instance of front_insert_iterator working on @p x.
51000db7afdSDavid E. O'Brien    *
51100db7afdSDavid E. O'Brien    *  This wrapper function helps in creating front_insert_iterator instances.
51200db7afdSDavid E. O'Brien    *  Typing the name of the %iterator requires knowing the precise full
51300db7afdSDavid E. O'Brien    *  type of the container, which can be tedious and impedes generic
51400db7afdSDavid E. O'Brien    *  programming.  Using this function lets you take advantage of automatic
51500db7afdSDavid E. O'Brien    *  template parameter deduction, making the compiler match the correct
51600db7afdSDavid E. O'Brien    *  types for you.
51700db7afdSDavid E. O'Brien   */
51800db7afdSDavid E. O'Brien   template<typename _Container>
51900db7afdSDavid E. O'Brien     inline front_insert_iterator<_Container>
front_inserter(_Container & __x)52000db7afdSDavid E. O'Brien     front_inserter(_Container& __x)
52100db7afdSDavid E. O'Brien     { return front_insert_iterator<_Container>(__x); }
52200db7afdSDavid E. O'Brien 
52300db7afdSDavid E. O'Brien   /**
5241b86b14eSAlexander Kabaev    *  @brief  Turns assignment into insertion.
5251b86b14eSAlexander Kabaev    *
52600db7afdSDavid E. O'Brien    *  These are output iterators, constructed from a container-of-T.
52700db7afdSDavid E. O'Brien    *  Assigning a T to the iterator inserts it in the container at the
52800db7afdSDavid E. O'Brien    *  %iterator's position, rather than overwriting the value at that
52900db7afdSDavid E. O'Brien    *  position.
53000db7afdSDavid E. O'Brien    *
53100db7afdSDavid E. O'Brien    *  (Sequences will actually insert a @e copy of the value before the
53200db7afdSDavid E. O'Brien    *  %iterator's position.)
53300db7afdSDavid E. O'Brien    *
53400db7afdSDavid E. O'Brien    *  Tip:  Using the inserter function to create these iterators can
53500db7afdSDavid E. O'Brien    *  save typing.
53600db7afdSDavid E. O'Brien   */
53700db7afdSDavid E. O'Brien   template<typename _Container>
53800db7afdSDavid E. O'Brien     class insert_iterator
53900db7afdSDavid E. O'Brien     : public iterator<output_iterator_tag, void, void, void, void>
54000db7afdSDavid E. O'Brien     {
54100db7afdSDavid E. O'Brien     protected:
54200db7afdSDavid E. O'Brien       _Container* container;
54300db7afdSDavid E. O'Brien       typename _Container::iterator iter;
54400db7afdSDavid E. O'Brien 
54500db7afdSDavid E. O'Brien     public:
54600db7afdSDavid E. O'Brien       /// A nested typedef for the type of whatever container you used.
54700db7afdSDavid E. O'Brien       typedef _Container          container_type;
54800db7afdSDavid E. O'Brien 
54900db7afdSDavid E. O'Brien       /**
55000db7afdSDavid E. O'Brien        *  The only way to create this %iterator is with a container and an
55100db7afdSDavid E. O'Brien        *  initial position (a normal %iterator into the container).
55200db7afdSDavid E. O'Brien       */
insert_iterator(_Container & __x,typename _Container::iterator __i)55300db7afdSDavid E. O'Brien       insert_iterator(_Container& __x, typename _Container::iterator __i)
55400db7afdSDavid E. O'Brien       : container(&__x), iter(__i) {}
55500db7afdSDavid E. O'Brien 
55600db7afdSDavid E. O'Brien       /**
55700db7afdSDavid E. O'Brien        *  @param  value  An instance of whatever type
55800db7afdSDavid E. O'Brien        *                 container_type::const_reference is; presumably a
55900db7afdSDavid E. O'Brien        *                 reference-to-const T for container<T>.
56000db7afdSDavid E. O'Brien        *  @return  This %iterator, for chained operations.
56100db7afdSDavid E. O'Brien        *
56200db7afdSDavid E. O'Brien        *  This kind of %iterator maintains its own position in the
56300db7afdSDavid E. O'Brien        *  container.  Assigning a value to the %iterator will insert the
56400db7afdSDavid E. O'Brien        *  value into the container at the place before the %iterator.
56500db7afdSDavid E. O'Brien        *
56600db7afdSDavid E. O'Brien        *  The position is maintained such that subsequent assignments will
56700db7afdSDavid E. O'Brien        *  insert values immediately after one another.  For example,
56800db7afdSDavid E. O'Brien        *  @code
56900db7afdSDavid E. O'Brien        *     // vector v contains A and Z
57000db7afdSDavid E. O'Brien        *
57100db7afdSDavid E. O'Brien        *     insert_iterator i (v, ++v.begin());
57200db7afdSDavid E. O'Brien        *     i = 1;
57300db7afdSDavid E. O'Brien        *     i = 2;
57400db7afdSDavid E. O'Brien        *     i = 3;
57500db7afdSDavid E. O'Brien        *
57600db7afdSDavid E. O'Brien        *     // vector v contains A, 1, 2, 3, and Z
57700db7afdSDavid E. O'Brien        *  @endcode
57800db7afdSDavid E. O'Brien       */
57900db7afdSDavid E. O'Brien       insert_iterator&
58000db7afdSDavid E. O'Brien       operator=(const typename _Container::const_reference __value)
58100db7afdSDavid E. O'Brien       {
58200db7afdSDavid E. O'Brien 	iter = container->insert(iter, __value);
58300db7afdSDavid E. O'Brien 	++iter;
58400db7afdSDavid E. O'Brien 	return *this;
58500db7afdSDavid E. O'Brien       }
58600db7afdSDavid E. O'Brien 
58700db7afdSDavid E. O'Brien       /// Simply returns *this.
58800db7afdSDavid E. O'Brien       insert_iterator&
589ffeaf689SAlexander Kabaev       operator*()
590ffeaf689SAlexander Kabaev       { return *this; }
59100db7afdSDavid E. O'Brien 
59200db7afdSDavid E. O'Brien       /// Simply returns *this.  (This %iterator does not "move".)
59300db7afdSDavid E. O'Brien       insert_iterator&
594ffeaf689SAlexander Kabaev       operator++()
595ffeaf689SAlexander Kabaev       { return *this; }
59600db7afdSDavid E. O'Brien 
59700db7afdSDavid E. O'Brien       /// Simply returns *this.  (This %iterator does not "move".)
59800db7afdSDavid E. O'Brien       insert_iterator&
599ffeaf689SAlexander Kabaev       operator++(int)
600ffeaf689SAlexander Kabaev       { return *this; }
60100db7afdSDavid E. O'Brien     };
60200db7afdSDavid E. O'Brien 
60300db7afdSDavid E. O'Brien   /**
60400db7afdSDavid E. O'Brien    *  @param  x  A container of arbitrary type.
60500db7afdSDavid E. O'Brien    *  @return  An instance of insert_iterator working on @p x.
60600db7afdSDavid E. O'Brien    *
60700db7afdSDavid E. O'Brien    *  This wrapper function helps in creating insert_iterator instances.
60800db7afdSDavid E. O'Brien    *  Typing the name of the %iterator requires knowing the precise full
60900db7afdSDavid E. O'Brien    *  type of the container, which can be tedious and impedes generic
61000db7afdSDavid E. O'Brien    *  programming.  Using this function lets you take advantage of automatic
61100db7afdSDavid E. O'Brien    *  template parameter deduction, making the compiler match the correct
61200db7afdSDavid E. O'Brien    *  types for you.
61300db7afdSDavid E. O'Brien   */
61400db7afdSDavid E. O'Brien   template<typename _Container, typename _Iterator>
61500db7afdSDavid E. O'Brien     inline insert_iterator<_Container>
inserter(_Container & __x,_Iterator __i)61600db7afdSDavid E. O'Brien     inserter(_Container& __x, _Iterator __i)
61700db7afdSDavid E. O'Brien     {
61800db7afdSDavid E. O'Brien       return insert_iterator<_Container>(__x,
61900db7afdSDavid E. O'Brien 					 typename _Container::iterator(__i));
62000db7afdSDavid E. O'Brien     }
62100db7afdSDavid E. O'Brien 
622*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
623*f8a1b7d9SAlexander Kabaev 
624*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
625*f8a1b7d9SAlexander Kabaev 
62600db7afdSDavid E. O'Brien   // This iterator adapter is 'normal' in the sense that it does not
62700db7afdSDavid E. O'Brien   // change the semantics of any of the operators of its iterator
62800db7afdSDavid E. O'Brien   // parameter.  Its primary purpose is to convert an iterator that is
62900db7afdSDavid E. O'Brien   // not a class, e.g. a pointer, into an iterator that is a class.
63000db7afdSDavid E. O'Brien   // The _Container parameter exists solely so that different containers
63100db7afdSDavid E. O'Brien   // using this template can instantiate different types, even if the
63200db7afdSDavid E. O'Brien   // _Iterator parameter is the same.
63300db7afdSDavid E. O'Brien   using std::iterator_traits;
63400db7afdSDavid E. O'Brien   using std::iterator;
63500db7afdSDavid E. O'Brien   template<typename _Iterator, typename _Container>
63600db7afdSDavid E. O'Brien     class __normal_iterator
63700db7afdSDavid E. O'Brien     {
63800db7afdSDavid E. O'Brien     protected:
63900db7afdSDavid E. O'Brien       _Iterator _M_current;
64000db7afdSDavid E. O'Brien 
64100db7afdSDavid E. O'Brien     public:
642ffeaf689SAlexander Kabaev       typedef typename iterator_traits<_Iterator>::iterator_category
643ffeaf689SAlexander Kabaev                                                              iterator_category;
644ffeaf689SAlexander Kabaev       typedef typename iterator_traits<_Iterator>::value_type  value_type;
64500db7afdSDavid E. O'Brien       typedef typename iterator_traits<_Iterator>::difference_type
64600db7afdSDavid E. O'Brien                                                              difference_type;
64700db7afdSDavid E. O'Brien       typedef typename iterator_traits<_Iterator>::reference reference;
64800db7afdSDavid E. O'Brien       typedef typename iterator_traits<_Iterator>::pointer   pointer;
64900db7afdSDavid E. O'Brien 
__normal_iterator()65000db7afdSDavid E. O'Brien       __normal_iterator() : _M_current(_Iterator()) { }
65100db7afdSDavid E. O'Brien 
65200db7afdSDavid E. O'Brien       explicit
__normal_iterator(const _Iterator & __i)65300db7afdSDavid E. O'Brien       __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
65400db7afdSDavid E. O'Brien 
65500db7afdSDavid E. O'Brien       // Allow iterator to const_iterator conversion
65600db7afdSDavid E. O'Brien       template<typename _Iter>
__normal_iterator(const __normal_iterator<_Iter,typename __enable_if<(std::__are_same<_Iter,typename _Container::pointer>::__value),_Container>::__type> & __i)657*f8a1b7d9SAlexander Kabaev         __normal_iterator(const __normal_iterator<_Iter,
658*f8a1b7d9SAlexander Kabaev 			  typename __enable_if<
659*f8a1b7d9SAlexander Kabaev       	       (std::__are_same<_Iter, typename _Container::pointer>::__value),
660*f8a1b7d9SAlexander Kabaev 		      _Container>::__type>& __i)
66100db7afdSDavid E. O'Brien         : _M_current(__i.base()) { }
66200db7afdSDavid E. O'Brien 
66300db7afdSDavid E. O'Brien       // Forward iterator requirements
66400db7afdSDavid E. O'Brien       reference
665ffeaf689SAlexander Kabaev       operator*() const
666ffeaf689SAlexander Kabaev       { return *_M_current; }
66700db7afdSDavid E. O'Brien 
66800db7afdSDavid E. O'Brien       pointer
669ffeaf689SAlexander Kabaev       operator->() const
670ffeaf689SAlexander Kabaev       { return _M_current; }
67100db7afdSDavid E. O'Brien 
67200db7afdSDavid E. O'Brien       __normal_iterator&
673ffeaf689SAlexander Kabaev       operator++()
674ffeaf689SAlexander Kabaev       {
675ffeaf689SAlexander Kabaev 	++_M_current;
676ffeaf689SAlexander Kabaev 	return *this;
677ffeaf689SAlexander Kabaev       }
67800db7afdSDavid E. O'Brien 
67900db7afdSDavid E. O'Brien       __normal_iterator
680ffeaf689SAlexander Kabaev       operator++(int)
681ffeaf689SAlexander Kabaev       { return __normal_iterator(_M_current++); }
68200db7afdSDavid E. O'Brien 
68300db7afdSDavid E. O'Brien       // Bidirectional iterator requirements
68400db7afdSDavid E. O'Brien       __normal_iterator&
685ffeaf689SAlexander Kabaev       operator--()
686ffeaf689SAlexander Kabaev       {
687ffeaf689SAlexander Kabaev 	--_M_current;
688ffeaf689SAlexander Kabaev 	return *this;
689ffeaf689SAlexander Kabaev       }
69000db7afdSDavid E. O'Brien 
69100db7afdSDavid E. O'Brien       __normal_iterator
692ffeaf689SAlexander Kabaev       operator--(int)
693ffeaf689SAlexander Kabaev       { return __normal_iterator(_M_current--); }
69400db7afdSDavid E. O'Brien 
69500db7afdSDavid E. O'Brien       // Random access iterator requirements
69600db7afdSDavid E. O'Brien       reference
69700db7afdSDavid E. O'Brien       operator[](const difference_type& __n) const
69800db7afdSDavid E. O'Brien       { return _M_current[__n]; }
69900db7afdSDavid E. O'Brien 
70000db7afdSDavid E. O'Brien       __normal_iterator&
70100db7afdSDavid E. O'Brien       operator+=(const difference_type& __n)
70200db7afdSDavid E. O'Brien       { _M_current += __n; return *this; }
70300db7afdSDavid E. O'Brien 
70400db7afdSDavid E. O'Brien       __normal_iterator
70500db7afdSDavid E. O'Brien       operator+(const difference_type& __n) const
70600db7afdSDavid E. O'Brien       { return __normal_iterator(_M_current + __n); }
70700db7afdSDavid E. O'Brien 
70800db7afdSDavid E. O'Brien       __normal_iterator&
70900db7afdSDavid E. O'Brien       operator-=(const difference_type& __n)
71000db7afdSDavid E. O'Brien       { _M_current -= __n; return *this; }
71100db7afdSDavid E. O'Brien 
71200db7afdSDavid E. O'Brien       __normal_iterator
71300db7afdSDavid E. O'Brien       operator-(const difference_type& __n) const
71400db7afdSDavid E. O'Brien       { return __normal_iterator(_M_current - __n); }
71500db7afdSDavid E. O'Brien 
71600db7afdSDavid E. O'Brien       const _Iterator&
base()717ffeaf689SAlexander Kabaev       base() const
718ffeaf689SAlexander Kabaev       { return _M_current; }
71900db7afdSDavid E. O'Brien     };
72000db7afdSDavid E. O'Brien 
72100db7afdSDavid E. O'Brien   // Note: In what follows, the left- and right-hand-side iterators are
72200db7afdSDavid E. O'Brien   // allowed to vary in types (conceptually in cv-qualification) so that
72300db7afdSDavid E. O'Brien   // comparaison between cv-qualified and non-cv-qualified iterators be
72400db7afdSDavid E. O'Brien   // valid.  However, the greedy and unfriendly operators in std::rel_ops
72500db7afdSDavid E. O'Brien   // will make overload resolution ambiguous (when in scope) if we don't
72600db7afdSDavid E. O'Brien   // provide overloads whose operands are of the same type.  Can someone
72700db7afdSDavid E. O'Brien   // remind me what generic programming is about? -- Gaby
72800db7afdSDavid E. O'Brien 
72900db7afdSDavid E. O'Brien   // Forward iterator requirements
73000db7afdSDavid E. O'Brien   template<typename _IteratorL, typename _IteratorR, typename _Container>
73100db7afdSDavid E. O'Brien     inline bool
73200db7afdSDavid E. O'Brien     operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
73300db7afdSDavid E. O'Brien 	       const __normal_iterator<_IteratorR, _Container>& __rhs)
73400db7afdSDavid E. O'Brien     { return __lhs.base() == __rhs.base(); }
73500db7afdSDavid E. O'Brien 
73600db7afdSDavid E. O'Brien   template<typename _Iterator, typename _Container>
73700db7afdSDavid E. O'Brien     inline bool
73800db7afdSDavid E. O'Brien     operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
73900db7afdSDavid E. O'Brien 	       const __normal_iterator<_Iterator, _Container>& __rhs)
74000db7afdSDavid E. O'Brien     { return __lhs.base() == __rhs.base(); }
74100db7afdSDavid E. O'Brien 
74200db7afdSDavid E. O'Brien   template<typename _IteratorL, typename _IteratorR, typename _Container>
74300db7afdSDavid E. O'Brien     inline bool
74400db7afdSDavid E. O'Brien     operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
74500db7afdSDavid E. O'Brien 	       const __normal_iterator<_IteratorR, _Container>& __rhs)
74600db7afdSDavid E. O'Brien     { return __lhs.base() != __rhs.base(); }
74700db7afdSDavid E. O'Brien 
74800db7afdSDavid E. O'Brien   template<typename _Iterator, typename _Container>
74900db7afdSDavid E. O'Brien     inline bool
75000db7afdSDavid E. O'Brien     operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
75100db7afdSDavid E. O'Brien 	       const __normal_iterator<_Iterator, _Container>& __rhs)
75200db7afdSDavid E. O'Brien     { return __lhs.base() != __rhs.base(); }
75300db7afdSDavid E. O'Brien 
75400db7afdSDavid E. O'Brien   // Random access iterator requirements
75500db7afdSDavid E. O'Brien   template<typename _IteratorL, typename _IteratorR, typename _Container>
75600db7afdSDavid E. O'Brien     inline bool
75700db7afdSDavid E. O'Brien     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
75800db7afdSDavid E. O'Brien 	      const __normal_iterator<_IteratorR, _Container>& __rhs)
75900db7afdSDavid E. O'Brien     { return __lhs.base() < __rhs.base(); }
76000db7afdSDavid E. O'Brien 
76100db7afdSDavid E. O'Brien   template<typename _Iterator, typename _Container>
76200db7afdSDavid E. O'Brien     inline bool
76300db7afdSDavid E. O'Brien     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
76400db7afdSDavid E. O'Brien 	      const __normal_iterator<_Iterator, _Container>& __rhs)
76500db7afdSDavid E. O'Brien     { return __lhs.base() < __rhs.base(); }
76600db7afdSDavid E. O'Brien 
76700db7afdSDavid E. O'Brien   template<typename _IteratorL, typename _IteratorR, typename _Container>
76800db7afdSDavid E. O'Brien     inline bool
76900db7afdSDavid E. O'Brien     operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
77000db7afdSDavid E. O'Brien 	      const __normal_iterator<_IteratorR, _Container>& __rhs)
77100db7afdSDavid E. O'Brien     { return __lhs.base() > __rhs.base(); }
77200db7afdSDavid E. O'Brien 
77300db7afdSDavid E. O'Brien   template<typename _Iterator, typename _Container>
77400db7afdSDavid E. O'Brien     inline bool
77500db7afdSDavid E. O'Brien     operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
77600db7afdSDavid E. O'Brien 	      const __normal_iterator<_Iterator, _Container>& __rhs)
77700db7afdSDavid E. O'Brien     { return __lhs.base() > __rhs.base(); }
77800db7afdSDavid E. O'Brien 
77900db7afdSDavid E. O'Brien   template<typename _IteratorL, typename _IteratorR, typename _Container>
78000db7afdSDavid E. O'Brien     inline bool
78100db7afdSDavid E. O'Brien     operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
78200db7afdSDavid E. O'Brien 	       const __normal_iterator<_IteratorR, _Container>& __rhs)
78300db7afdSDavid E. O'Brien     { return __lhs.base() <= __rhs.base(); }
78400db7afdSDavid E. O'Brien 
78500db7afdSDavid E. O'Brien   template<typename _Iterator, typename _Container>
78600db7afdSDavid E. O'Brien     inline bool
78700db7afdSDavid E. O'Brien     operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
78800db7afdSDavid E. O'Brien 	       const __normal_iterator<_Iterator, _Container>& __rhs)
78900db7afdSDavid E. O'Brien     { return __lhs.base() <= __rhs.base(); }
79000db7afdSDavid E. O'Brien 
79100db7afdSDavid E. O'Brien   template<typename _IteratorL, typename _IteratorR, typename _Container>
79200db7afdSDavid E. O'Brien     inline bool
79300db7afdSDavid E. O'Brien     operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
79400db7afdSDavid E. O'Brien 	       const __normal_iterator<_IteratorR, _Container>& __rhs)
79500db7afdSDavid E. O'Brien     { return __lhs.base() >= __rhs.base(); }
79600db7afdSDavid E. O'Brien 
79700db7afdSDavid E. O'Brien   template<typename _Iterator, typename _Container>
79800db7afdSDavid E. O'Brien     inline bool
79900db7afdSDavid E. O'Brien     operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
80000db7afdSDavid E. O'Brien 	       const __normal_iterator<_Iterator, _Container>& __rhs)
80100db7afdSDavid E. O'Brien     { return __lhs.base() >= __rhs.base(); }
80200db7afdSDavid E. O'Brien 
803ffeaf689SAlexander Kabaev   // _GLIBCXX_RESOLVE_LIB_DEFECTS
804ca6500fcSAlexander Kabaev   // According to the resolution of DR179 not only the various comparison
805ca6500fcSAlexander Kabaev   // operators but also operator- must accept mixed iterator/const_iterator
806ca6500fcSAlexander Kabaev   // parameters.
807ca6500fcSAlexander Kabaev   template<typename _IteratorL, typename _IteratorR, typename _Container>
808ca6500fcSAlexander Kabaev     inline typename __normal_iterator<_IteratorL, _Container>::difference_type
809ca6500fcSAlexander Kabaev     operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
810ca6500fcSAlexander Kabaev 	      const __normal_iterator<_IteratorR, _Container>& __rhs)
811ca6500fcSAlexander Kabaev     { return __lhs.base() - __rhs.base(); }
812ca6500fcSAlexander Kabaev 
81300db7afdSDavid E. O'Brien   template<typename _Iterator, typename _Container>
814*f8a1b7d9SAlexander Kabaev     inline typename __normal_iterator<_Iterator, _Container>::difference_type
815*f8a1b7d9SAlexander Kabaev     operator-(const __normal_iterator<_Iterator, _Container>& __lhs,
816*f8a1b7d9SAlexander Kabaev 	      const __normal_iterator<_Iterator, _Container>& __rhs)
817*f8a1b7d9SAlexander Kabaev     { return __lhs.base() - __rhs.base(); }
818*f8a1b7d9SAlexander Kabaev 
819*f8a1b7d9SAlexander Kabaev   template<typename _Iterator, typename _Container>
82000db7afdSDavid E. O'Brien     inline __normal_iterator<_Iterator, _Container>
821ffeaf689SAlexander Kabaev     operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
822ffeaf689SAlexander Kabaev 	      __n, const __normal_iterator<_Iterator, _Container>& __i)
82300db7afdSDavid E. O'Brien     { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
824*f8a1b7d9SAlexander Kabaev 
825*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
82600db7afdSDavid E. O'Brien 
82700db7afdSDavid E. O'Brien #endif
828