00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef PXFOUNDATION_PXSTRIDEITERATOR_H
00031 #define PXFOUNDATION_PXSTRIDEITERATOR_H
00032
00033 #include "foundation/Px.h"
00034 #include "foundation/PxAssert.h"
00035
00040 #if !PX_DOXYGEN
00041 namespace physx
00042 {
00043 #endif
00044
00080 template <typename T>
00081 class PxStrideIterator
00082 {
00083
00084 #if !PX_DOXYGEN
00085 template <typename X>
00086 struct StripConst
00087 {
00088 typedef X Type;
00089 };
00090
00091 template <typename X>
00092 struct StripConst<const X>
00093 {
00094 typedef X Type;
00095 };
00096 #endif
00097
00098 public:
00107 explicit PX_INLINE PxStrideIterator(T* ptr = NULL, PxU32 stride = sizeof(T)) : mPtr(ptr), mStride(stride)
00108 {
00109 PX_ASSERT(mStride == 0 || sizeof(T) <= mStride);
00110 }
00111
00117 PX_INLINE PxStrideIterator(const PxStrideIterator<typename StripConst<T>::Type>& strideIterator)
00118 : mPtr(strideIterator.ptr()), mStride(strideIterator.stride())
00119 {
00120 PX_ASSERT(mStride == 0 || sizeof(T) <= mStride);
00121 }
00122
00126 PX_INLINE T* ptr() const
00127 {
00128 return mPtr;
00129 }
00130
00134 PX_INLINE PxU32 stride() const
00135 {
00136 return mStride;
00137 }
00138
00142 PX_INLINE T& operator*() const
00143 {
00144 return *mPtr;
00145 }
00146
00150 PX_INLINE T* operator->() const
00151 {
00152 return mPtr;
00153 }
00154
00158 PX_INLINE T& operator[](unsigned int i) const
00159 {
00160 return *byteAdd(mPtr, i * stride());
00161 }
00162
00166 PX_INLINE PxStrideIterator& operator++()
00167 {
00168 mPtr = byteAdd(mPtr, stride());
00169 return *this;
00170 }
00171
00175 PX_INLINE PxStrideIterator operator++(int)
00176 {
00177 PxStrideIterator tmp = *this;
00178 mPtr = byteAdd(mPtr, stride());
00179 return tmp;
00180 }
00181
00185 PX_INLINE PxStrideIterator& operator--()
00186 {
00187 mPtr = byteSub(mPtr, stride());
00188 return *this;
00189 }
00190
00194 PX_INLINE PxStrideIterator operator--(int)
00195 {
00196 PxStrideIterator tmp = *this;
00197 mPtr = byteSub(mPtr, stride());
00198 return tmp;
00199 }
00200
00204 PX_INLINE PxStrideIterator operator+(unsigned int i) const
00205 {
00206 return PxStrideIterator(byteAdd(mPtr, i * stride()), stride());
00207 }
00208
00212 PX_INLINE PxStrideIterator operator-(unsigned int i) const
00213 {
00214 return PxStrideIterator(byteSub(mPtr, i * stride()), stride());
00215 }
00216
00220 PX_INLINE PxStrideIterator& operator+=(unsigned int i)
00221 {
00222 mPtr = byteAdd(mPtr, i * stride());
00223 return *this;
00224 }
00225
00229 PX_INLINE PxStrideIterator& operator-=(unsigned int i)
00230 {
00231 mPtr = byteSub(mPtr, i * stride());
00232 return *this;
00233 }
00234
00238 PX_INLINE int operator-(const PxStrideIterator& other) const
00239 {
00240 PX_ASSERT(isCompatible(other));
00241 int byteDiff = static_cast<int>(reinterpret_cast<const PxU8*>(mPtr) - reinterpret_cast<const PxU8*>(other.mPtr));
00242 return byteDiff / static_cast<int>(stride());
00243 }
00244
00248 PX_INLINE bool operator==(const PxStrideIterator& other) const
00249 {
00250 PX_ASSERT(isCompatible(other));
00251 return mPtr == other.mPtr;
00252 }
00253
00257 PX_INLINE bool operator!=(const PxStrideIterator& other) const
00258 {
00259 PX_ASSERT(isCompatible(other));
00260 return mPtr != other.mPtr;
00261 }
00262
00266 PX_INLINE bool operator<(const PxStrideIterator& other) const
00267 {
00268 PX_ASSERT(isCompatible(other));
00269 return mPtr < other.mPtr;
00270 }
00271
00275 PX_INLINE bool operator>(const PxStrideIterator& other) const
00276 {
00277 PX_ASSERT(isCompatible(other));
00278 return mPtr > other.mPtr;
00279 }
00280
00284 PX_INLINE bool operator<=(const PxStrideIterator& other) const
00285 {
00286 PX_ASSERT(isCompatible(other));
00287 return mPtr <= other.mPtr;
00288 }
00289
00293 PX_INLINE bool operator>=(const PxStrideIterator& other) const
00294 {
00295 PX_ASSERT(isCompatible(other));
00296 return mPtr >= other.mPtr;
00297 }
00298
00299 private:
00300 PX_INLINE static T* byteAdd(T* ptr, PxU32 bytes)
00301 {
00302 return const_cast<T*>(reinterpret_cast<const T*>(reinterpret_cast<const PxU8*>(ptr) + bytes));
00303 }
00304
00305 PX_INLINE static T* byteSub(T* ptr, PxU32 bytes)
00306 {
00307 return const_cast<T*>(reinterpret_cast<const T*>(reinterpret_cast<const PxU8*>(ptr) - bytes));
00308 }
00309
00310 PX_INLINE bool isCompatible(const PxStrideIterator& other) const
00311 {
00312 int byteDiff = static_cast<int>(reinterpret_cast<const PxU8*>(mPtr) - reinterpret_cast<const PxU8*>(other.mPtr));
00313 return (stride() == other.stride()) && (abs(byteDiff) % stride() == 0);
00314 }
00315
00316 T* mPtr;
00317 PxU32 mStride;
00318 };
00319
00323 template <typename T>
00324 PX_INLINE PxStrideIterator<T> operator+(int i, PxStrideIterator<T> it)
00325 {
00326 it += i;
00327 return it;
00328 }
00329
00333 template <typename T>
00334 PX_INLINE PxStrideIterator<T> PxMakeIterator(T* ptr, PxU32 stride = sizeof(T))
00335 {
00336 return PxStrideIterator<T>(ptr, stride);
00337 }
00338
00342 template <typename T>
00343 PX_INLINE PxStrideIterator<const T> PxMakeIterator(const T* ptr, PxU32 stride = sizeof(T))
00344 {
00345 return PxStrideIterator<const T>(ptr, stride);
00346 }
00347
00348 #if !PX_DOXYGEN
00349 }
00350 #endif
00351
00353 #endif // PXFOUNDATION_PXSTRIDEITERATOR_H