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