FBX C++ API Reference
fbxarray.h
Go to the documentation of this file.
1 /****************************************************************************************
2 
3  Copyright (C) 2017 Autodesk, Inc.
4  All rights reserved.
5 
6  Use of this software is subject to the terms of the Autodesk license agreement
7  provided at the time of installation or download, or which otherwise accompanies
8  this software in either electronic or hard copy form.
9 
10 ****************************************************************************************/
11 
13 #ifndef _FBXSDK_CORE_BASE_ARRAY_H_
14 #define _FBXSDK_CORE_BASE_ARRAY_H_
15 
16 #include <fbxsdk/fbxsdk_def.h>
17 
18 #include <fbxsdk/fbxsdk_nsbegin.h>
19 
23 template <class T> class FbxArray
24 {
25 public:
27  typedef int (*CompareFunc)(const void*, const void*);
28 
30  FbxArray() : mSize(0), mCapacity(0), mArray(NULL){}
31 
33  FbxArray(const int pCapacity) : mSize(0), mCapacity(0), mArray(NULL){ if( pCapacity > 0 ) Reserve(pCapacity); }
34 
36  FbxArray(const FbxArray& pArray) : mSize(0), mCapacity(0), mArray(NULL){ *this = pArray; }
37 
40  ~FbxArray(){ Clear(); }
41 
48  inline int InsertAt(const int pIndex, const T& pElement, bool pCompact=false)
49  {
50  FBX_ASSERT_RETURN_VALUE(pIndex >= 0, -1);
51  int lIndex = FbxMin(pIndex, mSize);
52  if( mSize >= mCapacity )
53  {
54  T lElement = pElement; //Copy element because we might move memory
55  int lNewCapacity = FbxMax(pCompact ? mCapacity + 1 : mCapacity * 2, 1); //We always double capacity when not compacting
56  T* lArray = Allocate(lNewCapacity);
57  FBX_ASSERT_RETURN_VALUE(lArray, -1);
58  mArray = lArray;
59  mCapacity = lNewCapacity;
60  return InsertAt(pIndex, lElement); //Insert copied element because reference might be moved
61  }
62 
63  if( lIndex < mSize ) //Move elements to leave a space open to insert the new element
64  {
65  //If pElement is inside memmove range, copy element and insert copy instead
66  if( (&pElement >= &mArray[lIndex]) && (&pElement < &mArray[mSize]) )
67  {
68  T lElement = pElement;
69  return InsertAt(pIndex, lElement);
70  }
71  memmove(&mArray[lIndex + 1], &mArray[lIndex], (mSize - lIndex) * sizeof(T));
72  }
73 
74  memcpy(&mArray[lIndex], &pElement, sizeof(T));
75  mSize++;
76 
77  return lIndex;
78  }
79 
83  inline int Add(const T& pElement)
84  {
85  return InsertAt(mSize, pElement);
86  }
87 
91  inline int AddUnique(const T& pElement)
92  {
93  int lIndex = Find(pElement);
94  return ( lIndex == -1 ) ? Add(pElement) : lIndex;
95  }
96 
100  inline int AddCompact(const T& pElement)
101  {
102  return InsertAt(mSize, pElement, true);
103  }
104 
108  inline int Size() const { return mSize; }
109 
113  inline int Capacity() const { return mCapacity; }
114 
119  inline T& operator[](const int pIndex) const
120  {
121  #ifdef _DEBUG
122  FBX_ASSERT_MSG(pIndex >= 0, "Index is out of range!");
123  if( pIndex >= mSize )
124  {
125  if( pIndex < mCapacity )
126  {
127  FBX_ASSERT_NOW("Index is out of range, but not outside of capacity! Call SetAt() to use reserved memory.");
128  }
129  else FBX_ASSERT_NOW("Index is out of range!");
130  }
131  #endif
132  return (T&)mArray[pIndex];
133  }
134 
139  inline T GetAt(const int pIndex) const
140  {
141  return operator[](pIndex);
142  }
143 
147  inline T GetFirst() const
148  {
149  return GetAt(0);
150  }
151 
155  inline T GetLast() const
156  {
157  return GetAt(mSize-1);
158  }
159 
164  inline int Find(const T& pElement, const int pStartIndex=0) const
165  {
166  FBX_ASSERT_RETURN_VALUE(pStartIndex >= 0, -1);
167  for( int i = pStartIndex; i < mSize; ++i )
168  {
169  if( operator[](i) == pElement ) return i;
170  }
171  return -1;
172  }
173 
178  inline int FindReverse(const T& pElement, const int pStartIndex=FBXSDK_INT_MAX) const
179  {
180  for( int i = FbxMin(pStartIndex, mSize-1); i >= 0; --i )
181  {
182  if( operator[](i) == pElement ) return i;
183  }
184  return -1;
185  }
186 
191  inline bool Reserve(const int pCapacity)
192  {
193  FBX_ASSERT_RETURN_VALUE(pCapacity > 0, false);
194  if( pCapacity > mCapacity )
195  {
196  T* lArray = Allocate(pCapacity);
197  FBX_ASSERT_RETURN_VALUE(lArray, false);
198  mArray = lArray;
199  mCapacity = pCapacity;
200 
201  //Initialize new memory to zero
202  memset(&mArray[mSize], 0, (mCapacity - mSize) * sizeof(T));
203  }
204  return true;
205  }
206 
212  inline void SetAt(const int pIndex, const T& pElement)
213  {
214  FBX_ASSERT_RETURN(pIndex >= 0 && pIndex < mCapacity);
215  if( pIndex >= mSize ) mSize = pIndex + 1;
216  if( mArray ) memcpy(&mArray[pIndex], &pElement, sizeof(T));
217  }
218 
222  inline void SetFirst(const T& pElement)
223  {
224  SetAt(0, pElement);
225  }
226 
230  inline void SetLast(const T& pElement)
231  {
232  SetAt(mSize-1, pElement);
233  }
234 
239  inline T RemoveAt(const int pIndex)
240  {
241  T lElement = GetAt(pIndex);
242  if( pIndex + 1 < mSize )
243  {
244  memmove(&mArray[pIndex], &mArray[pIndex + 1], (mSize - pIndex - 1) * sizeof(T));
245  }
246  mSize--;
247  return lElement;
248  }
249 
253  inline T RemoveFirst()
254  {
255  return RemoveAt(0);
256  }
257 
261  inline T RemoveLast()
262  {
263  return RemoveAt(mSize-1);
264  }
265 
269  inline bool RemoveIt(const T& pElement)
270  {
271  int Index = Find(pElement);
272  if( Index >= 0 )
273  {
274  RemoveAt(Index);
275  return true;
276  }
277  return false;
278  }
279 
284  inline void RemoveRange(const int pIndex, const int pCount)
285  {
286  FBX_ASSERT_RETURN(pIndex >= 0);
287  FBX_ASSERT_RETURN(pCount >= 0);
288  if( pIndex + pCount < mSize )
289  {
290  memmove(&mArray[pIndex], &mArray[pIndex + pCount], (mSize - pIndex - pCount) * sizeof(T));
291  }
292  mSize -= pCount;
293  }
294 
299  inline bool Resize(const int pSize)
300  {
301  if( pSize == mSize && mSize == mCapacity ) return true;
302 
303  if( pSize == 0 )
304  {
305  Clear();
306  return true;
307  }
308 
309  FBX_ASSERT_RETURN_VALUE(pSize > 0, false);
310  if( pSize != mCapacity )
311  {
312  T* lArray = Allocate(pSize);
313  FBX_ASSERT_RETURN_VALUE(lArray, false);
314  mArray = lArray;
315  }
316 
317  if( pSize > mCapacity ) //Initialize new memory to zero
318  {
319  memset(&mArray[mSize], 0, (pSize - mSize) * sizeof(T));
320  }
321 
322  mSize = pSize;
323  mCapacity = pSize;
324  return true;
325  }
326 
330  inline bool Grow(const int pSize)
331  {
332  return Resize(mSize + pSize);
333  }
334 
338  inline bool Shrink(const int pSize)
339  {
340  return Resize(mSize - pSize);
341  }
342 
345  inline bool Compact()
346  {
347  return Resize(mSize);
348  }
349 
352  inline void Clear()
353  {
354  if( mArray != NULL )
355  {
356  mSize = 0;
357  mCapacity = 0;
358  FbxFree(mArray);
359  mArray = NULL;
360  }
361  }
362 
365  inline void Sort(CompareFunc pCompareFunc)
366  {
367  qsort(mArray, mSize, sizeof(T), pCompareFunc);
368  }
369 
371  inline T* GetArray() const { return mArray ? (T*)mArray : NULL; }
372 
374  inline operator T* (){ return mArray ? (T*)mArray : NULL; }
375 
378  inline void AddArray(const FbxArray<T>& pOther)
379  {
380  if( Grow(pOther.mSize) )
381  {
382  memcpy(&mArray[mSize - pOther.mSize], pOther.mArray, pOther.mSize * sizeof(T));
383  }
384  }
385 
388  inline void AddArrayNoDuplicate(const FbxArray<T>& pOther)
389  {
390  for( int i = 0, c = pOther.mSize; i < c; ++i )
391  {
392  AddUnique(pOther[i]);
393  }
394  }
395 
398  inline void RemoveArray(const FbxArray<T>& pOther)
399  {
400  for( int i = 0, c = pOther.mSize; i < c; ++i )
401  {
402  RemoveIt(pOther[i]);
403  }
404  }
405 
408  inline FbxArray<T>& operator=(const FbxArray<T>& pOther)
409  {
410  if( this != &pOther )
411  {
412  if( Resize(pOther.mSize) )
413  {
414  memcpy(mArray, pOther.mArray, pOther.mSize * sizeof(T));
415  }
416  }
417  return *this;
418  }
419 
422  inline bool operator==(const FbxArray<T>& pOther) const
423  {
424  if( this == &pOther ) return true;
425  if( mSize != pOther.mSize ) return false;
426  return memcmp(mArray, pOther.mArray, sizeof(T) * mSize) == 0;
427  }
428 
429 /*****************************************************************************************************************************
430 ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
431 *****************************************************************************************************************************/
432 #ifndef DOXYGEN_SHOULD_SKIP_THIS
433  inline int GetCount() const { return mSize; }
434 
435 private:
436  inline T* Allocate(const int pCapacity)
437  {
438  return (T*)FbxRealloc(mArray, pCapacity * sizeof(T));
439  }
440 
441  int mSize;
442  int mCapacity;
443  T* mArray;
444 
445 #if defined(FBXSDK_COMPILER_MSC)
446  //Previously class FbxArray is for pointers. Somehow, it's used to store other types. Here's a compile-time checking for known incompatible classes.
447  //If it happens you find new incompatible ones, declare them with macro FBXSDK_INCOMPATIBLE_WITH_ARRAY. Also see file fbxstring.h.
448  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));
449 #endif
450 
451 #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
452 };
453 
455 template <class T> inline void FbxArrayFree(FbxArray<T>& pArray)
456 {
457  for( int i = 0, c = pArray.Size(); i < c; ++i )
458  {
459  FbxFree(pArray[i]);
460  }
461  pArray.Clear();
462 }
463 
465 template <class T> inline void FbxArrayDelete(FbxArray<T>& pArray)
466 {
467  for( int i = 0, c = pArray.Size(); i < c; ++i )
468  {
469  FbxDelete(pArray[i]);
470  }
471  pArray.Clear();
472 }
473 
475 template <class T> inline void FbxArrayDestroy(FbxArray<T>& pArray)
476 {
477  for( int i = 0, c = pArray.Size(); i < c; ++i )
478  {
479  (pArray[i])->Destroy();
480  }
481  pArray.Clear();
482 }
483 
486 
487 #include <fbxsdk/fbxsdk_nsend.h>
488 
489 #endif /* _FBXSDK_CORE_BASE_ARRAY_H_ */
T * GetArray() const
Get pointer to internal array of elements.
Definition: fbxarray.h:371
bool RemoveIt(const T &pElement)
Remove first matching element in the array.
Definition: fbxarray.h:269
FBX SDK environment definition.
int Size() const
Retrieve the number of element contained in the array.
Definition: fbxarray.h:108
void FbxArrayDelete(FbxArray< T > &pArray)
Call FbxDelete on each element of the array, and then clear it.
Definition: fbxarray.h:465
FBXSDK_INCOMPATIBLE_WITH_ARRAY_TEMPLATE(FbxArray< T >)
Make sure to break build if someone try to make FbxArray<FbxArray<T>>, which is not supported...
void FbxArrayDestroy(FbxArray< T > &pArray)
Call Destroy on each element of the array, and then clear it.
Definition: fbxarray.h:475
bool Grow(const int pSize)
Increase size of array by the specified size.
Definition: fbxarray.h:330
bool Compact()
Compact the array so that its capacity is the same as its size.
Definition: fbxarray.h:345
#define NULL
Definition: fbxarch.h:210
int Find(const T &pElement, const int pStartIndex=0) const
Find first matching element, from first to last.
Definition: fbxarray.h:164
void Sort(CompareFunc pCompareFunc)
Sort the array using the specified compare function pointer.
Definition: fbxarray.h:365
T RemoveAt(const int pIndex)
Remove an element at the given position in the array.
Definition: fbxarray.h:239
T GetFirst() const
Retrieve a copy of the first element.
Definition: fbxarray.h:147
void FbxDelete(T *p)
Deletion policy for pointer template classes that uses the FbxDelete() function.
Definition: fbxnew.h:341
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...
Definition: fbxarray.h:100
bool Shrink(const int pSize)
Reduce size of array by the specified size.
Definition: fbxarray.h:338
void RemoveArray(const FbxArray< T > &pOther)
Remove the elements of another array from this array is they are present.
Definition: fbxarray.h:398
T RemoveFirst()
Remove the first element in the array.
Definition: fbxarray.h:253
int(* CompareFunc)(const void *, const void *)
Element compare function pointer definition.
Definition: fbxarray.h:27
int AddUnique(const T &pElement)
Append an element at the end of array, if not already present, doubling the array if capacity is not ...
Definition: fbxarray.h:91
void Clear()
Reset the number of element to zero and free the memory allocated.
Definition: fbxarray.h:352
int FindReverse(const T &pElement, const int pStartIndex=0x7fffffff) const
Find first matching element, from last to first.
Definition: fbxarray.h:178
int Add(const T &pElement)
Append an element at the end of the array, doubling the array if capacity is not sufficient.
Definition: fbxarray.h:83
T GetAt(const int pIndex) const
Retrieve a copy of the element at given index position in the array.
Definition: fbxarray.h:139
T GetLast() const
Retrieve a copy of the last element.
Definition: fbxarray.h:155
FbxArray(const int pCapacity)
Reserve constructor.
Definition: fbxarray.h:33
void RemoveRange(const int pIndex, const int pCount)
Remove a range of elements at the given position in the array.
Definition: fbxarray.h:284
void SetAt(const int pIndex, const T &pElement)
Set the element at given position in the array.
Definition: fbxarray.h:212
~FbxArray()
Destructor.
Definition: fbxarray.h:40
const FbxChar FbxMin(const FbxChar)
Definition: fbxtypes.h:162
void AddArrayNoDuplicate(const FbxArray< T > &pOther)
Append the elements of another array at the end of this array if they are not present.
Definition: fbxarray.h:388
FbxArray< T > & operator=(const FbxArray< T > &pOther)
Operator to copy elements of an array.
Definition: fbxarray.h:408
int Capacity() const
Retrieve the current allocated memory capacity of the array.
Definition: fbxarray.h:113
#define FBXSDK_IS_SIMPLE_TYPE(T)
Definition: fbxnew.h:57
FbxArray()
Constructor.
Definition: fbxarray.h:30
void FbxArrayFree(FbxArray< T > &pArray)
Call FbxFree on each element of the array, and then clear it.
Definition: fbxarray.h:455
void SetFirst(const T &pElement)
Set the value of the first element.
Definition: fbxarray.h:222
T RemoveLast()
Remove the last element in the array.
Definition: fbxarray.h:261
T & operator[](const int pIndex) const
Retrieve a reference of the element at given index position in the array.
Definition: fbxarray.h:119
const FbxChar FbxMax(const FbxChar)
Definition: fbxtypes.h:173
#define FBXSDK_INT_MAX
Definition: fbxtypes.h:119
void SetLast(const T &pElement)
Set the value of the last element.
Definition: fbxarray.h:230
bool Resize(const int pSize)
Inserts or erases elements at the end such that Size() becomes pSize, increasing capacity if needed...
Definition: fbxarray.h:299
bool Reserve(const int pCapacity)
Request for allocation of additional memory without inserting new elements.
Definition: fbxarray.h:191
bool operator==(const FbxArray< T > &pOther) const
Operator to compare elements of an array.
Definition: fbxarray.h:422
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.
Definition: fbxarray.h:48
FbxArray(const FbxArray &pArray)
Copy constructor.
Definition: fbxarray.h:36
void AddArray(const FbxArray< T > &pOther)
Append another array at the end of this array.
Definition: fbxarray.h:378
Class for array of basic elements such as pointers and basic types.
Definition: fbxarray.h:23