iterator revision b6e436eb559cdcf43e21f6617dc0a3d90c7b89b6
1/* -*- c++ -*- */
2/*
3 * Copyright (C) 2010 The Android Open Source Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *  * Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 *  * Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in
13 *    the documentation and/or other materials provided with the
14 *    distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#ifndef ANDROID_ASTL_ITERATOR__
31#define ANDROID_ASTL_ITERATOR__
32
33#include <cstddef>
34
35// Iterators are a generalization of pointers to allow programs to
36// work with different data structures (containers) in a uniform
37// manner.
38namespace std {
39
40// Tags for the various iterator categories. Only input and forward
41// iterators are supported.
42struct input_iterator_tag {};
43struct output_iterator_tag {};
44struct forward_iterator_tag : public input_iterator_tag {};
45struct bidirectional_iterator_tag : public forward_iterator_tag {};
46struct random_access_iterator_tag : public bidirectional_iterator_tag {};
47
48template<typename _Category, typename _T, typename _Distance = ptrdiff_t,
49         typename _Pointer = _T*, typename _Reference = _T&>
50struct iterator
51{
52    typedef _Category  iterator_category;  // See tags above.
53    typedef _T         value_type;
54    typedef _Distance  difference_type;  // Distance between iterators.
55    typedef _Pointer   pointer;
56    typedef _Reference reference;
57};
58
59// Generic version, simply forward the typedef to the iterator
60// template argument.
61template<typename _Iterator>
62struct iterator_traits
63{
64    typedef typename _Iterator::iterator_category iterator_category;
65    typedef typename _Iterator::value_type        value_type;
66    typedef typename _Iterator::difference_type   difference_type;
67    typedef typename _Iterator::pointer           pointer;
68    typedef typename _Iterator::reference         reference;
69};
70
71// Specialization for pointers and const pointers. These are random
72// access iterators.
73template<typename _T>
74struct iterator_traits<_T*>
75{
76    typedef random_access_iterator_tag iterator_category;
77    typedef _T                         value_type;
78    typedef ptrdiff_t                  difference_type;
79    typedef _T*                        pointer;
80    typedef _T&                        reference;
81};
82
83template<typename _T>
84struct iterator_traits<const _T*>
85{
86    typedef random_access_iterator_tag iterator_category;
87    typedef _T                         value_type;
88    typedef ptrdiff_t                  difference_type;
89    typedef const _T*                  pointer;
90    typedef const _T&                  reference;
91};
92
93// Wrap an interator that is not a class (e.g pointer) into an
94// iterator that is a class.
95template<typename _Iterator, typename _Container>
96class __wrapper_iterator
97{
98  public:
99    typedef typename iterator_traits<_Iterator>::iterator_category
100    iterator_category;
101    typedef typename iterator_traits<_Iterator>::value_type value_type;
102    typedef typename iterator_traits<_Iterator>::difference_type
103    difference_type;
104    typedef typename iterator_traits<_Iterator>::reference reference;
105    typedef typename iterator_traits<_Iterator>::pointer pointer;
106
107    __wrapper_iterator() : mCurrent(_Iterator()) { }
108    explicit __wrapper_iterator(const _Iterator& i) : mCurrent(i) { }
109
110    // Allow iterator to const_iterator conversion
111    template<typename _Iter>
112    __wrapper_iterator(const __wrapper_iterator<_Iter, _Container>& i)
113        : mCurrent(i.base()) { }
114
115    // Forward iterator requirements
116    reference operator*() const { return *mCurrent; }
117    pointer operator->() const { return mCurrent; }
118    __wrapper_iterator& operator++() {
119        ++mCurrent;
120        return *this;
121    }
122    __wrapper_iterator operator++(int) {
123        return __wrapper_iterator(mCurrent++);
124    }
125
126    // Bidirectional iterator requirements
127    __wrapper_iterator& operator--() {
128        --mCurrent;
129        return *this;
130    }
131    __wrapper_iterator operator--(int) {
132        return __wrapper_iterator(mCurrent--);
133    }
134
135    // Random access iterator requirements
136    reference operator[](const difference_type& n) const {
137        return mCurrent[n];
138    }
139
140    __wrapper_iterator& operator+=(const difference_type& n) {
141        mCurrent += n;
142        return *this;
143    }
144
145    __wrapper_iterator operator+(const difference_type& n) const {
146        return __wrapper_iterator(mCurrent + n);
147    }
148
149    __wrapper_iterator& operator-=(const difference_type& n) {
150        mCurrent -= n; return *this;
151    }
152
153    __wrapper_iterator operator-(const difference_type& n) const {
154        return __wrapper_iterator(mCurrent - n);
155    }
156
157    const _Iterator& base() const {
158        return mCurrent;
159    }
160
161  private:
162    _Iterator mCurrent;
163};
164
165// Forward iterator requirements
166template<typename _IteratorL, typename _IteratorR, typename _Container>
167inline bool
168operator==(const __wrapper_iterator<_IteratorL, _Container>& lhs,
169           const __wrapper_iterator<_IteratorR, _Container>& rhs)
170{ return lhs.base() == rhs.base(); }
171
172template<typename _Iterator, typename _Container>
173inline bool
174operator==(const __wrapper_iterator<_Iterator, _Container>& lhs,
175           const __wrapper_iterator<_Iterator, _Container>& rhs)
176{ return lhs.base() == rhs.base(); }
177
178template<typename _IteratorL, typename _IteratorR, typename _Container>
179inline bool
180operator!=(const __wrapper_iterator<_IteratorL, _Container>& lhs,
181           const __wrapper_iterator<_IteratorR, _Container>& rhs)
182{ return lhs.base() != rhs.base(); }
183
184template<typename _Iterator, typename _Container>
185inline bool
186operator!=(const __wrapper_iterator<_Iterator, _Container>& lhs,
187           const __wrapper_iterator<_Iterator, _Container>& rhs)
188{ return lhs.base() != rhs.base(); }
189
190// operator+ so we support 100 + iterator<>.
191template<typename _Iterator, typename _Container>
192inline __wrapper_iterator<_Iterator, _Container>
193operator+(typename __wrapper_iterator<_Iterator, _Container>::difference_type n,
194          const __wrapper_iterator<_Iterator, _Container>& i)
195{ return __wrapper_iterator<_Iterator, _Container>(i.base() + n); }
196
197// operator- : diff is supported on iterators.
198
199template<typename _Iterator, typename _Container>
200inline typename __wrapper_iterator<_Iterator, _Container>::difference_type
201operator-(const __wrapper_iterator<_Iterator, _Container>& lhs,
202          const __wrapper_iterator<_Iterator, _Container>& rhs)
203{ return lhs.base() - rhs.base(); }
204
205}  // namespace std
206
207namespace android {
208
209// Shorthand to return the catogory of an iterator. Not part of the
210// STL -> android namespace.
211template<typename _Iterator>
212inline typename std::iterator_traits<_Iterator>::iterator_category
213iterator_category(const _Iterator&)
214{ return typename std::iterator_traits<_Iterator>::iterator_category(); }
215
216}  // namespace android
217
218namespace std {
219
220// Utilities: distance().
221
222template<typename _InputIterator>
223inline typename iterator_traits<_InputIterator>::difference_type
224distance(_InputIterator first, _InputIterator last,
225         input_iterator_tag)  // Match input iterators.
226{
227    typename iterator_traits<_InputIterator>::difference_type dist = 0;
228    while (first != last) {
229        ++first;
230        ++dist;
231    }
232    return dist;
233}
234
235// Random access iterator: equivalent to mem pointer arithmetic.
236template<typename _RandomAccessIterator>
237inline typename iterator_traits<_RandomAccessIterator>::difference_type
238distance(_RandomAccessIterator first, _RandomAccessIterator last,
239         random_access_iterator_tag)  // Match random access iterators.
240{
241    return last - first;
242}
243
244/**
245 * Iterator arithmetic.
246 * @param first An input iterator.
247 * @param last  An input iterator.
248 * @return The distance between them.
249 */
250template<typename _InputIterator>
251inline typename iterator_traits<_InputIterator>::difference_type
252distance(_InputIterator first, _InputIterator last)
253{
254    // The correct implementation (above) will be called based on the
255    // iterator's category.
256    return distance(first, last, android::iterator_category(first));
257}
258
259}  // namespace std
260
261#endif  // ANDROID_ASTL_ITERATOR__
262