2025-01-19 08:42:12 +00:00
|
|
|
#import <Foundation/Foundation.h>
|
2021-08-11 13:49:31 +00:00
|
|
|
#import "ObjectTesting.h"
|
|
|
|
#import "../../../Source/GSFastEnumeration.h"
|
|
|
|
|
2025-01-18 18:02:39 +00:00
|
|
|
static SEL add;
|
|
|
|
static SEL set;
|
|
|
|
static SEL key;
|
|
|
|
|
2025-01-19 08:42:12 +00:00
|
|
|
@implementation NSPointerArray (TestHelpers)
|
|
|
|
- (void) addObject: (id)anObject
|
|
|
|
{
|
|
|
|
[self addPointer: anObject];
|
|
|
|
}
|
|
|
|
- (void) removeObject: (id)anObject
|
|
|
|
{
|
|
|
|
int i = [self count];
|
|
|
|
|
|
|
|
while (i-- > 0)
|
|
|
|
{
|
|
|
|
if ([self pointerAtIndex: i] == (void*)anObject)
|
|
|
|
{
|
|
|
|
[self removePointerAtIndex: i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
2021-08-11 13:49:31 +00:00
|
|
|
void fast_enumeration_mutation_add(id mutableCollection)
|
|
|
|
{
|
2025-01-18 18:02:39 +00:00
|
|
|
NSUInteger i = 0;
|
2025-01-19 09:41:49 +00:00
|
|
|
NSUInteger c = [mutableCollection count]/2;
|
2025-01-18 18:02:39 +00:00
|
|
|
|
2021-08-11 13:49:31 +00:00
|
|
|
FOR_IN(id, o, mutableCollection)
|
2025-01-19 09:41:49 +00:00
|
|
|
if (i == c)
|
2025-01-18 18:02:39 +00:00
|
|
|
{
|
|
|
|
if ([mutableCollection respondsToSelector: set])
|
|
|
|
{
|
|
|
|
[mutableCollection setObject: @"boom" forKey: @"boom"];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[mutableCollection addObject: @"boom"];
|
|
|
|
}
|
2021-08-11 13:49:31 +00:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
END_FOR_IN(mutableCollection)
|
|
|
|
}
|
|
|
|
|
|
|
|
void fast_enumeration_mutation_remove(id mutableCollection)
|
|
|
|
{
|
2025-01-18 18:02:39 +00:00
|
|
|
NSUInteger i = 0;
|
2025-01-19 09:41:49 +00:00
|
|
|
NSUInteger c = [mutableCollection count]/2;
|
2025-01-18 18:02:39 +00:00
|
|
|
|
2021-08-11 13:49:31 +00:00
|
|
|
FOR_IN(id, o, mutableCollection)
|
2025-01-19 09:41:49 +00:00
|
|
|
if (i == c)
|
2025-01-18 18:02:39 +00:00
|
|
|
{
|
|
|
|
if ([mutableCollection respondsToSelector: key])
|
|
|
|
{
|
|
|
|
[mutableCollection removeObjectForKey: o];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[mutableCollection removeObject: o];
|
|
|
|
}
|
2021-08-11 13:49:31 +00:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
END_FOR_IN(mutableCollection)
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_fast_enumeration(id collection, NSArray *objects)
|
|
|
|
{
|
2024-11-15 20:48:09 +00:00
|
|
|
NSMutableArray *returnedObjects = [NSMutableArray array];
|
|
|
|
|
2021-08-11 13:49:31 +00:00
|
|
|
FOR_IN(id, o, collection)
|
2024-11-15 20:48:09 +00:00
|
|
|
[returnedObjects addObject: o];
|
2021-08-11 13:49:31 +00:00
|
|
|
END_FOR_IN(collection)
|
2024-11-15 20:48:09 +00:00
|
|
|
if (!([collection isKindOfClass: [NSArray class]]
|
|
|
|
|| [collection isKindOfClass: [NSOrderedSet class]]))
|
|
|
|
{
|
|
|
|
[returnedObjects sortUsingSelector: @selector(compare:)];
|
|
|
|
}
|
|
|
|
PASS_EQUAL(returnedObjects, objects, "fast enumeration returns all objects")
|
|
|
|
|
2025-01-18 18:02:39 +00:00
|
|
|
id mutableCollection;
|
|
|
|
if ([collection respondsToSelector: @selector(mutableCopyWithZone:)])
|
|
|
|
{
|
|
|
|
mutableCollection = AUTORELEASE([collection mutableCopy]);
|
|
|
|
}
|
|
|
|
else if ([collection respondsToSelector: add]
|
|
|
|
|| [collection respondsToSelector: set])
|
|
|
|
{
|
|
|
|
mutableCollection = collection; // It has a method to mutate it
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return; // No mutable version
|
|
|
|
}
|
2021-08-11 13:49:31 +00:00
|
|
|
PASS_EXCEPTION(
|
|
|
|
fast_enumeration_mutation_add(mutableCollection),
|
|
|
|
NSGenericException,
|
2024-11-15 20:48:09 +00:00
|
|
|
"Fast enumeration mutation add properly calls @\"NSGenericException\"")
|
2021-08-11 13:49:31 +00:00
|
|
|
PASS_EXCEPTION(
|
|
|
|
fast_enumeration_mutation_remove(mutableCollection),
|
|
|
|
NSGenericException,
|
2024-11-15 20:48:09 +00:00
|
|
|
"Fast enumeration mutation remove properly calls @\"NSGenericException\"")
|
2021-08-11 13:49:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
2025-01-18 18:02:39 +00:00
|
|
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
|
|
|
NSMutableArray *objects = [NSMutableArray array];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
add = @selector(addObject:);
|
|
|
|
set = @selector(setObject:forKey:);
|
|
|
|
key = @selector(removeObjectForKey:);
|
|
|
|
|
2025-01-19 09:41:49 +00:00
|
|
|
for (i = 0; i < 1000; i++)
|
2025-01-18 18:02:39 +00:00
|
|
|
{
|
|
|
|
[objects addObject: [NSString stringWithFormat: @"%.4d", i]];
|
|
|
|
}
|
2021-08-11 13:49:31 +00:00
|
|
|
|
|
|
|
START_SET("NSArray")
|
2024-11-15 20:48:09 +00:00
|
|
|
id array = [NSArray arrayWithArray: objects];
|
2021-08-11 13:49:31 +00:00
|
|
|
test_fast_enumeration(array, objects);
|
|
|
|
END_SET("NSArray")
|
|
|
|
|
|
|
|
START_SET("NSSet")
|
2024-11-15 20:48:09 +00:00
|
|
|
id set = [NSSet setWithArray: objects];
|
2021-08-11 13:49:31 +00:00
|
|
|
test_fast_enumeration(set, objects);
|
|
|
|
END_SET("NSSet")
|
|
|
|
|
|
|
|
START_SET("NSOrderedSet")
|
2024-11-15 20:48:09 +00:00
|
|
|
id orderedSet = [NSOrderedSet orderedSetWithArray: objects];
|
2021-08-11 13:49:31 +00:00
|
|
|
test_fast_enumeration(orderedSet, objects);
|
|
|
|
END_SET("NSOrderedSet")
|
|
|
|
|
|
|
|
START_SET("NSDictionary")
|
2024-11-15 20:48:09 +00:00
|
|
|
id dict = [NSDictionary dictionaryWithObjects: objects forKeys: objects];
|
2021-08-11 13:49:31 +00:00
|
|
|
test_fast_enumeration(dict, objects);
|
|
|
|
END_SET("NSDictionary")
|
|
|
|
|
2025-01-18 18:02:39 +00:00
|
|
|
START_SET("NSMapTable")
|
|
|
|
id map = [NSMapTable strongToStrongObjectsMapTable];
|
|
|
|
FOR_IN(id, o, objects)
|
|
|
|
[map setObject: o forKey: o];
|
|
|
|
END_FOR_IN(objects)
|
|
|
|
test_fast_enumeration(map, objects);
|
|
|
|
END_SET("NSMapTable")
|
|
|
|
|
|
|
|
START_SET("NSHashTable")
|
|
|
|
id table = [NSHashTable weakObjectsHashTable];
|
|
|
|
FOR_IN(id, o, objects)
|
|
|
|
[table addObject: o];
|
|
|
|
END_FOR_IN(objects)
|
|
|
|
test_fast_enumeration(table, objects);
|
|
|
|
END_SET("NSHashTable")
|
|
|
|
|
2025-01-19 08:42:12 +00:00
|
|
|
START_SET("NSPointerArray")
|
|
|
|
id array = [NSPointerArray weakObjectsPointerArray];
|
|
|
|
FOR_IN(id, o, objects)
|
|
|
|
[array addPointer: o];
|
|
|
|
END_FOR_IN(objects)
|
|
|
|
test_fast_enumeration(array, objects);
|
|
|
|
END_SET("NSPointerArray")
|
|
|
|
|
2021-08-11 13:49:31 +00:00
|
|
|
[arp release]; arp = nil;
|
|
|
|
return 0;
|
|
|
|
}
|