xref: /aosp_15_r20/external/deqp/framework/delibs/depool/dePoolSet.h (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker #ifndef _DEPOOLSET_H
2*35238bceSAndroid Build Coastguard Worker #define _DEPOOLSET_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 set 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 "dePoolArray.h"
29*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker #include <string.h> /* memset() */
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker enum
34*35238bceSAndroid Build Coastguard Worker {
35*35238bceSAndroid Build Coastguard Worker     DE_SET_ELEMENTS_PER_SLOT = 4
36*35238bceSAndroid Build Coastguard Worker };
37*35238bceSAndroid Build Coastguard Worker 
38*35238bceSAndroid Build Coastguard Worker DE_BEGIN_EXTERN_C
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker void dePoolSet_selfTest(void);
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker DE_END_EXTERN_C
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
45*35238bceSAndroid Build Coastguard Worker  * \brief Declare a template pool set class interface.
46*35238bceSAndroid Build Coastguard Worker  * \param TYPENAME    Type name of the declared set.
47*35238bceSAndroid Build Coastguard Worker  * \param KEYTYPE    Type of the key.
48*35238bceSAndroid Build Coastguard Worker  *
49*35238bceSAndroid Build Coastguard Worker  * This macro declares the interface for a set. For the implementation of
50*35238bceSAndroid Build Coastguard Worker  * the set, see DE_IMPLEMENT_POOL_HASH. Usually this macro is put into the
51*35238bceSAndroid Build Coastguard Worker  * header file and the implementation macro is put in some .c file.
52*35238bceSAndroid Build Coastguard Worker  *
53*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Detailed description.
54*35238bceSAndroid Build Coastguard Worker  *
55*35238bceSAndroid Build Coastguard Worker  * The functions for operating the set are:
56*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Figure out how to comment these in Doxygen-style.
57*35238bceSAndroid Build Coastguard Worker  *
58*35238bceSAndroid Build Coastguard Worker  * \code
59*35238bceSAndroid Build Coastguard Worker  * Set*     Set_create            (deMemPool* pool);
60*35238bceSAndroid Build Coastguard Worker  * int      Set_getNumElements    (const Set* array);
61*35238bceSAndroid Build Coastguard Worker  * bool   Set_exists            (const Set* array, Key key);
62*35238bceSAndroid Build Coastguard Worker  * bool   Set_insert            (Set* array, Key key);
63*35238bceSAndroid Build Coastguard Worker  * void     Set_delete            (Set* array, Key key);
64*35238bceSAndroid Build Coastguard Worker  * \endcode
65*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
66*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_SET(TYPENAME, KEYTYPE)                                                         \
67*35238bceSAndroid Build Coastguard Worker                                                                                                        \
68*35238bceSAndroid Build Coastguard Worker     typedef struct TYPENAME##Slot_s TYPENAME##Slot;                                                    \
69*35238bceSAndroid Build Coastguard Worker                                                                                                        \
70*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##Slot_s                                                                            \
71*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
72*35238bceSAndroid Build Coastguard Worker         int numUsed;                                                                                   \
73*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *nextSlot;                                                                      \
74*35238bceSAndroid Build Coastguard Worker         KEYTYPE keys[DE_SET_ELEMENTS_PER_SLOT];                                                        \
75*35238bceSAndroid Build Coastguard Worker     };                                                                                                 \
76*35238bceSAndroid Build Coastguard Worker                                                                                                        \
77*35238bceSAndroid Build Coastguard Worker     typedef struct TYPENAME##_s                                                                        \
78*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
79*35238bceSAndroid Build Coastguard Worker         deMemPool *pool;                                                                               \
80*35238bceSAndroid Build Coastguard Worker         int numElements;                                                                               \
81*35238bceSAndroid Build Coastguard Worker                                                                                                        \
82*35238bceSAndroid Build Coastguard Worker         int slotTableSize;                                                                             \
83*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot **slotTable;                                                                    \
84*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *slotFreeList;                                                                  \
85*35238bceSAndroid Build Coastguard Worker     } TYPENAME; /* NOLINT(TYPENAME) */                                                                 \
86*35238bceSAndroid Build Coastguard Worker                                                                                                        \
87*35238bceSAndroid Build Coastguard Worker     typedef struct TYPENAME##Iter_s                                                                    \
88*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
89*35238bceSAndroid Build Coastguard Worker         const TYPENAME *hash;                                                                          \
90*35238bceSAndroid Build Coastguard Worker         int curSlotIndex;                                                                              \
91*35238bceSAndroid Build Coastguard Worker         const TYPENAME##Slot *curSlot;                                                                 \
92*35238bceSAndroid Build Coastguard Worker         int curElemIndex;                                                                              \
93*35238bceSAndroid Build Coastguard Worker     } TYPENAME##Iter;                                                                                  \
94*35238bceSAndroid Build Coastguard Worker                                                                                                        \
95*35238bceSAndroid Build Coastguard Worker     TYPENAME *TYPENAME##_create(deMemPool *pool);                                                      \
96*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_reset(DE_PTR_TYPE(TYPENAME) set);                                                  \
97*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_reserve(DE_PTR_TYPE(TYPENAME) set, int capacity);                                  \
98*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_exists(const TYPENAME *set, KEYTYPE key);                                          \
99*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key);                                    \
100*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_delete(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key);                                    \
101*35238bceSAndroid Build Coastguard Worker                                                                                                        \
102*35238bceSAndroid Build Coastguard Worker     DE_INLINE int TYPENAME##_getNumElements(const TYPENAME *set) DE_UNUSED_FUNCTION;                   \
103*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##Iter_init(const TYPENAME *hash, TYPENAME##Iter *iter) DE_UNUSED_FUNCTION; \
104*35238bceSAndroid Build Coastguard Worker     DE_INLINE bool TYPENAME##Iter_hasItem(const TYPENAME##Iter *iter) DE_UNUSED_FUNCTION;              \
105*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##Iter_next(TYPENAME##Iter *iter) DE_UNUSED_FUNCTION;                       \
106*35238bceSAndroid Build Coastguard Worker     DE_INLINE KEYTYPE TYPENAME##Iter_getKey(const TYPENAME##Iter *iter) DE_UNUSED_FUNCTION;            \
107*35238bceSAndroid Build Coastguard Worker     DE_INLINE bool TYPENAME##_safeInsert(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key) DE_UNUSED_FUNCTION;   \
108*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##_safeDelete(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key) DE_UNUSED_FUNCTION;   \
109*35238bceSAndroid Build Coastguard Worker                                                                                                        \
110*35238bceSAndroid Build Coastguard Worker     DE_INLINE int TYPENAME##_getNumElements(const TYPENAME *set)                                       \
111*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
112*35238bceSAndroid Build Coastguard Worker         return set->numElements;                                                                       \
113*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
114*35238bceSAndroid Build Coastguard Worker                                                                                                        \
115*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##Iter_init(const TYPENAME *hash, TYPENAME##Iter *iter)                     \
116*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
117*35238bceSAndroid Build Coastguard Worker         iter->hash         = hash;                                                                     \
118*35238bceSAndroid Build Coastguard Worker         iter->curSlotIndex = 0;                                                                        \
119*35238bceSAndroid Build Coastguard Worker         iter->curSlot      = DE_NULL;                                                                  \
120*35238bceSAndroid Build Coastguard Worker         iter->curElemIndex = 0;                                                                        \
121*35238bceSAndroid Build Coastguard Worker         if (TYPENAME##_getNumElements(hash) > 0)                                                       \
122*35238bceSAndroid Build Coastguard Worker         {                                                                                              \
123*35238bceSAndroid Build Coastguard Worker             int slotTableSize = hash->slotTableSize;                                                   \
124*35238bceSAndroid Build Coastguard Worker             int slotNdx       = 0;                                                                     \
125*35238bceSAndroid Build Coastguard Worker             while (slotNdx < slotTableSize)                                                            \
126*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
127*35238bceSAndroid Build Coastguard Worker                 if (hash->slotTable[slotNdx])                                                          \
128*35238bceSAndroid Build Coastguard Worker                     break;                                                                             \
129*35238bceSAndroid Build Coastguard Worker                 slotNdx++;                                                                             \
130*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
131*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(slotNdx < slotTableSize);                                                        \
132*35238bceSAndroid Build Coastguard Worker             iter->curSlotIndex = slotNdx;                                                              \
133*35238bceSAndroid Build Coastguard Worker             iter->curSlot      = hash->slotTable[slotNdx];                                             \
134*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(iter->curSlot);                                                                  \
135*35238bceSAndroid Build Coastguard Worker         }                                                                                              \
136*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
137*35238bceSAndroid Build Coastguard Worker                                                                                                        \
138*35238bceSAndroid Build Coastguard Worker     DE_INLINE bool TYPENAME##Iter_hasItem(const TYPENAME##Iter *iter)                                  \
139*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
140*35238bceSAndroid Build Coastguard Worker         return (iter->curSlot != DE_NULL);                                                             \
141*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
142*35238bceSAndroid Build Coastguard Worker                                                                                                        \
143*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##Iter_next(TYPENAME##Iter *iter)                                           \
144*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
145*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(TYPENAME##Iter_hasItem(iter));                                                       \
146*35238bceSAndroid Build Coastguard Worker         if (++iter->curElemIndex == iter->curSlot->numUsed)                                            \
147*35238bceSAndroid Build Coastguard Worker         {                                                                                              \
148*35238bceSAndroid Build Coastguard Worker             iter->curElemIndex = 0;                                                                    \
149*35238bceSAndroid Build Coastguard Worker             if (iter->curSlot->nextSlot)                                                               \
150*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
151*35238bceSAndroid Build Coastguard Worker                 iter->curSlot = iter->curSlot->nextSlot;                                               \
152*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
153*35238bceSAndroid Build Coastguard Worker             else                                                                                       \
154*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
155*35238bceSAndroid Build Coastguard Worker                 const TYPENAME *hash = iter->hash;                                                     \
156*35238bceSAndroid Build Coastguard Worker                 int curSlotIndex     = iter->curSlotIndex;                                             \
157*35238bceSAndroid Build Coastguard Worker                 int slotTableSize    = hash->slotTableSize;                                            \
158*35238bceSAndroid Build Coastguard Worker                 while (++curSlotIndex < slotTableSize)                                                 \
159*35238bceSAndroid Build Coastguard Worker                 {                                                                                      \
160*35238bceSAndroid Build Coastguard Worker                     if (hash->slotTable[curSlotIndex])                                                 \
161*35238bceSAndroid Build Coastguard Worker                         break;                                                                         \
162*35238bceSAndroid Build Coastguard Worker                 }                                                                                      \
163*35238bceSAndroid Build Coastguard Worker                 iter->curSlotIndex = curSlotIndex;                                                     \
164*35238bceSAndroid Build Coastguard Worker                 if (curSlotIndex < slotTableSize)                                                      \
165*35238bceSAndroid Build Coastguard Worker                     iter->curSlot = hash->slotTable[curSlotIndex];                                     \
166*35238bceSAndroid Build Coastguard Worker                 else                                                                                   \
167*35238bceSAndroid Build Coastguard Worker                     iter->curSlot = DE_NULL;                                                           \
168*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
169*35238bceSAndroid Build Coastguard Worker         }                                                                                              \
170*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
171*35238bceSAndroid Build Coastguard Worker                                                                                                        \
172*35238bceSAndroid Build Coastguard Worker     DE_INLINE KEYTYPE TYPENAME##Iter_getKey(const TYPENAME##Iter *iter)                                \
173*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
174*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(TYPENAME##Iter_hasItem(iter));                                                       \
175*35238bceSAndroid Build Coastguard Worker         return iter->curSlot->keys[iter->curElemIndex];                                                \
176*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
177*35238bceSAndroid Build Coastguard Worker                                                                                                        \
178*35238bceSAndroid Build Coastguard Worker     DE_INLINE bool TYPENAME##_safeInsert(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key)                       \
179*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
180*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(set);                                                                                \
181*35238bceSAndroid Build Coastguard Worker         if (TYPENAME##_exists(set, key))                                                               \
182*35238bceSAndroid Build Coastguard Worker             return true;                                                                               \
183*35238bceSAndroid Build Coastguard Worker         return TYPENAME##_insert(set, key);                                                            \
184*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
185*35238bceSAndroid Build Coastguard Worker                                                                                                        \
186*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##_safeDelete(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key)                       \
187*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
188*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(set);                                                                                \
189*35238bceSAndroid Build Coastguard Worker         if (TYPENAME##_exists(set, key))                                                               \
190*35238bceSAndroid Build Coastguard Worker             TYPENAME##_delete(set, key);                                                               \
191*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
192*35238bceSAndroid Build Coastguard Worker                                                                                                        \
193*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##Unused_s                                                                          \
194*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
195*35238bceSAndroid Build Coastguard Worker         int unused;                                                                                    \
196*35238bceSAndroid Build Coastguard Worker     }
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
199*35238bceSAndroid Build Coastguard Worker  * \brief Implement a template pool set class.
200*35238bceSAndroid Build Coastguard Worker  * \param TYPENAME    Type name of the declared set.
201*35238bceSAndroid Build Coastguard Worker  * \param KEYTYPE    Type of the key.
202*35238bceSAndroid Build Coastguard Worker  * \param HASHFUNC    Function used for hashing the key.
203*35238bceSAndroid Build Coastguard Worker  * \param CMPFUNC    Function used for exact matching of the keys.
204*35238bceSAndroid Build Coastguard Worker  *
205*35238bceSAndroid Build Coastguard Worker  * This macro has implements the set declared with DE_DECLARE_POOL_SET.
206*35238bceSAndroid Build Coastguard Worker  * Usually this macro should be used from a .c file, since the macro expands
207*35238bceSAndroid Build Coastguard Worker  * into multiple functions. The TYPENAME and KEYTYPE parameters
208*35238bceSAndroid Build Coastguard Worker  * must match those of the declare macro.
209*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
210*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_SET(TYPENAME, KEYTYPE, HASHFUNC, CMPFUNC)                                                 \
211*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
212*35238bceSAndroid Build Coastguard Worker     DE_PTR_TYPE(TYPENAME) TYPENAME##_create(deMemPool *pool)                                                        \
213*35238bceSAndroid Build Coastguard Worker     {                                                                                                               \
214*35238bceSAndroid Build Coastguard Worker         /* Alloc struct. */                                                                                         \
215*35238bceSAndroid Build Coastguard Worker         DE_PTR_TYPE(TYPENAME) set = DE_POOL_NEW(pool, TYPENAME);                                                    \
216*35238bceSAndroid Build Coastguard Worker         if (!set)                                                                                                   \
217*35238bceSAndroid Build Coastguard Worker             return DE_NULL;                                                                                         \
218*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
219*35238bceSAndroid Build Coastguard Worker         /* Init array. */                                                                                           \
220*35238bceSAndroid Build Coastguard Worker         memset(set, 0, sizeof(TYPENAME));                                                                           \
221*35238bceSAndroid Build Coastguard Worker         set->pool = pool;                                                                                           \
222*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
223*35238bceSAndroid Build Coastguard Worker         return set;                                                                                                 \
224*35238bceSAndroid Build Coastguard Worker     }                                                                                                               \
225*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
226*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_reset(DE_PTR_TYPE(TYPENAME) set)                                                                \
227*35238bceSAndroid Build Coastguard Worker     {                                                                                                               \
228*35238bceSAndroid Build Coastguard Worker         int slotNdx;                                                                                                \
229*35238bceSAndroid Build Coastguard Worker         for (slotNdx = 0; slotNdx < set->slotTableSize; slotNdx++)                                                  \
230*35238bceSAndroid Build Coastguard Worker         {                                                                                                           \
231*35238bceSAndroid Build Coastguard Worker             TYPENAME##Slot *slot = set->slotTable[slotNdx];                                                         \
232*35238bceSAndroid Build Coastguard Worker             while (slot)                                                                                            \
233*35238bceSAndroid Build Coastguard Worker             {                                                                                                       \
234*35238bceSAndroid Build Coastguard Worker                 TYPENAME##Slot *nextSlot = slot->nextSlot;                                                          \
235*35238bceSAndroid Build Coastguard Worker                 slot->nextSlot           = set->slotFreeList;                                                       \
236*35238bceSAndroid Build Coastguard Worker                 set->slotFreeList        = slot;                                                                    \
237*35238bceSAndroid Build Coastguard Worker                 slot->numUsed            = 0;                                                                       \
238*35238bceSAndroid Build Coastguard Worker                 slot                     = nextSlot;                                                                \
239*35238bceSAndroid Build Coastguard Worker             }                                                                                                       \
240*35238bceSAndroid Build Coastguard Worker             set->slotTable[slotNdx] = DE_NULL;                                                                      \
241*35238bceSAndroid Build Coastguard Worker         }                                                                                                           \
242*35238bceSAndroid Build Coastguard Worker         set->numElements = 0;                                                                                       \
243*35238bceSAndroid Build Coastguard Worker     }                                                                                                               \
244*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
245*35238bceSAndroid Build Coastguard Worker     TYPENAME##Slot *TYPENAME##_allocSlot(DE_PTR_TYPE(TYPENAME) set)                                                 \
246*35238bceSAndroid Build Coastguard Worker     {                                                                                                               \
247*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *slot;                                                                                       \
248*35238bceSAndroid Build Coastguard Worker         if (set->slotFreeList)                                                                                      \
249*35238bceSAndroid Build Coastguard Worker         {                                                                                                           \
250*35238bceSAndroid Build Coastguard Worker             slot              = set->slotFreeList;                                                                  \
251*35238bceSAndroid Build Coastguard Worker             set->slotFreeList = set->slotFreeList->nextSlot;                                                        \
252*35238bceSAndroid Build Coastguard Worker         }                                                                                                           \
253*35238bceSAndroid Build Coastguard Worker         else                                                                                                        \
254*35238bceSAndroid Build Coastguard Worker             slot = (TYPENAME##Slot *)deMemPool_alloc(set->pool, sizeof(TYPENAME##Slot) * DE_SET_ELEMENTS_PER_SLOT); \
255*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
256*35238bceSAndroid Build Coastguard Worker         if (slot)                                                                                                   \
257*35238bceSAndroid Build Coastguard Worker         {                                                                                                           \
258*35238bceSAndroid Build Coastguard Worker             slot->nextSlot = DE_NULL;                                                                               \
259*35238bceSAndroid Build Coastguard Worker             slot->numUsed  = 0;                                                                                     \
260*35238bceSAndroid Build Coastguard Worker         }                                                                                                           \
261*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
262*35238bceSAndroid Build Coastguard Worker         return slot;                                                                                                \
263*35238bceSAndroid Build Coastguard Worker     }                                                                                                               \
264*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
265*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_rehash(DE_PTR_TYPE(TYPENAME) set, int newSlotTableSize)                                         \
266*35238bceSAndroid Build Coastguard Worker     {                                                                                                               \
267*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(deIsPowerOfTwo32(newSlotTableSize) && newSlotTableSize > 0);                                      \
268*35238bceSAndroid Build Coastguard Worker         if (newSlotTableSize > set->slotTableSize)                                                                  \
269*35238bceSAndroid Build Coastguard Worker         {                                                                                                           \
270*35238bceSAndroid Build Coastguard Worker             TYPENAME##Slot **oldSlotTable = set->slotTable;                                                         \
271*35238bceSAndroid Build Coastguard Worker             TYPENAME##Slot **newSlotTable =                                                                         \
272*35238bceSAndroid Build Coastguard Worker                 (TYPENAME##Slot **)deMemPool_alloc(set->pool, sizeof(TYPENAME##Slot *) * (size_t)newSlotTableSize); \
273*35238bceSAndroid Build Coastguard Worker             int oldSlotTableSize = set->slotTableSize;                                                              \
274*35238bceSAndroid Build Coastguard Worker             int slotNdx;                                                                                            \
275*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
276*35238bceSAndroid Build Coastguard Worker             if (!newSlotTable)                                                                                      \
277*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                       \
278*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
279*35238bceSAndroid Build Coastguard Worker             for (slotNdx = 0; slotNdx < oldSlotTableSize; slotNdx++)                                                \
280*35238bceSAndroid Build Coastguard Worker                 newSlotTable[slotNdx] = oldSlotTable[slotNdx];                                                      \
281*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
282*35238bceSAndroid Build Coastguard Worker             for (slotNdx = oldSlotTableSize; slotNdx < newSlotTableSize; slotNdx++)                                 \
283*35238bceSAndroid Build Coastguard Worker                 newSlotTable[slotNdx] = DE_NULL;                                                                    \
284*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
285*35238bceSAndroid Build Coastguard Worker             set->slotTableSize = newSlotTableSize;                                                                  \
286*35238bceSAndroid Build Coastguard Worker             set->slotTable     = newSlotTable;                                                                      \
287*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
288*35238bceSAndroid Build Coastguard Worker             for (slotNdx = 0; slotNdx < oldSlotTableSize; slotNdx++)                                                \
289*35238bceSAndroid Build Coastguard Worker             {                                                                                                       \
290*35238bceSAndroid Build Coastguard Worker                 TYPENAME##Slot *slot  = oldSlotTable[slotNdx];                                                      \
291*35238bceSAndroid Build Coastguard Worker                 newSlotTable[slotNdx] = DE_NULL;                                                                    \
292*35238bceSAndroid Build Coastguard Worker                 while (slot)                                                                                        \
293*35238bceSAndroid Build Coastguard Worker                 {                                                                                                   \
294*35238bceSAndroid Build Coastguard Worker                     int elemNdx;                                                                                    \
295*35238bceSAndroid Build Coastguard Worker                     for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++)                                           \
296*35238bceSAndroid Build Coastguard Worker                     {                                                                                               \
297*35238bceSAndroid Build Coastguard Worker                         set->numElements--;                                                                         \
298*35238bceSAndroid Build Coastguard Worker                         if (!TYPENAME##_insert(set, slot->keys[elemNdx]))                                           \
299*35238bceSAndroid Build Coastguard Worker                             return false;                                                                           \
300*35238bceSAndroid Build Coastguard Worker                     }                                                                                               \
301*35238bceSAndroid Build Coastguard Worker                     slot = slot->nextSlot;                                                                          \
302*35238bceSAndroid Build Coastguard Worker                 }                                                                                                   \
303*35238bceSAndroid Build Coastguard Worker             }                                                                                                       \
304*35238bceSAndroid Build Coastguard Worker         }                                                                                                           \
305*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
306*35238bceSAndroid Build Coastguard Worker         return true;                                                                                                \
307*35238bceSAndroid Build Coastguard Worker     }                                                                                                               \
308*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
309*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_exists(const TYPENAME *set, KEYTYPE key)                                                        \
310*35238bceSAndroid Build Coastguard Worker     {                                                                                                               \
311*35238bceSAndroid Build Coastguard Worker         if (set->numElements > 0)                                                                                   \
312*35238bceSAndroid Build Coastguard Worker         {                                                                                                           \
313*35238bceSAndroid Build Coastguard Worker             int slotNdx          = (int)(HASHFUNC(key) & (uint32_t)(set->slotTableSize - 1));                       \
314*35238bceSAndroid Build Coastguard Worker             TYPENAME##Slot *slot = set->slotTable[slotNdx];                                                         \
315*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(deInBounds32(slotNdx, 0, set->slotTableSize));                                                \
316*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
317*35238bceSAndroid Build Coastguard Worker             while (slot)                                                                                            \
318*35238bceSAndroid Build Coastguard Worker             {                                                                                                       \
319*35238bceSAndroid Build Coastguard Worker                 int elemNdx;                                                                                        \
320*35238bceSAndroid Build Coastguard Worker                 for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++)                                               \
321*35238bceSAndroid Build Coastguard Worker                 {                                                                                                   \
322*35238bceSAndroid Build Coastguard Worker                     if (CMPFUNC(slot->keys[elemNdx], key))                                                          \
323*35238bceSAndroid Build Coastguard Worker                         return true;                                                                                \
324*35238bceSAndroid Build Coastguard Worker                 }                                                                                                   \
325*35238bceSAndroid Build Coastguard Worker                 slot = slot->nextSlot;                                                                              \
326*35238bceSAndroid Build Coastguard Worker             }                                                                                                       \
327*35238bceSAndroid Build Coastguard Worker         }                                                                                                           \
328*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
329*35238bceSAndroid Build Coastguard Worker         return false;                                                                                               \
330*35238bceSAndroid Build Coastguard Worker     }                                                                                                               \
331*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
332*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key)                                                  \
333*35238bceSAndroid Build Coastguard Worker     {                                                                                                               \
334*35238bceSAndroid Build Coastguard Worker         int slotNdx;                                                                                                \
335*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *slot;                                                                                       \
336*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
337*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(set);                                                                                             \
338*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!TYPENAME##_exists(set, key));                                                                    \
339*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
340*35238bceSAndroid Build Coastguard Worker         if ((set->numElements + 1) >= set->slotTableSize * DE_SET_ELEMENTS_PER_SLOT)                                \
341*35238bceSAndroid Build Coastguard Worker             if (!TYPENAME##_rehash(set, deMax32(4, 2 * set->slotTableSize)))                                        \
342*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                       \
343*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
344*35238bceSAndroid Build Coastguard Worker         slotNdx = (int)(HASHFUNC(key) & (uint32_t)(set->slotTableSize - 1));                                        \
345*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(slotNdx >= 0 && slotNdx < set->slotTableSize);                                                    \
346*35238bceSAndroid Build Coastguard Worker         slot = set->slotTable[slotNdx];                                                                             \
347*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
348*35238bceSAndroid Build Coastguard Worker         if (!slot)                                                                                                  \
349*35238bceSAndroid Build Coastguard Worker         {                                                                                                           \
350*35238bceSAndroid Build Coastguard Worker             slot = TYPENAME##_allocSlot(set);                                                                       \
351*35238bceSAndroid Build Coastguard Worker             if (!slot)                                                                                              \
352*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                       \
353*35238bceSAndroid Build Coastguard Worker             set->slotTable[slotNdx] = slot;                                                                         \
354*35238bceSAndroid Build Coastguard Worker         }                                                                                                           \
355*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
356*35238bceSAndroid Build Coastguard Worker         for (;;)                                                                                                    \
357*35238bceSAndroid Build Coastguard Worker         {                                                                                                           \
358*35238bceSAndroid Build Coastguard Worker             if (slot->numUsed == DE_SET_ELEMENTS_PER_SLOT)                                                          \
359*35238bceSAndroid Build Coastguard Worker             {                                                                                                       \
360*35238bceSAndroid Build Coastguard Worker                 if (slot->nextSlot)                                                                                 \
361*35238bceSAndroid Build Coastguard Worker                     slot = slot->nextSlot;                                                                          \
362*35238bceSAndroid Build Coastguard Worker                 else                                                                                                \
363*35238bceSAndroid Build Coastguard Worker                 {                                                                                                   \
364*35238bceSAndroid Build Coastguard Worker                     TYPENAME##Slot *nextSlot = TYPENAME##_allocSlot(set);                                           \
365*35238bceSAndroid Build Coastguard Worker                     if (!nextSlot)                                                                                  \
366*35238bceSAndroid Build Coastguard Worker                         return false;                                                                               \
367*35238bceSAndroid Build Coastguard Worker                     slot->nextSlot = nextSlot;                                                                      \
368*35238bceSAndroid Build Coastguard Worker                     slot           = nextSlot;                                                                      \
369*35238bceSAndroid Build Coastguard Worker                 }                                                                                                   \
370*35238bceSAndroid Build Coastguard Worker             }                                                                                                       \
371*35238bceSAndroid Build Coastguard Worker             else                                                                                                    \
372*35238bceSAndroid Build Coastguard Worker             {                                                                                                       \
373*35238bceSAndroid Build Coastguard Worker                 slot->keys[slot->numUsed] = key;                                                                    \
374*35238bceSAndroid Build Coastguard Worker                 slot->numUsed++;                                                                                    \
375*35238bceSAndroid Build Coastguard Worker                 set->numElements++;                                                                                 \
376*35238bceSAndroid Build Coastguard Worker                 return true;                                                                                        \
377*35238bceSAndroid Build Coastguard Worker             }                                                                                                       \
378*35238bceSAndroid Build Coastguard Worker         }                                                                                                           \
379*35238bceSAndroid Build Coastguard Worker     }                                                                                                               \
380*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
381*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_delete(DE_PTR_TYPE(TYPENAME) set, KEYTYPE key)                                                  \
382*35238bceSAndroid Build Coastguard Worker     {                                                                                                               \
383*35238bceSAndroid Build Coastguard Worker         int slotNdx;                                                                                                \
384*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *slot;                                                                                       \
385*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *prevSlot = DE_NULL;                                                                         \
386*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
387*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(set->numElements > 0);                                                                            \
388*35238bceSAndroid Build Coastguard Worker         slotNdx = (int)(HASHFUNC(key) & (uint32_t)(set->slotTableSize - 1));                                        \
389*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(slotNdx >= 0 && slotNdx < set->slotTableSize);                                                    \
390*35238bceSAndroid Build Coastguard Worker         slot = set->slotTable[slotNdx];                                                                             \
391*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(slot);                                                                                            \
392*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
393*35238bceSAndroid Build Coastguard Worker         for (;;)                                                                                                    \
394*35238bceSAndroid Build Coastguard Worker         {                                                                                                           \
395*35238bceSAndroid Build Coastguard Worker             int elemNdx;                                                                                            \
396*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(slot->numUsed > 0);                                                                           \
397*35238bceSAndroid Build Coastguard Worker             for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++)                                                   \
398*35238bceSAndroid Build Coastguard Worker             {                                                                                                       \
399*35238bceSAndroid Build Coastguard Worker                 if (CMPFUNC(key, slot->keys[elemNdx]))                                                              \
400*35238bceSAndroid Build Coastguard Worker                 {                                                                                                   \
401*35238bceSAndroid Build Coastguard Worker                     TYPENAME##Slot *lastSlot = slot;                                                                \
402*35238bceSAndroid Build Coastguard Worker                     while (lastSlot->nextSlot)                                                                      \
403*35238bceSAndroid Build Coastguard Worker                     {                                                                                               \
404*35238bceSAndroid Build Coastguard Worker                         prevSlot = lastSlot;                                                                        \
405*35238bceSAndroid Build Coastguard Worker                         lastSlot = lastSlot->nextSlot;                                                              \
406*35238bceSAndroid Build Coastguard Worker                     }                                                                                               \
407*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
408*35238bceSAndroid Build Coastguard Worker                     slot->keys[elemNdx] = lastSlot->keys[lastSlot->numUsed - 1];                                    \
409*35238bceSAndroid Build Coastguard Worker                     lastSlot->numUsed--;                                                                            \
410*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
411*35238bceSAndroid Build Coastguard Worker                     if (lastSlot->numUsed == 0)                                                                     \
412*35238bceSAndroid Build Coastguard Worker                     {                                                                                               \
413*35238bceSAndroid Build Coastguard Worker                         if (prevSlot)                                                                               \
414*35238bceSAndroid Build Coastguard Worker                             prevSlot->nextSlot = DE_NULL;                                                           \
415*35238bceSAndroid Build Coastguard Worker                         else                                                                                        \
416*35238bceSAndroid Build Coastguard Worker                             set->slotTable[slotNdx] = DE_NULL;                                                      \
417*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
418*35238bceSAndroid Build Coastguard Worker                         lastSlot->nextSlot = set->slotFreeList;                                                     \
419*35238bceSAndroid Build Coastguard Worker                         set->slotFreeList  = lastSlot;                                                              \
420*35238bceSAndroid Build Coastguard Worker                     }                                                                                               \
421*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
422*35238bceSAndroid Build Coastguard Worker                     set->numElements--;                                                                             \
423*35238bceSAndroid Build Coastguard Worker                     return;                                                                                         \
424*35238bceSAndroid Build Coastguard Worker                 }                                                                                                   \
425*35238bceSAndroid Build Coastguard Worker             }                                                                                                       \
426*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
427*35238bceSAndroid Build Coastguard Worker             prevSlot = slot;                                                                                        \
428*35238bceSAndroid Build Coastguard Worker             slot     = slot->nextSlot;                                                                              \
429*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(slot);                                                                                        \
430*35238bceSAndroid Build Coastguard Worker         }                                                                                                           \
431*35238bceSAndroid Build Coastguard Worker     }                                                                                                               \
432*35238bceSAndroid Build Coastguard Worker                                                                                                                     \
433*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##Unused2_s                                                                                      \
434*35238bceSAndroid Build Coastguard Worker     {                                                                                                               \
435*35238bceSAndroid Build Coastguard Worker         int unused;                                                                                                 \
436*35238bceSAndroid Build Coastguard Worker     }
437*35238bceSAndroid Build Coastguard Worker 
438*35238bceSAndroid Build Coastguard Worker /* Copy-to-array templates. */
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_SET_TO_ARRAY(SETTYPENAME, ARRAYTYPENAME)                              \
441*35238bceSAndroid Build Coastguard Worker     bool SETTYPENAME##_copyToArray(const SETTYPENAME *set, DE_PTR_TYPE(ARRAYTYPENAME) array); \
442*35238bceSAndroid Build Coastguard Worker     struct SETTYPENAME##_##ARRAYTYPENAME##_declare_unused                                     \
443*35238bceSAndroid Build Coastguard Worker     {                                                                                         \
444*35238bceSAndroid Build Coastguard Worker         int unused;                                                                           \
445*35238bceSAndroid Build Coastguard Worker     }
446*35238bceSAndroid Build Coastguard Worker 
447*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_SET_TO_ARRAY(SETTYPENAME, ARRAYTYPENAME)                           \
448*35238bceSAndroid Build Coastguard Worker     bool SETTYPENAME##_copyToArray(const SETTYPENAME *set, DE_PTR_TYPE(ARRAYTYPENAME) array) \
449*35238bceSAndroid Build Coastguard Worker     {                                                                                        \
450*35238bceSAndroid Build Coastguard Worker         int numElements = set->numElements;                                                  \
451*35238bceSAndroid Build Coastguard Worker         int arrayNdx    = 0;                                                                 \
452*35238bceSAndroid Build Coastguard Worker         int slotNdx;                                                                         \
453*35238bceSAndroid Build Coastguard Worker                                                                                              \
454*35238bceSAndroid Build Coastguard Worker         if (!ARRAYTYPENAME##_setSize(array, numElements))                                    \
455*35238bceSAndroid Build Coastguard Worker             return false;                                                                    \
456*35238bceSAndroid Build Coastguard Worker                                                                                              \
457*35238bceSAndroid Build Coastguard Worker         for (slotNdx = 0; slotNdx < set->slotTableSize; slotNdx++)                           \
458*35238bceSAndroid Build Coastguard Worker         {                                                                                    \
459*35238bceSAndroid Build Coastguard Worker             const SETTYPENAME##Slot *slot = set->slotTable[slotNdx];                         \
460*35238bceSAndroid Build Coastguard Worker             while (slot)                                                                     \
461*35238bceSAndroid Build Coastguard Worker             {                                                                                \
462*35238bceSAndroid Build Coastguard Worker                 int elemNdx;                                                                 \
463*35238bceSAndroid Build Coastguard Worker                 for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++)                        \
464*35238bceSAndroid Build Coastguard Worker                     ARRAYTYPENAME##_set(array, arrayNdx++, slot->keys[elemNdx]);             \
465*35238bceSAndroid Build Coastguard Worker                 slot = slot->nextSlot;                                                       \
466*35238bceSAndroid Build Coastguard Worker             }                                                                                \
467*35238bceSAndroid Build Coastguard Worker         }                                                                                    \
468*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(arrayNdx == numElements);                                                  \
469*35238bceSAndroid Build Coastguard Worker         return true;                                                                         \
470*35238bceSAndroid Build Coastguard Worker     }                                                                                        \
471*35238bceSAndroid Build Coastguard Worker     struct SETTYPENAME##_##ARRAYTYPENAME##_implement_unused                                  \
472*35238bceSAndroid Build Coastguard Worker     {                                                                                        \
473*35238bceSAndroid Build Coastguard Worker         int unused;                                                                          \
474*35238bceSAndroid Build Coastguard Worker     }
475*35238bceSAndroid Build Coastguard Worker 
476*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
477*35238bceSAndroid Build Coastguard Worker  * \brief Declare set-wise operations for a set template.
478*35238bceSAndroid Build Coastguard Worker  * \param TYPENAME    Type name of the declared set.
479*35238bceSAndroid Build Coastguard Worker  * \param KEYTYPE    Type of the key.
480*35238bceSAndroid Build Coastguard Worker  *
481*35238bceSAndroid Build Coastguard Worker  * This macro declares union and intersection operations for a set.
482*35238bceSAndroid Build Coastguard Worker  * For implementation see DE_IMPLEMENT_POOL_SET_UNION_INTERSECT.
483*35238bceSAndroid Build Coastguard Worker  *
484*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Detailed description.
485*35238bceSAndroid Build Coastguard Worker  *
486*35238bceSAndroid Build Coastguard Worker  * The functions for operating the set are:
487*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Figure out how to comment these in Doxygen-style.
488*35238bceSAndroid Build Coastguard Worker  *
489*35238bceSAndroid Build Coastguard Worker  * \code
490*35238bceSAndroid Build Coastguard Worker  * bool    Set_union                (Set* to, const Set* a, const Set* b);
491*35238bceSAndroid Build Coastguard Worker  * bool    Set_unionInplace        (Set* a, const Set* b);
492*35238bceSAndroid Build Coastguard Worker  * bool    Set_intersect            (Set* to, const Set* a, const Set* b);
493*35238bceSAndroid Build Coastguard Worker  * void        Set_intersectInplace    (Set* a, const Set* b);
494*35238bceSAndroid Build Coastguard Worker  * bool   Set_difference            (Set* to, const Set* a, const Set* b);
495*35238bceSAndroid Build Coastguard Worker  * void     Set_differenceInplace    (Set* a, const Set* b);
496*35238bceSAndroid Build Coastguard Worker  * \endcode
497*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
498*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_SET_SETWISE_OPERATIONS(TYPENAME)                                        \
499*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_union(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b);      \
500*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_unionInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b);                   \
501*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_intersect(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b);  \
502*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_intersectInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b);               \
503*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_difference(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b); \
504*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_differenceInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b);              \
505*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##SetwiseDeclareUnused_s                                                     \
506*35238bceSAndroid Build Coastguard Worker     {                                                                                           \
507*35238bceSAndroid Build Coastguard Worker         int unused;                                                                             \
508*35238bceSAndroid Build Coastguard Worker     }
509*35238bceSAndroid Build Coastguard Worker 
510*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_SET_SETWISE_OPERATIONS(TYPENAME, KEYTYPE)                                    \
511*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_union(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b)              \
512*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
513*35238bceSAndroid Build Coastguard Worker         TYPENAME##_reset(to);                                                                          \
514*35238bceSAndroid Build Coastguard Worker         if (!TYPENAME##_unionInplace(to, a))                                                           \
515*35238bceSAndroid Build Coastguard Worker             return false;                                                                              \
516*35238bceSAndroid Build Coastguard Worker         if (!TYPENAME##_unionInplace(to, b))                                                           \
517*35238bceSAndroid Build Coastguard Worker             return false;                                                                              \
518*35238bceSAndroid Build Coastguard Worker         return true;                                                                                   \
519*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
520*35238bceSAndroid Build Coastguard Worker                                                                                                        \
521*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_unionInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b)                           \
522*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
523*35238bceSAndroid Build Coastguard Worker         TYPENAME##Iter iter;                                                                           \
524*35238bceSAndroid Build Coastguard Worker         for (TYPENAME##Iter_init(b, &iter); TYPENAME##Iter_hasItem(&iter); TYPENAME##Iter_next(&iter)) \
525*35238bceSAndroid Build Coastguard Worker         {                                                                                              \
526*35238bceSAndroid Build Coastguard Worker             KEYTYPE key = TYPENAME##Iter_getKey(&iter);                                                \
527*35238bceSAndroid Build Coastguard Worker             if (!TYPENAME##_exists(a, key))                                                            \
528*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
529*35238bceSAndroid Build Coastguard Worker                 if (!TYPENAME##_insert(a, key))                                                        \
530*35238bceSAndroid Build Coastguard Worker                     return false;                                                                      \
531*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
532*35238bceSAndroid Build Coastguard Worker         }                                                                                              \
533*35238bceSAndroid Build Coastguard Worker         return true;                                                                                   \
534*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
535*35238bceSAndroid Build Coastguard Worker                                                                                                        \
536*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_intersect(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b)          \
537*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
538*35238bceSAndroid Build Coastguard Worker         TYPENAME##Iter iter;                                                                           \
539*35238bceSAndroid Build Coastguard Worker         TYPENAME##_reset(to);                                                                          \
540*35238bceSAndroid Build Coastguard Worker         for (TYPENAME##Iter_init(a, &iter); TYPENAME##Iter_hasItem(&iter); TYPENAME##Iter_next(&iter)) \
541*35238bceSAndroid Build Coastguard Worker         {                                                                                              \
542*35238bceSAndroid Build Coastguard Worker             KEYTYPE key = TYPENAME##Iter_getKey(&iter);                                                \
543*35238bceSAndroid Build Coastguard Worker             if (TYPENAME##_exists(b, key))                                                             \
544*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
545*35238bceSAndroid Build Coastguard Worker                 if (!TYPENAME##_insert(to, key))                                                       \
546*35238bceSAndroid Build Coastguard Worker                     return false;                                                                      \
547*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
548*35238bceSAndroid Build Coastguard Worker         }                                                                                              \
549*35238bceSAndroid Build Coastguard Worker         return true;                                                                                   \
550*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
551*35238bceSAndroid Build Coastguard Worker                                                                                                        \
552*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_intersectInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b)                       \
553*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
554*35238bceSAndroid Build Coastguard Worker         DE_UNREF(a &&b);                                                                               \
555*35238bceSAndroid Build Coastguard Worker         DE_FATAL("Not implemented.");                                                                  \
556*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
557*35238bceSAndroid Build Coastguard Worker                                                                                                        \
558*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_difference(DE_PTR_TYPE(TYPENAME) to, const TYPENAME *a, const TYPENAME *b)         \
559*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
560*35238bceSAndroid Build Coastguard Worker         TYPENAME##Iter iter;                                                                           \
561*35238bceSAndroid Build Coastguard Worker         TYPENAME##_reset(to);                                                                          \
562*35238bceSAndroid Build Coastguard Worker         for (TYPENAME##Iter_init(a, &iter); TYPENAME##Iter_hasItem(&iter); TYPENAME##Iter_next(&iter)) \
563*35238bceSAndroid Build Coastguard Worker         {                                                                                              \
564*35238bceSAndroid Build Coastguard Worker             KEYTYPE key = TYPENAME##Iter_getKey(&iter);                                                \
565*35238bceSAndroid Build Coastguard Worker             if (!TYPENAME##_exists(b, key))                                                            \
566*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
567*35238bceSAndroid Build Coastguard Worker                 if (!TYPENAME##_insert(to, key))                                                       \
568*35238bceSAndroid Build Coastguard Worker                     return false;                                                                      \
569*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
570*35238bceSAndroid Build Coastguard Worker         }                                                                                              \
571*35238bceSAndroid Build Coastguard Worker         return true;                                                                                   \
572*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
573*35238bceSAndroid Build Coastguard Worker                                                                                                        \
574*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_differenceInplace(DE_PTR_TYPE(TYPENAME) a, const TYPENAME *b)                      \
575*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
576*35238bceSAndroid Build Coastguard Worker         TYPENAME##Iter iter;                                                                           \
577*35238bceSAndroid Build Coastguard Worker         for (TYPENAME##Iter_init(b, &iter); TYPENAME##Iter_hasItem(&iter); TYPENAME##Iter_next(&iter)) \
578*35238bceSAndroid Build Coastguard Worker         {                                                                                              \
579*35238bceSAndroid Build Coastguard Worker             KEYTYPE key = TYPENAME##Iter_getKey(&iter);                                                \
580*35238bceSAndroid Build Coastguard Worker             if (TYPENAME##_exists(a, key))                                                             \
581*35238bceSAndroid Build Coastguard Worker                 TYPENAME##_delete(a, key);                                                             \
582*35238bceSAndroid Build Coastguard Worker         }                                                                                              \
583*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
584*35238bceSAndroid Build Coastguard Worker                                                                                                        \
585*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##UnionIntersectImplementUnused_s                                                   \
586*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
587*35238bceSAndroid Build Coastguard Worker         int unused;                                                                                    \
588*35238bceSAndroid Build Coastguard Worker     }
589*35238bceSAndroid Build Coastguard Worker 
590*35238bceSAndroid Build Coastguard Worker #endif /* _DEPOOLSET_H */
591