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
00034 ~FbxArray(){ Clear(); }
00035
00041 inline int InsertAt(const int pIndex, const T pElement)
00042 {
00043 FBX_ASSERT_RETURN_VALUE(pIndex >= 0, -1);
00044 int lIndex = FbxMin(pIndex, mSize);
00045 if( mSize >= mCapacity )
00046 {
00047 int lNewCapacity = FbxMax(mCapacity * 2, 1);
00048 T* lArray = Allocate(lNewCapacity);
00049 FBX_ASSERT_RETURN_VALUE(lArray, -1);
00050 mArray = lArray;
00051 mCapacity = lNewCapacity;
00052 }
00053
00054 if( lIndex < mSize )
00055 {
00056 memmove(&mArray[lIndex + 1], &mArray[lIndex], (mSize - lIndex) * sizeof(T));
00057 }
00058
00059 memcpy(&mArray[lIndex], &pElement, sizeof(T));
00060 mSize++;
00061
00062 return lIndex;
00063 }
00064
00068 inline int Add(const T pElement)
00069 {
00070 return InsertAt(mSize, pElement);
00071 }
00072
00076 inline int AddUnique(const T pElement)
00077 {
00078 int lIndex = Find(pElement);
00079 return ( lIndex == -1 ) ? Add(pElement) : lIndex;
00080 }
00081
00085 inline int Size() const { return mSize; }
00086
00090 inline int Capacity() const { return mCapacity; }
00091
00096 inline T& operator[](int pIndex) const
00097 {
00098 #ifdef _DEBUG
00099 FBX_ASSERT_MSG(pIndex >= 0, "Index is out of range!");
00100 if( pIndex >= mSize )
00101 {
00102 if( pIndex < mCapacity )
00103 {
00104 FBX_ASSERT_NOW("Index is out of range, but not outside of capacity! Call SetAt() to use reserved memory.");
00105 }
00106 else FBX_ASSERT_NOW("Index is out of range!");
00107 }
00108 #endif
00109 return (T&)mArray[pIndex];
00110 }
00111
00116 inline T GetAt(const int pIndex) const
00117 {
00118 return operator[](pIndex);
00119 }
00120
00124 inline T GetFirst() const
00125 {
00126 return GetAt(0);
00127 }
00128
00132 inline T GetLast() const
00133 {
00134 return GetAt(mSize-1);
00135 }
00136
00141 inline int Find(const T pElement, const int pStartIndex=0) const
00142 {
00143 FBX_ASSERT_RETURN_VALUE(pStartIndex >= 0, -1);
00144 for( int i = pStartIndex; i < mSize; ++i )
00145 {
00146 if( GetAt(i) == pElement ) return i;
00147 }
00148 return -1;
00149 }
00150
00155 inline int FindReverse(const T pElement, const int pStartIndex=FBXSDK_INT_MAX) const
00156 {
00157 for( int i = FbxMin(pStartIndex, mSize-1); i >= 0; --i )
00158 {
00159 if( GetAt(i) == pElement ) return i;
00160 }
00161 return -1;
00162 }
00163
00168 inline bool Reserve(const int pCapacity)
00169 {
00170 FBX_ASSERT_RETURN_VALUE(pCapacity > 0, false);
00171 if( pCapacity > mCapacity )
00172 {
00173 T* lArray = Allocate(pCapacity);
00174 FBX_ASSERT_RETURN_VALUE(lArray, false);
00175 mArray = lArray;
00176 mCapacity = pCapacity;
00177
00178
00179 memset(&mArray[mSize], 0, (mCapacity - mSize) * sizeof(T));
00180 }
00181 return true;
00182 }
00183
00189 inline void SetAt(const int pIndex, const T pElement)
00190 {
00191 if( pIndex >= mSize )
00192 {
00193 FBX_ASSERT_RETURN(pIndex < mCapacity);
00194 mSize = pIndex + 1;
00195 }
00196 memcpy(&mArray[pIndex], &pElement, sizeof(T));
00197 }
00198
00202 inline void SetFirst(const T pElement)
00203 {
00204 SetAt(0, pElement);
00205 }
00206
00210 inline void SetLast(const T pElement)
00211 {
00212 SetAt(mSize-1, pElement);
00213 }
00214
00219 inline T RemoveAt(const int pIndex)
00220 {
00221 T lElement = GetAt(pIndex);
00222 if( pIndex + 1 < mSize )
00223 {
00224 memmove(&mArray[pIndex], &mArray[pIndex + 1], (mSize - pIndex - 1) * sizeof(T));
00225 }
00226 mSize--;
00227 return lElement;
00228 }
00229
00233 inline T RemoveFirst()
00234 {
00235 return RemoveAt(0);
00236 }
00237
00241 inline T RemoveLast()
00242 {
00243 return RemoveAt(mSize-1);
00244 }
00245
00249 inline bool RemoveIt(const T pElement)
00250 {
00251 int Index = Find(pElement);
00252 if( Index >= 0 )
00253 {
00254 RemoveAt(Index);
00255 return true;
00256 }
00257 return false;
00258 }
00259
00264 inline bool Resize(const int pSize)
00265 {
00266 if( pSize == 0 )
00267 {
00268 Clear();
00269 return true;
00270 }
00271
00272 FBX_ASSERT_RETURN_VALUE(pSize > 0, false);
00273 if( pSize != mCapacity )
00274 {
00275 T* lArray = Allocate(pSize);
00276 FBX_ASSERT_RETURN_VALUE(lArray, false);
00277 mArray = lArray;
00278 }
00279
00280 if( pSize > mCapacity )
00281 {
00282 memset(&mArray[mSize], 0, (pSize - mSize) * sizeof(T));
00283 }
00284
00285 mSize = pSize;
00286 mCapacity = pSize;
00287
00288 return true;
00289 }
00290
00294 inline bool Grow(const int pSize)
00295 {
00296 return Resize(mSize + pSize);
00297 }
00298
00301 inline void Clear()
00302 {
00303 if( mArray != NULL )
00304 {
00305 mSize = 0;
00306 mCapacity = 0;
00307 FbxFree(mArray);
00308 mArray = NULL;
00309 }
00310 }
00311
00313 inline T* GetArray() const { return mArray ? (T*)mArray : NULL; }
00314
00316 inline operator T* (){ return (T*)mArray; }
00317
00320 inline void AddArray(const FbxArray<T>& pOther)
00321 {
00322 if( Grow(pOther.mSize) )
00323 {
00324 memcpy(&mArray[mSize - pOther.mSize], pOther.mArray, pOther.mSize * sizeof(T));
00325 }
00326 }
00327
00330 inline void AddArrayNoDuplicate(const FbxArray<T>& pOther)
00331 {
00332 for( int i = 0, c = pOther.mSize; i < c; ++i )
00333 {
00334 AddUnique(pOther[i]);
00335 }
00336 }
00337
00340 inline void RemoveArray(const FbxArray<T>& pOther)
00341 {
00342 for( int i = 0, c = pOther.mSize; i < c; ++i )
00343 {
00344 RemoveIt(pOther[i]);
00345 }
00346 }
00347
00350 inline FbxArray<T>& operator=(const FbxArray<T>& pOther)
00351 {
00352 if( this != &pOther )
00353 {
00354 if( Resize(pOther.mSize) )
00355 {
00356 memcpy(mArray, pOther.mArray, pOther.mSize * sizeof(T));
00357 }
00358 }
00359 return *this;
00360 }
00361
00362
00363
00364
00365 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00366 inline int GetCount() const { return mSize; }
00367 FBX_DEPRECATED inline void Empty(){ Clear(); }
00368 FBX_DEPRECATED inline int FindAfter(int pAfterIndex, T pItem) const { return Find(pItem, pAfterIndex+1); }
00369 FBX_DEPRECATED inline int FindBefore(int pBeforeIndex, T pItem) const { return FindReverse(pItem, pBeforeIndex-1); }
00370 FBX_DEPRECATED inline void AddMultiple(int pItemCount){ Grow(pItemCount); }
00371
00372 private:
00373 inline T* Allocate(const int pCapacity)
00374 {
00375 return (T*)FbxRealloc(mArray, pCapacity * sizeof(T));
00376 }
00377
00378 int mSize;
00379 int mCapacity;
00380 T* mArray;
00381
00382 #if defined(FBXSDK_COMPILER_MSC)
00383
00384
00385 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));
00386 #endif
00387
00388 #endif
00389 };
00390
00392 template <class T> inline void FbxArrayFree(FbxArray<T>& pArray)
00393 {
00394 for( int i = 0, c = pArray.Size(); i < c; ++i )
00395 {
00396 FbxFree(pArray[i]);
00397 }
00398 pArray.Clear();
00399 }
00400
00402 template <class T> inline void FbxArrayDelete(FbxArray<T>& pArray)
00403 {
00404 for( int i = 0, c = pArray.Size(); i < c; ++i )
00405 {
00406 FbxDelete(pArray[i]);
00407 }
00408 pArray.Clear();
00409 }
00410
00412 template <class T> inline void FbxArrayDestroy(FbxArray<T>& pArray)
00413 {
00414 for( int i = 0, c = pArray.Size(); i < c; ++i )
00415 {
00416 (pArray[i])->Destroy();
00417 }
00418 pArray.Clear();
00419 }
00420
00422 template <class T> FBXSDK_INCOMPATIBLE_WITH_ARRAY_TEMPLATE(FbxArray<T>);
00423
00424 #include <fbxsdk/fbxsdk_nsend.h>
00425
00426 #endif