include/AK/Tools/Common/AkArray.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _AKARRAY_H
00029 #define _AKARRAY_H
00030
00031 #include <AK/Tools/Common/AkObject.h>
00032 #include <AK/Tools/Common/AkAssert.h>
00033
00034 #define AK_DEFINE_ARRAY_POOL( _name_, _poolID_ ) \
00035 struct _name_ \
00036 { \
00037 static AkMemPoolId Get() \
00038 { \
00039 return _poolID_; \
00040 } \
00041 };
00042
00043 AK_DEFINE_ARRAY_POOL( _ArrayPoolDefault, g_DefaultPoolId )
00044 AK_DEFINE_ARRAY_POOL( _ArrayPoolLEngineDefault, g_LEngineDefaultPoolId )
00045
00046 template <class U_POOL>
00047 struct AkArrayAllocatorNoAlign
00048 {
00049 static AkForceInline void * Alloc( size_t in_uSize )
00050 {
00051 return AK::MemoryMgr::Malloc( U_POOL::Get(), in_uSize );
00052 }
00053
00054 static AkForceInline void Free( void * in_pAddress )
00055 {
00056 AK::MemoryMgr::Free( U_POOL::Get(), in_pAddress );
00057 }
00058 };
00059
00060 template <class U_POOL>
00061 struct AkArrayAllocatorAlignedSimd
00062 {
00063 static AkForceInline void * Alloc( size_t in_uSize )
00064 {
00065 return AK::MemoryMgr::Malign( U_POOL::Get(), in_uSize, AK_SIMD_ALIGNMENT );
00066 }
00067
00068 static AkForceInline void Free( void * in_pAddress )
00069 {
00070 AK::MemoryMgr::Falign( U_POOL::Get(), in_pAddress );
00071 }
00072 };
00073
00074
00075 template <class T>
00076 struct AkAssignmentMovePolicy
00077 {
00078
00079
00080 static AkForceInline void Move( T& in_Dest, T& in_Src )
00081 {
00082 in_Dest = in_Src;
00083 }
00084 };
00085
00086
00087 template <class T>
00088 struct AkTransferMovePolicy
00089 {
00090 static AkForceInline void Move( T& in_Dest, T& in_Src )
00091 {
00092 in_Dest.Transfer(in_Src);
00093 }
00094 };
00095
00096
00097 typedef AkArrayAllocatorNoAlign<_ArrayPoolDefault> ArrayPoolDefault;
00098 typedef AkArrayAllocatorNoAlign<_ArrayPoolLEngineDefault> ArrayPoolLEngineDefault;
00099 typedef AkArrayAllocatorAlignedSimd<_ArrayPoolLEngineDefault> ArrayPoolLEngineDefaultAlignedSimd;
00100
00102 template <class T, class ARG_T, class TAlloc = ArrayPoolDefault, unsigned long TGrowBy = 1, class TMovePolicy = AkAssignmentMovePolicy<T> > class AkArray : public TAlloc
00103 {
00104 public:
00106 AkArray()
00107 : m_pItems( 0 )
00108 , m_uLength( 0 )
00109 , m_ulReserved( 0 )
00110 {
00111 }
00112
00114 ~AkArray()
00115 {
00116 AKASSERT( m_pItems == 0 );
00117 AKASSERT( m_uLength == 0 );
00118 AKASSERT( m_ulReserved == 0 );
00119 }
00120
00121
00122
00123 #ifndef SWIG
00124
00125 struct Iterator
00126 {
00127 T* pItem;
00128
00130 Iterator& operator++()
00131 {
00132 AKASSERT( pItem );
00133 ++pItem;
00134 return *this;
00135 }
00136
00138 Iterator& operator--()
00139 {
00140 AKASSERT( pItem );
00141 --pItem;
00142 return *this;
00143 }
00144
00146 T& operator*()
00147 {
00148 AKASSERT( pItem );
00149 return *pItem;
00150 }
00151
00153 bool operator ==( const Iterator& in_rOp ) const
00154 {
00155 return ( pItem == in_rOp.pItem );
00156 }
00157
00159 bool operator !=( const Iterator& in_rOp ) const
00160 {
00161 return ( pItem != in_rOp.pItem );
00162 }
00163 };
00164 #endif // #ifndef SWIG
00165
00167 Iterator Begin() const
00168 {
00169 Iterator returnedIt;
00170 returnedIt.pItem = m_pItems;
00171 return returnedIt;
00172 }
00173
00175 Iterator End() const
00176 {
00177 Iterator returnedIt;
00178 returnedIt.pItem = m_pItems + m_uLength;
00179 return returnedIt;
00180 }
00181
00183 Iterator FindEx( ARG_T in_Item ) const
00184 {
00185 Iterator it = Begin();
00186
00187 for ( Iterator itEnd = End(); it != itEnd; ++it )
00188 {
00189 if ( *it == in_Item )
00190 break;
00191 }
00192
00193 return it;
00194 }
00195
00198 Iterator BinarySearch( ARG_T in_Item ) const
00199 {
00200 Iterator itResult = End();
00201 if (m_pItems)
00202 {
00203 T * pTop = m_pItems, * pBottom = m_pItems + m_uLength;
00204
00205 while ( pTop <= pBottom )
00206 {
00207 T* pThis = ( pBottom - pTop ) / 2 + pTop;
00208 if( in_Item < *pThis )
00209 pBottom = pThis - 1;
00210 else if ( in_Item > *pThis )
00211 pTop = pThis + 1;
00212 else
00213 {
00214 itResult.pItem = pThis;
00215 break;
00216 }
00217 }
00218 }
00219
00220 return itResult;
00221 }
00222
00224 Iterator Erase( Iterator& in_rIter )
00225 {
00226 AKASSERT( m_pItems != 0 );
00227
00228
00229
00230 T * pItemLast = m_pItems + m_uLength - 1;
00231
00232 for ( T * pItem = in_rIter.pItem; pItem < pItemLast; pItem++ )
00233 TMovePolicy::Move( pItem[ 0 ], pItem[ 1 ] );
00234
00235
00236
00237 pItemLast->~T();
00238
00239 m_uLength--;
00240
00241 return in_rIter;
00242 }
00243
00245 void Erase( unsigned int in_uIndex )
00246 {
00247 AKASSERT( m_pItems != 0 );
00248
00249
00250
00251 T * pItemLast = m_pItems + m_uLength - 1;
00252
00253 for ( T * pItem = m_pItems+in_uIndex; pItem < pItemLast; pItem++ )
00254 TMovePolicy::Move( pItem[ 0 ], pItem[ 1 ] );
00255
00256
00257
00258 pItemLast->~T();
00259
00260 m_uLength--;
00261 }
00262
00265 Iterator EraseSwap( Iterator& in_rIter )
00266 {
00267 AKASSERT( m_pItems != 0 );
00268
00269 if ( Length( ) > 1 )
00270 {
00271
00272 TMovePolicy::Move( *in_rIter.pItem, Last( ) );
00273 }
00274
00275
00276 AKASSERT( Length( ) > 0 );
00277 Last( ).~T();
00278
00279 m_uLength--;
00280
00281 return in_rIter;
00282 }
00283
00285 AKRESULT Reserve( AkUInt32 in_ulReserve )
00286 {
00287 AKASSERT( m_pItems == 0 && m_uLength == 0 );
00288 AKASSERT( in_ulReserve || TGrowBy );
00289
00290 if ( in_ulReserve )
00291 {
00292 m_pItems = (T *) TAlloc::Alloc( sizeof( T ) * in_ulReserve );
00293 if ( m_pItems == 0 )
00294 return AK_InsufficientMemory;
00295
00296 m_ulReserved = in_ulReserve;
00297 }
00298
00299 return AK_Success;
00300 }
00301
00302 AkUInt32 Reserved() const { return m_ulReserved; }
00303
00305 void Term()
00306 {
00307 if ( m_pItems )
00308 {
00309 RemoveAll();
00310 TAlloc::Free( m_pItems );
00311 m_pItems = 0;
00312 m_ulReserved = 0;
00313 }
00314 }
00315
00317 AkForceInline AkUInt32 Length() const
00318 {
00319 return m_uLength;
00320 }
00321
00323 AkForceInline bool IsEmpty() const
00324 {
00325 return m_uLength == 0;
00326 }
00327
00329 T* Exists(ARG_T in_Item) const
00330 {
00331 Iterator it = FindEx( in_Item );
00332 return ( it != End() ) ? it.pItem : 0;
00333 }
00334
00337 T * AddLast()
00338 {
00339 size_t cItems = Length();
00340
00341 #if defined(_MSC_VER)
00342 #pragma warning( push )
00343 #pragma warning( disable : 4127 )
00344 #endif
00345 if ( ( cItems >= m_ulReserved ) && TGrowBy > 0 )
00346 {
00347 if ( !GrowArray() )
00348 return 0;
00349 }
00350 #if defined(_MSC_VER)
00351 #pragma warning( pop )
00352 #endif
00353
00354
00355 if( cItems < m_ulReserved )
00356 {
00357 T * pEnd = m_pItems + m_uLength++;
00358 AkPlacementNew( pEnd ) T;
00359 return pEnd;
00360 }
00361
00362 return 0;
00363 }
00364
00366 T * AddLast(ARG_T in_rItem)
00367 {
00368 T * pItem = AddLast();
00369 if ( pItem )
00370 *pItem = in_rItem;
00371 return pItem;
00372 }
00373
00375 T& Last()
00376 {
00377 AKASSERT( m_uLength );
00378
00379 return *( m_pItems + m_uLength - 1 );
00380 }
00381
00383 void RemoveLast()
00384 {
00385 AKASSERT( m_uLength );
00386 ( m_pItems + m_uLength - 1 )->~T();
00387 m_uLength--;
00388 }
00389
00391 AKRESULT Remove(ARG_T in_rItem)
00392 {
00393 Iterator it = FindEx( in_rItem );
00394 if ( it != End() )
00395 {
00396 Erase( it );
00397 return AK_Success;
00398 }
00399
00400 return AK_Fail;
00401 }
00402
00405 AKRESULT RemoveSwap(ARG_T in_rItem)
00406 {
00407 Iterator it = FindEx( in_rItem );
00408 if ( it != End() )
00409 {
00410 EraseSwap( it );
00411 return AK_Success;
00412 }
00413
00414 return AK_Fail;
00415 }
00416
00418 void RemoveAll()
00419 {
00420 for ( Iterator it = Begin(), itEnd = End(); it != itEnd; ++it )
00421 (*it).~T();
00422 m_uLength = 0;
00423 }
00424
00426 T& operator[](unsigned int uiIndex) const
00427 {
00428 AKASSERT( m_pItems );
00429 AKASSERT( uiIndex < Length() );
00430 return m_pItems[uiIndex];
00431 }
00432
00435 T * Insert(unsigned int in_uIndex)
00436 {
00437 AKASSERT( in_uIndex <= Length() );
00438
00439 size_t cItems = Length();
00440
00441 #if defined(_MSC_VER)
00442 #pragma warning( push )
00443 #pragma warning( disable : 4127 )
00444 #endif
00445 if ( ( cItems >= m_ulReserved ) && TGrowBy > 0 )
00446 {
00447 if ( !GrowArray() )
00448 return 0;
00449 }
00450 #if defined(_MSC_VER)
00451 #pragma warning( pop )
00452 #endif
00453
00454
00455 if( cItems < m_ulReserved )
00456 {
00457 T * pItemLast = m_pItems + m_uLength++;
00458 AkPlacementNew( pItemLast ) T;
00459
00460
00461
00462 for ( T * pItem = pItemLast; pItem > ( m_pItems + in_uIndex ); --pItem )
00463 TMovePolicy::Move( pItem[ 0 ], pItem[ -1 ] );
00464
00465
00466
00467 ( m_pItems + in_uIndex )->~T();
00468 AkPlacementNew( m_pItems + in_uIndex ) T;
00469
00470 return m_pItems + in_uIndex;
00471 }
00472
00473 return 0;
00474 }
00475
00477 bool GrowArray( AkUInt32 in_uGrowBy = TGrowBy )
00478 {
00479 AKASSERT( in_uGrowBy );
00480
00481 AkUInt32 ulNewReserve = m_ulReserved + in_uGrowBy;
00482 T * pNewItems = (T *) TAlloc::Alloc( sizeof( T ) * ulNewReserve );
00483 if ( !pNewItems )
00484 return false;
00485
00486
00487
00488 size_t cItems = Length();
00489
00490 if ( m_pItems )
00491 {
00492 for ( size_t i = 0; i < cItems; ++i )
00493 {
00494 AkPlacementNew( pNewItems + i ) T;
00495
00496 TMovePolicy::Move( pNewItems[ i ], m_pItems[ i ] );
00497
00498 m_pItems[ i ].~T();
00499 }
00500
00501 TAlloc::Free( m_pItems );
00502 }
00503
00504 m_pItems = pNewItems;
00505 m_ulReserved = ulNewReserve;
00506
00507 return true;
00508 }
00509
00511 bool Resize(AkUInt32 in_uiSize)
00512 {
00513 AkUInt32 cItems = Length();
00514 if (in_uiSize < cItems)
00515 {
00516
00517 for(AkUInt32 i = in_uiSize - 1 ; i < cItems; i++)
00518 {
00519 m_pItems[ i ].~T();
00520 }
00521 m_uLength = in_uiSize;
00522 return true;
00523 }
00524
00525 if ( in_uiSize > m_ulReserved )
00526 {
00527 if ( !GrowArray(in_uiSize - cItems) )
00528 return false;
00529 }
00530
00531
00532 for(size_t i = cItems; i < in_uiSize; i++)
00533 {
00534 AkPlacementNew( m_pItems + i ) T;
00535 }
00536
00537 m_uLength = in_uiSize;
00538 return true;
00539 }
00540
00541 void Transfer(AkArray<T,ARG_T,TAlloc,TGrowBy,TMovePolicy>& in_rSource)
00542 {
00543 if (m_pItems)
00544 Term();
00545
00546 m_pItems = in_rSource.m_pItems;
00547 m_uLength = in_rSource.m_uLength;
00548 m_ulReserved = in_rSource.m_ulReserved;
00549
00550 in_rSource.m_pItems = NULL;
00551 in_rSource.m_uLength = 0;
00552 in_rSource.m_ulReserved = 0;
00553 }
00554
00555 protected:
00556
00557 T * m_pItems;
00558 AkUInt32 m_uLength;
00559 AkUInt32 m_ulReserved;
00560 };
00561
00562 #endif
介绍一下自己的项目。我们会竭力为您提供帮助。
来注册自己的项目,我们帮您快速入门,不带任何附加条件!
开始 Wwise 之旅