Version

menu_open
Warning: you were redirected to the latest documentation corresponding to your major release ( 2024.1.1.8691 ). Should you wish to access your specific version's documentation, please download the offline documentation from the Audiokinetic Launcher and check the Offline Documentation option in Wwise Authoring.
Wwise SDK 2024.1.1
AkArray.h
Go to the documentation of this file.
1 /*******************************************************************************
2 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
3 released in source code form as part of the SDK installer package.
4 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Copyright (c) 2024 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 #ifndef _AKARRAY_H
28 #define _AKARRAY_H
29 
34 
35 #include <utility>
36 
37 template <AkMemID T_MEMID>
39 {
40  static AkForceInline void * Alloc( size_t in_uSize )
41  {
42  return AkAlloc(T_MEMID, in_uSize);
43  }
44 
45  static AkForceInline void * ReAlloc( void * in_pCurrent, size_t in_uOldSize, size_t in_uNewSize )
46  {
47  AK_UNUSEDVAR(in_uOldSize);
48  return AkRealloc(T_MEMID, in_pCurrent, in_uNewSize);
49  }
50 
51  static AkForceInline void Free( void * in_pAddress )
52  {
53  AkFree(T_MEMID, in_pAddress);
54  }
55 
56  static AkForceInline void TransferMem(void *& io_pDest, AkArrayAllocatorNoAlign<T_MEMID> in_srcAlloc, void * in_pSrc )
57  {
58  io_pDest = in_pSrc;
59  }
60 };
61 
62 template <AkMemID T_MEMID>
64 {
65  AkForceInline void * Alloc( size_t in_uSize )
66  {
67  return AkMalign(T_MEMID, in_uSize, AK_SIMD_ALIGNMENT);
68  }
69 
70  AkForceInline void * ReAlloc(void * in_pCurrent, size_t in_uOldSize, size_t in_uNewSize)
71  {
72  return AkReallocAligned(T_MEMID, in_pCurrent, in_uNewSize, AK_SIMD_ALIGNMENT);
73  }
74 
75  AkForceInline void Free( void * in_pAddress )
76  {
77  AkFree(T_MEMID, in_pAddress);
78  }
79 
80  AkForceInline void TransferMem(void *& io_pDest, AkArrayAllocatorAlignedSimd<T_MEMID> in_srcAlloc, void * in_pSrc )
81  {
82  io_pDest = in_pSrc;
83  }
84 };
85 
86 // AkHybridAllocator
87 // Attempts to allocate from a small buffer of size uBufferSizeBytes, which is contained within the array type. Useful if the array is expected to contain a small number of elements.
88 // If the array grows to a larger size than uBufferSizeBytes, the the memory is allocated with the specified AkMemID.
89 // NOTE: The use of this allocator is not allowed when AkArray::TMovePolicy::IsTrivial() == false,
90 // since TMovePolicy::Move will not be invoked in TransferMem.
91 template< AkUInt32 uBufferSizeBytes, AkUInt8 uAlignmentSize = 1, AkMemID T_MEMID = AkMemID_Object>
93 {
94  static const AkUInt32 _uBufferSizeBytes = uBufferSizeBytes;
95 
96  AkForceInline void * Alloc(size_t in_uSize)
97  {
98  if (in_uSize <= uBufferSizeBytes)
99  return (void *)&m_buffer;
100  return AkMalign(T_MEMID, in_uSize, uAlignmentSize);
101  }
102 
103  AkForceInline void * ReAlloc(void * in_pCurrent, size_t in_uOldSize, size_t in_uNewSize)
104  {
105  if (in_uNewSize <= uBufferSizeBytes)
106  return (void *)&m_buffer;
107 
108  if (&m_buffer != in_pCurrent)
109  return AkReallocAligned(T_MEMID, in_pCurrent, in_uNewSize, uAlignmentSize);
110 
111  void* pAddress = AkMalign(T_MEMID, in_uNewSize, uAlignmentSize);
112  if (!pAddress)
113  return NULL;
114 
115  AKPLATFORM::AkMemCpy(pAddress, m_buffer, (AkUInt32)in_uOldSize);
116  return pAddress;
117  }
118 
119  AkForceInline void Free(void * in_pAddress)
120  {
121  if (&m_buffer != in_pAddress)
122  AkFree(T_MEMID, in_pAddress);
123  }
124 
126  {
127  if (&in_srcAlloc.m_buffer == in_pSrc)
128  {
129  AKPLATFORM::AkMemCpy(m_buffer, in_srcAlloc.m_buffer, uBufferSizeBytes);
130  io_pDest = m_buffer;
131  }
132  else
133  {
134  io_pDest = in_pSrc;
135  }
136  }
137 
138  AK_ALIGN(char m_buffer[uBufferSizeBytes], uAlignmentSize);
139 };
140 
141 // Helper for AkHybridAllocator for uCount items of type T.
142 // NOTE: The use of this allocator is not allowed when AkArray::TMovePolicy::IsTrivial() == false,
143 // since TMovePolicy::Move will not be invoked in TransferMem.
144 template <class T, AkUInt32 uCount = 1, AkMemID MemID = AkMemID_Object>
145 using AkSmallArrayAllocator = AkHybridAllocator<sizeof(T)* uCount, alignof(T), MemID>;
146 
147 template <class T>
149 {
150  // By default the assignment operator is invoked to move elements of an array from slot to slot. If desired,
151  // a custom 'Move' operation can be passed into TMovePolicy to transfer ownership of resources from in_Src to in_Dest.
152  static AkForceInline void Move( T& in_Dest, T& in_Src )
153  {
154  in_Dest = in_Src;
155  }
156 
157  // todo: use std::is_trivially_copyable<T>::value everywhere instead
158  // To do so, we must revise usage of the different policies first.
159  // Until then, it is not recommended to use this policy if T is not trivially copyable.
160  static AkForceInline bool IsTrivial()
161  {
162  return true;
163  }
164 };
165 
166 // AkStdMovePolicy, for non-trivially copyable types.
168 {
169  template <class T>
170  static AkForceInline void Move(T&& io_Dest, T&& io_Src)
171  {
172  io_Dest = std::move(io_Src);
173  }
174 
175  static AkForceInline bool IsTrivial()
176  {
177  return false;
178  }
179 };
180 
181 // AkStdMovePolicy, for trivially copyable types.
183 {
184  template <class T>
185  static AkForceInline void Move(T&& io_Dest, T&& io_Src)
186  {
187  io_Dest = std::move(io_Src);
188  }
189 
190  static AkForceInline bool IsTrivial()
191  {
192  return true;
193  }
194 };
195 
196 // Can be used as TMovePolicy to create arrays of arrays.
197 template <class T>
199 {
200  static AkForceInline void Move( T& in_Dest, T& in_Src )
201  {
202  in_Dest.Transfer(in_Src); //transfer ownership of resources.
203  }
204 
205  static AkForceInline bool IsTrivial()
206  {
207  return false;
208  }
209 };
210 
211 // Common allocators:
216 
218 {
219  static AkUInt32 GrowBy( AkUInt32 /*in_CurrentArraySize*/ ) { return 1; }
220 };
221 
223 {
224  static AkUInt32 GrowBy( AkUInt32 /*in_CurrentArraySize*/ ) { return 0; }
225 };
226 
227 // The hybrid GrowBy policy will try to grow to exactly uCount before growing farther to prevent unneccesary allocations.
228 // The goal is to avoid expanding past uBufferSizeBytes until you have to, then behave like AkGrowByPolicy_Proportional
229 // uCount should be uBufferSizeBytes / sizeof(T)
230 template <AkUInt32 uCount>
232 {
233  static AkUInt32 GrowBy(AkUInt32 in_CurrentArraySize)
234  {
235  if (in_CurrentArraySize < uCount)
236  return uCount - in_CurrentArraySize;
237  else
238  {
239  return in_CurrentArraySize + (in_CurrentArraySize >> 1);
240  }
241  }
242 };
243 
245 {
246  static AkUInt32 GrowBy( AkUInt32 in_CurrentArraySize )
247  {
248  if ( in_CurrentArraySize == 0 )
249  return 1;
250  else
251  return in_CurrentArraySize + ( in_CurrentArraySize >> 1 );
252  }
253 };
254 
255 //#define AkGrowByPolicy_DEFAULT AkGrowByPolicy_Legacy
256 #define AkGrowByPolicy_DEFAULT AkGrowByPolicy_Proportional
257 
258 /// Specific implementation of array
259 template <class T, class ARG_T, class TAlloc = ArrayPoolDefault, class TGrowBy = AkGrowByPolicy_DEFAULT, class TMovePolicy = AkAssignmentMovePolicy<T> > class AkArray : public TAlloc
260 {
261 public:
262  /// Constructor
264  : m_pItems( 0 )
265  , m_uLength( 0 )
266  , m_ulReserved( 0 )
267  {
268  }
269 
270  /// Destructor
272  {
273  AKASSERT( m_pItems == 0 );
274  AKASSERT( m_uLength == 0 );
275  AKASSERT( m_ulReserved == 0 );
276  }
277 
278 // Workaround for SWIG to parse nested structure:
279 // Bypass this inner struct and use a proxy in a separate header.
280 #ifndef SWIG
281  /// Iterator
282  struct Iterator
283  {
284  T* pItem; ///< Pointer to the item in the array.
285 
286  /// + operator
288  {
289  AKASSERT( pItem );
290  Iterator returnedIt;
291  returnedIt.pItem = pItem + inc;
292  return returnedIt;
293  }
294 
295  /// - operator
296  AkUInt32 operator-(Iterator const& rhs) const
297  {
298  AKASSERT((pItem && rhs.pItem)||(!pItem && !rhs.pItem));
299  return (AkUInt32)(pItem - rhs.pItem);
300  }
301 
302  /// ++ operator
304  {
305  AKASSERT( pItem );
306  ++pItem;
307  return *this;
308  }
309 
310  /// -- operator
312  {
313  AKASSERT( pItem );
314  --pItem;
315  return *this;
316  }
317 
318  /// * operator
320  {
321  AKASSERT( pItem );
322  return *pItem;
323  }
324 
325  T* operator->() const
326  {
327  AKASSERT( pItem );
328  return pItem;
329  }
330 
331  /// == operator
332  bool operator ==( const Iterator& in_rOp ) const
333  {
334  return ( pItem == in_rOp.pItem );
335  }
336 
337  /// != operator
338  bool operator !=( const Iterator& in_rOp ) const
339  {
340  return ( pItem != in_rOp.pItem );
341  }
342  };
343 #endif // #ifndef SWIG
344 
345  /// Returns the iterator to the first item of the array, will be End() if the array is empty.
346  Iterator Begin() const
347  {
348  Iterator returnedIt;
349  returnedIt.pItem = m_pItems;
350  return returnedIt;
351  }
352 
353  /// Returns the iterator to the end of the array
354  Iterator End() const
355  {
356  Iterator returnedIt;
357  returnedIt.pItem = m_pItems + m_uLength;
358  return returnedIt;
359  }
360 
361  /// Returns the iterator th the specified item, will be End() if the item is not found
362  Iterator FindEx( ARG_T in_Item ) const
363  {
364  Iterator it = Begin();
365 
366  for ( Iterator itEnd = End(); it != itEnd; ++it )
367  {
368  if ( *it == in_Item )
369  break;
370  }
371 
372  return it;
373  }
374 
375  /// Returns the iterator of the specified item, will be End() if the item is not found
376  /// The array must be in ascending sorted order.
377  Iterator BinarySearch( ARG_T in_Item ) const
378  {
379  AkUInt32 uNumToSearch = Length();
380  T* pBase = m_pItems;
381  T* pPivot;
382 
383  while ( uNumToSearch > 0 )
384  {
385  pPivot = pBase + ( uNumToSearch >> 1 );
386  if ( in_Item == *pPivot )
387  {
388  Iterator result;
389  result.pItem = pPivot;
390  return result;
391  }
392 
393  if ( in_Item > *pPivot )
394  {
395  pBase = pPivot + 1;
396  uNumToSearch--;
397  }
398  uNumToSearch >>= 1;
399  }
400 
401  return End();
402  }
403 
404  /// Erase the specified iterator from the array
405  Iterator Erase( Iterator& in_rIter )
406  {
407  AKASSERT( m_pItems != 0 );
408 
409  if (TMovePolicy::IsTrivial())
410  {
411  T* pItem = in_rIter.pItem;
412  T* pLastItem = m_pItems + (m_uLength - 1);
413 
414  // Destroy item
415  pItem->~T();
416 
417  // Move all others by one <-
418  if (pItem < pLastItem)
419  {
421  pItem,
422  pItem + 1,
423  (AkUInt32)(pLastItem - pItem) * sizeof(T)
424  );
425  }
426  }
427  else
428  {
429  // Move items by 1 <-
430  T* pItemLast = m_pItems + m_uLength - 1;
431 
432  for (T* pItem = in_rIter.pItem; pItem < pItemLast; pItem++)
433  TMovePolicy::Move(pItem[0], pItem[1]);
434 
435  // Destroy the last item
436  pItemLast->~T();
437  }
438 
439  m_uLength--;
440 
441  return in_rIter;
442  }
443 
444  /// Erase the item at the specified index
445  void Erase( unsigned int in_uIndex )
446  {
447  AKASSERT( m_pItems != 0 );
448 
449  if (TMovePolicy::IsTrivial())
450  {
451  T* pItem = m_pItems + in_uIndex;
452 
453  // Destroy item
454  pItem->~T();
455 
456  // Move all others by one <-
457  if (in_uIndex + 1 < m_uLength)
458  {
460  pItem,
461  pItem + 1,
462  (m_uLength - in_uIndex - 1) * sizeof(T)
463  );
464  }
465  }
466  else
467  {
468  // Move items by 1 <-
469  T* pItemLast = m_pItems + m_uLength - 1;
470 
471  for (T* pItem = m_pItems + in_uIndex; pItem < pItemLast; pItem++)
472  TMovePolicy::Move(pItem[0], pItem[1]);
473 
474  // Destroy the last item
475  pItemLast->~T();
476  }
477 
478  m_uLength--;
479  }
480 
481  /// Erase the specified iterator in the array. but it does not guarantee the ordering in the array.
482  /// This version should be used only when the order in the array is not an issue.
483  Iterator EraseSwap( Iterator& in_rIter )
484  {
485  AKASSERT( m_pItems != 0 && Length() > 0 );
486 
487  if (in_rIter.pItem < (m_pItems + m_uLength - 1))
488  {
489  // Swap last item with this one.
490  TMovePolicy::Move( *in_rIter.pItem, Last( ) );
491  }
492 
493  // Destroy.
494  AKASSERT( Length( ) > 0 );
495  Last( ).~T();
496 
497  m_uLength--;
498 
499  return in_rIter;
500  }
501 
502  /// Erase the item at the specified index, but it does not guarantee the ordering in the array.
503  /// This version should be used only when the order in the array is not an issue.
504  void EraseSwap(unsigned int in_uIndex)
505  {
506  Iterator Iterator;
507  Iterator.pItem = m_pItems + in_uIndex;
508  EraseSwap(Iterator);
509  }
510 
511  bool IsGrowingAllowed() const
512  {
513  return TGrowBy::GrowBy( 1 ) != 0;
514  }
515 
516  /// Ensure preallocation of a number of items.
517  ///
518  /// Reserve() won't change the Length() of the array and does nothing if
519  /// in_ulReserve is smaller or equal to current Reserved() size.
520  ///
521  /// If an allocation occurs, i.e. `in_ulReserve > Reserved()`, all iterators and
522  /// all references to the array elements are invalidated.
523  ///
524  /// \note When template parameter `TGrowBy = AkGrowByPolicy_NoGrow`, Reserve() shall
525  /// only be called if the current reserved size is zero.
526  /// It should normally only be called once on init.
527  ///
528  /// \note When template parameter `TGrowBy = AkGrowByPolicy_Proportional`, inappropriate
529  /// calls to Reserve(), e.g. calling it before every AddLast(), may increase the
530  /// number of reallocations and result in decreased performance.
531  inline AKRESULT Reserve(AkUInt32 in_ulReserve)
532  {
533  if (in_ulReserve <= m_ulReserved)
534  return AK_Success;
535 
536  if (m_ulReserved && !IsGrowingAllowed())
537  {
538  AKASSERT(!"AkArray calling Reserve() with AkGrowByPolicy_NoGrow is only allowed when reserved size is zero");
539  return AK_InvalidParameter;
540  }
541 
542  return GrowArray(in_ulReserve - m_ulReserved) ? AK_Success : AK_InsufficientMemory;
543  }
544 
545  /// Ensure preallocation of a number of extra items on top of current array size.
546  /// Same as calling `myArray.Reserve(myArray.Length() + extraItemCount)`.
547  /// \see Reserve()
548  inline AKRESULT ReserveExtra(AkUInt32 in_ulReserve)
549  {
550  return Reserve(Length() + in_ulReserve);
551  }
552 
553  AkUInt32 Reserved() const { return m_ulReserved; }
554 
555  /// Term the array. Must be called before destroying the object.
556  void Term()
557  {
558  if ( m_pItems )
559  {
560  RemoveAll();
562  m_pItems = 0;
563  m_ulReserved = 0;
564  }
565  }
566 
567  /// Returns the numbers of items in the array.
569  {
570  return m_uLength;
571  }
572 
573  /// Returns a pointer to the first item in the array.
574  AkForceInline T * Data() const
575  {
576  return m_pItems;
577  }
578 
579  /// Returns true if the number items in the array is 0, false otherwise.
580  AkForceInline bool IsEmpty() const
581  {
582  return m_uLength == 0;
583  }
584 
585  /// Returns a pointer to the specified item in the list if it exists, 0 if not found.
586  AkForceInline T* Exists(ARG_T in_Item) const
587  {
588  Iterator it = FindEx( in_Item );
589  return ( it != End() ) ? it.pItem : 0;
590  }
591 
592  /// Add an item in the array, without filling it.
593  /// Returns a pointer to the location to be filled.
595  {
596  size_t cItems = Length();
597 
598 #if defined(_MSC_VER)
599 #pragma warning( push )
600 #pragma warning( disable : 4127 )
601 #endif
602  if ( ( cItems >= m_ulReserved ) && IsGrowingAllowed() )
603  {
604  if ( !GrowArray() )
605  return 0;
606  }
607 #if defined(_MSC_VER)
608 #pragma warning( pop )
609 #endif
610 
611  // have we got space for a new one ?
612  if( cItems < m_ulReserved )
613  {
614  T * pEnd = m_pItems + m_uLength++;
615  AkPlacementNew( pEnd ) T;
616  return pEnd;
617  }
618 
619  return 0;
620  }
621 
622  /// Add an item in the array, and fills it with the provided item.
623  AkForceInline T * AddLast(ARG_T in_rItem)
624  {
625  T * pItem = AddLast();
626  if ( pItem )
627  *pItem = in_rItem;
628  return pItem;
629  }
630 
631  /// Returns a reference to the last item in the array.
632  T& Last()
633  {
634  AKASSERT( m_uLength );
635 
636  return *( m_pItems + m_uLength - 1 );
637  }
638 
639  /// Removes the last item from the array.
640  void RemoveLast()
641  {
642  AKASSERT( m_uLength );
643  ( m_pItems + m_uLength - 1 )->~T();
644  m_uLength--;
645  }
646 
647  /// Removes the specified item if found in the array.
648  AKRESULT Remove(ARG_T in_rItem)
649  {
650  Iterator it = FindEx( in_rItem );
651  if ( it != End() )
652  {
653  Erase( it );
654  return AK_Success;
655  }
656 
657  return AK_Fail;
658  }
659 
660  /// Fast remove of the specified item in the array.
661  /// This method do not guarantee keeping ordering of the array.
662  AKRESULT RemoveSwap(ARG_T in_rItem)
663  {
664  Iterator it = FindEx( in_rItem );
665  if ( it != End() )
666  {
667  EraseSwap( it );
668  return AK_Success;
669  }
670 
671  return AK_Fail;
672  }
673 
674  /// Removes all items in the array
675  void RemoveAll()
676  {
677  for ( Iterator it = Begin(), itEnd = End(); it != itEnd; ++it )
678  (*it).~T();
679  m_uLength = 0;
680  }
681 
682  /// Operator [], return a reference to the specified index.
683  AkForceInline T& operator[](unsigned int uiIndex) const
684  {
685  AKASSERT( m_pItems );
686  AKASSERT( uiIndex < Length() );
687  return m_pItems[uiIndex];
688  }
689 
690  /// Insert an item at the specified position without filling it.
691  /// Success: returns an iterator pointing to the new item.
692  /// Failure: returns end iterator.
693  Iterator Insert(Iterator& in_rIter)
694  {
695  AKASSERT(!in_rIter.pItem || m_pItems);
696 
697  AkUInt32 index = (in_rIter.pItem && m_pItems) ? (AkUInt32)(in_rIter.pItem - m_pItems) : 0;
698  if (index <= Length())
699  {
700  if (T* ptr = Insert(index))
701  {
702  Iterator it;
703  it.pItem = ptr;
704  return it;
705  }
706  }
707 
708  return End();
709  }
710 
711  /// Insert an item at the specified position without filling it.
712  /// Returns the pointer to the item to be filled.
713  T * Insert(unsigned int in_uIndex)
714  {
715  AKASSERT( in_uIndex <= Length() );
716 
717  size_t cItems = Length();
718 
719 #if defined(_MSC_VER)
720 #pragma warning( push )
721 #pragma warning( disable : 4127 )
722 #endif
723  if ( ( cItems >= m_ulReserved ) && IsGrowingAllowed() )
724  {
725  if ( !GrowArray() )
726  return 0;
727  }
728 #if defined(_MSC_VER)
729 #pragma warning( pop )
730 #endif
731 
732  // have we got space for a new one ?
733  if (cItems < m_ulReserved)
734  {
735  if (TMovePolicy::IsTrivial())
736  {
737  T* pItem = m_pItems + in_uIndex;
738 
739  // Move items by one ->
740  if (in_uIndex < m_uLength)
741  {
743  pItem + 1,
744  pItem,
745  (m_uLength - in_uIndex) * sizeof(T)
746  );
747  }
748 
749  // Initialize the new item
750  AkPlacementNew(pItem) T;
751 
752  m_uLength++;
753  }
754  else
755  {
756  T* pItemLast = m_pItems + m_uLength++;
757  AkPlacementNew(pItemLast) T;
758 
759  // Move items by 1 ->
760  for (T* pItem = pItemLast; pItem > (m_pItems + in_uIndex); --pItem)
761  TMovePolicy::Move(pItem[0], pItem[-1]);
762 
763  // Reinitialize item at index
764  (m_pItems + in_uIndex)->~T();
765  AkPlacementNew(m_pItems + in_uIndex) T;
766  }
767 
768  return m_pItems + in_uIndex;
769  }
770 
771  return 0;
772  }
773 
774  bool GrowArray()
775  {
776  // If no size specified, growing by the declared growth policy of the array.
777  return GrowArray( TGrowBy::GrowBy( m_ulReserved ) );
778  }
779 
780  /// Resize the array.
781  bool GrowArray( AkUInt32 in_uGrowBy )
782  {
783  AKASSERT( in_uGrowBy );
784 
785  AkUInt32 ulNewReserve = m_ulReserved + in_uGrowBy;
786  T * pNewItems = NULL;
787  size_t cItems = Length();
788 
789  // Reallocate only if IsTrivial() and m_pItems is already allocated.
790  if (m_pItems && TMovePolicy::IsTrivial())
791  {
792  pNewItems = (T *)TAlloc::ReAlloc(m_pItems, sizeof(T) * cItems, sizeof(T) * ulNewReserve);
793  if (!pNewItems)
794  return false;
795  }
796  else
797  {
798  pNewItems = (T *)TAlloc::Alloc(sizeof(T) * ulNewReserve);
799  if (!pNewItems)
800  return false;
801 
802  // Copy all elements in new array, destroy old ones
803  if (m_pItems && m_pItems != pNewItems /*AkHybridAllocator may serve up same memory*/)
804  {
805  for (size_t i = 0; i < cItems; ++i)
806  {
807  AkPlacementNew(pNewItems + i) T;
808 
809  TMovePolicy::Move(pNewItems[i], m_pItems[i]);
810 
811  m_pItems[i].~T();
812  }
813 
815  }
816  }
817 
818  m_pItems = pNewItems;
819  m_ulReserved = ulNewReserve;
820  return true;
821  }
822 
823  /// Resize the array to the specified size.
824  bool Resize(AkUInt32 in_uiSize)
825  {
826  AkUInt32 cItems = Length();
827  if (in_uiSize < cItems)
828  {
829  for (AkUInt32 i = in_uiSize; i < cItems; i++)
830  {
831  m_pItems[i].~T();
832  }
833 
834  m_uLength = in_uiSize;
835  return true;
836  }
837 
838  if ( in_uiSize > m_ulReserved )
839  {
840  if ( !GrowArray(in_uiSize - m_ulReserved) )
841  return false;
842  }
843 
844  //Create the missing items.
845  for(size_t i = cItems; i < in_uiSize; i++)
846  {
847  AkPlacementNew( m_pItems + i ) T;
848  }
849 
850  m_uLength = in_uiSize;
851  return true;
852  }
853 
855  {
856  Term();
857 
858  TAlloc::TransferMem( (void*&)m_pItems, in_rSource, (void*)in_rSource.m_pItems );
859  m_uLength = in_rSource.m_uLength;
860  m_ulReserved = in_rSource.m_ulReserved;
861 
862  in_rSource.m_pItems = NULL;
863  in_rSource.m_uLength = 0;
864  in_rSource.m_ulReserved = 0;
865  }
866 
868  {
869  RemoveAll();
870 
871  if (Resize(in_rSource.Length()))
872  {
873  for (AkUInt32 i = 0; i < in_rSource.Length(); ++i)
874  m_pItems[i] = in_rSource.m_pItems[i];
875  return AK_Success;
876  }
877  return AK_Fail;
878  }
879 
880 protected:
881 
882  T * m_pItems; ///< pointer to the beginning of the array.
883  AkUInt32 m_uLength; ///< number of items in the array.
884  AkUInt32 m_ulReserved; ///< how many we can have at most (currently allocated).
885 };
886 
887 
888 #endif
void EraseSwap(unsigned int in_uIndex)
Definition: AkArray.h:504
static AkForceInline void TransferMem(void *&io_pDest, AkArrayAllocatorNoAlign< T_MEMID > in_srcAlloc, void *in_pSrc)
Definition: AkArray.h:56
AkForceInline void TransferMem(void *&io_pDest, AkHybridAllocator< uBufferSizeBytes, uAlignmentSize, T_MEMID > &in_srcAlloc, void *in_pSrc)
Definition: AkArray.h:125
AkUInt32 operator-(Iterator const &rhs) const
Definition: AkArray.h:296
AkForceInline void * Alloc(size_t in_uSize)
Definition: AkArray.h:65
AkForceInline void Free(void *in_pAddress)
Definition: AkArray.h:75
Iterator & operator++()
++ operator
Definition: AkArray.h:303
static const AkUInt32 _uBufferSizeBytes
Definition: AkArray.h:94
AkForceInline void AkMemMove(void *pDest, const void *pSrc, AkUInt32 uSize)
~AkArray()
Destructor.
Definition: AkArray.h:271
@ AK_Fail
The operation failed.
Definition: AkTypes.h:137
bool IsGrowingAllowed() const
Definition: AkArray.h:511
AkForceInline void * ReAlloc(void *in_pCurrent, size_t in_uOldSize, size_t in_uNewSize)
Definition: AkArray.h:103
AKRESULT Copy(const AkArray< T, ARG_T, TAlloc, TGrowBy, TMovePolicy > &in_rSource)
Definition: AkArray.h:867
Iterator FindEx(ARG_T in_Item) const
Returns the iterator th the specified item, will be End() if the item is not found.
Definition: AkArray.h:362
#define AkPlacementNew(_memory)
void RemoveAll()
Removes all items in the array.
Definition: AkArray.h:675
#define AkFree(_pool, _pvmem)
Definition: AkObject.h:58
AKSOUNDENGINE_API void Free(AkMemPoolId in_poolId, void *in_pMemAddress)
AK_ALIGN(char m_buffer[uBufferSizeBytes], uAlignmentSize)
T & Last()
Returns a reference to the last item in the array.
Definition: AkArray.h:632
AKRESULT
Standard function call result.
Definition: AkTypes.h:134
AkForceInline void * ReAlloc(void *in_pCurrent, size_t in_uOldSize, size_t in_uNewSize)
Definition: AkArray.h:70
AKRESULT RemoveSwap(ARG_T in_rItem)
Definition: AkArray.h:662
AkArrayAllocatorAlignedSimd< AkMemID_Processing > ArrayPoolLEngineDefaultAlignedSimd
Definition: AkArray.h:215
AkForceInline void Free(void *in_pAddress)
Definition: AkArray.h:119
static AkUInt32 GrowBy(AkUInt32 in_CurrentArraySize)
Definition: AkArray.h:233
AkForceInline T * Exists(ARG_T in_Item) const
Returns a pointer to the specified item in the list if it exists, 0 if not found.
Definition: AkArray.h:586
Specific implementation of array.
Definition: AkArray.h:260
#define AkAlloc(_pool, _size)
Definition: AkObject.h:51
#define NULL
Definition: AkTypes.h:46
static AkForceInline bool IsTrivial()
Definition: AkArray.h:175
T * pItem
Pointer to the item in the array.
Definition: AkArray.h:284
@ AK_Success
The operation was successful.
Definition: AkTypes.h:136
bool GrowArray(AkUInt32 in_uGrowBy)
Resize the array.
Definition: AkArray.h:781
T * operator->() const
Definition: AkArray.h:325
AkArrayAllocatorNoAlign< AkMemID_Profiler > ArrayPoolProfiler
Definition: AkArray.h:214
AkArrayAllocatorNoAlign< AkMemID_Processing > ArrayPoolLEngineDefault
Definition: AkArray.h:213
AkForceInline void TransferMem(void *&io_pDest, AkArrayAllocatorAlignedSimd< T_MEMID > in_srcAlloc, void *in_pSrc)
Definition: AkArray.h:80
bool operator==(const Iterator &in_rOp) const
== operator
Definition: AkArray.h:332
void RemoveLast()
Removes the last item from the array.
Definition: AkArray.h:640
@ AK_InvalidParameter
Something is not within bounds, check the documentation of the function returning this code.
Definition: AkTypes.h:152
static AkForceInline void * Alloc(size_t in_uSize)
Definition: AkArray.h:40
AkUInt32 m_uLength
number of items in the array.
Definition: AkArray.h:883
bool Resize(AkUInt32 in_uiSize)
Resize the array to the specified size.
Definition: AkArray.h:824
AkArray()
Constructor.
Definition: AkArray.h:263
AkForceInline T * AddLast(ARG_T in_rItem)
Add an item in the array, and fills it with the provided item.
Definition: AkArray.h:623
Iterator.
Definition: AkArray.h:283
#define AKASSERT(Condition)
Definition: AkAssert.h:67
static AkUInt32 GrowBy(AkUInt32)
Definition: AkArray.h:224
static AkForceInline void * ReAlloc(void *in_pCurrent, size_t in_uOldSize, size_t in_uNewSize)
Definition: AkArray.h:45
AKRESULT ReserveExtra(AkUInt32 in_ulReserve)
Definition: AkArray.h:548
AkForceInline void AkMemCpy(void *pDest, const void *pSrc, AkUInt32 uSize)
Platform Independent Helper for memcpy/memmove/memset.
Iterator End() const
Returns the iterator to the end of the array.
Definition: AkArray.h:354
AkUInt32 Reserved() const
Definition: AkArray.h:553
Iterator Insert(Iterator &in_rIter)
Definition: AkArray.h:693
AkForceInline void * Alloc(size_t in_uSize)
Definition: AkArray.h:96
#define AK_SIMD_ALIGNMENT
Platform-specific alignment requirement for SIMD data.
Definition: AkTypes.h:52
void Transfer(AkArray< T, ARG_T, TAlloc, TGrowBy, TMovePolicy > &in_rSource)
Definition: AkArray.h:854
Iterator Erase(Iterator &in_rIter)
Erase the specified iterator from the array.
Definition: AkArray.h:405
static AkForceInline void Move(T &in_Dest, T &in_Src)
Definition: AkArray.h:200
#define AkMalign(_pool, _size, _align)
Definition: AkObject.h:52
AkUInt32 m_ulReserved
how many we can have at most (currently allocated).
Definition: AkArray.h:884
Iterator Begin() const
Returns the iterator to the first item of the array, will be End() if the array is empty.
Definition: AkArray.h:346
AkForceInline AkUInt32 Length() const
Returns the numbers of items in the array.
Definition: AkArray.h:568
static AkForceInline bool IsTrivial()
Definition: AkArray.h:205
#define AkRealloc(_pool, _pvmem, _size)
Definition: AkObject.h:54
AkArrayAllocatorNoAlign< AkMemID_Object > ArrayPoolDefault
Definition: AkArray.h:212
AKRESULT Remove(ARG_T in_rItem)
Removes the specified item if found in the array.
Definition: AkArray.h:648
void Erase(unsigned int in_uIndex)
Erase the item at the specified index.
Definition: AkArray.h:445
bool operator!=(const Iterator &in_rOp) const
!= operator
Definition: AkArray.h:338
bool GrowArray()
Definition: AkArray.h:774
AkForceInline T * AddLast()
Definition: AkArray.h:594
static AkForceInline void Free(void *in_pAddress)
Definition: AkArray.h:51
uint32_t AkUInt32
Unsigned 32-bit integer.
#define AK_UNUSEDVAR(x)
Definition: AkPlatforms.h:153
void Term()
Term the array. Must be called before destroying the object.
Definition: AkArray.h:556
static AkForceInline bool IsTrivial()
Definition: AkArray.h:160
@ AK_InsufficientMemory
Memory error.
Definition: AkTypes.h:164
static AkUInt32 GrowBy(AkUInt32 in_CurrentArraySize)
Definition: AkArray.h:246
static AkUInt32 GrowBy(AkUInt32)
Definition: AkArray.h:219
AkForceInline bool IsEmpty() const
Returns true if the number items in the array is 0, false otherwise.
Definition: AkArray.h:580
static AkForceInline void Move(T &in_Dest, T &in_Src)
Definition: AkArray.h:152
#define AkForceInline
Definition: AkTypes.h:63
AkForceInline T * Data() const
Returns a pointer to the first item in the array.
Definition: AkArray.h:574
T * Insert(unsigned int in_uIndex)
Definition: AkArray.h:713
Iterator & operator--()
– operator
Definition: AkArray.h:311
Iterator EraseSwap(Iterator &in_rIter)
Definition: AkArray.h:483
AkForceInline T & operator[](unsigned int uiIndex) const
Operator [], return a reference to the specified index.
Definition: AkArray.h:683
#define AkReallocAligned(_pool, _pvmem, _size, _align)
Definition: AkObject.h:55
AKRESULT Reserve(AkUInt32 in_ulReserve)
Definition: AkArray.h:531
Iterator operator+(AkUInt32 inc) const
Definition: AkArray.h:287
static AkForceInline void Move(T &&io_Dest, T &&io_Src)
Definition: AkArray.h:170
Iterator BinarySearch(ARG_T in_Item) const
Definition: AkArray.h:377
T * m_pItems
pointer to the beginning of the array.
Definition: AkArray.h:882
static AkForceInline void Move(T &&io_Dest, T &&io_Src)
Definition: AkArray.h:185
static AkForceInline bool IsTrivial()
Definition: AkArray.h:190

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise