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