PxStrideIterator.h

Go to the documentation of this file.
00001 //
00002 // Redistribution and use in source and binary forms, with or without
00003 // modification, are permitted provided that the following conditions
00004 // are met:
00005 //  * Redistributions of source code must retain the above copyright
00006 //    notice, this list of conditions and the following disclaimer.
00007 //  * Redistributions in binary form must reproduce the above copyright
00008 //    notice, this list of conditions and the following disclaimer in the
00009 //    documentation and/or other materials provided with the distribution.
00010 //  * Neither the name of NVIDIA CORPORATION nor the names of its
00011 //    contributors may be used to endorse or promote products derived
00012 //    from this software without specific prior written permission.
00013 //
00014 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
00015 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00016 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00017 // PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00018 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00019 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00020 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00021 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00022 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00023 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00024 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 //
00026 // Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved.
00027 // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
00028 // Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
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 } // namespace physx
00350 #endif
00351 
00353 #endif // PXFOUNDATION_PXSTRIDEITERATOR_H


Copyright © 2008-2018 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com