Home | History | Annotate | Download | only in include
      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 #include <type_traits.h>
     35 
     36 // Iterators are a generalization of pointers to allow programs to
     37 // work with different data structures (containers) in a uniform
     38 // manner.
     39 namespace std {
     40 
     41 // Tags for the various iterator categories. Only input and forward
     42 // iterators are supported.
     43 struct input_iterator_tag {};
     44 struct output_iterator_tag {};
     45 struct forward_iterator_tag : public input_iterator_tag {};
     46 struct bidirectional_iterator_tag : public forward_iterator_tag {};
     47 struct random_access_iterator_tag : public bidirectional_iterator_tag {};
     48 
     49 template<typename _Category, typename _T, typename _Distance = ptrdiff_t,
     50          typename _Pointer = _T*, typename _Reference = _T&>
     51 struct iterator
     52 {
     53     typedef _Category  iterator_category;  // See tags above.
     54     typedef _T         value_type;
     55     typedef _Distance  difference_type;  // Distance between iterators.
     56     typedef _Pointer   pointer;
     57     typedef _Reference reference;
     58 };
     59 
     60 // Generic version, simply forward the typedef to the iterator
     61 // template argument.
     62 template<typename _Iterator>
     63 struct iterator_traits
     64 {
     65     typedef typename _Iterator::iterator_category iterator_category;
     66     typedef typename _Iterator::value_type        value_type;
     67     typedef typename _Iterator::difference_type   difference_type;
     68     typedef typename _Iterator::pointer           pointer;
     69     typedef typename _Iterator::reference         reference;
     70 };
     71 
     72 // Specialization for pointers and const pointers. These are random
     73 // access iterators.
     74 template<typename _T>
     75 struct iterator_traits<_T*>
     76 {
     77     typedef random_access_iterator_tag iterator_category;
     78     typedef _T                         value_type;
     79     typedef ptrdiff_t                  difference_type;
     80     typedef _T*                        pointer;
     81     typedef _T&                        reference;
     82 };
     83 
     84 template<typename _T>
     85 struct iterator_traits<const _T*>
     86 {
     87     typedef random_access_iterator_tag iterator_category;
     88     typedef _T                         value_type;
     89     typedef ptrdiff_t                  difference_type;
     90     typedef const _T*                  pointer;
     91     typedef const _T&                  reference;
     92 };
     93 
     94 // Wrap an interator that is not a class (e.g pointer) into an
     95 // iterator that is a class.
     96 // TODO: move this definition in the android ns.
     97 template<typename _Iterator, typename _Container>
     98 class __wrapper_iterator
     99 {
    100   public:
    101     typedef _Iterator iterator_type;
    102     typedef typename iterator_traits<_Iterator>::iterator_category
    103     iterator_category;
    104     typedef typename iterator_traits<_Iterator>::value_type value_type;
    105     typedef typename iterator_traits<_Iterator>::difference_type
    106     difference_type;
    107     typedef typename iterator_traits<_Iterator>::reference reference;
    108     typedef typename iterator_traits<_Iterator>::pointer pointer;
    109 
    110     __wrapper_iterator() : mCurrent(_Iterator()) { }
    111     explicit __wrapper_iterator(const _Iterator& i) : mCurrent(i) { }
    112 
    113     // Allow iterator to const_iterator conversion
    114     template<typename _Iter>
    115     __wrapper_iterator(const __wrapper_iterator<_Iter, _Container>& i)
    116         : mCurrent(i.base()) { }
    117 
    118     // Forward iterator requirements
    119     reference operator*() const { return *mCurrent; }
    120     pointer operator->() const { return mCurrent; }
    121     __wrapper_iterator& operator++() {
    122         ++mCurrent;
    123         return *this;
    124     }
    125     __wrapper_iterator operator++(int) {
    126         return __wrapper_iterator(mCurrent++);
    127     }
    128 
    129     // Bidirectional iterator requirements
    130     __wrapper_iterator& operator--() {
    131         --mCurrent;
    132         return *this;
    133     }
    134     __wrapper_iterator operator--(int) {
    135         return __wrapper_iterator(mCurrent--);
    136     }
    137 
    138     // Random access iterator requirements
    139     reference operator[](const difference_type& n) const {
    140         return mCurrent[n];
    141     }
    142 
    143     __wrapper_iterator& operator+=(const difference_type& n) {
    144         mCurrent += n;
    145         return *this;
    146     }
    147 
    148     __wrapper_iterator operator+(const difference_type& n) const {
    149         return __wrapper_iterator(mCurrent + n);
    150     }
    151 
    152     __wrapper_iterator& operator-=(const difference_type& n) {
    153         mCurrent -= n; return *this;
    154     }
    155 
    156     __wrapper_iterator operator-(const difference_type& n) const {
    157         return __wrapper_iterator(mCurrent - n);
    158     }
    159 
    160     const _Iterator& base() const {
    161         return mCurrent;
    162     }
    163 
    164   private:
    165     _Iterator mCurrent;
    166 };
    167 
    168 // Forward iterator requirements
    169 template<typename _IteratorL, typename _IteratorR, typename _Container>
    170 inline bool
    171 operator==(const __wrapper_iterator<_IteratorL, _Container>& lhs,
    172            const __wrapper_iterator<_IteratorR, _Container>& rhs)
    173 { return lhs.base() == rhs.base(); }
    174 
    175 template<typename _Iterator, typename _Container>
    176 inline bool
    177 operator==(const __wrapper_iterator<_Iterator, _Container>& lhs,
    178            const __wrapper_iterator<_Iterator, _Container>& rhs)
    179 { return lhs.base() == rhs.base(); }
    180 
    181 template<typename _IteratorL, typename _IteratorR, typename _Container>
    182 inline bool
    183 operator!=(const __wrapper_iterator<_IteratorL, _Container>& lhs,
    184            const __wrapper_iterator<_IteratorR, _Container>& rhs)
    185 { return lhs.base() != rhs.base(); }
    186 
    187 template<typename _Iterator, typename _Container>
    188 inline bool
    189 operator!=(const __wrapper_iterator<_Iterator, _Container>& lhs,
    190            const __wrapper_iterator<_Iterator, _Container>& rhs)
    191 { return lhs.base() != rhs.base(); }
    192 
    193 // operator+ so we support 100 + iterator<>.
    194 template<typename _Iterator, typename _Container>
    195 inline __wrapper_iterator<_Iterator, _Container>
    196 operator+(typename __wrapper_iterator<_Iterator, _Container>::difference_type n,
    197           const __wrapper_iterator<_Iterator, _Container>& i)
    198 { return __wrapper_iterator<_Iterator, _Container>(i.base() + n); }
    199 
    200 // operator- : diff is supported on iterators.
    201 
    202 template<typename _Iterator, typename _Container>
    203 inline typename __wrapper_iterator<_Iterator, _Container>::difference_type
    204 operator-(const __wrapper_iterator<_Iterator, _Container>& lhs,
    205           const __wrapper_iterator<_Iterator, _Container>& rhs)
    206 { return lhs.base() - rhs.base(); }
    207 
    208 }  // namespace std
    209 
    210 namespace android {
    211 
    212 // Shorthand to return the catogory of an iterator. Not part of the
    213 // STL -> android namespace.
    214 template<typename _Iterator>
    215 inline typename std::iterator_traits<_Iterator>::iterator_category
    216 iterator_category(const _Iterator&)
    217 { return typename std::iterator_traits<_Iterator>::iterator_category(); }
    218 
    219 // Detect wrapper iterators.
    220 template<typename _T>
    221 struct is_wrapper_iterator: public std::false_type { };
    222 
    223 template<typename _Iterator, typename _Container>
    224 struct is_wrapper_iterator<std::__wrapper_iterator<_Iterator, _Container> >:
    225             public std::true_type { };
    226 
    227 // iter::base
    228 //
    229 // For wrapper iterators, android::iter::base(it) returns a pointer
    230 // (it.base()) which is going to match implementation(s) that use
    231 // pointers (e.g memmove).
    232 template<typename _Iterator,
    233          bool _IsWrapper = is_wrapper_iterator<_Iterator>::value>
    234 struct iter {
    235     static _Iterator base(_Iterator it) { return it; }
    236 };
    237 
    238 template<typename _Iterator>
    239 struct iter<_Iterator, true> {
    240     static typename _Iterator::iterator_type base(_Iterator it) {
    241         return it.base();
    242     }
    243 };
    244 
    245 }  // namespace android
    246 
    247 namespace std {
    248 
    249 // Utilities: distance().
    250 
    251 template<typename _InputIterator>
    252 inline typename iterator_traits<_InputIterator>::difference_type
    253 distance(_InputIterator first, _InputIterator last,
    254          input_iterator_tag)  // Match input iterators.
    255 {
    256     typename iterator_traits<_InputIterator>::difference_type dist = 0;
    257     while (first != last) {
    258         ++first;
    259         ++dist;
    260     }
    261     return dist;
    262 }
    263 
    264 // Random access iterator: equivalent to mem pointer arithmetic.
    265 template<typename _RandomAccessIterator>
    266 inline typename iterator_traits<_RandomAccessIterator>::difference_type
    267 distance(_RandomAccessIterator first, _RandomAccessIterator last,
    268          random_access_iterator_tag)  // Match random access iterators.
    269 {
    270     return last - first;
    271 }
    272 
    273 /**
    274  * Iterator arithmetic.
    275  * @param first An input iterator.
    276  * @param last  An input iterator.
    277  * @return The distance between them.
    278  */
    279 template<typename _InputIterator>
    280 inline typename iterator_traits<_InputIterator>::difference_type
    281 distance(_InputIterator first, _InputIterator last)
    282 {
    283     // The correct implementation (above) will be called based on the
    284     // iterator's category.
    285     return distance(first, last, android::iterator_category(first));
    286 }
    287 
    288 }  // namespace std
    289 
    290 #endif  // ANDROID_ASTL_ITERATOR__
    291