13 #ifndef _FBXSDK_CORE_BASE_ARRAY_H_
14 #define _FBXSDK_CORE_BASE_ARRAY_H_
20 #if defined(FBXSDK_COMPILER_MSC)
21 #pragma warning( push )
22 #pragma warning( disable : 4201 ) // nonstandard extension used: nameless struct/union
25 #ifdef THROW_EXCEPTIONS
26 #define FBX_THROW(x) throw std::runtime_error(x)
27 #define FBX_ARRAY_INLINE __forceinline
29 #define FBX_THROW(x) FBX_ASSERT_NOW(x)
30 #define FBX_ARRAY_INLINE inline
37 template <
class T, const
int Alignment = 16>
class FbxArray
73 inline int InsertAt(
const int pIndex,
const T& pElement,
bool pCompact=
false)
75 FBX_ASSERT_RETURN_VALUE(pIndex >= 0, -1);
76 int lIndex =
FbxMin(pIndex, GetSize());
77 if( GetSize() >= GetCapacity() )
79 T lElement = pElement;
80 int lNewCapacity =
FbxMax(pCompact ? GetCapacity() + 1 : GetCapacity() * 2, 1);
81 Allocate(lNewCapacity);
82 FBX_ASSERT_RETURN_VALUE(
mData, -1);
87 if( lIndex < GetSize() )
90 if( (&pElement >= &
GetArray()[lIndex]) && (&pElement < &
GetArray()[GetSize()]) )
92 T lElement = pElement;
95 memmove(&
GetArray()[lIndex + 1], &
GetArray()[lIndex], (GetSize() - lIndex) *
sizeof(T));
98 memcpy(&
GetArray()[lIndex], &pElement,
sizeof(T));
108 inline int Add(
const T& pElement)
110 int lIndex = GetSize();
112 if (lIndex >= GetCapacity())
114 T lElement = pElement;
115 int lNewCapacity =
FbxMax(GetCapacity() * 2, 1);
116 Allocate(lNewCapacity);
117 FBX_ASSERT_RETURN_VALUE(
mData, -1);
119 return Add(lElement);
122 memcpy(&
GetArray()[lIndex], &pElement,
sizeof(T));
133 int lIndex =
Find(pElement);
134 return ( lIndex == -1 ) ?
Add(pElement) : lIndex;
142 return InsertAt(GetSize(), pElement,
true);
148 inline int Size()
const {
return GetSize(); }
153 inline int Capacity()
const {
return GetCapacity(); }
166 if (pIndex >= GetSize())
168 if (pIndex < GetCapacity())
170 FBX_THROW(
"Index is out of range, but not outside of capacity! Call SetAt() to use reserved memory.");
183 inline T
GetAt(
const int pIndex)
const
201 return GetAt(GetSize() - 1);
208 inline int Find(
const T& pElement,
const int pStartIndex = 0)
const
210 const int size = GetSize();
212 FBX_ASSERT_RETURN_VALUE(pStartIndex >= 0, -1);
213 FBX_ASSERT_RETURN_VALUE(size >= 0, -1);
215 for (
int i = pStartIndex; i < size; ++i)
217 if (
GetArray()[i] == pElement)
return i;
228 const int size = GetSize();
230 FBX_ASSERT_RETURN_VALUE(size > 0, -1);
232 for (
int i =
FbxMin(pStartIndex, size - 1); i >= 0; --i)
234 if (
GetArray()[i] == pElement)
return i;
245 FBX_ASSERT_RETURN_VALUE(pCapacity >= 0,
false);
246 if( pCapacity > GetCapacity() )
249 FBX_ASSERT_RETURN_VALUE(
mData,
false);
253 memset(&
GetArray()[GetSize()], 0, (GetCapacity() - GetSize()) *
sizeof(T));
263 inline void SetAt(
const int pIndex,
const T& pElement)
265 FBX_ASSERT_RETURN(pIndex >= 0 && pIndex < GetCapacity());
266 if( pIndex >= GetSize() )
mData->
mSize = pIndex + 1;
269 if (array) memcpy(&array[pIndex], &pElement,
sizeof(T));
285 SetAt(GetSize() - 1, pElement);
294 const int size = GetSize();
295 const int index = pIndex + 1;
296 if (index < 0 || index > size)
301 T lElement =
GetAt(pIndex);
304 memmove(&
GetArray()[pIndex], &
GetArray()[index], (size - pIndex - 1) *
sizeof(T));
331 int Index =
Find(pElement);
347 const int size = GetSize();
354 FBX_ASSERT_RETURN(pCount > 0);
355 FBX_ASSERT_RETURN(pIndex >= 0);
357 size_t lastItem = pIndex + pCount;
358 FBX_ASSERT_RETURN(lastItem >= 0);
359 FBX_ASSERT_RETURN(lastItem <= (
size_t)size);
362 if (lastItem < (
size_t)size)
364 memmove(&
GetArray()[pIndex], &
GetArray()[pIndex + pCount], (size - pIndex - pCount) * (
unsigned)
sizeof(T));
380 if( pSize == GetSize() && GetSize() == GetCapacity() )
return true;
388 FBX_ASSERT_RETURN_VALUE(pSize > 0,
false);
391 if (pPreserveCapacityIfPossible)
392 lReallocate = pSize > GetCapacity();
394 lReallocate = pSize != GetCapacity();
399 FBX_ASSERT_RETURN_VALUE(
mData,
false);
412 inline bool Resize(
const int pSize,
bool pPreserveCapacityIfPossible =
false)
414 if (pSize == GetSize() && GetSize() == GetCapacity())
return true;
422 FBX_ASSERT_RETURN_VALUE(pSize > 0,
false);
425 if (pPreserveCapacityIfPossible)
426 lReallocate = pSize > GetCapacity();
428 lReallocate = pSize != GetCapacity();
433 FBX_ASSERT_RETURN_VALUE(
mData,
false);
435 if (pSize > GetCapacity())
437 memset(&
GetArray()[GetSize()], 0, (pSize - GetSize()) *
sizeof(T));
450 inline bool Grow(
const int pSize)
452 const int size = GetSize();
461 return Resize(size + pSize);
469 const int size = GetSize();
473 if (pSize < 0 || newSize < 0 || newSize > size)
478 return Resize(size - pSize);
503 qsort(
GetArray(), GetSize(),
sizeof(T), pCompareFunc);
516 if(
Grow(pOther.GetSize()) )
518 memcpy(&
GetArray()[GetSize() - pOther.GetSize()], pOther.
GetArray(), pOther.GetSize() *
sizeof(T));
526 for(
int i = 0, c = pOther.GetSize(); i < c; ++i )
536 for(
int i = 0, c = pOther.GetSize(); i < c; ++i )
546 if(
this != &pOther )
548 if(
Resize(pOther.GetSize()) )
560 if(
this == &pOther )
return true;
561 if( GetSize() != pOther.GetSize() )
return false;
568 #ifndef DOXYGEN_SHOULD_SKIP_THIS
572 inline void Allocate(
const int pCapacity)
574 tData* lOldData =
mData;
575 tData* lData = (tData*)FbxRealloc(
mData, (
size_t)Alignment + FbxAllocSize(pCapacity,
sizeof(T)));
594 #if defined(FBXSDK_COMPILER_MSC)
597 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));
603 #if defined(FBXSDK_COMPILER_MSC)
604 #pragma warning( pop )
610 for(
int i = 0, c = pArray.
Size(); i < c; ++i )
620 for(
int i = 0, c = pArray.
Size(); i < c; ++i )
630 for(
int i = 0, c = pArray.
Size(); i < c; ++i )
632 (pArray[i])->Destroy();
642 #undef FBX_ARRAY_INLINE
bool RemoveIt(const T &pElement)
Remove first matching element in the array.
FBX SDK environment definition.
T & operator[](const int pIndex) const
Retrieve a reference of the element at given index position in the array.
void FbxArrayDelete(FbxArray< T > &pArray)
Call FbxDelete on each element of the array, and then clear it.
FBXSDK_INCOMPATIBLE_WITH_ARRAY_TEMPLATE(FbxArray< T >)
Make sure to break build if someone try to make FbxArray>, which is not supported...
void FbxArrayDestroy(FbxArray< T > &pArray)
Call Destroy on each element of the array, and then clear it.
int Size() const
Retrieve the number of element contained in the array.
bool Grow(const int pSize)
Increase size of array by the specified size.
bool Compact()
Compact the array so that its capacity is the same as its size.
int Capacity() const
Retrieve the current allocated memory capacity of the array.
void Sort(CompareFunc pCompareFunc)
Sort the array using the specified compare function pointer.
T RemoveAt(const int pIndex)
Remove an element at the given position in the array.
T GetAt(const int pIndex) const
Retrieve a copy of the element at given index position in the array.
void FbxDelete(T *p)
Deletion policy for pointer template classes that uses the FbxDelete() function.
int AddCompact(const T &pElement)
Append an element at the end of the array, growing the array by one element if capacity is not suffic...
bool Shrink(const int pSize)
Reduce size of array by the specified size.
void RemoveArray(const FbxArray< T > &pOther)
Remove the elements of another array from this array is they are present.
T RemoveFirst()
Remove the first element in the array.
int(* CompareFunc)(const void *, const void *)
Element compare function pointer definition.
int AddUnique(const T &pElement)
Append an element at the end of array, if not already present, doubling the array if capacity is not ...
void Clear()
Reset the number of element to zero and free the memory allocated.
int Add(const T &pElement)
Append an element at the end of the array, doubling the array if capacity is not sufficient.
FbxArray(const int pCapacity)
Reserve constructor.
void RemoveRange(const int pIndex, const int pCount)
Remove a range of elements at the given position in the array.
void SetAt(const int pIndex, const T &pElement)
Set the element at given position in the array.
bool operator==(const FbxArray< T > &pOther) const
Operator to compare elements of an array.
void AddArrayNoDuplicate(const FbxArray< T > &pOther)
Append the elements of another array at the end of this array if they are not present.
FbxArray< T > & operator=(const FbxArray< T > &pOther)
Operator to copy elements of an array.
#define FBXSDK_IS_SIMPLE_TYPE(T)
T mArray[15]
15 represent only the number of items to see debug
void FbxArrayFree(FbxArray< T > &pArray)
Call FbxFree on each element of the array, and then clear it.
FbxChar FbxMax(const FbxChar)
T * GetArray() const
Get pointer to internal array of elements.
bool Resize(const int pSize, bool pPreserveCapacityIfPossible=false)
Inserts or erases elements at the end such that Size() becomes pSize, increasing capacity if needed...
struct FbxArray::tData * mData
void SetFirst(const T &pElement)
Set the value of the first element.
T RemoveLast()
Remove the last element in the array.
void SetLast(const T &pElement)
Set the value of the last element.
FbxChar FbxMin(const FbxChar)
bool Reserve(const int pCapacity)
Request for allocation of additional memory without inserting new elements.
int InsertAt(const int pIndex, const T &pElement, bool pCompact=false)
Insert an element at the given position, growing the array if capacity is not sufficient.
FbxArray(const FbxArray &pArray)
Copy constructor.
int FindReverse(const T &pElement, const int pStartIndex=0x7fffffff) const
Find first matching element, from last to first.
T GetLast() const
Retrieve a copy of the last element.
void AddArray(const FbxArray< T > &pOther)
Append another array at the end of this array.
Class for array of basic elements such as pointers and basic types.
T GetFirst() const
Retrieve a copy of the first element.
bool ResizeUninitialized(const int pSize, bool pPreserveCapacityIfPossible=false)
Inserts or erases elements at the end such that Size() becomes pSize, increasing capacity if needed...
int Find(const T &pElement, const int pStartIndex=0) const
Find first matching element, from first to last.