///////////////////////////////////////////////////////////////////////////// // Copyright (c) Electronic Arts Inc. All rights reserved. ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Implements a generic iterator from a given iteratable type, such as a pointer. // We cannot put this file into our own iterator.h file because we need to // still be able to use this file when we have our iterator.h disabled. // /////////////////////////////////////////////////////////////////////////////// #ifndef EASTL_INTERNAL_GENERIC_ITERATOR_H #define EASTL_INTERNAL_GENERIC_ITERATOR_H #include #if defined(EA_PRAGMA_ONCE_SUPPORTED) #pragma once #endif #include #include #include // There is no warning number 'number'. // Member template functions cannot be used for copy-assignment or copy-construction. EA_DISABLE_VC_WARNING(4619 4217); namespace eastl { /// generic_iterator /// /// Converts something which can be iterated into a formal iterator. /// While this class' primary purpose is to allow the conversion of /// a pointer to an iterator, you can convert anything else to an /// iterator by defining an iterator_traits<> specialization for that /// object type. See EASTL iterator.h for this. /// /// Example usage: /// typedef generic_iterator IntArrayIterator; /// typedef generic_iterator IntArrayIteratorOther; /// template class generic_iterator { protected: Iterator mIterator; public: typedef typename eastl::iterator_traits::iterator_category iterator_category; typedef typename eastl::iterator_traits::value_type value_type; typedef typename eastl::iterator_traits::difference_type difference_type; typedef typename eastl::iterator_traits::reference reference; typedef typename eastl::iterator_traits::pointer pointer; typedef Iterator iterator_type; typedef iterator_type wrapped_iterator_type; // This is not in the C++ Standard; it's used by use to identify it as a wrapping iterator type. typedef Container container_type; typedef generic_iterator this_type; generic_iterator() : mIterator(iterator_type()) { } explicit generic_iterator(const iterator_type& x) : mIterator(x) { } this_type& operator=(const iterator_type& x) { mIterator = x; return *this; } template generic_iterator(const generic_iterator& x) : mIterator(x.base()) { } reference operator*() const { return *mIterator; } pointer operator->() const { return mIterator; } this_type& operator++() { ++mIterator; return *this; } this_type operator++(int) { return this_type(mIterator++); } this_type& operator--() { --mIterator; return *this; } this_type operator--(int) { return this_type(mIterator--); } reference operator[](const difference_type& n) const { return mIterator[n]; } this_type& operator+=(const difference_type& n) { mIterator += n; return *this; } this_type operator+(const difference_type& n) const { return this_type(mIterator + n); } this_type& operator-=(const difference_type& n) { mIterator -= n; return *this; } this_type operator-(const difference_type& n) const { return this_type(mIterator - n); } const iterator_type& base() const { return mIterator; } }; // class generic_iterator template inline bool operator==(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() == rhs.base(); } template inline bool operator==(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() == rhs.base(); } template inline bool operator!=(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() != rhs.base(); } template inline bool operator!=(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() != rhs.base(); } template inline bool operator<(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() < rhs.base(); } template inline bool operator<(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() < rhs.base(); } template inline bool operator>(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() > rhs.base(); } template inline bool operator>(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() > rhs.base(); } template inline bool operator<=(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() <= rhs.base(); } template inline bool operator<=(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() <= rhs.base(); } template inline bool operator>=(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() >= rhs.base(); } template inline bool operator>=(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() >= rhs.base(); } template inline typename generic_iterator::difference_type operator-(const generic_iterator& lhs, const generic_iterator& rhs) { return lhs.base() - rhs.base(); } template inline generic_iterator operator+(typename generic_iterator::difference_type n, const generic_iterator& x) { return generic_iterator(x.base() + n); } /// is_generic_iterator /// /// Tells if an iterator is one of these generic_iterators. This is useful if you want to /// write code that uses miscellaneous iterators but wants to tell if they are generic_iterators. /// A primary reason to do so is that you can get at the pointer within the generic_iterator. /// template struct is_generic_iterator : public false_type { }; template struct is_generic_iterator > : public true_type { }; /// unwrap_generic_iterator /// /// Returns Iterator::get_base() if it's a generic_iterator, else returns Iterator as-is. /// /// Example usage: /// vector intVector; /// eastl::generic_iterator::iterator> genericIterator(intVector.begin()); /// vector::iterator it = unwrap_generic_iterator(genericIterator); /// template inline typename eastl::is_iterator_wrapper_helper::value>::iterator_type unwrap_generic_iterator(Iterator it) { return eastl::is_iterator_wrapper_helper::value>::get_base(it); } } // namespace eastl EA_RESTORE_VC_WARNING(); #endif // Header include guard