Wwise SDK 2015.1.9
_ak_list_bare_8h_source
Version
menu_open
link
include/AK/Tools/Common/AkListBare.h
Go to the documentation of this file.00001 00002 // 00003 // Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved 00004 // 00006 00007 // AkListBare.h 00008 00009 #ifndef _AKLISTBARE_H 00010 #define _AKLISTBARE_H 00011 00012 // this one lets you define the structure 00013 // only requirement is that T must have member pNextItem (if using the default AkListBareNextItem policy struct). 00014 // client is responsible for allocation/deallocation of T. 00015 00016 // WATCH OUT ! 00017 // - remember that removeall/term can't delete the elements for you. 00018 // - be sure to destroy elements AFTER removing them from the list, as remove will 00019 // access members of the element. 00020 00021 /* Usage: List of AkMyType. 00022 00023 - With default AkMyType::pNextItem, no count (Length() is not available): 00024 typedef AkListBare<AkMyType> AkMyList1; 00025 00026 - With custom AkMyType::pNextItemCustom, no count: 00027 struct AkListBareNextItemCustom 00028 { 00029 static AkForceInline AkMyType *& Get( AkMyType * in_pItem ) 00030 { 00031 return in_pItem->pNextItemCustom; 00032 } 00033 }; 00034 typedef AkListBare<AkMyType,AkListBareNextItemCustom> AkMyList2; 00035 00036 - With default AkMyType::pNextItem, WITH count (Length() is available): 00037 typedef AkListBare<AkMyType,AkListBareNextItem,AkCountPolicyWithCount> AkMyList3; 00038 00039 */ 00040 00041 // 00042 // List bare policy classes. 00043 // 00044 00046 template <class T> struct AkListBareNextItem 00047 { 00049 static AkForceInline T *& Get( T * in_pItem ) 00050 { 00051 return in_pItem->pNextItem; 00052 } 00053 }; 00054 00057 template <class T> 00058 class AkCountPolicyNoCount 00059 { 00060 protected: 00061 AkForceInline void ResetCount( T* ) {} 00062 AkForceInline void IncrementCount( T* ) {} 00063 AkForceInline void DecrementCount( T* ) {} 00064 }; 00065 00066 template <class T> 00067 class AkCountPolicyWithCount 00068 { 00069 public: 00071 AkForceInline unsigned int Length() const 00072 { 00073 return m_ulNumListItems; 00074 } 00075 00076 protected: 00077 AkCountPolicyWithCount() :m_ulNumListItems( 0 ) {} 00078 00079 AkForceInline void ResetCount( T* ) { m_ulNumListItems = 0; } 00080 AkForceInline void IncrementCount( T* ) { ++m_ulNumListItems; } 00081 AkForceInline void DecrementCount( T* ) { --m_ulNumListItems; } 00082 00083 private: 00084 unsigned int m_ulNumListItems; 00085 }; 00086 00089 template <class T> 00090 class AkLastPolicyWithLast 00091 { 00092 public: 00094 AkForceInline T * Last() 00095 { 00096 return m_pLast; 00097 } 00098 00099 protected: 00100 AkForceInline AkLastPolicyWithLast() : m_pLast( NULL ) {} 00101 00102 // Policy interface: 00103 // UpdateLast() is called by host to inform the policy that it should set the last item to a new value. 00104 // The policy is thus free to do what it wants. On the other hand, SetLast() must make sense for the user of the list, 00105 // otherwise it must not be implemented. 00106 AkForceInline void UpdateLast( T * in_pLast ) { m_pLast = in_pLast; } 00107 AkForceInline void SetLast( T * in_pLast ) { m_pLast = in_pLast; } 00108 AkForceInline void RemoveItem( T * in_pItem, T * in_pPrevItem ) 00109 { 00110 // Is it the last one ? 00111 if( in_pItem == m_pLast ) 00112 { 00113 // new last one is the previous one 00114 m_pLast = in_pPrevItem; 00115 } 00116 } 00117 AkForceInline void AddItem( T * in_pItem, T * in_pNextItem ) 00118 { 00119 // Update tail. 00120 // Note: will never occur since it is used with iteratorEx (have EndEx?). 00121 if ( in_pNextItem == NULL ) 00122 m_pLast = in_pItem; 00123 } 00124 00125 protected: 00126 T * m_pLast; 00127 }; 00128 00129 template <class T> 00130 class AkLastPolicyNoLast 00131 { 00132 protected: 00133 // Policy interface: 00134 // UpdateLast() is called by host to inform the policy that it should set the last item to a new value. 00135 // The policy is thus free to do what it wants. On the other hand, SetLast() must make sense for the user of the list, 00136 // otherwise it must not be implemented. 00137 AkForceInline void UpdateLast( T * ) {} 00138 // SetLast is voluntarily left undefined so that calling AkListBare::AddLast() with this policy results in a compile-time error. 00139 //AkForceInline void SetLast( T * in_pLast ); 00140 AkForceInline void RemoveItem( T *, T * ) {} 00141 AkForceInline void AddItem( T *, T * ) {} 00142 }; 00143 00144 00146 template <class T, template <class> class U_NEXTITEM = AkListBareNextItem, template <class> class COUNT_POLICY = AkCountPolicyNoCount, template <class> class LAST_POLICY = AkLastPolicyWithLast > class AkListBare : public COUNT_POLICY< T >, public LAST_POLICY< T > 00147 { 00148 public: 00150 struct Iterator 00151 { 00152 T* pItem; 00153 00155 inline Iterator& operator++() 00156 { 00157 AKASSERT( pItem ); 00158 pItem = U_NEXTITEM<T>::Get( pItem ); 00159 return *this; 00160 } 00161 00163 inline T * operator*() const 00164 { 00165 AKASSERT( pItem ); 00166 return pItem; 00167 } 00168 00170 bool operator !=( const Iterator& in_rOp ) const 00171 { 00172 return ( pItem != in_rOp.pItem ); 00173 } 00174 00176 bool operator ==( const Iterator& in_rOp ) const 00177 { 00178 return ( pItem == in_rOp.pItem ); 00179 } 00180 }; 00181 00184 struct IteratorEx : public Iterator 00185 { 00186 T* pPrevItem; 00187 00189 IteratorEx& operator++() 00190 { 00191 AKASSERT( this->pItem ); 00192 00193 pPrevItem = this->pItem; 00194 this->pItem = U_NEXTITEM<T>::Get( this->pItem ); 00195 00196 return *this; 00197 } 00198 }; 00199 00201 IteratorEx Erase( const IteratorEx& in_rIter ) 00202 { 00203 IteratorEx returnedIt; 00204 returnedIt.pItem = U_NEXTITEM<T>::Get( in_rIter.pItem ); 00205 returnedIt.pPrevItem = in_rIter.pPrevItem; 00206 00207 RemoveItem( in_rIter.pItem, in_rIter.pPrevItem ); 00208 00209 return returnedIt; 00210 } 00211 00213 IteratorEx Insert( const IteratorEx& in_rIter, 00214 T * in_pItem ) 00215 { 00216 IteratorEx returnedIt; 00217 AddItem( in_pItem, in_rIter.pItem, in_rIter.pPrevItem ); 00218 returnedIt = in_rIter; 00219 returnedIt.pPrevItem = in_pItem; 00220 return returnedIt; 00221 } 00222 00224 inline Iterator End() 00225 { 00226 Iterator returnedIt; 00227 returnedIt.pItem = NULL; 00228 return returnedIt; 00229 } 00230 00232 inline IteratorEx BeginEx() 00233 { 00234 IteratorEx returnedIt; 00235 00236 returnedIt.pItem = m_pFirst; 00237 returnedIt.pPrevItem = NULL; 00238 00239 return returnedIt; 00240 } 00241 00243 inline Iterator Begin() 00244 { 00245 Iterator returnedIt; 00246 00247 returnedIt.pItem = m_pFirst; 00248 00249 return returnedIt; 00250 } 00251 00253 inline IteratorEx FindEx( T * in_pItem ) 00254 { 00255 IteratorEx it = BeginEx(); 00256 for ( ; it != End(); ++it ) 00257 { 00258 if ( it.pItem == in_pItem ) 00259 break; 00260 } 00261 00262 return it; 00263 } 00264 00266 AkListBare() 00267 : m_pFirst( NULL ) 00268 { 00269 } 00270 00272 ~AkListBare() 00273 { 00274 } 00275 00277 void Term() 00278 { 00279 RemoveAll(); 00280 } 00281 00283 void AddFirst( T * in_pItem ) 00284 { 00285 if ( m_pFirst == NULL ) 00286 { 00287 m_pFirst = in_pItem; 00288 LAST_POLICY<T>::UpdateLast( in_pItem ); 00289 U_NEXTITEM<T>::Get( in_pItem ) = NULL; 00290 } 00291 else 00292 { 00293 U_NEXTITEM<T>::Get( in_pItem ) = m_pFirst; 00294 m_pFirst = in_pItem; 00295 } 00296 00297 COUNT_POLICY<T>::IncrementCount( in_pItem ); 00298 } 00299 00301 void AddLast( T * in_pItem ) 00302 { 00303 U_NEXTITEM<T>::Get( in_pItem ) = NULL; 00304 00305 if ( m_pFirst == NULL ) 00306 { 00307 m_pFirst = in_pItem; 00308 } 00309 else 00310 { 00311 U_NEXTITEM<T>::Get( LAST_POLICY<T>::Last() ) = in_pItem; 00312 } 00313 00314 LAST_POLICY<T>::SetLast( in_pItem ); 00315 00316 COUNT_POLICY<T>::IncrementCount( in_pItem ); 00317 } 00318 00320 AKRESULT Remove( T * in_pItem ) 00321 { 00322 IteratorEx it = FindEx( in_pItem ); 00323 if ( it != End() ) 00324 { 00325 Erase( it ); 00326 return AK_Success; 00327 } 00328 00329 return AK_Fail; 00330 } 00331 00333 AKRESULT RemoveFirst() 00334 { 00335 if( m_pFirst == NULL ) 00336 return AK_Fail; 00337 00338 if ( U_NEXTITEM<T>::Get( m_pFirst ) == NULL ) 00339 { 00340 m_pFirst = NULL; 00341 LAST_POLICY<T>::UpdateLast( NULL ); 00342 } 00343 else 00344 { 00345 m_pFirst = U_NEXTITEM<T>::Get( m_pFirst ); 00346 } 00347 00348 COUNT_POLICY<T>::DecrementCount( m_pFirst ); 00349 00350 return AK_Success; 00351 } 00352 00354 AkForceInline void RemoveAll() 00355 { 00356 // Items being externally managed, all we need to do here is clear our members. 00357 m_pFirst = NULL; 00358 LAST_POLICY<T>::UpdateLast( NULL ); 00359 COUNT_POLICY<T>::ResetCount( m_pFirst ); 00360 } 00361 00363 AkForceInline T * First() 00364 { 00365 return m_pFirst; 00366 } 00367 00369 AkForceInline bool IsEmpty() const 00370 { 00371 return m_pFirst == NULL; 00372 } 00373 00375 void RemoveItem( T * in_pItem, T * in_pPrevItem ) 00376 { 00377 // Is it the first one ? 00378 00379 if( in_pItem == m_pFirst ) 00380 { 00381 // new first one is the next one 00382 m_pFirst = U_NEXTITEM<T>::Get( in_pItem ); 00383 } 00384 else 00385 { 00386 // take it out of the used space 00387 U_NEXTITEM<T>::Get( in_pPrevItem ) = U_NEXTITEM<T>::Get( in_pItem ); 00388 } 00389 00390 LAST_POLICY<T>::RemoveItem( in_pItem, in_pPrevItem ); 00391 00392 COUNT_POLICY<T>::DecrementCount( m_pFirst ); 00393 } 00394 00396 void AddItem( T * in_pItem, T * in_pNextItem, T * in_pPrevItem ) 00397 { 00398 U_NEXTITEM<T>::Get( in_pItem ) = in_pNextItem; 00399 00400 if ( in_pPrevItem == NULL ) 00401 m_pFirst = in_pItem; 00402 else 00403 U_NEXTITEM<T>::Get( in_pPrevItem ) = in_pItem; 00404 00405 LAST_POLICY<T>::AddItem( in_pItem, in_pNextItem ); 00406 00407 COUNT_POLICY<T>::IncrementCount( in_pItem ); 00408 } 00409 00410 protected: 00411 T * m_pFirst; 00412 }; 00413 00414 #endif // _AKLISTBARE_H
Was this page helpful?
Need Support?
Questions? Problems? Need more info? Contact us, and we can help!
Visit our Support pageTell 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