/* -*- 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> #include <type_traits.h> // 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. // TODO: move this definition in the android ns. template<typename _Iterator, typename _Container> class __wrapper_iterator { public: typedef _Iterator iterator_type; 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(); } // operator+ so we support 100 + iterator<>. template<typename _Iterator, typename _Container> inline __wrapper_iterator<_Iterator, _Container> operator+(typename __wrapper_iterator<_Iterator, _Container>::difference_type n, const __wrapper_iterator<_Iterator, _Container>& i) { return __wrapper_iterator<_Iterator, _Container>(i.base() + n); } // operator- : diff is supported on iterators. template<typename _Iterator, typename _Container> inline typename __wrapper_iterator<_Iterator, _Container>::difference_type operator-(const __wrapper_iterator<_Iterator, _Container>& lhs, const __wrapper_iterator<_Iterator, _Container>& rhs) { return lhs.base() - rhs.base(); } } // namespace std namespace android { // Shorthand to return the catogory of an iterator. Not part of the // STL -> android namespace. template<typename _Iterator> inline typename std::iterator_traits<_Iterator>::iterator_category iterator_category(const _Iterator&) { return typename std::iterator_traits<_Iterator>::iterator_category(); } // Detect wrapper iterators. template<typename _T> struct is_wrapper_iterator: public std::false_type { }; template<typename _Iterator, typename _Container> struct is_wrapper_iterator<std::__wrapper_iterator<_Iterator, _Container> >: public std::true_type { }; // iter::base // // For wrapper iterators, android::iter::base(it) returns a pointer // (it.base()) which is going to match implementation(s) that use // pointers (e.g memmove). template<typename _Iterator, bool _IsWrapper = is_wrapper_iterator<_Iterator>::value> struct iter { static _Iterator base(_Iterator it) { return it; } }; template<typename _Iterator> struct iter<_Iterator, true> { static typename _Iterator::iterator_type base(_Iterator it) { return it.base(); } }; } // namespace android namespace std { // Utilities: distance(). template<typename _InputIterator> inline typename iterator_traits<_InputIterator>::difference_type distance(_InputIterator first, _InputIterator last, input_iterator_tag) // Match input iterators. { typename iterator_traits<_InputIterator>::difference_type dist = 0; while (first != last) { ++first; ++dist; } return dist; } // Random access iterator: equivalent to mem pointer arithmetic. template<typename _RandomAccessIterator> inline typename iterator_traits<_RandomAccessIterator>::difference_type distance(_RandomAccessIterator first, _RandomAccessIterator last, random_access_iterator_tag) // Match random access iterators. { return last - first; } /** * Iterator arithmetic. * @param first An input iterator. * @param last An input iterator. * @return The distance between them. */ template<typename _InputIterator> inline typename iterator_traits<_InputIterator>::difference_type distance(_InputIterator first, _InputIterator last) { // The correct implementation (above) will be called based on the // iterator's category. return distance(first, last, android::iterator_category(first)); } } // namespace std #endif // ANDROID_ASTL_ITERATOR__