1 // 2 // Boost.Pointer Container 3 // 4 // Copyright Thorsten Ottosen 2003-2005. Use, modification and 5 // distribution is subject to the Boost Software License, Version 6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // For more information, see http://www.boost.org/libs/ptr_container/ 10 // 11 12 #ifndef BOOST_PTR_CONTAINER_DETAIL_VOID_PTR_ITERATOR_HPP 13 #define BOOST_PTR_CONTAINER_DETAIL_VOID_PTR_ITERATOR_HPP 14 15 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 # pragma once 17 #endif 18 19 #include <boost/config.hpp> 20 #include <boost/iterator/iterator_traits.hpp> 21 #include <boost/type_traits/remove_const.hpp> 22 23 namespace boost 24 { 25 template 26 < 27 class VoidIter, 28 class T 29 > 30 class void_ptr_iterator 31 { 32 public: 33 typedef BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type 34 value_type; 35 typedef T& reference; 36 typedef T* pointer; 37 38 typedef BOOST_DEDUCED_TYPENAME iterator_difference<VoidIter>::type 39 difference_type; 40 typedef BOOST_DEDUCED_TYPENAME iterator_category<VoidIter>::type 41 iterator_category; 42 private: 43 44 VoidIter iter_; 45 46 public: void_ptr_iterator()47 void_ptr_iterator() : iter_() 48 { } 49 void_ptr_iterator(VoidIter r)50 void_ptr_iterator( VoidIter r ) : iter_(r) 51 { } 52 53 // 54 // Remark: passing by value breaks vc7.1 55 // 56 template< class MutableIterator, class MutableT > void_ptr_iterator(const void_ptr_iterator<MutableIterator,MutableT> & r)57 void_ptr_iterator( const void_ptr_iterator<MutableIterator,MutableT>& r ) 58 #ifdef BOOST_NO_SFINAE 59 : iter_( VoidIter(const_cast<void**>(&*r.base())) ) 60 #else 61 62 : iter_(r.base()) 63 #endif 64 { } 65 operator *() const66 T& operator*() const 67 { 68 return *static_cast<T*>( *iter_ ); 69 } 70 operator ->() const71 T* operator->() const 72 { 73 return static_cast<T*>( *iter_ ); 74 } 75 operator ++()76 void_ptr_iterator& operator++() 77 { 78 ++iter_; 79 return *this; 80 } 81 operator ++(int)82 void_ptr_iterator operator++(int) 83 { 84 void_ptr_iterator res = *this; 85 ++iter_; 86 return res; 87 } 88 operator --()89 void_ptr_iterator& operator--() 90 { 91 --iter_; 92 return *this; 93 } 94 operator --(int)95 void_ptr_iterator operator--(int) 96 { 97 void_ptr_iterator res = *this; 98 --iter_; 99 return res; 100 } 101 operator +=(difference_type n)102 void_ptr_iterator& operator+=( difference_type n ) 103 { 104 iter_ += n; 105 return *this; 106 } 107 operator -=(difference_type n)108 void_ptr_iterator& operator-=( difference_type n ) 109 { 110 iter_ -= n; 111 return *this; 112 } 113 operator [](difference_type n) const114 T& operator[]( difference_type n ) const 115 { 116 return *static_cast<T*>( *(iter_ + n) ); 117 } 118 base() const119 VoidIter base() const 120 { 121 return iter_; 122 } 123 124 }; // class 'void_ptr_iterator' 125 126 template< class VoidIter, class T > 127 inline void_ptr_iterator<VoidIter,T> operator +(void_ptr_iterator<VoidIter,T> l,BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type n)128 operator+( void_ptr_iterator<VoidIter,T> l, 129 BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type n ) 130 { 131 l += n; 132 return l; 133 } 134 135 template< class VoidIter, class T > 136 inline void_ptr_iterator<VoidIter,T> operator +(BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type n,void_ptr_iterator<VoidIter,T> r)137 operator+( BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type n, 138 void_ptr_iterator<VoidIter,T> r ) 139 140 { 141 r += n; 142 return r; 143 } 144 145 template< class VoidIter, class T > 146 inline void_ptr_iterator<VoidIter,T> operator -(void_ptr_iterator<VoidIter,T> l,BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type n)147 operator-( void_ptr_iterator<VoidIter,T> l, 148 BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type n ) 149 { 150 l -= n; 151 return l; 152 } 153 154 template< class VoidIter, class T > 155 inline void_ptr_iterator<VoidIter,T> operator -(BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type n,void_ptr_iterator<VoidIter,T> r)156 operator-( BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type n, 157 void_ptr_iterator<VoidIter,T> r ) 158 159 { 160 r -= n; 161 return r; 162 } 163 164 165 namespace ptr_container_detail 166 { 167 template<typename T, typename U> 168 struct is_compatible 169 { 170 static const bool value = boost::is_same< typename boost::remove_const<T>::type, typename boost::remove_const<U>::type >::value; 171 }; 172 } 173 174 175 template< class VoidIter, class T, class VoidIterU, class U > 176 inline BOOST_DEDUCED_TYPENAME boost::enable_if< 177 ptr_container_detail::is_compatible<T, U>, 178 BOOST_DEDUCED_TYPENAME void_ptr_iterator<VoidIter,T>::difference_type 179 >::type operator -(void_ptr_iterator<VoidIter,T> l,void_ptr_iterator<VoidIterU,U> r)180 operator-( void_ptr_iterator<VoidIter,T> l, 181 void_ptr_iterator<VoidIterU,U> r ) 182 183 { 184 return l.base() - r.base(); 185 } 186 187 188 189 template< class VoidIterT, class T, class VoidIterU, class U > 190 inline BOOST_DEDUCED_TYPENAME boost::enable_if< 191 ptr_container_detail::is_compatible<T, U>, 192 bool 193 >::type operator ==(const void_ptr_iterator<VoidIterT,T> & l,const void_ptr_iterator<VoidIterU,U> & r)194 operator==( const void_ptr_iterator<VoidIterT,T>& l, 195 const void_ptr_iterator<VoidIterU,U>& r ) 196 { 197 return l.base() == r.base(); 198 } 199 200 201 202 template< class VoidIterT, class T, class VoidIterU, class U > 203 inline BOOST_DEDUCED_TYPENAME boost::enable_if< 204 ptr_container_detail::is_compatible<T, U>, 205 bool 206 >::type operator !=(const void_ptr_iterator<VoidIterT,T> & l,const void_ptr_iterator<VoidIterU,U> & r)207 operator!=( const void_ptr_iterator<VoidIterT,T>& l, 208 const void_ptr_iterator<VoidIterU,U>& r ) 209 { 210 return l.base() != r.base(); 211 } 212 213 214 215 template< class VoidIterT, class T, class VoidIterU, class U > 216 inline BOOST_DEDUCED_TYPENAME boost::enable_if< 217 ptr_container_detail::is_compatible<T, U>, 218 bool 219 >::type operator <(const void_ptr_iterator<VoidIterT,T> & l,const void_ptr_iterator<VoidIterU,U> & r)220 operator<( const void_ptr_iterator<VoidIterT,T>& l, 221 const void_ptr_iterator<VoidIterU,U>& r ) 222 { 223 return l.base() < r.base(); 224 } 225 226 227 228 template< class VoidIterT, class T, class VoidIterU, class U > 229 inline BOOST_DEDUCED_TYPENAME boost::enable_if< 230 ptr_container_detail::is_compatible<T, U>, 231 bool 232 >::type operator <=(const void_ptr_iterator<VoidIterT,T> & l,const void_ptr_iterator<VoidIterU,U> & r)233 operator<=( const void_ptr_iterator<VoidIterT,T>& l, 234 const void_ptr_iterator<VoidIterU,U>& r ) 235 { 236 return l.base() <= r.base(); 237 } 238 239 240 241 template< class VoidIterT, class T, class VoidIterU, class U > 242 inline BOOST_DEDUCED_TYPENAME boost::enable_if< 243 ptr_container_detail::is_compatible<T, U>, 244 bool 245 >::type operator >(const void_ptr_iterator<VoidIterT,T> & l,const void_ptr_iterator<VoidIterU,U> & r)246 operator>( const void_ptr_iterator<VoidIterT,T>& l, 247 const void_ptr_iterator<VoidIterU,U>& r ) 248 { 249 return l.base() > r.base(); 250 } 251 252 253 254 template< class VoidIterT, class T, class VoidIterU, class U > 255 inline BOOST_DEDUCED_TYPENAME boost::enable_if< 256 ptr_container_detail::is_compatible<T, U>, 257 bool 258 >::type operator >=(const void_ptr_iterator<VoidIterT,T> & l,const void_ptr_iterator<VoidIterU,U> & r)259 operator>=( const void_ptr_iterator<VoidIterT,T>& l, 260 const void_ptr_iterator<VoidIterU,U>& r ) 261 { 262 return l.base() >= r.base(); 263 } 264 265 } 266 267 #endif 268