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

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