Table of Contents

Wwise SDK 2019.2.1
AkListBare.h
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  Version: <VERSION> Build: <BUILDNUMBER>
25  Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc.
26 *******************************************************************************/
27 
28 // AkListBare.h
29 
30 #ifndef _AKLISTBARE_H
31 #define _AKLISTBARE_H
32 
33 // this one lets you define the structure
34 // only requirement is that T must have member pNextItem (if using the default AkListBareNextItem policy struct).
35 // client is responsible for allocation/deallocation of T.
36 
37 // WATCH OUT !
38 // - remember that removeall/term can't delete the elements for you.
39 // - be sure to destroy elements AFTER removing them from the list, as remove will
40 // access members of the element.
41 
42 /* Usage: List of AkMyType.
43 
44 - With default AkMyType::pNextItem, no count (Length() is not available):
45 typedef AkListBare<AkMyType> AkMyList1;
46 
47 - With custom AkMyType::pNextItemCustom, no count:
48 struct AkListBareNextItemCustom
49 {
50  static AkForceInline AkMyType *& Get( AkMyType * in_pItem )
51  {
52  return in_pItem->pNextItemCustom;
53  }
54 };
55 typedef AkListBare<AkMyType,AkListBareNextItemCustom> AkMyList2;
56 
57 - With default AkMyType::pNextItem, WITH count (Length() is available):
58 typedef AkListBare<AkMyType,AkListBareNextItem,AkCountPolicyWithCount> AkMyList3;
59 
60 */
61 
62 //
63 // List bare policy classes.
64 //
65 
66 /// Next item name policy.
67 template <class T> struct AkListBareNextItem
68 {
69  /// Default policy.
70  static AkForceInline T *& Get( T * in_pItem )
71  {
72  return in_pItem->pNextItem;
73  }
74 };
75 
76 /// Item count policy. These policy classes must define protected methods
77 /// ResetCount(), IncrementCount(), DecrementCount() and optionally, public unsigned int Length() const.
78 template <class T>
80 {
81 protected:
82  AkForceInline void ResetCount( T* ) {}
83  AkForceInline void IncrementCount( T* ) {}
84  AkForceInline void DecrementCount( T* ) {}
85 };
86 
87 template <class T>
89 {
90 public:
91  /// Get list length.
92  AkForceInline unsigned int Length() const
93  {
94  return m_ulNumListItems;
95  }
96 
97 protected:
98  AkCountPolicyWithCount() :m_ulNumListItems( 0 ) {}
99 
100  AkForceInline void ResetCount( T* ) { m_ulNumListItems = 0; }
101  AkForceInline void IncrementCount( T* ) { ++m_ulNumListItems; }
102  AkForceInline void DecrementCount( T* ) { --m_ulNumListItems; }
103 
104 private:
105  unsigned int m_ulNumListItems; ///< how many we have
106 };
107 
108 /// Last item policy. These policy classes must define protected methods
109 /// UpdateLast(), SetLast(), RemoveItem() and AddItem().
110 template <class T>
112 {
113 public:
114  /// Get last element.
115  AkForceInline T * Last() { return m_pLast; }
116  AkForceInline const T * Last() const { return m_pLast; }
117 
118 protected:
119  AkForceInline AkLastPolicyWithLast() : m_pLast( NULL ) {}
120 
121  // Policy interface:
122  // UpdateLast() is called by host to inform the policy that it should set the last item to a new value.
123  // The policy is thus free to do what it wants. On the other hand, SetLast() must make sense for the user of the list,
124  // otherwise it must not be implemented.
125  AkForceInline void UpdateLast( T * in_pLast ) { m_pLast = in_pLast; }
126  AkForceInline void SetLast( T * in_pLast ) { m_pLast = in_pLast; }
127  AkForceInline void RemoveItem( T * in_pItem, T * in_pPrevItem )
128  {
129  // Is it the last one ?
130  if( in_pItem == m_pLast )
131  {
132  // new last one is the previous one
133  m_pLast = in_pPrevItem;
134  }
135  }
136  AkForceInline void AddItem( T * in_pItem, T * in_pNextItem )
137  {
138  // Update tail.
139  // Note: will never occur since it is used with iteratorEx (have EndEx?).
140  if ( in_pNextItem == NULL )
141  m_pLast = in_pItem;
142  }
143 
144 protected:
145  T * m_pLast; ///< bottom of list
146 };
147 
148 template <class T>
150 {
151 protected:
152  // Policy interface:
153  // UpdateLast() is called by host to inform the policy that it should set the last item to a new value.
154  // The policy is thus free to do what it wants. On the other hand, SetLast() must make sense for the user of the list,
155  // otherwise it must not be implemented.
156  AkForceInline void UpdateLast( T * ) {}
157  // SetLast is voluntarily left undefined so that calling AkListBare::AddLast() with this policy results in a compile-time error.
158  //AkForceInline void SetLast( T * in_pLast );
159  AkForceInline void RemoveItem( T *, T * ) {}
160  AkForceInline void AddItem( T *, T * ) {}
161 };
162 
163 
164 /// Implementation of List Bare.
165 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 >
166 {
167 public:
168  /// Iterator.
169  struct Iterator
170  {
171  T* pItem; ///< Next item.
172 
173  /// Operator ++.
175  {
176  AKASSERT( pItem );
177  pItem = U_NEXTITEM<T>::Get( pItem );
178  return *this;
179  }
180 
181  /// Operator *.
182  inline T * operator*() const
183  {
184  AKASSERT( pItem );
185  return pItem;
186  }
187 
188  /// Operator !=.
189  bool operator !=( const Iterator& in_rOp ) const
190  {
191  return ( pItem != in_rOp.pItem );
192  }
193 
194  /// Operator ==.
195  bool operator ==( const Iterator& in_rOp ) const
196  {
197  return ( pItem == in_rOp.pItem );
198  }
199  };
200 
201  /// The IteratorEx iterator is intended for usage when a possible erase may occurs
202  /// when simply iterating trough a list, use the simple Iterator, it is faster and lighter.
203  struct IteratorEx : public Iterator
204  {
205  T* pPrevItem; ///< Previous item.
206 
207  /// Operator ++.
209  {
210  AKASSERT( this->pItem );
211 
212  pPrevItem = this->pItem;
213  this->pItem = U_NEXTITEM<T>::Get( this->pItem );
214 
215  return *this;
216  }
217  };
218 
219  /// Erase item.
220  IteratorEx Erase( const IteratorEx& in_rIter )
221  {
222  IteratorEx returnedIt;
223  returnedIt.pItem = U_NEXTITEM<T>::Get( in_rIter.pItem );
224  returnedIt.pPrevItem = in_rIter.pPrevItem;
225 
226  RemoveItem( in_rIter.pItem, in_rIter.pPrevItem );
227 
228  return returnedIt;
229  }
230 
231  /// Insert item.
232  IteratorEx Insert( const IteratorEx& in_rIter,
233  T * in_pItem )
234  {
235  IteratorEx returnedIt;
236  AddItem( in_pItem, in_rIter.pItem, in_rIter.pPrevItem );
237  returnedIt = in_rIter;
238  returnedIt.pPrevItem = in_pItem;
239  return returnedIt;
240  }
241 
242  /// End condition.
243  inline Iterator End() const
244  {
245  Iterator returnedIt;
246  returnedIt.pItem = NULL;
247  return returnedIt;
248  }
249 
250  /// Get IteratorEx at beginning.
251  inline IteratorEx BeginEx()
252  {
253  IteratorEx returnedIt;
254 
255  returnedIt.pItem = m_pFirst;
256  returnedIt.pPrevItem = NULL;
257 
258  return returnedIt;
259  }
260 
261  /// Get Iterator at beginning.
262  inline Iterator Begin() const
263  {
264  Iterator returnedIt;
265 
266  returnedIt.pItem = m_pFirst;
267 
268  return returnedIt;
269  }
270 
271  /// Get Iterator from item.
272  inline IteratorEx FindEx( T * in_pItem )
273  {
274  IteratorEx it = BeginEx();
275  for ( ; it != End(); ++it )
276  {
277  if ( it.pItem == in_pItem )
278  break;
279  }
280 
281  return it;
282  }
283 
284  /// Constructor.
286  : m_pFirst( NULL )
287  {
288  }
289 
290  /// Destructor.
292  {
293  }
294 
295  /// Terminate.
296  void Term()
297  {
298  RemoveAll();
299  }
300 
301  /// Add element at the beginning of list.
302  void AddFirst( T * in_pItem )
303  {
304  if ( m_pFirst == NULL )
305  {
306  m_pFirst = in_pItem;
307  LAST_POLICY<T>::UpdateLast( in_pItem );
308  U_NEXTITEM<T>::Get( in_pItem ) = NULL;
309  }
310  else
311  {
312  U_NEXTITEM<T>::Get( in_pItem ) = m_pFirst;
313  m_pFirst = in_pItem;
314  }
315 
316  COUNT_POLICY<T>::IncrementCount( in_pItem );
317  }
318 
319  /// Add element at the end of list.
320  void AddLast( T * in_pItem )
321  {
322  U_NEXTITEM<T>::Get( in_pItem ) = NULL;
323 
324  if ( m_pFirst == NULL )
325  {
326  m_pFirst = in_pItem;
327  }
328  else
329  {
330  U_NEXTITEM<T>::Get( LAST_POLICY<T>::Last() ) = in_pItem;
331  }
332 
333  LAST_POLICY<T>::SetLast( in_pItem );
334 
335  COUNT_POLICY<T>::IncrementCount( in_pItem );
336  }
337 
338  /// Remove an element.
339  AKRESULT Remove( T * in_pItem )
340  {
341  IteratorEx it = FindEx( in_pItem );
342  if ( it != End() )
343  {
344  Erase( it );
345  return AK_Success;
346  }
347 
348  return AK_Fail;
349  }
350 
351  /// Remove the first element.
352  AKRESULT RemoveFirst()
353  {
354  if( m_pFirst == NULL )
355  return AK_Fail;
356 
357  if ( U_NEXTITEM<T>::Get( m_pFirst ) == NULL )
358  {
359  m_pFirst = NULL;
360  LAST_POLICY<T>::UpdateLast( NULL );
361  }
362  else
363  {
364  m_pFirst = U_NEXTITEM<T>::Get( m_pFirst );
365  }
366 
367  COUNT_POLICY<T>::DecrementCount( m_pFirst );
368 
369  return AK_Success;
370  }
371 
372  /// Remove all elements.
373  AkForceInline void RemoveAll()
374  {
375  // Items being externally managed, all we need to do here is clear our members.
376  m_pFirst = NULL;
377  LAST_POLICY<T>::UpdateLast( NULL );
378  COUNT_POLICY<T>::ResetCount( m_pFirst );
379  }
380 
381  /// Get first element.
382  AkForceInline T * First()
383  {
384  return m_pFirst;
385  }
386 
387  /// Empty condition.
388  AkForceInline bool IsEmpty() const
389  {
390  return m_pFirst == NULL;
391  }
392 
393  /// Remove an element.
394  void RemoveItem( T * in_pItem, T * in_pPrevItem )
395  {
396  // Is it the first one ?
397 
398  if( in_pItem == m_pFirst )
399  {
400  // new first one is the next one
401  m_pFirst = U_NEXTITEM<T>::Get( in_pItem );
402  }
403  else
404  {
405  // take it out of the used space
406  U_NEXTITEM<T>::Get( in_pPrevItem ) = U_NEXTITEM<T>::Get( in_pItem );
407  }
408 
409  LAST_POLICY<T>::RemoveItem( in_pItem, in_pPrevItem );
410 
411  COUNT_POLICY<T>::DecrementCount( m_pFirst );
412  }
413 
414  /// Add an element.
415  void AddItem( T * in_pItem, T * in_pNextItem, T * in_pPrevItem )
416  {
417  U_NEXTITEM<T>::Get( in_pItem ) = in_pNextItem;
418 
419  if ( in_pPrevItem == NULL )
420  m_pFirst = in_pItem;
421  else
422  U_NEXTITEM<T>::Get( in_pPrevItem ) = in_pItem;
423 
424  LAST_POLICY<T>::AddItem( in_pItem, in_pNextItem );
425 
426  COUNT_POLICY<T>::IncrementCount( in_pItem );
427  }
428 
429 protected:
430  T * m_pFirst; ///< top of list
431 };
432 
433 #endif // _AKLISTBARE_H
T * operator *() const
Operator *.
Definition: AkListBare.h:182
AkForceInline void ResetCount(T *)
Definition: AkListBare.h:82
AkForceInline void AddItem(T *, T *)
Definition: AkListBare.h:160
AkForceInline void RemoveAll()
Remove all elements.
Definition: AkListBare.h:373
AkForceInline void RemoveItem(T *, T *)
Definition: AkListBare.h:159
void Term()
Terminate.
Definition: AkListBare.h:296
IteratorEx BeginEx()
Get IteratorEx at beginning.
Definition: AkListBare.h:251
IteratorEx Insert(const IteratorEx &in_rIter, T *in_pItem)
Insert item.
Definition: AkListBare.h:232
AkForceInline bool IsEmpty() const
Empty condition.
Definition: AkListBare.h:388
Iterator End() const
End condition.
Definition: AkListBare.h:243
T * pItem
Next item.
Definition: AkListBare.h:171
AkForceInline void ResetCount(T *)
Definition: AkListBare.h:100
IteratorEx FindEx(T *in_pItem)
Get Iterator from item.
Definition: AkListBare.h:272
T * m_pLast
bottom of list
Definition: AkListBare.h:145
AkForceInline void DecrementCount(T *)
Definition: AkListBare.h:84
AkForceInline unsigned int Length() const
Get list length.
Definition: AkListBare.h:92
AkForceInline void AddItem(T *in_pItem, T *in_pNextItem)
Definition: AkListBare.h:136
bool operator !=(const Iterator &in_rOp) const
Operator !=.
Definition: AkListBare.h:189
T * m_pFirst
top of list
Definition: AkListBare.h:430
AkForceInline void SetLast(T *in_pLast)
Definition: AkListBare.h:126
AkForceInline T * Last()
Get last element.
Definition: AkListBare.h:115
AKRESULT RemoveFirst()
Remove the first element.
Definition: AkListBare.h:352
T * pPrevItem
Previous item.
Definition: AkListBare.h:205
void AddFirst(T *in_pItem)
Add element at the beginning of list.
Definition: AkListBare.h:302
AkForceInline void UpdateLast(T *in_pLast)
Definition: AkListBare.h:125
AkForceInline void RemoveItem(T *in_pItem, T *in_pPrevItem)
Definition: AkListBare.h:127
AkForceInline void IncrementCount(T *)
Definition: AkListBare.h:101
Next item name policy.
Definition: AkListBare.h:67
static AkForceInline T *& Get(T *in_pItem)
Default policy.
Definition: AkListBare.h:70
AKRESULT Remove(T *in_pItem)
Remove an element.
Definition: AkListBare.h:339
Iterator & operator++()
Operator ++.
Definition: AkListBare.h:174
Iterator Begin() const
Get Iterator at beginning.
Definition: AkListBare.h:262
Iterator.
Definition: AkListBare.h:169
void AddItem(T *in_pItem, T *in_pNextItem, T *in_pPrevItem)
Add an element.
Definition: AkListBare.h:415
~AkListBare()
Destructor.
Definition: AkListBare.h:291
void RemoveItem(T *in_pItem, T *in_pPrevItem)
Remove an element.
Definition: AkListBare.h:394
AkListBare()
Constructor.
Definition: AkListBare.h:285
AkForceInline void UpdateLast(T *)
Definition: AkListBare.h:156
AkForceInline void DecrementCount(T *)
Definition: AkListBare.h:102
IteratorEx Erase(const IteratorEx &in_rIter)
Erase item.
Definition: AkListBare.h:220
Implementation of List Bare.
Definition: AkListBare.h:165
bool operator==(const Iterator &in_rOp) const
Operator ==.
Definition: AkListBare.h:195
void AddLast(T *in_pItem)
Add element at the end of list.
Definition: AkListBare.h:320
AkForceInline AkLastPolicyWithLast()
Definition: AkListBare.h:119
IteratorEx & operator++()
Operator ++.
Definition: AkListBare.h:208
AkForceInline void IncrementCount(T *)
Definition: AkListBare.h:83
AkForceInline T * First()
Get first element.
Definition: AkListBare.h:382
AkForceInline const T * Last() const
Definition: AkListBare.h:116