]> git.saurik.com Git - apple/cf.git/blame - CFSet.c
CF-744.12.tar.gz
[apple/cf.git] / CFSet.c
CommitLineData
bd5b749c 1/*
259c77ee 2 * Copyright (c) 2012 Apple Inc. All rights reserved.
bd5b749c
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
f64f9b69 23
bd5b749c 24/* CFSet.c
856091c5 25 Copyright (c) 1998-2012, Apple Inc. All rights reserved.
bd5b749c 26 Responsibility: Christopher Kane
cf7d2af9 27 Machine generated from Notes/HashingCode.template
bd5b749c
A
28*/
29
30
31
32
cf7d2af9 33
bd5b749c
A
34#include <CoreFoundation/CFSet.h>
35#include "CFInternal.h"
cf7d2af9
A
36#include "CFBasicHash.h"
37#include <CoreFoundation/CFString.h>
bd5b749c 38
856091c5 39
bd5b749c
A
40#define CFDictionary 0
41#define CFSet 0
42#define CFBag 0
43#undef CFSet
44#define CFSet 1
45
46#if CFDictionary
47const CFSetKeyCallBacks kCFTypeSetKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
48const CFSetKeyCallBacks kCFCopyStringSetKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
49const CFSetValueCallBacks kCFTypeSetValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
8ca704e1 50__private_extern__ const CFSetValueCallBacks kCFTypeSetValueCompactableCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
bd5b749c
A
51static const CFSetKeyCallBacks __kCFNullSetKeyCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
52static const CFSetValueCallBacks __kCFNullSetValueCallBacks = {0, NULL, NULL, NULL, NULL};
53
54#define CFHashRef CFDictionaryRef
55#define CFMutableHashRef CFMutableDictionaryRef
cf7d2af9
A
56#define CFHashKeyCallBacks CFSetKeyCallBacks
57#define CFHashValueCallBacks CFSetValueCallBacks
bd5b749c
A
58#endif
59
60#if CFSet
61const CFSetCallBacks kCFTypeSetCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
62const CFSetCallBacks kCFCopyStringSetCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
63static const CFSetCallBacks __kCFNullSetCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
64
65#define CFSetKeyCallBacks CFSetCallBacks
66#define CFSetValueCallBacks CFSetCallBacks
67#define kCFTypeSetKeyCallBacks kCFTypeSetCallBacks
68#define kCFTypeSetValueCallBacks kCFTypeSetCallBacks
69#define __kCFNullSetKeyCallBacks __kCFNullSetCallBacks
70#define __kCFNullSetValueCallBacks __kCFNullSetCallBacks
71
72#define CFHashRef CFSetRef
73#define CFMutableHashRef CFMutableSetRef
cf7d2af9
A
74#define CFHashKeyCallBacks CFSetCallBacks
75#define CFHashValueCallBacks CFSetCallBacks
bd5b749c
A
76#endif
77
78#if CFBag
79const CFSetCallBacks kCFTypeSetCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
80const CFSetCallBacks kCFCopyStringSetCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
81static const CFSetCallBacks __kCFNullSetCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
82
83#define CFSetKeyCallBacks CFSetCallBacks
84#define CFSetValueCallBacks CFSetCallBacks
85#define kCFTypeSetKeyCallBacks kCFTypeSetCallBacks
86#define kCFTypeSetValueCallBacks kCFTypeSetCallBacks
87#define __kCFNullSetKeyCallBacks __kCFNullSetCallBacks
88#define __kCFNullSetValueCallBacks __kCFNullSetCallBacks
89
90#define CFHashRef CFBagRef
91#define CFMutableHashRef CFMutableBagRef
cf7d2af9
A
92#define CFHashKeyCallBacks CFSetCallBacks
93#define CFHashValueCallBacks CFSetCallBacks
bd5b749c
A
94#endif
95
bd5b749c
A
96
97typedef uintptr_t any_t;
98typedef const void * const_any_pointer_t;
99typedef void * any_pointer_t;
100
bd5b749c 101static Boolean __CFSetEqual(CFTypeRef cf1, CFTypeRef cf2) {
cf7d2af9 102 return __CFBasicHashEqual((CFBasicHashRef)cf1, (CFBasicHashRef)cf2);
bd5b749c
A
103}
104
105static CFHashCode __CFSetHash(CFTypeRef cf) {
cf7d2af9 106 return __CFBasicHashHash((CFBasicHashRef)cf);
bd5b749c
A
107}
108
109static CFStringRef __CFSetCopyDescription(CFTypeRef cf) {
cf7d2af9 110 return __CFBasicHashCopyDescription((CFBasicHashRef)cf);
bd5b749c
A
111}
112
113static void __CFSetDeallocate(CFTypeRef cf) {
cf7d2af9 114 __CFBasicHashDeallocate((CFBasicHashRef)cf);
bd5b749c
A
115}
116
117static CFTypeID __kCFSetTypeID = _kCFRuntimeNotATypeID;
118
119static const CFRuntimeClass __CFSetClass = {
120 _kCFRuntimeScannedObject,
121 "CFSet",
122 NULL, // init
123 NULL, // copy
124 __CFSetDeallocate,
125 __CFSetEqual,
126 __CFSetHash,
127 NULL, //
128 __CFSetCopyDescription
129};
130
bd5b749c 131CFTypeID CFSetGetTypeID(void) {
cf7d2af9
A
132 if (_kCFRuntimeNotATypeID == __kCFSetTypeID) __kCFSetTypeID = _CFRuntimeRegisterClass(&__CFSetClass);
133 return __kCFSetTypeID;
bd5b749c
A
134}
135
8ca704e1
A
136#define GCRETAIN(A, B) kCFTypeSetCallBacks.retain(A, B)
137#define GCRELEASE(A, B) kCFTypeSetCallBacks.release(A, B)
138
139static uintptr_t __CFSetStandardRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
140 if (CFBasicHashGetSpecialBits(ht) & 0x0100) return stack_value;
141 return (CFBasicHashHasStrongValues(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_value) : (uintptr_t)CFRetain((CFTypeRef)stack_value);
142}
143
144static uintptr_t __CFSetStandardRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
145 if (CFBasicHashGetSpecialBits(ht) & 0x0001) return stack_key;
146 return (CFBasicHashHasStrongKeys(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_key) : (uintptr_t)CFRetain((CFTypeRef)stack_key);
147}
148
149static void __CFSetStandardReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
150 if (CFBasicHashGetSpecialBits(ht) & 0x0200) return;
151 if (CFBasicHashHasStrongValues(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_value); else CFRelease((CFTypeRef)stack_value);
152}
153
154static void __CFSetStandardReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
155 if (CFBasicHashGetSpecialBits(ht) & 0x0002) return;
156 if (CFBasicHashHasStrongKeys(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_key); else CFRelease((CFTypeRef)stack_key);
157}
158
159static Boolean __CFSetStandardEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
160 if (CFBasicHashGetSpecialBits(ht) & 0x0400) return coll_value1 == stack_value2;
161 return CFEqual((CFTypeRef)coll_value1, (CFTypeRef)stack_value2);
162}
163
164static Boolean __CFSetStandardEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
165 if (CFBasicHashGetSpecialBits(ht) & 0x0004) return coll_key1 == stack_key2;
166 return CFEqual((CFTypeRef)coll_key1, (CFTypeRef)stack_key2);
167}
168
169static uintptr_t __CFSetStandardHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
170 if (CFBasicHashGetSpecialBits(ht) & 0x0008) return stack_key;
171 return (uintptr_t)CFHash((CFTypeRef)stack_key);
172}
173
174static uintptr_t __CFSetStandardGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
175 return 0;
176}
177
178static CFStringRef __CFSetStandardCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
179 if (CFBasicHashGetSpecialBits(ht) & 0x0800) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_value);
180 return CFCopyDescription((CFTypeRef)stack_value);
181}
182
183static CFStringRef __CFSetStandardCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
184 if (CFBasicHashGetSpecialBits(ht) & 0x0010) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_key);
185 return CFCopyDescription((CFTypeRef)stack_key);
186}
187
188static CFBasicHashCallbacks *__CFSetStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
189static void __CFSetStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
190
191static const CFBasicHashCallbacks CFSetStandardCallbacks = {
192 __CFSetStandardCopyCallbacks,
193 __CFSetStandardFreeCallbacks,
194 __CFSetStandardRetainValue,
195 __CFSetStandardRetainKey,
196 __CFSetStandardReleaseValue,
197 __CFSetStandardReleaseKey,
198 __CFSetStandardEquateValues,
199 __CFSetStandardEquateKeys,
200 __CFSetStandardHashKey,
201 __CFSetStandardGetIndirectKey,
202 __CFSetStandardCopyValueDescription,
203 __CFSetStandardCopyKeyDescription
204};
205
206static CFBasicHashCallbacks *__CFSetStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
207 return (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
208}
209
210static void __CFSetStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
211}
212
213
214static CFBasicHashCallbacks *__CFSetCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
215 CFBasicHashCallbacks *newcb = NULL;
216 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
217 newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
218 } else {
219 newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
cf7d2af9 220 }
856091c5 221 if (!newcb) return NULL;
8ca704e1
A
222 memmove(newcb, (void *)cb, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *));
223 return newcb;
224}
225
226static void __CFSetFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
227 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
228 } else {
229 CFAllocatorDeallocate(allocator, cb);
cf7d2af9 230 }
8ca704e1
A
231}
232
233static uintptr_t __CFSetRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
234 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
235 const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[0];
236 if (NULL == value_retain) return stack_value;
237 return (uintptr_t)INVOKE_CALLBACK2(value_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_value);
238}
239
240static uintptr_t __CFSetRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
241 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
242 const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[1];
243 if (NULL == key_retain) return stack_key;
244 return (uintptr_t)INVOKE_CALLBACK2(key_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_key);
245}
246
247static void __CFSetReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
248 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
249 void (*value_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[2];
250 if (NULL != value_release) INVOKE_CALLBACK2(value_release, CFGetAllocator(ht), (const_any_pointer_t) stack_value);
251}
252
253static void __CFSetReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
254 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
255 void (*key_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[3];
256 if (NULL != key_release) INVOKE_CALLBACK2(key_release, CFGetAllocator(ht), (const_any_pointer_t) stack_key);
257}
258
259static Boolean __CFSetEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
260 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
261 Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[4];
262 if (NULL == value_equal) return (coll_value1 == stack_value2);
263 return INVOKE_CALLBACK2(value_equal, (const_any_pointer_t) coll_value1, (const_any_pointer_t) stack_value2) ? 1 : 0;
264}
265
266static Boolean __CFSetEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
267 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
268 Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[5];
269 if (NULL == key_equal) return (coll_key1 == stack_key2);
270 return INVOKE_CALLBACK2(key_equal, (const_any_pointer_t) coll_key1, (const_any_pointer_t) stack_key2) ? 1 : 0;
271}
272
273static uintptr_t __CFSetHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
274 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
275 CFHashCode (*hash)(const_any_pointer_t) = (CFHashCode (*)(const_any_pointer_t))cb->context[6];
276 if (NULL == hash) return stack_key;
277 return (uintptr_t)INVOKE_CALLBACK1(hash, (const_any_pointer_t) stack_key);
278}
279
280static uintptr_t __CFSetGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
cf7d2af9
A
281 return 0;
282}
283
8ca704e1
A
284static CFStringRef __CFSetCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
285 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
286 CFStringRef (*value_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[8];
287 if (NULL == value_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_value);
288 return (CFStringRef)INVOKE_CALLBACK1(value_describe, (const_any_pointer_t) stack_value);
289}
cf7d2af9 290
8ca704e1
A
291static CFStringRef __CFSetCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
292 const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
293 CFStringRef (*key_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[9];
294 if (NULL == key_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_key);
295 return (CFStringRef)INVOKE_CALLBACK1(key_describe, (const_any_pointer_t) stack_key);
296}
297
298static CFBasicHashRef __CFSetCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) {
cf7d2af9
A
299 CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
300 flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
301
8ca704e1
A
302 CFBasicHashCallbacks *cb = NULL;
303 Boolean std_cb = false;
304 uint16_t specialBits = 0;
cf7d2af9
A
305 const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
306 void (*key_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
307 const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
308 void (*value_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
8ca704e1
A
309
310 if ((NULL == keyCallBacks || 0 == keyCallBacks->version) && (!useValueCB || NULL == valueCallBacks || 0 == valueCallBacks->version)) {
311 Boolean keyRetainNull = NULL == keyCallBacks || NULL == keyCallBacks->retain;
312 Boolean keyReleaseNull = NULL == keyCallBacks || NULL == keyCallBacks->release;
313 Boolean keyEquateNull = NULL == keyCallBacks || NULL == keyCallBacks->equal;
314 Boolean keyHashNull = NULL == keyCallBacks || NULL == keyCallBacks->hash;
315 Boolean keyDescribeNull = NULL == keyCallBacks || NULL == keyCallBacks->copyDescription;
316
317 Boolean valueRetainNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->retain)) || (!useValueCB && keyRetainNull);
318 Boolean valueReleaseNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->release)) || (!useValueCB && keyReleaseNull);
319 Boolean valueEquateNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->equal)) || (!useValueCB && keyEquateNull);
320 Boolean valueDescribeNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeNull);
321
322 Boolean keyRetainStd = keyRetainNull || __CFTypeCollectionRetain == keyCallBacks->retain;
323 Boolean keyReleaseStd = keyReleaseNull || __CFTypeCollectionRelease == keyCallBacks->release;
324 Boolean keyEquateStd = keyEquateNull || CFEqual == keyCallBacks->equal;
325 Boolean keyHashStd = keyHashNull || CFHash == keyCallBacks->hash;
326 Boolean keyDescribeStd = keyDescribeNull || CFCopyDescription == keyCallBacks->copyDescription;
327
328 Boolean valueRetainStd = (useValueCB && (valueRetainNull || __CFTypeCollectionRetain == valueCallBacks->retain)) || (!useValueCB && keyRetainStd);
329 Boolean valueReleaseStd = (useValueCB && (valueReleaseNull || __CFTypeCollectionRelease == valueCallBacks->release)) || (!useValueCB && keyReleaseStd);
330 Boolean valueEquateStd = (useValueCB && (valueEquateNull || CFEqual == valueCallBacks->equal)) || (!useValueCB && keyEquateStd);
331 Boolean valueDescribeStd = (useValueCB && (valueDescribeNull || CFCopyDescription == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeStd);
332
333 if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) {
334 cb = (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
335 if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) {
336 std_cb = true;
337 } else {
338 // just set these to tickle the GC Strong logic below in a way that mimics past practice
339 key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
340 key_release = keyCallBacks ? keyCallBacks->release : NULL;
341 if (useValueCB) {
342 value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
343 value_release = valueCallBacks ? valueCallBacks->release : NULL;
344 } else {
345 value_retain = key_retain;
346 value_release = key_release;
347 }
348 }
349 if (keyRetainNull) specialBits |= 0x0001;
350 if (keyReleaseNull) specialBits |= 0x0002;
351 if (keyEquateNull) specialBits |= 0x0004;
352 if (keyHashNull) specialBits |= 0x0008;
353 if (keyDescribeNull) specialBits |= 0x0010;
354 if (valueRetainNull) specialBits |= 0x0100;
355 if (valueReleaseNull) specialBits |= 0x0200;
356 if (valueEquateNull) specialBits |= 0x0400;
357 if (valueDescribeNull) specialBits |= 0x0800;
358 }
359 }
360
361 if (!cb) {
cf7d2af9
A
362 Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
363 Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
364 CFStringRef (*key_describe)(const_any_pointer_t) = NULL;
365 CFStringRef (*value_describe)(const_any_pointer_t) = NULL;
366 CFHashCode (*hash_key)(const_any_pointer_t) = NULL;
367 key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
368 key_release = keyCallBacks ? keyCallBacks->release : NULL;
369 key_equal = keyCallBacks ? keyCallBacks->equal : NULL;
370 key_describe = keyCallBacks ? keyCallBacks->copyDescription : NULL;
371 if (useValueCB) {
372 value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
373 value_release = valueCallBacks ? valueCallBacks->release : NULL;
374 value_equal = valueCallBacks ? valueCallBacks->equal : NULL;
375 value_describe = valueCallBacks ? valueCallBacks->copyDescription : NULL;
376 } else {
377 value_retain = key_retain;
378 value_release = key_release;
379 value_equal = key_equal;
380 value_describe = key_describe;
381 }
382 hash_key = keyCallBacks ? keyCallBacks->hash : NULL;
cf7d2af9
A
383
384 CFBasicHashCallbacks *newcb = NULL;
385 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
8ca704e1 386 newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
cf7d2af9 387 } else {
8ca704e1 388 newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
cf7d2af9 389 }
856091c5 390 if (!newcb) return NULL;
8ca704e1
A
391 newcb->copyCallbacks = __CFSetCopyCallbacks;
392 newcb->freeCallbacks = __CFSetFreeCallbacks;
393 newcb->retainValue = __CFSetRetainValue;
394 newcb->retainKey = __CFSetRetainKey;
395 newcb->releaseValue = __CFSetReleaseValue;
396 newcb->releaseKey = __CFSetReleaseKey;
397 newcb->equateValues = __CFSetEquateValues;
398 newcb->equateKeys = __CFSetEquateKeys;
399 newcb->hashKey = __CFSetHashKey;
400 newcb->getIndirectKey = __CFSetGetIndirectKey;
401 newcb->copyValueDescription = __CFSetCopyValueDescription;
402 newcb->copyKeyDescription = __CFSetCopyKeyDescription;
cf7d2af9
A
403 newcb->context[0] = (uintptr_t)value_retain;
404 newcb->context[1] = (uintptr_t)key_retain;
405 newcb->context[2] = (uintptr_t)value_release;
406 newcb->context[3] = (uintptr_t)key_release;
407 newcb->context[4] = (uintptr_t)value_equal;
408 newcb->context[5] = (uintptr_t)key_equal;
409 newcb->context[6] = (uintptr_t)hash_key;
8ca704e1
A
410 newcb->context[8] = (uintptr_t)value_describe;
411 newcb->context[9] = (uintptr_t)key_describe;
cf7d2af9
A
412 cb = newcb;
413 }
414
bd5b749c 415 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
cf7d2af9
A
416 if (std_cb || value_retain != NULL || value_release != NULL) {
417 flags |= kCFBasicHashStrongValues;
bd5b749c 418 }
cf7d2af9
A
419 if (std_cb || key_retain != NULL || key_release != NULL) {
420 flags |= kCFBasicHashStrongKeys;
bd5b749c 421 }
8ca704e1
A
422#if CFDictionary
423 if (valueCallBacks == &kCFTypeDictionaryValueCompactableCallBacks) {
424 // Foundation allocated collections will have compactable values
425 flags |= kCFBasicHashCompactableValues;
426 }
427#endif
bd5b749c 428 }
cf7d2af9 429
8ca704e1 430 CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
856091c5
A
431 if (ht) CFBasicHashSetSpecialBits(ht, specialBits);
432 if (!ht && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, cb);
8ca704e1
A
433 return ht;
434}
435
436#if CFDictionary
437__private_extern__ CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) {
438#endif
439#if CFSet || CFBag
440__private_extern__ CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) {
441 const_any_pointer_t *vlist = klist;
442#endif
443 CFTypeID typeID = CFSetGetTypeID();
444 CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
445 CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
446 flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
447 CFBasicHashCallbacks *cb = (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
448 CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
449 CFBasicHashSetSpecialBits(ht, 0x0303);
450 if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
451 for (CFIndex idx = 0; idx < numValues; idx++) {
452 CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
453 }
454 CFBasicHashSetSpecialBits(ht, 0x0000);
455 CFBasicHashMakeImmutable(ht);
456 *(uintptr_t *)ht = __CFISAForTypeID(typeID);
457 _CFRuntimeSetInstanceTypeID(ht, typeID);
458 if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)");
459 return (CFHashRef)ht;
bd5b749c
A
460}
461
462#if CFDictionary
cf7d2af9 463CFHashRef CFSetCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues, const CFSetKeyCallBacks *keyCallBacks, const CFSetValueCallBacks *valueCallBacks) {
bd5b749c
A
464#endif
465#if CFSet || CFBag
cf7d2af9
A
466CFHashRef CFSetCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues, const CFSetKeyCallBacks *keyCallBacks) {
467 const_any_pointer_t *vlist = klist;
468 const CFSetValueCallBacks *valueCallBacks = 0;
bd5b749c 469#endif
cf7d2af9 470 CFTypeID typeID = CFSetGetTypeID();
bd5b749c 471 CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
cf7d2af9 472 CFBasicHashRef ht = __CFSetCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary);
856091c5 473 if (!ht) return NULL;
cf7d2af9 474 if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
bd5b749c 475 for (CFIndex idx = 0; idx < numValues; idx++) {
cf7d2af9 476 CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
bd5b749c 477 }
cf7d2af9
A
478 CFBasicHashMakeImmutable(ht);
479 *(uintptr_t *)ht = __CFISAForTypeID(typeID);
480 _CFRuntimeSetInstanceTypeID(ht, typeID);
481 if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)");
482 return (CFHashRef)ht;
bd5b749c
A
483}
484
485#if CFDictionary
486CFMutableHashRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFSetKeyCallBacks *keyCallBacks, const CFSetValueCallBacks *valueCallBacks) {
487#endif
488#if CFSet || CFBag
489CFMutableHashRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFSetKeyCallBacks *keyCallBacks) {
cf7d2af9 490 const CFSetValueCallBacks *valueCallBacks = 0;
bd5b749c 491#endif
cf7d2af9 492 CFTypeID typeID = CFSetGetTypeID();
bd5b749c 493 CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
cf7d2af9 494 CFBasicHashRef ht = __CFSetCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary);
856091c5 495 if (!ht) return NULL;
cf7d2af9
A
496 *(uintptr_t *)ht = __CFISAForTypeID(typeID);
497 _CFRuntimeSetInstanceTypeID(ht, typeID);
498 if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (mutable)");
499 return (CFMutableHashRef)ht;
bd5b749c
A
500}
501
cf7d2af9
A
502CFHashRef CFSetCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
503 CFTypeID typeID = CFSetGetTypeID();
504 CFAssert1(other, __kCFLogAssertion, "%s(): other CFSet cannot be NULL", __PRETTY_FUNCTION__);
505 __CFGenericValidateType(other, typeID);
506 CFBasicHashRef ht = NULL;
507 if (CF_IS_OBJC(typeID, other)) {
508 CFIndex numValues = CFSetGetCount(other);
509 const_any_pointer_t vbuffer[256], kbuffer[256];
510 const_any_pointer_t *vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0);
bd5b749c 511#if CFSet || CFBag
cf7d2af9
A
512 const_any_pointer_t *klist = vlist;
513 CFSetGetValues(other, vlist);
bd5b749c
A
514#endif
515#if CFDictionary
cf7d2af9
A
516 const_any_pointer_t *klist = (numValues <= 256) ? kbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0);
517 CFDictionaryGetKeysAndValues(other, klist, vlist);
bd5b749c 518#endif
cf7d2af9 519 ht = __CFSetCreateGeneric(allocator, & kCFTypeSetKeyCallBacks, CFDictionary ? & kCFTypeSetValueCallBacks : NULL, CFDictionary);
856091c5
A
520 if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues);
521 for (CFIndex idx = 0; ht && idx < numValues; idx++) {
cf7d2af9 522 CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
bd5b749c 523 }
cf7d2af9
A
524 if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist);
525 if (vlist != vbuffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist);
526 } else {
527 ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
bd5b749c 528 }
856091c5 529 if (!ht) return NULL;
cf7d2af9
A
530 CFBasicHashMakeImmutable(ht);
531 *(uintptr_t *)ht = __CFISAForTypeID(typeID);
532 _CFRuntimeSetInstanceTypeID(ht, typeID);
533 if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)");
534 return (CFHashRef)ht;
bd5b749c
A
535}
536
537CFMutableHashRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFHashRef other) {
cf7d2af9
A
538 CFTypeID typeID = CFSetGetTypeID();
539 CFAssert1(other, __kCFLogAssertion, "%s(): other CFSet cannot be NULL", __PRETTY_FUNCTION__);
540 __CFGenericValidateType(other, typeID);
541 CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
542 CFBasicHashRef ht = NULL;
543 if (CF_IS_OBJC(typeID, other)) {
544 CFIndex numValues = CFSetGetCount(other);
545 const_any_pointer_t vbuffer[256], kbuffer[256];
546 const_any_pointer_t *vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0);
bd5b749c 547#if CFSet || CFBag
cf7d2af9
A
548 const_any_pointer_t *klist = vlist;
549 CFSetGetValues(other, vlist);
bd5b749c
A
550#endif
551#if CFDictionary
cf7d2af9
A
552 const_any_pointer_t *klist = (numValues <= 256) ? kbuffer : (const_any_pointer_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, numValues * sizeof(const_any_pointer_t), 0);
553 CFDictionaryGetKeysAndValues(other, klist, vlist);
bd5b749c 554#endif
cf7d2af9 555 ht = __CFSetCreateGeneric(allocator, & kCFTypeSetKeyCallBacks, CFDictionary ? & kCFTypeSetValueCallBacks : NULL, CFDictionary);
856091c5
A
556 if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues);
557 for (CFIndex idx = 0; ht && idx < numValues; idx++) {
cf7d2af9
A
558 CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
559 }
560 if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist);
561 if (vlist != vbuffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist);
bd5b749c 562 } else {
cf7d2af9 563 ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
bd5b749c 564 }
856091c5 565 if (!ht) return NULL;
cf7d2af9
A
566 *(uintptr_t *)ht = __CFISAForTypeID(typeID);
567 _CFRuntimeSetInstanceTypeID(ht, typeID);
568 if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (mutable)");
569 return (CFMutableHashRef)ht;
bd5b749c
A
570}
571
572CFIndex CFSetGetCount(CFHashRef hc) {
856091c5
A
573 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSDictionary *)hc, count);
574 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSSet *)hc, count);
cf7d2af9
A
575 __CFGenericValidateType(hc, __kCFSetTypeID);
576 return CFBasicHashGetCount((CFBasicHashRef)hc);
bd5b749c
A
577}
578
579#if CFDictionary
580CFIndex CFSetGetCountOfKey(CFHashRef hc, const_any_pointer_t key) {
581#endif
582#if CFSet || CFBag
583CFIndex CFSetGetCountOfValue(CFHashRef hc, const_any_pointer_t key) {
584#endif
856091c5
A
585 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSDictionary *)hc, countForKey:(id)key);
586 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSSet *)hc, countForObject:(id)key);
cf7d2af9
A
587 __CFGenericValidateType(hc, __kCFSetTypeID);
588 return CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key);
bd5b749c
A
589}
590
591#if CFDictionary
592Boolean CFSetContainsKey(CFHashRef hc, const_any_pointer_t key) {
593#endif
594#if CFSet || CFBag
595Boolean CFSetContainsValue(CFHashRef hc, const_any_pointer_t key) {
596#endif
856091c5
A
597 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, char, (NSDictionary *)hc, containsKey:(id)key);
598 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, char, (NSSet *)hc, containsObject:(id)key);
cf7d2af9
A
599 __CFGenericValidateType(hc, __kCFSetTypeID);
600 return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key));
bd5b749c
A
601}
602
cf7d2af9 603const_any_pointer_t CFSetGetValue(CFHashRef hc, const_any_pointer_t key) {
856091c5
A
604 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, const_any_pointer_t, (NSDictionary *)hc, objectForKey:(id)key);
605 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, const_any_pointer_t, (NSSet *)hc, member:(id)key);
cf7d2af9
A
606 __CFGenericValidateType(hc, __kCFSetTypeID);
607 CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
608 return (0 < bkt.count ? (const_any_pointer_t)bkt.weak_value : 0);
bd5b749c
A
609}
610
cf7d2af9 611Boolean CFSetGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) {
856091c5
A
612 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key);
613 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key);
cf7d2af9
A
614 __CFGenericValidateType(hc, __kCFSetTypeID);
615 CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
616 if (0 < bkt.count) {
617 if (value) {
618 if (kCFUseCollectableAllocator && (CFBasicHashGetFlags((CFBasicHashRef)hc) & kCFBasicHashStrongValues)) {
619 __CFAssignWithWriteBarrier((void **)value, (void *)bkt.weak_value);
620 } else {
621 *value = (const_any_pointer_t)bkt.weak_value;
bd5b749c
A
622 }
623 }
cf7d2af9 624 return true;
bd5b749c
A
625 }
626 return false;
627}
bd5b749c 628
cf7d2af9
A
629#if CFDictionary
630CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t value) {
856091c5 631 CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSDictionary *)hc, countForObject:(id)value);
cf7d2af9
A
632 __CFGenericValidateType(hc, __kCFSetTypeID);
633 return CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value);
bd5b749c
A
634}
635
cf7d2af9 636Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t value) {
856091c5 637 CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, char, (NSDictionary *)hc, containsObject:(id)value);
cf7d2af9
A
638 __CFGenericValidateType(hc, __kCFSetTypeID);
639 return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value));
bd5b749c
A
640}
641
cf7d2af9 642CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) {
cf7d2af9
A
643 __CFGenericValidateType(hc, __kCFSetTypeID);
644 CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
645 if (0 < bkt.count) {
646 if (actualkey) {
647 if (kCFUseCollectableAllocator && (CFBasicHashGetFlags((CFBasicHashRef)hc) & kCFBasicHashStrongKeys)) {
648 __CFAssignWithWriteBarrier((void **)actualkey, (void *)bkt.weak_key);
649 } else {
650 *actualkey = (const_any_pointer_t)bkt.weak_key;
651 }
652 }
653 return true;
654 }
655 return false;
bd5b749c
A
656}
657#endif
658
659#if CFDictionary
660void CFSetGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, const_any_pointer_t *valuebuf) {
661#endif
662#if CFSet || CFBag
663void CFSetGetValues(CFHashRef hc, const_any_pointer_t *keybuf) {
664 const_any_pointer_t *valuebuf = 0;
665#endif
856091c5
A
666 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf);
667 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSSet *)hc, getObjects:(id *)keybuf);
cf7d2af9
A
668 __CFGenericValidateType(hc, __kCFSetTypeID);
669 if (kCFUseCollectableAllocator) {
670 CFOptionFlags flags = CFBasicHashGetFlags((CFBasicHashRef)hc);
8ca704e1
A
671 __block const_any_pointer_t *keys = keybuf;
672 __block const_any_pointer_t *values = valuebuf;
cf7d2af9
A
673 CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) {
674 for (CFIndex cnt = bkt.count; cnt--;) {
675 if (keybuf && (flags & kCFBasicHashStrongKeys)) { __CFAssignWithWriteBarrier((void **)keys, (void *)bkt.weak_key); keys++; }
676 if (keybuf && !(flags & kCFBasicHashStrongKeys)) { *keys++ = (const_any_pointer_t)bkt.weak_key; }
677 if (valuebuf && (flags & kCFBasicHashStrongValues)) { __CFAssignWithWriteBarrier((void **)values, (void *)bkt.weak_value); values++; }
678 if (valuebuf && !(flags & kCFBasicHashStrongValues)) { *values++ = (const_any_pointer_t)bkt.weak_value; }
679 }
680 return (Boolean)true;
681 });
682 } else {
8ca704e1 683 CFBasicHashGetElements((CFBasicHashRef)hc, CFSetGetCount(hc), (uintptr_t *)valuebuf, (uintptr_t *)keybuf);
bd5b749c 684 }
bd5b749c 685}
bd5b749c
A
686
687void CFSetApplyFunction(CFHashRef hc, CFSetApplierFunction applier, any_pointer_t context) {
688 FAULT_CALLBACK((void **)&(applier));
856091c5
A
689 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context);
690 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context);
cf7d2af9
A
691 __CFGenericValidateType(hc, __kCFSetTypeID);
692 CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) {
bd5b749c 693#if CFDictionary
cf7d2af9 694 INVOKE_CALLBACK3(applier, (const_any_pointer_t)bkt.weak_key, (const_any_pointer_t)bkt.weak_value, context);
bd5b749c 695#endif
cf7d2af9
A
696#if CFSet
697 INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context);
bd5b749c 698#endif
cf7d2af9
A
699#if CFBag
700 for (CFIndex cnt = bkt.count; cnt--;) {
701 INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context);
bd5b749c 702 }
cf7d2af9
A
703#endif
704 return (Boolean)true;
705 });
bd5b749c
A
706}
707
cf7d2af9
A
708// This function is for Foundation's benefit; no one else should use it.
709CF_EXPORT unsigned long _CFSetFastEnumeration(CFHashRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) {
710 if (CF_IS_OBJC(__kCFSetTypeID, hc)) return 0;
711 __CFGenericValidateType(hc, __kCFSetTypeID);
712 return __CFBasicHashFastEnumeration((CFBasicHashRef)hc, (struct __objcFastEnumerationStateEquivalent2 *)state, stackbuffer, count);
bd5b749c
A
713}
714
715// This function is for Foundation's benefit; no one else should use it.
cf7d2af9
A
716CF_EXPORT Boolean _CFSetIsMutable(CFHashRef hc) {
717 if (CF_IS_OBJC(__kCFSetTypeID, hc)) return false;
718 __CFGenericValidateType(hc, __kCFSetTypeID);
719 return CFBasicHashIsMutable((CFBasicHashRef)hc);
bd5b749c
A
720}
721
cf7d2af9
A
722// This function is for Foundation's benefit; no one else should use it.
723CF_EXPORT void _CFSetSetCapacity(CFMutableHashRef hc, CFIndex cap) {
724 if (CF_IS_OBJC(__kCFSetTypeID, hc)) return;
725 __CFGenericValidateType(hc, __kCFSetTypeID);
726 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
727 CFAssert3(CFSetGetCount(hc) <= cap, __kCFLogAssertion, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__, cap, CFSetGetCount(hc));
728 CFBasicHashSetCapacity((CFBasicHashRef)hc, cap);
729}
730
731CF_INLINE CFIndex __CFSetGetKVOBit(CFHashRef hc) {
732 return __CFBitfieldGetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0);
733}
734
735CF_INLINE void __CFSetSetKVOBit(CFHashRef hc, CFIndex bit) {
736 __CFBitfieldSetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0, ((uintptr_t)bit & 0x1));
737}
738
739// This function is for Foundation's benefit; no one else should use it.
740CF_EXPORT CFIndex _CFSetGetKVOBit(CFHashRef hc) {
741 return __CFSetGetKVOBit(hc);
742}
743
744// This function is for Foundation's benefit; no one else should use it.
745CF_EXPORT void _CFSetSetKVOBit(CFHashRef hc, CFIndex bit) {
746 __CFSetSetKVOBit(hc, bit);
747}
748
749
750#if !defined(CF_OBJC_KVO_WILLCHANGE)
751#define CF_OBJC_KVO_WILLCHANGE(obj, key)
752#define CF_OBJC_KVO_DIDCHANGE(obj, key)
753#define CF_OBJC_KVO_WILLCHANGEALL(obj)
754#define CF_OBJC_KVO_DIDCHANGEALL(obj)
755#endif
bd5b749c
A
756
757#if CFDictionary
758void CFSetAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) {
759#endif
760#if CFSet || CFBag
761void CFSetAddValue(CFMutableHashRef hc, const_any_pointer_t key) {
cf7d2af9 762 const_any_pointer_t value = key;
bd5b749c 763#endif
856091c5
A
764 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key);
765 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, addObject:(id)key);
cf7d2af9
A
766 __CFGenericValidateType(hc, __kCFSetTypeID);
767 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
768 if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
769 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc);
bd5b749c 770 }
cf7d2af9
A
771 CF_OBJC_KVO_WILLCHANGE(hc, key);
772 CFBasicHashAddValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value);
773 CF_OBJC_KVO_DIDCHANGE(hc, key);
bd5b749c
A
774}
775
776#if CFDictionary
777void CFSetReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) {
778#endif
779#if CFSet || CFBag
780void CFSetReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) {
cf7d2af9 781 const_any_pointer_t value = key;
bd5b749c 782#endif
856091c5
A
783 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key);
784 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSSet *)hc, replaceObject:(id)key);
cf7d2af9
A
785 __CFGenericValidateType(hc, __kCFSetTypeID);
786 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
787 if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
788 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc);
bd5b749c 789 }
cf7d2af9
A
790 CF_OBJC_KVO_WILLCHANGE(hc, key);
791 CFBasicHashReplaceValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value);
792 CF_OBJC_KVO_DIDCHANGE(hc, key);
bd5b749c
A
793}
794
795#if CFDictionary
796void CFSetSetValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) {
797#endif
798#if CFSet || CFBag
799void CFSetSetValue(CFMutableHashRef hc, const_any_pointer_t key) {
cf7d2af9 800 const_any_pointer_t value = key;
bd5b749c 801#endif
856091c5
A
802 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, setObject:(id)value forKey:(id)key);
803 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, setObject:(id)key);
cf7d2af9
A
804 __CFGenericValidateType(hc, __kCFSetTypeID);
805 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
806 if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
807 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc);
bd5b749c 808 }
cf7d2af9
A
809 CF_OBJC_KVO_WILLCHANGE(hc, key);
810//#warning this for a dictionary used to not replace the key
811 CFBasicHashSetValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value);
812 CF_OBJC_KVO_DIDCHANGE(hc, key);
bd5b749c
A
813}
814
815void CFSetRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) {
856091c5
A
816 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key);
817 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, removeObject:(id)key);
cf7d2af9
A
818 __CFGenericValidateType(hc, __kCFSetTypeID);
819 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
820 if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
821 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc);
bd5b749c 822 }
cf7d2af9
A
823 CF_OBJC_KVO_WILLCHANGE(hc, key);
824 CFBasicHashRemoveValue((CFBasicHashRef)hc, (uintptr_t)key);
825 CF_OBJC_KVO_DIDCHANGE(hc, key);
bd5b749c
A
826}
827
828void CFSetRemoveAllValues(CFMutableHashRef hc) {
856091c5
A
829 if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, removeAllObjects);
830 if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, removeAllObjects);
cf7d2af9
A
831 __CFGenericValidateType(hc, __kCFSetTypeID);
832 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
833 if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
834 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__, hc);
bd5b749c 835 }
cf7d2af9
A
836 CF_OBJC_KVO_WILLCHANGEALL(hc);
837 CFBasicHashRemoveAllValues((CFBasicHashRef)hc);
838 CF_OBJC_KVO_DIDCHANGEALL(hc);
bd5b749c
A
839}
840
841#undef CF_OBJC_KVO_WILLCHANGE
842#undef CF_OBJC_KVO_DIDCHANGE
cf7d2af9
A
843#undef CF_OBJC_KVO_WILLCHANGEALL
844#undef CF_OBJC_KVO_DIDCHANGEALL
bd5b749c 845