バージョン
menu

Wwise SDK 2025.1.2
AkSet.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  Copyright (c) 2025 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 //////////////////////////////////////////////////////////////////////
28 //
29 // AkSet.h
30 //
31 //////////////////////////////////////////////////////////////////////
32 #ifndef _AKSET_H_
33 #define _AKSET_H_
34 
37 
38 // AkSetType
39 // - An optional set type specifier which is passed into some set operations. If it is not included, SetType_Inclusion is assumed.
40 //
42 {
43  SetType_Inclusion, // <- An AkSet object with type SetType_Inclusion is a set where each element in the array
44  // represents an element in the set. An empty array represents the empty set.
45  SetType_Exclusion // <- An AkSet object with type SetType_Exclusion is an 'inverted' set, where each element in the array
46  // represents and element NOT in the set. An empty array represents the universal set.
47 };
48 
49 template<typename T>
50 struct AkSetGetKey{ static AkForceInline T& Get(T& in_item){ return in_item; } };
51 
52 // AkSet
53 //
54 // Set container type, implemented as a sorted array of unique items
55 //
56 template< typename T, class U_POOL = ArrayPoolDefault, class uGrowBy = AkGrowByPolicy_DEFAULT, class TMovePolicy = AkAssignmentMovePolicy<T>, class TComparePolicy = AkDefaultSortedKeyCompare<T> >
57 class AkSet : public AkSortedKeyArray < T, T, U_POOL, AkSetGetKey<T>, uGrowBy, TMovePolicy, TComparePolicy >
58 {
59 public:
60  bool Contains(T in_item) const { return AkSortedKeyArray < T, T, U_POOL, AkSetGetKey<T>, uGrowBy, TMovePolicy, TComparePolicy >::Exists(in_item) != NULL; }
61 };
62 
63 // AkBookmarkSet
64 //
65 // Same as AkSet, but uses the bookmark allocator for short term allocations.
66 // Example usage:
67 //
68 // AK::BookmarkAlloc::BookmarkAllocRegion mark; // scoped bookmark
69 // AkBookmarkSet<AkUInt32> mySet(AK::BookmarkAlloc::MemAlloc::GetAllocator());
70 // mySet.Set(1); // use the set ..
71 // ...
72 // // memory is freed when bookmark falls out of scope. Do not call Term();
73 //
74 template< typename T, class TMovePolicy = AkAssignmentMovePolicy<T>, class TComparePolicy = AkDefaultSortedKeyCompare<T> >
75 class AkBookmarkSet : public AkSet<T, AkPluginArrayAllocator, AkGrowByPolicy_DEFAULT, TMovePolicy, TComparePolicy>
76 {
78 public:
80  {
81  AkPluginArrayAllocator::Init(in_pAllocator);
82  }
83 
85  {
86  // The memory will get cleaned up when AK::BookmarkAlloc::BookmarkAllocRegion mark goes out of scope.
87  tBase::m_uLength = 0;
89  tBase::m_pItems = nullptr;
90  }
91 };
92 
93 // AkDisjoint
94 // - Returns true if the intersection of A and B is the empty set.
95 //
96 template< typename T, class U_POOL = ArrayPoolDefault, class uGrowBy, class TMovePolicy, class TComparePolicy >
98 {
101  while (itA != in_A.End() && itB != in_B.End())
102  {
103  if (*itA == *itB)
104  return false;
105  else if (*itA < *itB)
106  ++itA;
107  else
108  ++itB;
109  }
110  return true;
111 }
112 
113 // AkIntersect
114 // - Return true if the intersection of A and B is not the empty set.
115 //
116 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
118 {
119  return !AkDisjoint(in_A, in_B);
120 }
121 
122 // AkIsSubset
123 // - Return true if in_A is a subset of in_B
124 //
125 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
127 {
130  while (itA != in_A.End() && itB != in_B.End())
131  {
132  if (TComparePolicy::Equal(&in_A, *itA, *itB))
133  {
134  ++itA; ++itB;
135  }
136  else if (TComparePolicy::Lesser(&in_A, *itA, *itB))
137  {
138  return false;//an element of A is not in B
139  }
140  else
141  ++itB;
142  }
143  return (itA == in_A.End());
144 }
145 
146 // AkCountIntersection
147 // - Helper function to count the number of elements that are in both in_A and in_B.
148 //
149 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
151 {
152  AkUInt32 uSize = 0;
155  while (itA != in_A.End() && itB != in_B.End())
156  {
157  if (TComparePolicy::Equal(&in_A, *itA, *itB))
158  {
159  ++uSize; ++itA; ++itB;
160  }
161  else if (TComparePolicy::Lesser(&in_A, *itA, *itB))
162  {
163  ++itA;
164  }
165  else
166  {
167  ++itB;
168  }
169  }
170  return uSize;
171 }
172 
173 // AkSubtraction
174 // - In-place set subtraction ( A = A - B )
175 //
176 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy>
178 {
180  itAr = itAw = in_A.Begin();
182  while (itAr != in_A.End())
183  {
184  if (itB == in_B.End() || TComparePolicy::Lesser(&in_A, *itAr, *itB))
185  {
186  if (itAw != itAr)
187  *itAw = *itAr;
188 
189  ++itAw;
190  ++itAr;
191  }
192  else if (TComparePolicy::Equal(&in_A, *itAr, *itB))
193  {
194  ++itB;
195  ++itAr;
196  }
197  else
198  {
199  ++itB;
200  }
201  }
202  in_A.Resize((AkUInt32)(itAw.pItem - in_A.Begin().pItem));
203  return true;
204 }
205 
206 // AkIntersection
207 // - In-place set intersection ( A = A n B )
208 //
209 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
211 {
213  itAr = itAw = in_A.Begin();
215  while (itAr != in_A.End() && itB != in_B.End())
216  {
217  if (TComparePolicy::Equal(&in_A, *itAr, *itB))
218  {
219  if (itAw != itAr)
220  *itAw = *itAr;
221 
222  ++itAw;
223  ++itAr;
224  ++itB;
225  }
226  else if (TComparePolicy::Lesser(&in_A, *itAr,*itB))
227  {
228  ++itAr;
229  }
230  else
231  {
232  ++itB;
233  }
234  }
235  in_A.Resize((AkUInt32)(itAw.pItem - in_A.Begin().pItem));
236  return true;
237 }
238 
239 // AkIntersection
240 // - Out-of-place set intersection ( res = A n B )
241 //
242 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
244 {
245  out_res.RemoveAll();
246 
249  while (itA != in_A.End() && itB != in_B.End())
250  {
251  if (TComparePolicy::Equal(&in_A, *itA, *itB))
252  {
253  out_res.AddLast(*itA);
254 
255  ++itA;
256  ++itB;
257  }
258  else if (TComparePolicy::Lesser(&in_A, *itA,*itB))
259  {
260  ++itA;
261  }
262  else
263  {
264  ++itB;
265  }
266  }
267  return true;
268 }
269 
270 // AkUnion
271 // - Set union ( A = A U B ).
272 // NOTE: Preforms a memory allocation and may fail.
273 //
274 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
276 {
277  AkInt32 uSizeNeeded = io_A.Length() + in_B.Length() - AkCountIntersection(io_A, in_B);
279 
280  if (result.Resize(uSizeNeeded))
281  {
285 
286  while (itB != in_B.End() || itA != io_A.End())
287  {
288  if ( itB != in_B.End() && (itA == io_A.End() || TComparePolicy::Lesser(&io_A, *itB, *itA)))
289  {
290  *itRes = *itB;
291  ++itB;
292  }
293  else if (itB == in_B.End() || TComparePolicy::Lesser(&io_A, *itA,*itB) )
294  {
295  *itRes = *itA;
296  ++itA;
297  }
298  else //if ( *itA == *itC)
299  {
300  *itRes = *itA;
301  ++itA;
302  ++itB;
303  }
304 
305  ++itRes;
306  }
307 
308  io_A.Transfer(result);
309  return true;
310  }
311 
312  return false;
313 }
314 
316 
317 // AkIntersect
318 // - Return true if the intersection of in_A (a set of type in_typeA), and in_B (a set of type in_typeB) is not the empty set.
319 //
320 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
322 {
323  if (in_typeA == SetType_Inclusion)
324  {
325  if (in_typeB == SetType_Inclusion)
326  return !AkDisjoint(in_A, in_B);
327  else//(in_typeB == SetType_Exclusion)
328  return !AkIsSubset(in_A, in_B);
329  }
330  else//(in_typeA == SetType_Exclusion)
331  {
332  if (in_typeB == SetType_Inclusion)
333  return !AkIsSubset(in_B, in_A);
334  else//(in_typeB == SetType_Exclusion)
335  return true;//Assuming an infinite space of possible elements.
336  }
337 }
338 
339 // AkContains
340 // - Return true if the element in_item is contained in in_Set, a set of type in_type.
341 //
342 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
343 static inline bool AkContains(const AkSet<T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy>& in_Set, AkSetType in_type, T in_item)
344 {
345  return (in_type == SetType_Inclusion && in_Set.Contains(in_item)) ||
346  (in_type == SetType_Exclusion && !in_Set.Contains(in_item));
347 }
348 
349 // AkSubtraction
350 // - pseudo in-place set subtraction (A = A - B) with set type specifiers.
351 // NOTE: Memory may be allocated (in AkUnion) so prepare for failure.
352 //
353 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
355 {
356  if (in_typeA == SetType_Inclusion)
357  {
358  if (in_typeB == SetType_Inclusion)
359  return AkSubtraction(in_A, in_B);
360  else//(in_typeB == SetType_Exclusion)
361  return AkIntersection(in_A, in_B);
362  }
363  else//(in_typeA == SetType_Exclusion)
364  {
365  if (in_typeB == SetType_Inclusion)
366  return AkUnion(in_A, in_B);
367  else//(in_typeB == SetType_Exclusion)
368  return AkIntersection(in_A, in_B);
369  }
370 }
371 
372 // AkUnion
373 // - Pseudo in-place set union (A = A + B)
374 // NOTE: Memory may be allocated (in AkUnion) so prepare for failure.
375 //
376 template< typename T, class U_POOL, class uGrowBy, class TMovePolicy, class TComparePolicy >
378 {
379  if (io_typeA == SetType_Inclusion)
380  {
381  if (in_typeB == SetType_Inclusion)
382  return AkUnion(io_A, in_B);
383  else//(in_typeB == SetType_Exclusion)
384  {
386  temp.Transfer(io_A);
387  if (io_A.Copy(in_B) == AK_Success)
388  {
389  io_typeA = SetType_Exclusion;
390  AkSubtraction(io_A, temp);
391  temp.Term();
392  return true;
393  }
394  else
395  {
396  io_A.Transfer(temp);
397  return false;
398  }
399  }
400  }
401  else//(in_typeA == SetType_Exclusion)
402  {
403  if (in_typeB == SetType_Inclusion)
404  return AkSubtraction(io_A, in_B);
405  else//(in_typeB == SetType_Exclusion)
406  return AkIntersection(io_A, in_B);
407  }
408 }
409 
410 #endif
411 
static bool AkContains(const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_Set, AkSetType in_type, T in_item)
Definition: AkSet.h:343
Definition: AkSet.h:58
AKRESULT Copy(const AkArray< T, const T &, ArrayPoolDefault, AkGrowByPolicy_DEFAULT, AkAssignmentMovePolicy< T > > &in_rSource)
Definition: AkArray.h:867
static bool AkIntersection(AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_A, const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_B)
Definition: AkSet.h:210
static AkUInt32 AkCountIntersection(const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_A, const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_B)
Definition: AkSet.h:150
static bool AkUnion(AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &io_A, const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_B)
Definition: AkSet.h:275
int32_t AkInt32
Signed 32-bit integer
@ SetType_Exclusion
Definition: AkSet.h:45
AkForceInline void Init(AK::IAkPluginMemAlloc *in_pAllocator)
AkSetType
Definition: AkSet.h:42
bool Resize(AkUInt32 in_uiSize)
Resize the array to the specified size.
Definition: AkArray.h:824
AkBookmarkSet(AK::IAkPluginMemAlloc *in_pAllocator)
Definition: AkSet.h:79
@ SetType_Inclusion
Definition: AkSet.h:43
Iterator End() const
Returns the iterator to the end of the array
Definition: AkArray.h:354
#define NULL
Definition: AkTypedefs.h:33
~AkBookmarkSet()
Definition: AkSet.h:84
void Transfer(AkArray< T, const T &, ArrayPoolDefault, AkGrowByPolicy_DEFAULT, AkAssignmentMovePolicy< T > > &in_rSource)
Definition: AkArray.h:854
static bool AkSubtraction(AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_A, const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_B)
Definition: AkSet.h:177
AkUInt32 m_ulReserved
how many we can have at most (currently allocated).
Definition: AkArray.h:884
Iterator Begin() const
Returns the iterator to the first item of the array, will be End() if the array is empty.
Definition: AkArray.h:346
AkForceInline AkUInt32 Length() const
Returns the numbers of items in the array.
Definition: AkArray.h:568
static bool AkIsSubset(const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_A, const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_B)
Definition: AkSet.h:126
static bool AkDisjoint(const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_A, const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_B)
Definition: AkSet.h:97
uint32_t AkUInt32
Unsigned 32-bit integer
void Term()
Term the array. Must be called before destroying the object.
Definition: AkArray.h:556
@ AK_Success
The operation was successful.
Definition: AkEnums.h:34
bool Contains(T in_item) const
Definition: AkSet.h:60
#define AkForceInline
Definition: AkTypes.h:63
AkSet< AkUniqueID, ArrayPoolDefault > AkUniqueIDSet
Definition: AkSet.h:315
static AkForceInline T & Get(T &in_item)
Definition: AkSet.h:50
static bool AkIntersect(const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_A, const AkSet< T, U_POOL, uGrowBy, TMovePolicy, TComparePolicy > &in_B)
Definition: AkSet.h:117

このページはお役に立ちましたか?

サポートは必要ですか?

ご質問や問題、ご不明点はございますか?お気軽にお問い合わせください。

サポートページをご確認ください

あなたのプロジェクトについて教えてください。ご不明な点はありませんか。

プロジェクトを登録していただくことで、ご利用開始のサポートをいたします。

Wwiseからはじめよう