aboutsummaryrefslogtreecommitdiff
path: root/include/iterator
blob: b983a1c2e4d0672743d7f057d93361b0ac0e6f85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* -*- c++ -*- */
/*
 * Copyright (C) 2010 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef ANDROID_ASTL_ITERATOR__
#define ANDROID_ASTL_ITERATOR__

#include <cstddef>

// Iterators are a generalization of pointers to allow programs to
// work with different data structures (containers) in a uniform
// manner.
namespace std {

// Tags for the various iterator categories. Only input and forward
// iterators are supported.
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};

template<typename _Category, typename _T, typename _Distance = ptrdiff_t,
         typename _Pointer = _T*, typename _Reference = _T&>
struct iterator
{
    typedef _Category  iterator_category;  // See tags above.
    typedef _T         value_type;
    typedef _Distance  difference_type;  // Distance between iterators.
    typedef _Pointer   pointer;
    typedef _Reference reference;
};

// Generic version, simply forward the typedef to the iterator
// template argument.
template<typename _Iterator>
struct iterator_traits
{
    typedef typename _Iterator::iterator_category iterator_category;
    typedef typename _Iterator::value_type        value_type;
    typedef typename _Iterator::difference_type   difference_type;
    typedef typename _Iterator::pointer           pointer;
    typedef typename _Iterator::reference         reference;
};

// Specialization for pointers and const pointers. These are random
// access iterators.
template<typename _T>
struct iterator_traits<_T*>
{
    typedef random_access_iterator_tag iterator_category;
    typedef _T                         value_type;
    typedef ptrdiff_t                  difference_type;
    typedef _T*                        pointer;
    typedef _T&                        reference;
};

template<typename _T>
struct iterator_traits<const _T*>
{
    typedef random_access_iterator_tag iterator_category;
    typedef _T                         value_type;
    typedef ptrdiff_t                  difference_type;
    typedef const _T*                  pointer;
    typedef const _T&                  reference;
};

// Wrap an interator that is not a class (e.g pointer) into an
// iterator that is a class.
template<typename _Iterator, typename _Container>
class __wrapper_iterator
{
  public:
    typedef typename iterator_traits<_Iterator>::iterator_category
    iterator_category;
    typedef typename iterator_traits<_Iterator>::value_type value_type;
    typedef typename iterator_traits<_Iterator>::difference_type
    difference_type;
    typedef typename iterator_traits<_Iterator>::reference reference;
    typedef typename iterator_traits<_Iterator>::pointer pointer;

    __wrapper_iterator() : mCurrent(_Iterator()) { }
    explicit __wrapper_iterator(const _Iterator& i) : mCurrent(i) { }

    // Allow iterator to const_iterator conversion
    template<typename _Iter>
    __wrapper_iterator(const __wrapper_iterator<_Iter, _Container>& i)
        : mCurrent(i.base()) { }

    // Forward iterator requirements
    reference operator*() const { return *mCurrent; }
    pointer operator->() const { return mCurrent; }
    __wrapper_iterator& operator++() {
        ++mCurrent;
        return *this;
    }
    __wrapper_iterator operator++(int) {
        return __wrapper_iterator(mCurrent++);
    }

    // Bidirectional iterator requirements
    __wrapper_iterator& operator--() {
        --mCurrent;
        return *this;
    }
    __wrapper_iterator operator--(int) {
        return __wrapper_iterator(mCurrent--);
    }

    // Random access iterator requirements
    reference operator[](const difference_type& n) const {
        return mCurrent[n];
    }

    __wrapper_iterator& operator+=(const difference_type& n) {
        mCurrent += n;
        return *this;
    }

    __wrapper_iterator operator+(const difference_type& n) const {
        return __wrapper_iterator(mCurrent + n);
    }

    __wrapper_iterator& operator-=(const difference_type& n) {
        mCurrent -= n; return *this;
    }

    __wrapper_iterator operator-(const difference_type& n) const {
        return __wrapper_iterator(mCurrent - n);
    }

    const _Iterator& base() const {
        return mCurrent;
    }

  private:
    _Iterator mCurrent;
};

// Forward iterator requirements
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator==(const __wrapper_iterator<_IteratorL, _Container>& __lhs,
	       const __wrapper_iterator<_IteratorR, _Container>& __rhs)
{ return __lhs.base() == __rhs.base(); }

template<typename _Iterator, typename _Container>
inline bool
operator==(const __wrapper_iterator<_Iterator, _Container>& __lhs,
	       const __wrapper_iterator<_Iterator, _Container>& __rhs)
{ return __lhs.base() == __rhs.base(); }

template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator!=(const __wrapper_iterator<_IteratorL, _Container>& __lhs,
	       const __wrapper_iterator<_IteratorR, _Container>& __rhs)
{ return __lhs.base() != __rhs.base(); }

template<typename _Iterator, typename _Container>
inline bool
operator!=(const __wrapper_iterator<_Iterator, _Container>& __lhs,
	       const __wrapper_iterator<_Iterator, _Container>& __rhs)
{ return __lhs.base() != __rhs.base(); }

}  // namespace std

#endif  // ANDROID_ASTL_ITERATOR__