NSPointerArray: Implement fast enumeration (#477)

* NSPointerArray: Implement NSFastEnumeration

* NSPointerArray: Test for duplicate values in array

* NSPointerArray: Fast enumeration tests
This commit is contained in:
Hugo Melder 2024-12-13 03:01:07 -08:00 committed by GitHub
parent 4a4a802060
commit 4b3bd1aa90
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 89 additions and 2 deletions

View file

@ -42,7 +42,7 @@ extern "C" {
* or grow (adding nil/zero items).
*/
GS_EXPORT_CLASS
@interface NSPointerArray : NSObject <NSCopying, NSCoding>
@interface NSPointerArray : NSObject <NSCoding, NSCopying, NSFastEnumeration>
/** Allocate an instance, initialise using initWithOptions: and
* return it autoreleased.

View file

@ -197,6 +197,34 @@ static Class concreteClass = Nil;
[self subclassResponsibility: _cmd];
}
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
objects: (__unsafe_unretained id[])stackbuf
count: (NSUInteger)len
{
NSInteger count;
state->mutationsPtr = (unsigned long *)&state->mutationsPtr;
count = MIN(len, [self count] - state->state);
if (count > 0)
{
IMP imp = [self methodForSelector: @selector(pointerAtIndex:)];
int p = state->state;
int i;
for (i = 0; i < count; i++, p++)
{
stackbuf[i] = (*imp)(self, @selector(pointerAtIndex:), p);
}
state->state += count;
}
else
{
count = 0;
}
state->itemsPtr = stackbuf;
return count;
}
@end
@implementation NSPointerArray (NSArrayConveniences)

View file

@ -27,11 +27,13 @@ int main()
PASS([obj count] == 1, "+addPointer: increments count");
[obj addPointer: nil];
PASS([obj count] == 2, "+addPointer: works with nil");
[obj addPointer: nil];
PASS([obj count] == 3, "+addPointer: respects duplicate values");
[obj insertPointer: (void*)vals[0] atIndex: 0];
[obj insertPointer: (void*)vals[1] atIndex: 0];
[obj insertPointer: (void*)vals[2] atIndex: 0];
PASS([obj count] == 5 && [obj pointerAtIndex: 2] == (void*)vals[0],
PASS([obj count] == 6 && [obj pointerAtIndex: 2] == (void*)vals[0],
"+insertPointer:atIndex: works");
LEAVE_POOL

View file

@ -0,0 +1,57 @@
#import "ObjectTesting.h"
#import <Foundation/NSPointerArray.h>
#import <Foundation/NSAutoreleasePool.h>
#if defined(__clang__)
int main()
{
ENTER_POOL
NSPointerArray *obj = AUTORELEASE([NSPointerArray new]);
NSString *str = @"test";
NSString *str2 = @"string";
// Fast iteration over empty pointer array
for (id ptr in obj) {
PASS(0, "No element returned by fast iteration");
}
[obj addPointer: str];
[obj addPointer: str2];
[obj addPointer: nil];
[obj addPointer: nil];
int count = 0;
for (id ptr in obj) {
count += 1;
switch (count) {
case 1:
PASS(ptr == str, "first obj returned is pointer to 'test'");
break;
case 2:
PASS(ptr == str2, "second obj returned is pointer to 'string'");
break;
case 3:
case 4:
PASS(ptr == nil, "third and fourth pointers are nil");
break;
default:
PASS(0, "unexpected count of pointers");
}
}
PASS(count == 4, "got 4 pointers in fast iteration");
LEAVE_POOL
return 0;
}
#else
int main()
{
return 0;
}
#endif