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