xref: /aosp_15_r20/external/deqp/framework/delibs/depool/dePoolMultiSet.h (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker #ifndef _DEPOOLMULTISET_H
2*35238bceSAndroid Build Coastguard Worker #define _DEPOOLMULTISET_H
3*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  * drawElements Memory Pool Library
5*35238bceSAndroid Build Coastguard Worker  * --------------------------------
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
8*35238bceSAndroid Build Coastguard Worker  *
9*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
10*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
11*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
14*35238bceSAndroid Build Coastguard Worker  *
15*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
16*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
17*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
19*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
20*35238bceSAndroid Build Coastguard Worker  *
21*35238bceSAndroid Build Coastguard Worker  *//*!
22*35238bceSAndroid Build Coastguard Worker  * \file
23*35238bceSAndroid Build Coastguard Worker  * \brief Memory pool multiset class.
24*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "deDefs.h"
27*35238bceSAndroid Build Coastguard Worker #include "deMemPool.h"
28*35238bceSAndroid Build Coastguard Worker #include "dePoolHash.h"
29*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker DE_BEGIN_EXTERN_C
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker void dePoolMultiSet_selfTest(void);
34*35238bceSAndroid Build Coastguard Worker 
35*35238bceSAndroid Build Coastguard Worker DE_END_EXTERN_C
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
38*35238bceSAndroid Build Coastguard Worker  * \brief Declare a template pool multiset class interface.
39*35238bceSAndroid Build Coastguard Worker  * \param TYPENAME    Type name of the declared multiset.
40*35238bceSAndroid Build Coastguard Worker  * \param KEYTYPE    Type of the key.
41*35238bceSAndroid Build Coastguard Worker  *
42*35238bceSAndroid Build Coastguard Worker  * This macro declares the interface for a multiset. For the implementation
43*35238bceSAndroid Build Coastguard Worker  * of the multiset, see DE_IMPLEMENT_POOL_MULTISET. Usually this macro is put
44*35238bceSAndroid Build Coastguard Worker  * into the header file and the implementation macro is put in some .c file.
45*35238bceSAndroid Build Coastguard Worker  *
46*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Detailed description.
47*35238bceSAndroid Build Coastguard Worker  *
48*35238bceSAndroid Build Coastguard Worker  * The functions for operating the multiset are:
49*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Figure out how to comment these in Doxygen-style.
50*35238bceSAndroid Build Coastguard Worker  *
51*35238bceSAndroid Build Coastguard Worker  * \code
52*35238bceSAndroid Build Coastguard Worker  * MultiSet* MultiSet_create            (deMemPool* pool);
53*35238bceSAndroid Build Coastguard Worker  * int       MultiSet_getNumElements    (const MultiSet* set);
54*35238bceSAndroid Build Coastguard Worker  * bool    MultiSet_exists            (const MultiSet* set, Key key);
55*35238bceSAndroid Build Coastguard Worker  * bool    MultiSet_insert            (MultiSet* set, Key key);
56*35238bceSAndroid Build Coastguard Worker  * void      MultiSet_delete            (MultiSet* set, Key key);
57*35238bceSAndroid Build Coastguard Worker  * int       MultiSet_getKeyCount       (const MultiSet* set, Key key);
58*35238bceSAndroid Build Coastguard Worker  * bool    MultiSet_setKeyCount       (MultiSet* set, Key key, int count);
59*35238bceSAndroid Build Coastguard Worker  * \endcode
60*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
61*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_MULTISET(TYPENAME, KEYTYPE)                                    \
62*35238bceSAndroid Build Coastguard Worker                                                                                        \
63*35238bceSAndroid Build Coastguard Worker     DE_DECLARE_POOL_HASH(TYPENAME##Hash, KEYTYPE, int);                                \
64*35238bceSAndroid Build Coastguard Worker                                                                                        \
65*35238bceSAndroid Build Coastguard Worker     typedef struct TYPENAME##_s                                                        \
66*35238bceSAndroid Build Coastguard Worker     {                                                                                  \
67*35238bceSAndroid Build Coastguard Worker         deMemPool *pool;                                                               \
68*35238bceSAndroid Build Coastguard Worker         int numElements;                                                               \
69*35238bceSAndroid Build Coastguard Worker         TYPENAME##Hash *hash;                                                          \
70*35238bceSAndroid Build Coastguard Worker     } TYPENAME; /* NOLINT(TYPENAME) */                                                 \
71*35238bceSAndroid Build Coastguard Worker                                                                                        \
72*35238bceSAndroid Build Coastguard Worker     TYPENAME *TYPENAME##_create(deMemPool *pool);                                      \
73*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_reset(DE_PTR_TYPE(TYPENAME) set);                                  \
74*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_setKeyCount(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key, int newCount); \
75*35238bceSAndroid Build Coastguard Worker                                                                                        \
76*35238bceSAndroid Build Coastguard Worker     DE_INLINE int TYPENAME##_getNumElements(const TYPENAME *set)                       \
77*35238bceSAndroid Build Coastguard Worker     {                                                                                  \
78*35238bceSAndroid Build Coastguard Worker         return set->numElements;                                                       \
79*35238bceSAndroid Build Coastguard Worker     }                                                                                  \
80*35238bceSAndroid Build Coastguard Worker                                                                                        \
81*35238bceSAndroid Build Coastguard Worker     DE_INLINE int TYPENAME##_getKeyCount(const TYPENAME *set, KEYTYPE key)             \
82*35238bceSAndroid Build Coastguard Worker     {                                                                                  \
83*35238bceSAndroid Build Coastguard Worker         int *countPtr = TYPENAME##Hash_find(set->hash, key);                           \
84*35238bceSAndroid Build Coastguard Worker         int count     = countPtr ? *countPtr : 0;                                      \
85*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(count > 0 || !countPtr);                                             \
86*35238bceSAndroid Build Coastguard Worker         return count;                                                                  \
87*35238bceSAndroid Build Coastguard Worker     }                                                                                  \
88*35238bceSAndroid Build Coastguard Worker                                                                                        \
89*35238bceSAndroid Build Coastguard Worker     DE_INLINE bool TYPENAME##_exists(const TYPENAME *set, KEYTYPE key)                 \
90*35238bceSAndroid Build Coastguard Worker     {                                                                                  \
91*35238bceSAndroid Build Coastguard Worker         return (TYPENAME##_getKeyCount(set, key) > 0);                                 \
92*35238bceSAndroid Build Coastguard Worker     }                                                                                  \
93*35238bceSAndroid Build Coastguard Worker                                                                                        \
94*35238bceSAndroid Build Coastguard Worker     DE_INLINE bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key)           \
95*35238bceSAndroid Build Coastguard Worker     {                                                                                  \
96*35238bceSAndroid Build Coastguard Worker         int oldCount = TYPENAME##_getKeyCount(set, key);                               \
97*35238bceSAndroid Build Coastguard Worker         return TYPENAME##_setKeyCount(set, key, oldCount + 1);                         \
98*35238bceSAndroid Build Coastguard Worker     }                                                                                  \
99*35238bceSAndroid Build Coastguard Worker                                                                                        \
100*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##_delete(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key)           \
101*35238bceSAndroid Build Coastguard Worker     {                                                                                  \
102*35238bceSAndroid Build Coastguard Worker         int oldCount = TYPENAME##_getKeyCount(set, key);                               \
103*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(oldCount > 0);                                                       \
104*35238bceSAndroid Build Coastguard Worker         TYPENAME##_setKeyCount(set, key, oldCount - 1);                                \
105*35238bceSAndroid Build Coastguard Worker     }                                                                                  \
106*35238bceSAndroid Build Coastguard Worker                                                                                        \
107*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##DeclareUnused_s                                                   \
108*35238bceSAndroid Build Coastguard Worker     {                                                                                  \
109*35238bceSAndroid Build Coastguard Worker         int unused;                                                                    \
110*35238bceSAndroid Build Coastguard Worker     }
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
113*35238bceSAndroid Build Coastguard Worker  * \brief Implement a template pool multiset class.
114*35238bceSAndroid Build Coastguard Worker  * \param TYPENAME    Type name of the declared multiset.
115*35238bceSAndroid Build Coastguard Worker  * \param KEYTYPE    Type of the key.
116*35238bceSAndroid Build Coastguard Worker  * \param HASHFUNC    Function used for hashing the key.
117*35238bceSAndroid Build Coastguard Worker  * \param CMPFUNC    Function used for exact matching of the keys.
118*35238bceSAndroid Build Coastguard Worker  *
119*35238bceSAndroid Build Coastguard Worker  * This macro has implements the set declared with DE_DECLARE_POOL_MULTISET.
120*35238bceSAndroid Build Coastguard Worker  * Usually this macro should be used from a .c file, since the macro expands
121*35238bceSAndroid Build Coastguard Worker  * into multiple functions. The TYPENAME and KEYTYPE parameters
122*35238bceSAndroid Build Coastguard Worker  * must match those of the declare macro.
123*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
124*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_MULTISET(TYPENAME, KEYTYPE, HASHFUNC, CMPFUNC)              \
125*35238bceSAndroid Build Coastguard Worker                                                                                       \
126*35238bceSAndroid Build Coastguard Worker     DE_IMPLEMENT_POOL_HASH(TYPENAME##Hash, KEYTYPE, int, HASHFUNC, CMPFUNC);          \
127*35238bceSAndroid Build Coastguard Worker                                                                                       \
128*35238bceSAndroid Build Coastguard Worker     TYPENAME *TYPENAME##_create(deMemPool *pool)                                      \
129*35238bceSAndroid Build Coastguard Worker     {                                                                                 \
130*35238bceSAndroid Build Coastguard Worker         /* Alloc struct. */                                                           \
131*35238bceSAndroid Build Coastguard Worker         DE_PTR_TYPE(TYPENAME) set = DE_POOL_NEW(pool, TYPENAME);                      \
132*35238bceSAndroid Build Coastguard Worker         if (!set)                                                                     \
133*35238bceSAndroid Build Coastguard Worker             return DE_NULL;                                                           \
134*35238bceSAndroid Build Coastguard Worker                                                                                       \
135*35238bceSAndroid Build Coastguard Worker         /* Init. */                                                                   \
136*35238bceSAndroid Build Coastguard Worker         memset(set, 0, sizeof(TYPENAME));                                             \
137*35238bceSAndroid Build Coastguard Worker         set->pool = pool;                                                             \
138*35238bceSAndroid Build Coastguard Worker                                                                                       \
139*35238bceSAndroid Build Coastguard Worker         set->hash = TYPENAME##Hash_create(pool);                                      \
140*35238bceSAndroid Build Coastguard Worker                                                                                       \
141*35238bceSAndroid Build Coastguard Worker         return set;                                                                   \
142*35238bceSAndroid Build Coastguard Worker     }                                                                                 \
143*35238bceSAndroid Build Coastguard Worker                                                                                       \
144*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_reset(DE_PTR_TYPE(TYPENAME) set)                                  \
145*35238bceSAndroid Build Coastguard Worker     {                                                                                 \
146*35238bceSAndroid Build Coastguard Worker         TYPENAME##Hash_reset(set->hash);                                              \
147*35238bceSAndroid Build Coastguard Worker         set->numElements = 0;                                                         \
148*35238bceSAndroid Build Coastguard Worker     }                                                                                 \
149*35238bceSAndroid Build Coastguard Worker                                                                                       \
150*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_setKeyCount(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key, int newCount) \
151*35238bceSAndroid Build Coastguard Worker     {                                                                                 \
152*35238bceSAndroid Build Coastguard Worker         int *countPtr = TYPENAME##Hash_find(set->hash, key);                          \
153*35238bceSAndroid Build Coastguard Worker         int oldCount  = countPtr ? *countPtr : 0;                                     \
154*35238bceSAndroid Build Coastguard Worker                                                                                       \
155*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(oldCount > 0 || !countPtr);                                         \
156*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(newCount >= 0);                                                     \
157*35238bceSAndroid Build Coastguard Worker         set->numElements += (newCount - oldCount);                                    \
158*35238bceSAndroid Build Coastguard Worker                                                                                       \
159*35238bceSAndroid Build Coastguard Worker         if (newCount == 0 && countPtr)                                                \
160*35238bceSAndroid Build Coastguard Worker             TYPENAME##Hash_delete(set->hash, key);                                    \
161*35238bceSAndroid Build Coastguard Worker         else if (newCount > 0 && countPtr)                                            \
162*35238bceSAndroid Build Coastguard Worker             *countPtr = newCount;                                                     \
163*35238bceSAndroid Build Coastguard Worker         else if (newCount > 0)                                                        \
164*35238bceSAndroid Build Coastguard Worker             return TYPENAME##Hash_insert(set->hash, key, newCount);                   \
165*35238bceSAndroid Build Coastguard Worker         return true;                                                                  \
166*35238bceSAndroid Build Coastguard Worker     }                                                                                 \
167*35238bceSAndroid Build Coastguard Worker                                                                                       \
168*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##ImplementUnused_s                                                \
169*35238bceSAndroid Build Coastguard Worker     {                                                                                 \
170*35238bceSAndroid Build Coastguard Worker         int unused;                                                                   \
171*35238bceSAndroid Build Coastguard Worker     }
172*35238bceSAndroid Build Coastguard Worker 
173*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
174*35238bceSAndroid Build Coastguard Worker  * \brief Declare set-wise operations for a multiset template.
175*35238bceSAndroid Build Coastguard Worker  * \param TYPENAME    Type name of the declared set.
176*35238bceSAndroid Build Coastguard Worker  * \param KEYTYPE    Type of the key.
177*35238bceSAndroid Build Coastguard Worker  *
178*35238bceSAndroid Build Coastguard Worker  * This macro declares union and intersection operations for a multiset.
179*35238bceSAndroid Build Coastguard Worker  * For implementation see DE_IMPLEMENT_POOL_MULTISET_UNION_INTERSECT.
180*35238bceSAndroid Build Coastguard Worker  *
181*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Detailed description.
182*35238bceSAndroid Build Coastguard Worker  *
183*35238bceSAndroid Build Coastguard Worker  * The functions for operating the set are:
184*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Figure out how to comment these in Doxygen-style.
185*35238bceSAndroid Build Coastguard Worker  *
186*35238bceSAndroid Build Coastguard Worker  * \code
187*35238bceSAndroid Build Coastguard Worker  * bool    MultiSet_union                (Set* to, const Set* a, const Set* b);
188*35238bceSAndroid Build Coastguard Worker  * bool    MultiSet_unionInplace        (Set* a, const Set* b);
189*35238bceSAndroid Build Coastguard Worker  * bool    MultiSet_intersect            (Set* to, const Set* a, const Set* b);
190*35238bceSAndroid Build Coastguard Worker  * void        MultiSet_intersectInplace    (Set* a, const Set* b);
191*35238bceSAndroid Build Coastguard Worker  * bool   MultiSet_sum                (Set* to, const Set* a, const Set* b);
192*35238bceSAndroid Build Coastguard Worker  * bool   MultiSet_sumInplace            (Set* a, const Set* b);
193*35238bceSAndroid Build Coastguard Worker  * bool   MultiSet_difference            (Set* to, const Set* a, const Set* b);
194*35238bceSAndroid Build Coastguard Worker  * void        MultiSet_differenceInplace    (Set* a, const Set* b);
195*35238bceSAndroid Build Coastguard Worker  * \endcode
196*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
197*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_MULTISET_SETWISE_OPERATIONS(TYPENAME)                                   \
198*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_union(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b);      \
199*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_unionInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b);                   \
200*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_intersect(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b);  \
201*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_intersectInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b);               \
202*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_sum(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b);        \
203*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_sumInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b);                     \
204*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_difference(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b); \
205*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_differenceInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b);              \
206*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##SetwiseDeclareUnused_s                                                     \
207*35238bceSAndroid Build Coastguard Worker     {                                                                                           \
208*35238bceSAndroid Build Coastguard Worker         int unused;                                                                             \
209*35238bceSAndroid Build Coastguard Worker     }
210*35238bceSAndroid Build Coastguard Worker 
211*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_MULTISET_SETWISE_OPERATIONS(TYPENAME, KEYTYPE)                                           \
212*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_union(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b)                          \
213*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
214*35238bceSAndroid Build Coastguard Worker         TYPENAME##_reset(to);                                                                                      \
215*35238bceSAndroid Build Coastguard Worker         return TYPENAME##_unionInplace(to, a) && TYPENAME##_unionInplace(to, b);                                   \
216*35238bceSAndroid Build Coastguard Worker     }                                                                                                              \
217*35238bceSAndroid Build Coastguard Worker                                                                                                                    \
218*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_unionInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b)                                       \
219*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
220*35238bceSAndroid Build Coastguard Worker         TYPENAME##HashIter iter;                                                                                   \
221*35238bceSAndroid Build Coastguard Worker         for (TYPENAME##HashIter_init(b, &iter); TYPENAME##HashIter_hasItem(&iter); TYPENAME##HashIter_next(&iter)) \
222*35238bceSAndroid Build Coastguard Worker         {                                                                                                          \
223*35238bceSAndroid Build Coastguard Worker             KEYTYPE key = TYPENAME##HashIter_getKey(&iter);                                                        \
224*35238bceSAndroid Build Coastguard Worker             int bCount  = TYPENAME##HashIter_getValue(&iter);                                                      \
225*35238bceSAndroid Build Coastguard Worker             int aCount  = TYPENAME##_getKeyCount(a, key);                                                          \
226*35238bceSAndroid Build Coastguard Worker             int count   = deMax32(aCount, bCount);                                                                 \
227*35238bceSAndroid Build Coastguard Worker             if (bCount && !TYPENAME##_setKeyCount(a, key, aCount + bCount))                                        \
228*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                      \
229*35238bceSAndroid Build Coastguard Worker         }                                                                                                          \
230*35238bceSAndroid Build Coastguard Worker         return true;                                                                                               \
231*35238bceSAndroid Build Coastguard Worker     }                                                                                                              \
232*35238bceSAndroid Build Coastguard Worker                                                                                                                    \
233*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_intersect(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b)                      \
234*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
235*35238bceSAndroid Build Coastguard Worker         TYPENAME##HashIter iter;                                                                                   \
236*35238bceSAndroid Build Coastguard Worker         TYPENAME##_reset(to);                                                                                      \
237*35238bceSAndroid Build Coastguard Worker         for (TYPENAME##HashIter_init(a, &iter); TYPENAME##HashIter_hasItem(&iter); TYPENAME##HashIter_next(&iter)) \
238*35238bceSAndroid Build Coastguard Worker         {                                                                                                          \
239*35238bceSAndroid Build Coastguard Worker             KEYTYPE key = TYPENAME##HashIter_getKey(&iter);                                                        \
240*35238bceSAndroid Build Coastguard Worker             int aCount  = TYPENAME##HashIter_getValue(&iter);                                                      \
241*35238bceSAndroid Build Coastguard Worker             int bCount  = TYPENAME##_getKeyValue(b, key);                                                          \
242*35238bceSAndroid Build Coastguard Worker             int count   = deMin32(aCount, bCount);                                                                 \
243*35238bceSAndroid Build Coastguard Worker             if (count && !TYPENAME##_setKeyCount(to, key, count))                                                  \
244*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                      \
245*35238bceSAndroid Build Coastguard Worker         }                                                                                                          \
246*35238bceSAndroid Build Coastguard Worker         return true;                                                                                               \
247*35238bceSAndroid Build Coastguard Worker     }                                                                                                              \
248*35238bceSAndroid Build Coastguard Worker                                                                                                                    \
249*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_intersectInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b)                                   \
250*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
251*35238bceSAndroid Build Coastguard Worker         DE_FATAL("Not implemented.");                                                                              \
252*35238bceSAndroid Build Coastguard Worker     }                                                                                                              \
253*35238bceSAndroid Build Coastguard Worker                                                                                                                    \
254*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_sum(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b)                            \
255*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
256*35238bceSAndroid Build Coastguard Worker         TYPENAME##_reset(to);                                                                                      \
257*35238bceSAndroid Build Coastguard Worker         return TYPENAME##_sumInplace(to, a) && TYPENAME##_sumInplace(to, b);                                       \
258*35238bceSAndroid Build Coastguard Worker     }                                                                                                              \
259*35238bceSAndroid Build Coastguard Worker                                                                                                                    \
260*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_sumInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b)                                         \
261*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
262*35238bceSAndroid Build Coastguard Worker         TYPENAME##HashIter iter;                                                                                   \
263*35238bceSAndroid Build Coastguard Worker         for (TYPENAME##HashIter_init(b, &iter); TYPENAME##HashIter_hasItem(&iter); TYPENAME##HashIter_next(&iter)) \
264*35238bceSAndroid Build Coastguard Worker         {                                                                                                          \
265*35238bceSAndroid Build Coastguard Worker             KEYTYPE key = TYPENAME##HashIter_getKey(&iter);                                                        \
266*35238bceSAndroid Build Coastguard Worker             int aCount  = TYPENAME##_getKeyValue(a, key);                                                          \
267*35238bceSAndroid Build Coastguard Worker             int bCount  = TYPENAME##HashIter_getValue(&iter);                                                      \
268*35238bceSAndroid Build Coastguard Worker             int count   = aCount + bCount;                                                                         \
269*35238bceSAndroid Build Coastguard Worker             if (!TYPENAME##_setKeyCount(a, key, count))                                                            \
270*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                      \
271*35238bceSAndroid Build Coastguard Worker         }                                                                                                          \
272*35238bceSAndroid Build Coastguard Worker     }                                                                                                              \
273*35238bceSAndroid Build Coastguard Worker                                                                                                                    \
274*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_difference(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b)                     \
275*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
276*35238bceSAndroid Build Coastguard Worker         TYPENAME##HashIter iter;                                                                                   \
277*35238bceSAndroid Build Coastguard Worker         TYPENAME##_reset(to);                                                                                      \
278*35238bceSAndroid Build Coastguard Worker         for (TYPENAME##HashIter_init(a, &iter); TYPENAME##HashIter_hasItem(&iter); TYPENAME##HashIter_next(&iter)) \
279*35238bceSAndroid Build Coastguard Worker         {                                                                                                          \
280*35238bceSAndroid Build Coastguard Worker             KEYTYPE key = TYPENAME##HashIter_getKey(&iter);                                                        \
281*35238bceSAndroid Build Coastguard Worker             int aCount  = TYPENAME##HashIter_getValue(&iter);                                                      \
282*35238bceSAndroid Build Coastguard Worker             int bCount  = TYPENAME##_getKeyValue(b, key);                                                          \
283*35238bceSAndroid Build Coastguard Worker             int count   = deMax32(0, aCount - bCount);                                                             \
284*35238bceSAndroid Build Coastguard Worker             if (count && !TYPENAME##_setKeyCount(to, key, count))                                                  \
285*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                      \
286*35238bceSAndroid Build Coastguard Worker         }                                                                                                          \
287*35238bceSAndroid Build Coastguard Worker         return true;                                                                                               \
288*35238bceSAndroid Build Coastguard Worker     }                                                                                                              \
289*35238bceSAndroid Build Coastguard Worker                                                                                                                    \
290*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_differenceInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b)                                  \
291*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
292*35238bceSAndroid Build Coastguard Worker         DE_FATAL("Not implemented.");                                                                              \
293*35238bceSAndroid Build Coastguard Worker     }                                                                                                              \
294*35238bceSAndroid Build Coastguard Worker                                                                                                                    \
295*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##SetwiseImplementUnused_s                                                                      \
296*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
297*35238bceSAndroid Build Coastguard Worker         int unused;                                                                                                \
298*35238bceSAndroid Build Coastguard Worker     }
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker #endif /* _DEPOOLMULTISET_H */
301