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

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