diff --git a/Source/CFBag.c b/Source/CFBag.c index d94da9b6..12f8cd06 100644 --- a/Source/CFBag.c +++ b/Source/CFBag.c @@ -108,7 +108,7 @@ CFBagCreate (CFAllocatorRef allocator, const void **values, CFIndex numValues, { return (CFBagRef)GSHashTableCreate (allocator, _kCFBagTypeID, values, values, numValues, - (const GSHashTableKeyCallBacks*)callBacks, NULL); + (const GSHashTableKeyCallBacks*)callBacks, NULL, true); } CFBagRef diff --git a/Source/CFDictionary.c b/Source/CFDictionary.c index 0945e690..60b27421 100644 --- a/Source/CFDictionary.c +++ b/Source/CFDictionary.c @@ -119,7 +119,7 @@ CFDictionaryCreate (CFAllocatorRef allocator, const void **keys, return (CFDictionaryRef)GSHashTableCreate (allocator, _kCFDictionaryTypeID, keys, values, numValues, (const GSHashTableKeyCallBacks*)keyCallBacks, - (const GSHashTableValueCallBacks*)valueCallBacks); + (const GSHashTableValueCallBacks*)valueCallBacks, false); } CFDictionaryRef diff --git a/Source/CFSet.c b/Source/CFSet.c index cc748744..5d3ca672 100644 --- a/Source/CFSet.c +++ b/Source/CFSet.c @@ -108,7 +108,7 @@ CFSetCreate (CFAllocatorRef allocator, const void **values, CFIndex numValues, return (CFSetRef) GSHashTableCreate (allocator, _kCFSetTypeID, values, values, numValues, (const GSHashTableKeyCallBacks *) - callBacks, NULL); + callBacks, NULL, false); } CFSetRef diff --git a/Source/GSHashTable.c b/Source/GSHashTable.c index 6dc18026..baafefdb 100644 --- a/Source/GSHashTable.c +++ b/Source/GSHashTable.c @@ -268,7 +268,8 @@ GSHashTableRef GSHashTableCreate (CFAllocatorRef alloc, CFTypeID typeID, const void **keys, const void **values, CFIndex numValues, const GSHashTableKeyCallBacks * keyCallBacks, - const GSHashTableValueCallBacks * valueCallBacks) + const GSHashTableValueCallBacks * valueCallBacks, + Boolean shouldCount) { CFIndex arraySize; CFIndex capacity; @@ -290,6 +291,9 @@ GSHashTableCreate (CFAllocatorRef alloc, CFTypeID typeID, new->_capacity = capacity; + if (shouldCount) + GSHashTableSetShouldCount (new); + if (keyCallBacks == NULL) keyCallBacks = &_kGSNullHashTableKeyCallBacks; if (valueCallBacks == NULL) @@ -306,8 +310,12 @@ GSHashTableCreate (CFAllocatorRef alloc, CFTypeID typeID, { bucket = GSHashTableFindBucket (new, keys[idx], _kGSHashTableInsert); - GSHashTableAddKeyValuePair (new, bucket, keys[idx], values[idx]); - new->_count += 1; + if (shouldCount || bucket->count <= 0) + { + GSHashTableAddKeyValuePair (new, bucket, keys[idx], + values[idx]); + new->_count += 1; + } } } } @@ -324,7 +332,8 @@ GSHashTableCreateCopy (CFAllocatorRef alloc, GSHashTableRef table) count = GSHashTableGetCount (table); new = GSHashTableCreate (alloc, CFGetTypeID (table), NULL, NULL, count, &table->_keyCallBacks, - &table->_valueCallBacks); + &table->_valueCallBacks, + GSHashTableShouldCount (table)); if (new) { CFIndex idx; diff --git a/Source/GSHashTable.h b/Source/GSHashTable.h index a6fb0574..c40d2a03 100644 --- a/Source/GSHashTable.h +++ b/Source/GSHashTable.h @@ -92,7 +92,8 @@ GS_PRIVATE GSHashTableRef GSHashTableCreate (CFAllocatorRef alloc, CFTypeID typeID, const void **keys, const void **values, CFIndex count, const GSHashTableKeyCallBacks * keyCallBacks, - const GSHashTableValueCallBacks * valueCallBacks); + const GSHashTableValueCallBacks * valueCallBacks, + Boolean shouldCount); GS_PRIVATE GSHashTableRef GSHashTableCreateCopy (CFAllocatorRef alloc, GSHashTableRef table); diff --git a/Tests/CFDictionary/create_duplicates.m b/Tests/CFDictionary/create_duplicates.m new file mode 100644 index 00000000..f5b3713e --- /dev/null +++ b/Tests/CFDictionary/create_duplicates.m @@ -0,0 +1,27 @@ +#include "CoreFoundation/CFDictionary.h" +#include "CoreFoundation/CFString.h" +#include "../CFTesting.h" + +int main (void) +{ + const void *keys[2]; + const void *values[2]; + CFDictionaryRef dict; + + keys[0] = CFSTR ("k"); + keys[1] = CFSTR ("k"); + values[0] = CFSTR ("v1"); + values[1] = CFSTR ("v2"); + + dict = CFDictionaryCreate (NULL, keys, values, 2, + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + PASS_CF(CFDictionaryGetCount (dict) == 1, + "A key repeated in the input array is stored once."); + PASS_CF(CFDictionaryContainsKey (dict, CFSTR ("k")), + "The key is present."); + + CFRelease (dict); + + return 0; +} diff --git a/Tests/CFSet/create_duplicates.m b/Tests/CFSet/create_duplicates.m new file mode 100644 index 00000000..afbea63c --- /dev/null +++ b/Tests/CFSet/create_duplicates.m @@ -0,0 +1,24 @@ +#include "CoreFoundation/CFSet.h" +#include "CoreFoundation/CFString.h" +#include "../CFTesting.h" + +int main (void) +{ + const void *values[3]; + CFSetRef set; + + values[0] = CFSTR ("a"); + values[1] = CFSTR ("b"); + values[2] = CFSTR ("a"); + + set = CFSetCreate (NULL, values, 3, &kCFTypeSetCallBacks); + PASS_CF(CFSetGetCount (set) == 2, + "A value repeated in the input array is stored once."); + PASS_CF(CFSetContainsValue (set, CFSTR ("a")) + && CFSetContainsValue (set, CFSTR ("b")), + "Both distinct values are present."); + + CFRelease (set); + + return 0; +}