目次

Wwise SDK 2018.1.11
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* ) {}
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.
116  {
117  return m_pLast;
118  }
119 
120 protected:
122 
123  // Policy interface:
124  // UpdateLast() is called by host to inform the policy that it should set the last item to a new value.
125  // The policy is thus free to do what it wants. On the other hand, SetLast() must make sense for the user of the list,
126  // otherwise it must not be implemented.
127  AkForceInline void UpdateLast( T * in_pLast ) { m_pLast = in_pLast; }
128  AkForceInline void SetLast( T * in_pLast ) { m_pLast = in_pLast; }
129  AkForceInline void RemoveItem( T * in_pItem, T * in_pPrevItem )
130  {
131  // Is it the last one ?
132  if( in_pItem == m_pLast )
133  {
134  // new last one is the previous one
135  m_pLast = in_pPrevItem;
136  }
137  }
138  AkForceInline void AddItem( T * in_pItem, T * in_pNextItem )
139  {
140  // Update tail.
141  // Note: will never occur since it is used with iteratorEx (have EndEx?).
142  if ( in_pNextItem == NULL )
143  m_pLast = in_pItem;
144  }
145 
146 protected:
147  T * m_pLast; ///< bottom of list
148 };
149 
150 template <class T>
152 {
153 protected:
154  // Policy interface:
155  // UpdateLast() is called by host to inform the policy that it should set the last item to a new value.
156  // The policy is thus free to do what it wants. On the other hand, SetLast() must make sense for the user of the list,
157  // otherwise it must not be implemented.
158  AkForceInline void UpdateLast( T * ) {}
159  // SetLast is voluntarily left undefined so that calling AkListBare::AddLast() with this policy results in a compile-time error.
160  //AkForceInline void SetLast( T * in_pLast );
161  AkForceInline void RemoveItem( T *, T * ) {}
162  AkForceInline void AddItem( T *, T * ) {}
163 };
164 
165 
166 /// Implementation of List Bare.
167 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 >
168 {
169 public:
170  /// Iterator.
171  struct Iterator
172  {
173  T* pItem; ///< Next item.
174 
175  /// Operator ++.
177  {
178  AKASSERT( pItem );
179  pItem = U_NEXTITEM<T>::Get( pItem );
180  return *this;
181  }
182 
183  /// Operator *.
184  inline T * operator*() const
185  {
186  AKASSERT( pItem );
187  return pItem;
188  }
189 
190  /// Operator !=.
191  bool operator !=( const Iterator& in_rOp ) const
192  {
193  return ( pItem != in_rOp.pItem );
194  }
195 
196  /// Operator ==.
197  bool operator ==( const Iterator& in_rOp ) const
198  {
199  return ( pItem == in_rOp.pItem );
200  }
201  };
202 
203  /// The IteratorEx iterator is intended for usage when a possible erase may occurs
204  /// when simply iterating trough a list, use the simple Iterator, it is faster and lighter.
205  struct IteratorEx : public Iterator
206  {
207  T* pPrevItem; ///< Previous item.
208 
209  /// Operator ++.
211  {
212  AKASSERT( this->pItem );
213 
214  pPrevItem = this->pItem;
215  this->pItem = U_NEXTITEM<T>::Get( this->pItem );
216 
217  return *this;
218  }
219  };
220 
221  /// Erase item.
222  IteratorEx Erase( const IteratorEx& in_rIter )
223  {
224  IteratorEx returnedIt;
225  returnedIt.pItem = U_NEXTITEM<T>::Get( in_rIter.pItem );
226  returnedIt.pPrevItem = in_rIter.pPrevItem;
227 
228  RemoveItem( in_rIter.pItem, in_rIter.pPrevItem );
229 
230  return returnedIt;
231  }
232 
233  /// Insert item.
234  IteratorEx Insert( const IteratorEx& in_rIter,
235  T * in_pItem )
236  {
237  IteratorEx returnedIt;
238  AddItem( in_pItem, in_rIter.pItem, in_rIter.pPrevItem );
239  returnedIt = in_rIter;
240  returnedIt.pPrevItem = in_pItem;
241  return returnedIt;
242  }
243 
244  /// End condition.
245  inline Iterator End() const
246  {
247  Iterator returnedIt;
248  returnedIt.pItem = NULL;
249  return returnedIt;
250  }
251 
252  /// Get IteratorEx at beginning.
253  inline IteratorEx BeginEx()
254  {
255  IteratorEx returnedIt;
256 
257  returnedIt.pItem = m_pFirst;
258  returnedIt.pPrevItem = NULL;
259 
260  return returnedIt;
261  }
262 
263  /// Get Iterator at beginning.
264  inline Iterator Begin() const
265  {
266  Iterator returnedIt;
267 
268  returnedIt.pItem = m_pFirst;
269 
270  return returnedIt;
271  }
272 
273  /// Get Iterator from item.
274  inline IteratorEx FindEx( T * in_pItem )
275  {
276  IteratorEx it = BeginEx();
277  for ( ; it != End(); ++it )
278  {
279  if ( it.pItem == in_pItem )
280  break;
281  }
282 
283  return it;
284  }
285 
286  /// Constructor.
288  : m_pFirst( NULL )
289  {
290  }
291 
292  /// Destructor.
294  {
295  }
296 
297  /// Terminate.
298  void Term()
299  {
300  RemoveAll();
301  }
302 
303  /// Add element at the beginning of list.
304  void AddFirst( T * in_pItem )
305  {
306  if ( m_pFirst == NULL )
307  {
308  m_pFirst = in_pItem;
309  LAST_POLICY<T>::UpdateLast( in_pItem );
310  U_NEXTITEM<T>::Get( in_pItem ) = NULL;
311  }
312  else
313  {
314  U_NEXTITEM<T>::Get( in_pItem ) = m_pFirst;
315  m_pFirst = in_pItem;
316  }
317 
318  COUNT_POLICY<T>::IncrementCount( in_pItem );
319  }
320 
321  /// Add element at the end of list.
322  void AddLast( T * in_pItem )
323  {
324  U_NEXTITEM<T>::Get( in_pItem ) = NULL;
325 
326  if ( m_pFirst == NULL )
327  {
328  m_pFirst = in_pItem;
329  }
330  else
331  {
332  U_NEXTITEM<T>::Get( LAST_POLICY<T>::Last() ) = in_pItem;
333  }
334 
335  LAST_POLICY<T>::SetLast( in_pItem );
336 
337  COUNT_POLICY<T>::IncrementCount( in_pItem );
338  }
339 
340  /// Remove an element.
341  AKRESULT Remove( T * in_pItem )
342  {
343  IteratorEx it = FindEx( in_pItem );
344  if ( it != End() )
345  {
346  Erase( it );
347  return AK_Success;
348  }
349 
350  return AK_Fail;
351  }
352 
353  /// Remove the first element.
355  {
356  if( m_pFirst == NULL )
357  return AK_Fail;
358 
359  if ( U_NEXTITEM<T>::Get( m_pFirst ) == NULL )
360  {
361  m_pFirst = NULL;
362  LAST_POLICY<T>::UpdateLast( NULL );
363  }
364  else
365  {
366  m_pFirst = U_NEXTITEM<T>::Get( m_pFirst );
367  }
368 
369  COUNT_POLICY<T>::DecrementCount( m_pFirst );
370 
371  return AK_Success;
372  }
373 
374  /// Remove all elements.
376  {
377  // Items being externally managed, all we need to do here is clear our members.
378  m_pFirst = NULL;
379  LAST_POLICY<T>::UpdateLast( NULL );
380  COUNT_POLICY<T>::ResetCount( m_pFirst );
381  }
382 
383  /// Get first element.
385  {
386  return m_pFirst;
387  }
388 
389  /// Empty condition.
390  AkForceInline bool IsEmpty() const
391  {
392  return m_pFirst == NULL;
393  }
394 
395  /// Remove an element.
396  void RemoveItem( T * in_pItem, T * in_pPrevItem )
397  {
398  // Is it the first one ?
399 
400  if( in_pItem == m_pFirst )
401  {
402  // new first one is the next one
403  m_pFirst = U_NEXTITEM<T>::Get( in_pItem );
404  }
405  else
406  {
407  // take it out of the used space
408  U_NEXTITEM<T>::Get( in_pPrevItem ) = U_NEXTITEM<T>::Get( in_pItem );
409  }
410 
411  LAST_POLICY<T>::RemoveItem( in_pItem, in_pPrevItem );
412 
413  COUNT_POLICY<T>::DecrementCount( m_pFirst );
414  }
415 
416  /// Add an element.
417  void AddItem( T * in_pItem, T * in_pNextItem, T * in_pPrevItem )
418  {
419  U_NEXTITEM<T>::Get( in_pItem ) = in_pNextItem;
420 
421  if ( in_pPrevItem == NULL )
422  m_pFirst = in_pItem;
423  else
424  U_NEXTITEM<T>::Get( in_pPrevItem ) = in_pItem;
425 
426  LAST_POLICY<T>::AddItem( in_pItem, in_pNextItem );
427 
428  COUNT_POLICY<T>::IncrementCount( in_pItem );
429  }
430 
431 protected:
432  T * m_pFirst; ///< top of list
433 };
434 
435 #endif // _AKLISTBARE_H
T * operator *() const
Operator *.
Definition: AkListBare.h:184
AkForceInline void ResetCount(T *)
Definition: AkListBare.h:82
AkForceInline void AddItem(T *, T *)
Definition: AkListBare.h:162
AkForceInline void RemoveAll()
Remove all elements.
Definition: AkListBare.h:375
AkForceInline void RemoveItem(T *, T *)
Definition: AkListBare.h:161
void Term()
Terminate.
Definition: AkListBare.h:298
The operation was successful.
Definition: AkTypes.h:129
IteratorEx BeginEx()
Get IteratorEx at beginning.
Definition: AkListBare.h:253
IteratorEx Insert(const IteratorEx &in_rIter, T *in_pItem)
Insert item.
Definition: AkListBare.h:234
AkForceInline bool IsEmpty() const
Empty condition.
Definition: AkListBare.h:390
Iterator End() const
End condition.
Definition: AkListBare.h:245
AKRESULT
Standard function call result.
Definition: AkTypes.h:126
T * pItem
Next item.
Definition: AkListBare.h:173
AkForceInline void ResetCount(T *)
Definition: AkListBare.h:100
IteratorEx FindEx(T *in_pItem)
Get Iterator from item.
Definition: AkListBare.h:274
The operation failed.
Definition: AkTypes.h:130
T * m_pLast
bottom of list
Definition: AkListBare.h:147
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:138
#define AKASSERT(Condition)
Definition: AkAssert.h:69
bool operator !=(const Iterator &in_rOp) const
Operator !=.
Definition: AkListBare.h:191
T * m_pFirst
top of list
Definition: AkListBare.h:432
AkForceInline void SetLast(T *in_pLast)
Definition: AkListBare.h:128
AkForceInline T * Last()
Get last element.
Definition: AkListBare.h:115
AKRESULT RemoveFirst()
Remove the first element.
Definition: AkListBare.h:354
#define AkForceInline
Force inlining
Definition: AkTypes.h:63
T * pPrevItem
Previous item.
Definition: AkListBare.h:207
void AddFirst(T *in_pItem)
Add element at the beginning of list.
Definition: AkListBare.h:304
AkForceInline void UpdateLast(T *in_pLast)
Definition: AkListBare.h:127
AkForceInline void RemoveItem(T *in_pItem, T *in_pPrevItem)
Definition: AkListBare.h:129
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:341
Iterator & operator++()
Operator ++.
Definition: AkListBare.h:176
#define NULL
Definition: AkTypes.h:49
Iterator Begin() const
Get Iterator at beginning.
Definition: AkListBare.h:264
Iterator.
Definition: AkListBare.h:171
void AddItem(T *in_pItem, T *in_pNextItem, T *in_pPrevItem)
Add an element.
Definition: AkListBare.h:417
~AkListBare()
Destructor.
Definition: AkListBare.h:293
void RemoveItem(T *in_pItem, T *in_pPrevItem)
Remove an element.
Definition: AkListBare.h:396
AkListBare()
Constructor.
Definition: AkListBare.h:287
AkForceInline void UpdateLast(T *)
Definition: AkListBare.h:158
AkForceInline void DecrementCount(T *)
Definition: AkListBare.h:102
IteratorEx Erase(const IteratorEx &in_rIter)
Erase item.
Definition: AkListBare.h:222
Implementation of List Bare.
Definition: AkListBare.h:167
bool operator==(const Iterator &in_rOp) const
Operator ==.
Definition: AkListBare.h:197
void AddLast(T *in_pItem)
Add element at the end of list.
Definition: AkListBare.h:322
AkForceInline AkLastPolicyWithLast()
Definition: AkListBare.h:121
IteratorEx & operator++()
Operator ++.
Definition: AkListBare.h:210
AkForceInline void IncrementCount(T *)
Definition: AkListBare.h:83
AkForceInline T * First()
Get first element.
Definition: AkListBare.h:384