- Main Page
- Classes
- Files
- Directories

- File List
- File Members

# fbxarray.h

Go to the documentation of this file.

    00001 /****************************************************************************************
    00002
    00003    Copyright (C) 2013 Autodesk, Inc.
    00004    All rights reserved.
    00005
    00006    Use of this software is subject to the terms of the Autodesk license agreement
    00007    provided at the time of installation or download, or which otherwise accompanies
    00008    this software in either electronic or hard copy form.
    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);    //Double capacity
    00048             T* lArray = Allocate(lNewCapacity);
    00049             FBX_ASSERT_RETURN_VALUE(lArray, -1);
    00050             mArray = lArray;
    00051             mCapacity = lNewCapacity;
    00052         }
    00053
    00054         if( lIndex < mSize )    //Move elements to leave a space open to insert the new element
    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             //Initialize new memory to zero
    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 ) //Initialize new memory to zero
    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 ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
    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     //Previously class FbxArray is for pointers. Somehow, it's used to store other types. Here's a compile-time checking for known incompatible classes.
    00384     //If it happens you find new incompatible ones, declare them with macro FBXSDK_INCOMPATIBLE_WITH_ARRAY. Also see file fbxstring.h.
    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 /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
    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 /* _FBXSDK_CORE_BASE_ARRAY_H_ */