- Main Page
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# fbxdynamicarray.h

Go to the documentation of this file.

    00001 /****************************************************************************************
    00002
    00003    Copyright (C) 2012 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_DYNAMICARRAY_H_
    00014 #define _FBXSDK_CORE_BASE_DYNAMICARRAY_H_
    00015
    00016 #include <fbxsdk/fbxsdk_def.h>
    00017
    00018 #include <fbxsdk/core/base/fbxcontainerallocators.h>
    00019
    00020 #include <fbxsdk/fbxsdk_nsbegin.h>
    00021
    00026 template <typename VALUE_TYPE, typename ALLOCATOR = FbxBaseAllocator> class FbxDynamicArray
    00027 {
    00028 public:
    00030     typedef VALUE_TYPE ValueType;
    00032     typedef ALLOCATOR AllocatorType;
    00033
    00035     FbxDynamicArray()
    00036         : mArray(NULL)
    00037         , mArrayCapacity(0)
    00038         , mValueCount(0)
    00039         , mAllocator(sizeof(ValueType))
    00040     {
    00041     }
    00042
    00046     FbxDynamicArray(const size_t pInitialSize)
    00047         : mArray(NULL)
    00048         , mArrayCapacity(0)
    00049         , mValueCount(0)
    00050         , mAllocator(sizeof(ValueType))
    00051     {
    00052         Reserve(pInitialSize);
    00053     }
    00054
    00060     FbxDynamicArray(const FbxDynamicArray& pArray)
    00061         : mArray(NULL)
    00062         , mArrayCapacity(0)
    00063         , mValueCount(0)
    00064         , mAllocator(sizeof(ValueType))
    00065     {
    00066         Reserve(pArray.mArrayCapacity);
    00067         CopyArray(mArray, pArray.mArray, pArray.mValueCount);
    00068         mValueCount = pArray.mValueCount;
    00069     }
    00070
    00072     ~FbxDynamicArray()
    00073     {
    00074         for (size_t i = 0; i < mValueCount; i++)
    00075         {
    00076             mArray[i].~VALUE_TYPE();
    00077         }
    00078
    00079         mAllocator.FreeMemory(mArray);
    00080     }
    00081
    00083     size_t GetCapacity() const
    00084     {
    00085         return mArrayCapacity;
    00086     }
    00087
    00089     size_t GetSize() const
    00090     {
    00091         return mValueCount;
    00092     }
    00093
    00098     void Reserve(const size_t pCount)
    00099     {
    00100         if (pCount > mArrayCapacity)
    00101         {
    00102             // We don't use mAllocator.PreAllocate, because we want our array
    00103             // to be continuous in memory.
    00104             void* lBuffer = mAllocator.AllocateRecords(pCount);
    00105             ValueType* lNewArray = reinterpret_cast<ValueType*>(lBuffer);
    00106
    00107             MoveArray(lNewArray, mArray, mValueCount);
    00108
    00109             mAllocator.FreeMemory(mArray);
    00110             mArray = lNewArray;
    00111             mArrayCapacity = pCount;
    00112         }
    00113     }
    00114
    00119     void PushBack(const ValueType& pValue, const size_t pNCopies = 1)
    00120     {
    00121         if (mValueCount + pNCopies > mArrayCapacity)
    00122         {
    00123             // grow by 50%
    00124             size_t lNewSize = mArrayCapacity + mArrayCapacity / 2;
    00125
    00126             if (mValueCount + pNCopies > lNewSize)
    00127             {
    00128                 lNewSize = mValueCount + pNCopies;
    00129             }
    00130
    00131             Reserve(lNewSize);
    00132         }
    00133
    00134         FBX_ASSERT(mValueCount + pNCopies <= mArrayCapacity);
    00135
    00136         Fill(mArray + mValueCount, pValue, pNCopies);
    00137
    00138         mValueCount += pNCopies;
    00139     }
    00140
    00146     void Insert(const size_t pIndex, const ValueType& pValue, const size_t pNCopies = 1)
    00147     {
    00148         FBX_ASSERT(pIndex >= 0);
    00149         FBX_ASSERT(pIndex <= mValueCount);
    00150
    00151         ValueType lValue = pValue; // in case pValue is in array
    00152
    00153         if (pNCopies == 0)
    00154         {
    00155         }
    00156         else if (pIndex >= mValueCount)
    00157         {
    00158             PushBack(pValue, pNCopies);
    00159         }
    00160         else if (mValueCount + pNCopies > mArrayCapacity)
    00161         {
    00162             // not enough room
    00163             // grow by 50%
    00164             size_t lNewSize = mArrayCapacity + mArrayCapacity / 2;
    00165
    00166             if (mValueCount + pNCopies > lNewSize)
    00167             {
    00168                 lNewSize = mValueCount + pNCopies;
    00169             }
    00170
    00171             void* lBuffer = mAllocator.AllocateRecords(lNewSize);
    00172             ValueType* lNewArray = reinterpret_cast<ValueType*>(lBuffer);
    00173
    00174             MoveArray(lNewArray, mArray, pIndex); // copy prefix
    00175             Fill(lNewArray + pIndex, pValue, pNCopies); // copy values
    00176             MoveArray(lNewArray + pIndex + pNCopies, mArray + pIndex, mValueCount - pIndex); // copy suffix
    00177
    00178             mAllocator.FreeMemory(mArray);
    00179             mArray = lNewArray;
    00180             mValueCount += pNCopies;
    00181             mArrayCapacity = lNewSize;
    00182         }
    00183         else
    00184         {
    00185             // copy suffix backwards
    00186             MoveArrayBackwards(mArray + pIndex + pNCopies, mArray + pIndex, mValueCount - pIndex);
    00187             Fill(mArray + pIndex, pValue, pNCopies); // copy values
    00188             mValueCount += pNCopies;
    00189         }
    00190     }
    00191
    00195     void PopBack(size_t pNElements = 1)
    00196     {
    00197         FBX_ASSERT(pNElements <= mValueCount);
    00198
    00199         for (size_t i = mValueCount - pNElements; i < mValueCount; i++)
    00200         {
    00201             mArray[i].~VALUE_TYPE();
    00202         }
    00203
    00204         mValueCount -= pNElements;
    00205     }
    00206
    00211     void Remove(const size_t pIndex, size_t pNElements = 1)
    00212     {
    00213         FBX_ASSERT(pIndex >= 0);
    00214         FBX_ASSERT(pIndex <= mValueCount);
    00215         FBX_ASSERT(pIndex + pNElements <= mValueCount);
    00216
    00217         if (pIndex + pNElements >= mValueCount)
    00218         {
    00219             PopBack(pNElements);
    00220         }
    00221         else
    00222         {
    00223             for (size_t i = pIndex; i < pIndex + pNElements; i++)
    00224             {
    00225                 mArray[i].~VALUE_TYPE();
    00226             }
    00227
    00228             MoveOverlappingArray(mArray + pIndex, mArray + pIndex + pNElements, mValueCount - pNElements);
    00229
    00230             mValueCount -= pNElements;
    00231         }
    00232     }
    00233
    00237     ValueType& operator[](const size_t pIndex)
    00238     {
    00239         return *(mArray + pIndex);
    00240     }
    00241
    00245     ValueType const& operator[](const size_t pIndex) const
    00246     {
    00247         return *(mArray + pIndex);
    00248     }
    00249
    00255     FbxDynamicArray& operator=(const FbxDynamicArray& pArray)
    00256     {
    00257         Reserve(pArray.mArrayCapacity);
    00258         CopyArray(mArray, pArray.mArray, pArray.mValueCount);
    00259         mValueCount = pArray.mValueCount;
    00260
    00261         return *this;
    00262     }
    00263
    00265     //
    00266     //  WARNING!
    00267     //
    00268     //  Anything beyond these lines may not be documented accurately and is
    00269     //  subject to change without notice.
    00270     //
    00272
    00273 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00274
    00275 private:
    00276     static void CopyArray(ValueType* pDest, const ValueType* pSrc, size_t pCount)
    00277     {
    00278         for( int i = 0; i < int(pCount); i++ )
    00279         {
    00280             new(&(pDest[i])) ValueType(pSrc[i]);
    00281         }
    00282     }
    00283
    00284     static void MoveArray(ValueType* pDest, const ValueType* pSrc, size_t pCount)
    00285     {
    00286         for( int i = 0; i < int(pCount); i++ )
    00287         {
    00288             new(&(pDest[i])) ValueType(pSrc[i]);
    00289         }
    00290
    00291         for( int i = 0; i < int(pCount); i++ )
    00292         {
    00293             pSrc[i].~VALUE_TYPE();
    00294         }
    00295     }
    00296
    00297     static void MoveOverlappingArray(ValueType* pDest, const ValueType* pSrc, size_t pCount)
    00298     {
    00299         for( int i = 0; i < int(pCount); i++ )
    00300         {
    00301             new(&(pDest[i])) ValueType(pSrc[i]);
    00302             pSrc[i].~VALUE_TYPE();
    00303         }
    00304     }
    00305
    00306     static void MoveArrayBackwards(ValueType* pDest, const ValueType* pSrc, size_t pCount)
    00307     {
    00308         for( int i = 0; i < int(pCount); ++i )
    00309         {
    00310             new(&(pDest[pCount-1-i])) ValueType(pSrc[pCount-1-i]);
    00311             pSrc[pCount-1-i].~VALUE_TYPE();
    00312         }
    00313     }
    00314
    00315     static void Fill(ValueType* pDest, const ValueType& pValue, size_t pCount)
    00316     {
    00317         for( int i = 0; i < int(pCount); i++ )
    00318         {
    00319             new(&(pDest[i])) ValueType(pValue);
    00320         }
    00321     }
    00322
    00323
    00324     ValueType* mArray;
    00325     size_t mArrayCapacity;
    00326     size_t mValueCount;
    00327
    00328     AllocatorType mAllocator;
    00329
    00330 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00331
    00332 };
    00333
    00334 #include <fbxsdk/fbxsdk_nsend.h>
    00335
    00336 #endif /* _FBXSDK_CORE_BASE_DYNAMICARRAY_H_ */