00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00013 #ifndef _FBXSDK_CORE_BASE_ARRAY_H_
00014 #define _FBXSDK_CORE_BASE_ARRAY_H_
00015
00016 #include <fbxsdk/fbxsdk_def.h>
00017
00018 #include <fbxsdk/fbxsdk_nsbegin.h>
00019
00023 template <class T> class FbxArray
00024 {
00025 public:
00027 FbxArray() : mSize(0), mCapacity(0), mArray(NULL){}
00028
00030 FbxArray(const FbxArray& pArray) : mSize(0), mCapacity(0), mArray(NULL){ *this = pArray; }
00031
00033 FbxArray(int pCapacity) : mSize(0), mCapacity(0), mArray(NULL){ if( pCapacity > 0 ) Reserve(pCapacity); }
00034
00037 ~FbxArray(){ Clear(); }
00038
00044 inline int InsertAt(const int pIndex, const T pElement)
00045 {
00046 FBX_ASSERT_RETURN_VALUE(pIndex >= 0, -1);
00047 int lIndex = FbxMin(pIndex, mSize);
00048 if( mSize >= mCapacity )
00049 {
00050 int lNewCapacity = FbxMax(mCapacity * 2, 1);
00051 T* lArray = Allocate(lNewCapacity);
00052 FBX_ASSERT_RETURN_VALUE(lArray, -1);
00053 mArray = lArray;
00054 mCapacity = lNewCapacity;
00055 }
00056
00057 if( lIndex < mSize )
00058 {
00059 memmove(&mArray[lIndex + 1], &mArray[lIndex], (mSize - lIndex) * sizeof(T));
00060 }
00061
00062 memcpy(&mArray[lIndex], &pElement, sizeof(T));
00063 mSize++;
00064
00065 return lIndex;
00066 }
00067
00071 inline int Add(const T pElement)
00072 {
00073 return InsertAt(mSize, pElement);
00074 }
00075
00079 inline int AddUnique(const T pElement)
00080 {
00081 int lIndex = Find(pElement);
00082 return ( lIndex == -1 ) ? Add(pElement) : lIndex;
00083 }
00084
00088 inline int Size() const { return mSize; }
00089
00093 inline int Capacity() const { return mCapacity; }
00094
00099 inline T& operator[](int pIndex) const
00100 {
00101 #ifdef _DEBUG
00102 FBX_ASSERT_MSG(pIndex >= 0, "Index is out of range!");
00103 if( pIndex >= mSize )
00104 {
00105 if( pIndex < mCapacity )
00106 {
00107 FBX_ASSERT_NOW("Index is out of range, but not outside of capacity! Call SetAt() to use reserved memory.");
00108 }
00109 else FBX_ASSERT_NOW("Index is out of range!");
00110 }
00111 #endif
00112 return (T&)mArray[pIndex];
00113 }
00114
00119 inline T GetAt(const int pIndex) const
00120 {
00121 return operator[](pIndex);
00122 }
00123
00127 inline T GetFirst() const
00128 {
00129 return GetAt(0);
00130 }
00131
00135 inline T GetLast() const
00136 {
00137 return GetAt(mSize-1);
00138 }
00139
00144 inline int Find(const T pElement, const int pStartIndex=0) const
00145 {
00146 FBX_ASSERT_RETURN_VALUE(pStartIndex >= 0, -1);
00147 for( int i = pStartIndex; i < mSize; ++i )
00148 {
00149 if( GetAt(i) == pElement ) return i;
00150 }
00151 return -1;
00152 }
00153
00158 inline int FindReverse(const T pElement, const int pStartIndex=FBXSDK_INT_MAX) const
00159 {
00160 for( int i = FbxMin(pStartIndex, mSize-1); i >= 0; --i )
00161 {
00162 if( GetAt(i) == pElement ) return i;
00163 }
00164 return -1;
00165 }
00166
00171 inline bool Reserve(const int pCapacity)
00172 {
00173 FBX_ASSERT_RETURN_VALUE(pCapacity > 0, false);
00174 if( pCapacity > mCapacity )
00175 {
00176 T* lArray = Allocate(pCapacity);
00177 FBX_ASSERT_RETURN_VALUE(lArray, false);
00178 mArray = lArray;
00179 mCapacity = pCapacity;
00180
00181
00182 memset(&mArray[mSize], 0, (mCapacity - mSize) * sizeof(T));
00183 }
00184 return true;
00185 }
00186
00192 inline void SetAt(const int pIndex, const T pElement)
00193 {
00194 if( pIndex >= mSize )
00195 {
00196 FBX_ASSERT_RETURN(pIndex < mCapacity);
00197 mSize = pIndex + 1;
00198 }
00199 memcpy(&mArray[pIndex], &pElement, sizeof(T));
00200 }
00201
00205 inline void SetFirst(const T pElement)
00206 {
00207 SetAt(0, pElement);
00208 }
00209
00213 inline void SetLast(const T pElement)
00214 {
00215 SetAt(mSize-1, pElement);
00216 }
00217
00222 inline T RemoveAt(const int pIndex)
00223 {
00224 T lElement = GetAt(pIndex);
00225 if( pIndex + 1 < mSize )
00226 {
00227 memmove(&mArray[pIndex], &mArray[pIndex + 1], (mSize - pIndex - 1) * sizeof(T));
00228 }
00229 mSize--;
00230 return lElement;
00231 }
00232
00236 inline T RemoveFirst()
00237 {
00238 return RemoveAt(0);
00239 }
00240
00244 inline T RemoveLast()
00245 {
00246 return RemoveAt(mSize-1);
00247 }
00248
00252 inline bool RemoveIt(const T pElement)
00253 {
00254 int Index = Find(pElement);
00255 if( Index >= 0 )
00256 {
00257 RemoveAt(Index);
00258 return true;
00259 }
00260 return false;
00261 }
00262
00267 inline bool Resize(const int pSize)
00268 {
00269 if( pSize == 0 )
00270 {
00271 Clear();
00272 return true;
00273 }
00274
00275 FBX_ASSERT_RETURN_VALUE(pSize > 0, false);
00276 if( pSize != mCapacity )
00277 {
00278 T* lArray = Allocate(pSize);
00279 FBX_ASSERT_RETURN_VALUE(lArray, false);
00280 mArray = lArray;
00281 }
00282
00283 if( pSize > mCapacity )
00284 {
00285 memset(&mArray[mSize], 0, (pSize - mSize) * sizeof(T));
00286 }
00287
00288 mSize = pSize;
00289 mCapacity = pSize;
00290
00291 return true;
00292 }
00293
00297 inline bool Grow(const int pSize)
00298 {
00299 return Resize(mSize + pSize);
00300 }
00301
00304 inline void Clear()
00305 {
00306 if( mArray != NULL )
00307 {
00308 mSize = 0;
00309 mCapacity = 0;
00310 FbxFree(mArray);
00311 mArray = NULL;
00312 }
00313 }
00314
00316 inline T* GetArray() const { return mArray ? (T*)mArray : NULL; }
00317
00319 inline operator T* (){ return (T*)mArray; }
00320
00323 inline void AddArray(const FbxArray<T>& pOther)
00324 {
00325 if( Grow(pOther.mSize) )
00326 {
00327 memcpy(&mArray[mSize - pOther.mSize], pOther.mArray, pOther.mSize * sizeof(T));
00328 }
00329 }
00330
00333 inline void AddArrayNoDuplicate(const FbxArray<T>& pOther)
00334 {
00335 for( int i = 0, c = pOther.mSize; i < c; ++i )
00336 {
00337 AddUnique(pOther[i]);
00338 }
00339 }
00340
00343 inline void RemoveArray(const FbxArray<T>& pOther)
00344 {
00345 for( int i = 0, c = pOther.mSize; i < c; ++i )
00346 {
00347 RemoveIt(pOther[i]);
00348 }
00349 }
00350
00353 inline FbxArray<T>& operator=(const FbxArray<T>& pOther)
00354 {
00355 if( this != &pOther )
00356 {
00357 if( Resize(pOther.mSize) )
00358 {
00359 memcpy(mArray, pOther.mArray, pOther.mSize * sizeof(T));
00360 }
00361 }
00362 return *this;
00363 }
00364
00365
00366
00367
00368 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00369 inline int GetCount() const { return mSize; }
00370 FBX_DEPRECATED inline void Empty(){ Clear(); }
00371 FBX_DEPRECATED inline int FindAfter(int pAfterIndex, T pItem) const { return Find(pItem, pAfterIndex+1); }
00372 FBX_DEPRECATED inline int FindBefore(int pBeforeIndex, T pItem) const { return FindReverse(pItem, pBeforeIndex-1); }
00373 FBX_DEPRECATED inline void AddMultiple(int pItemCount){ Grow(pItemCount); }
00374
00375 private:
00376 inline T* Allocate(const int pCapacity)
00377 {
00378 return (T*)FbxRealloc(mArray, pCapacity * sizeof(T));
00379 }
00380
00381 int mSize;
00382 int mCapacity;
00383 T* mArray;
00384
00385 #if defined(FBXSDK_COMPILER_MSC)
00386
00387
00388 FBX_ASSERT_STATIC(FBXSDK_IS_SIMPLE_TYPE(T) || __is_enum(T) || (__has_trivial_constructor(T)&&__has_trivial_destructor(T)) || !FBXSDK_IS_INCOMPATIBLE_WITH_ARRAY(T));
00389 #endif
00390
00391 #endif
00392 };
00393
00395 template <class T> inline void FbxArrayFree(FbxArray<T>& pArray)
00396 {
00397 for( int i = 0, c = pArray.Size(); i < c; ++i )
00398 {
00399 FbxFree(pArray[i]);
00400 }
00401 pArray.Clear();
00402 }
00403
00405 template <class T> inline void FbxArrayDelete(FbxArray<T>& pArray)
00406 {
00407 for( int i = 0, c = pArray.Size(); i < c; ++i )
00408 {
00409 FbxDelete(pArray[i]);
00410 }
00411 pArray.Clear();
00412 }
00413
00415 template <class T> inline void FbxArrayDestroy(FbxArray<T>& pArray)
00416 {
00417 for( int i = 0, c = pArray.Size(); i < c; ++i )
00418 {
00419 (pArray[i])->Destroy();
00420 }
00421 pArray.Clear();
00422 }
00423
00425 template <class T> FBXSDK_INCOMPATIBLE_WITH_ARRAY_TEMPLATE(FbxArray<T>);
00426
00427 #include <fbxsdk/fbxsdk_nsend.h>
00428
00429 #endif