FBX C++ API Reference
fbxdynamicarray.h
Go to the documentation of this file.
1 /****************************************************************************************
2 
3  Copyright (C) 2015 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_DYNAMICARRAY_H_
14 #define _FBXSDK_CORE_BASE_DYNAMICARRAY_H_
15 
16 #include <fbxsdk/fbxsdk_def.h>
17 
19 
20 #include <fbxsdk/fbxsdk_nsbegin.h>
21 
26 template <typename Type, typename Allocator=FbxBaseAllocator> class FbxDynamicArray
27 {
28 public:
31  mArray(NULL),
32  mCapacity(0),
33  mSize(0),
34  mAllocator(sizeof(Type))
35  {
36  }
37 
40  FbxDynamicArray(const size_t pInitialSize) :
41  mArray(NULL),
42  mCapacity(0),
43  mSize(0),
44  mAllocator(sizeof(Type))
45  {
46  Reserve(pInitialSize);
47  }
48 
55  mArray(NULL),
56  mCapacity(0),
57  mSize(0),
58  mAllocator(sizeof(Type))
59  {
60  Reserve(pArray.mCapacity);
61  CopyArray(mArray, pArray.mArray, pArray.mSize);
62  mSize = pArray.mSize;
63  }
64 
67  {
68  for( size_t i = 0; i < mSize; ++i )
69  {
70  mArray[i].~Type();
71  }
72  mAllocator.FreeMemory(mArray);
73  }
74 
76  size_t Capacity() const
77  {
78  return mCapacity;
79  }
80 
82  size_t Size() const
83  {
84  return mSize;
85  }
86 
89  void Reserve(const size_t pCount)
90  {
91  if( pCount > mCapacity )
92  {
93  //We don't use mAllocator.PreAllocate, because we want our array to be continuous in memory.
94  Type* lNewArray = (Type*)mAllocator.AllocateRecords(pCount);
95  MoveArray(lNewArray, mArray, mSize);
96  mAllocator.FreeMemory(mArray);
97  mArray = lNewArray;
98  mCapacity = pCount;
99  }
100  }
101 
105  void PushBack(const Type& pItem, const size_t pNCopies = 1)
106  {
107  if( mSize + pNCopies > mCapacity )
108  {
109  size_t lNewSize = mCapacity + mCapacity / 2; //grow by 50%
110  if( mSize + pNCopies > lNewSize )
111  {
112  lNewSize = mSize + pNCopies;
113  }
114  Reserve(lNewSize);
115  }
116  FBX_ASSERT(mSize + pNCopies <= mCapacity);
117  Fill(mArray + mSize, pItem, pNCopies);
118  mSize += pNCopies;
119  }
120 
125  void Insert(const size_t pIndex, const Type& pItem, const size_t pNCopies=1)
126  {
127  FBX_ASSERT(pIndex >= 0);
128  FBX_ASSERT(pIndex <= mSize);
129  Type lValue = pItem; // in case pItem is in array
130  if( pNCopies == 0 )
131  {
132  }
133  else if( pIndex >= mSize )
134  {
135  PushBack(pItem, pNCopies);
136  }
137  else if( mSize + pNCopies > mCapacity )
138  {
139  size_t lNewSize = mCapacity + mCapacity / 2; //not enough room, grow by 50%
140  if( mSize + pNCopies > lNewSize )
141  {
142  lNewSize = mSize + pNCopies;
143  }
144 
145  Type* lNewArray = (Type*)mAllocator.AllocateRecords(lNewSize);
146  MoveArray(lNewArray, mArray, pIndex); // copy prefix
147  Fill(lNewArray + pIndex, pItem, pNCopies); // copy values
148  MoveArray(lNewArray + pIndex + pNCopies, mArray + pIndex, mSize - pIndex); // copy suffix
149  mAllocator.FreeMemory(mArray);
150  mArray = lNewArray;
151  mSize += pNCopies;
152  mCapacity = lNewSize;
153  }
154  else
155  {
156  // copy suffix backwards
157  MoveArrayBackwards(mArray + pIndex + pNCopies, mArray + pIndex, mSize - pIndex);
158  Fill(mArray + pIndex, pItem, pNCopies); // copy values
159  mSize += pNCopies;
160  }
161  }
162 
165  void PopBack(size_t pNElements=1)
166  {
167  FBX_ASSERT(pNElements <= mSize);
168  for( size_t i = mSize - pNElements; i < mSize; ++i )
169  {
170  mArray[i].~Type();
171  }
172  mSize -= pNElements;
173  }
174 
178  void Remove(const size_t pIndex, size_t pNElements=1)
179  {
180  FBX_ASSERT(pIndex >= 0);
181  FBX_ASSERT(pIndex <= mSize);
182  FBX_ASSERT(pIndex + pNElements <= mSize);
183  if( pIndex + pNElements >= mSize )
184  {
185  PopBack(pNElements);
186  }
187  else
188  {
189  for( size_t i = pIndex; i < pIndex + pNElements; ++i )
190  {
191  mArray[i].~Type();
192  }
193  MoveOverlappingArray(&mArray[pIndex], &mArray[pIndex + pNElements], mSize - pIndex - pNElements);
194  mSize -= pNElements;
195  }
196  }
197 
200  Type& operator[](const size_t pIndex)
201  {
202  return mArray[pIndex];
203  }
204 
207  const Type& operator[](const size_t pIndex) const
208  {
209  return mArray[pIndex];
210  }
211 
214  Type& First()
215  {
216  return operator[](0);
217  }
218 
221  const Type& First() const
222  {
223  return operator[](0);
224  }
225 
228  Type& Last()
229  {
230  return operator[](mSize-1);
231  }
232 
235  const Type& Last() const
236  {
237  return operator[](mSize-1);
238  }
239 
244  size_t Find(const Type& pItem, const size_t pStartIndex=0) const
245  {
246  for( size_t i = pStartIndex; i < mSize; ++i )
247  {
248  if( operator[](i) == pItem ) return i;
249  }
250  return -1;
251  }
252 
256  {
257  Reserve(pArray.mCapacity);
258  CopyArray(mArray, pArray.mArray, pArray.mSize);
259  mSize = pArray.mSize;
260  return *this;
261  }
262 
263 /*****************************************************************************************************************************
264 ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
265 *****************************************************************************************************************************/
266 #ifndef DOXYGEN_SHOULD_SKIP_THIS
267 private:
268  static void CopyArray(Type* pDest, const Type* pSrc, size_t pCount)
269  {
270  for( int i = 0; i < int(pCount); i++ )
271  {
272  new(&(pDest[i])) Type(pSrc[i]); //in-place new won't allocate memory, so it is safe
273  }
274  }
275 
276  static void MoveArray(Type* pDest, const Type* pSrc, size_t pCount)
277  {
278  for( int i = 0; i < int(pCount); i++ )
279  {
280  new(&(pDest[i])) Type(pSrc[i]); //in-place new won't allocate memory, so it is safe
281  }
282 
283  for( int i = 0; i < int(pCount); i++ )
284  {
285  pSrc[i].~Type();
286  }
287  }
288 
289  static void MoveOverlappingArray(Type* pDest, const Type* pSrc, size_t pCount)
290  {
291  for( int i = 0; i < int(pCount); i++ )
292  {
293  new(&(pDest[i])) Type(pSrc[i]); //in-place new won't allocate memory, so it is safe
294  pSrc[i].~Type();
295  }
296  }
297 
298  static void MoveArrayBackwards(Type* pDest, const Type* pSrc, size_t pCount)
299  {
300  for( int i = 0; i < int(pCount); ++i )
301  {
302  new(&(pDest[pCount-1-i])) Type(pSrc[pCount-1-i]); //in-place new won't allocate memory, so it is safe
303  pSrc[pCount-1-i].~Type();
304  }
305  }
306 
307  static void Fill(Type* pDest, const Type& pItem, size_t pCount)
308  {
309  for( int i = 0; i < int(pCount); i++ )
310  {
311  new(&(pDest[i])) Type(pItem); //in-place new won't allocate memory, so it is safe
312  }
313  }
314 
315  Type* mArray;
316  size_t mCapacity;
317  size_t mSize;
318  Allocator mAllocator;
319 #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
320 };
321 
322 #include <fbxsdk/fbxsdk_nsend.h>
323 
324 #endif /* _FBXSDK_CORE_BASE_DYNAMICARRAY_H_ */
Type & operator[](const size_t pIndex)
Gets nth object in the array.
FBX SDK environment definition.
FbxDynamicArray()
Default constructor.
FbxDynamicArray & operator=(const FbxDynamicArray &pArray)
Assignment operator.
void Insert(const size_t pIndex, const Type &pItem, const size_t pNCopies=1)
Inserts n objects at the specified position.
size_t Size() const
Gets the size of the array.
#define NULL
Definition: fbxarch.h:210
FbxDynamicArray(const FbxDynamicArray &pArray)
Copy constructor.
void Remove(const size_t pIndex, size_t pNElements=1)
Removes n objects at the specified position.
const Type & First() const
Retrieve the first item in the array.
size_t Capacity() const
Gets the current capacity of the array.
FbxDynamicArray(const size_t pInitialSize)
Constructor.
~FbxDynamicArray()
Destructor.
size_t Find(const Type &pItem, const size_t pStartIndex=0) const
Find first matching element, from first to last.
const Type & Last() const
Retrieve the last item in the array.
Template class for dynamic array holding objects.
const Type & operator[](const size_t pIndex) const
Gets nth object in the array.
void PushBack(const Type &pItem, const size_t pNCopies=1)
Appends n objects at the end of the array.
void Reserve(const size_t pCount)
Assures that sufficient memory is allocated to hold n objects in the array, and increases the capacit...
Type & Last()
Retrieve the last item in the array.
void PopBack(size_t pNElements=1)
Removes n objects at the end.
Type & First()
Retrieve the first item in the array.