Implement fast enumeration for GSMutableOrderedSet.

Implement fast version of getObjects:range: in GSOrderedSet. This
gets used for fast enumeration.
Base the array method on fast enumeration.
This commit is contained in:
fredkiefer 2019-06-29 20:08:01 +02:00
parent baef055670
commit fb3930df96
2 changed files with 47 additions and 5 deletions

View file

@ -227,6 +227,21 @@ static Class mutableSetClass;
return item.obj;
}
- (void) getObjects: (__unsafe_unretained id[])aBuffer range: (NSRange)aRange
{
NSUInteger i, j = 0;
NSUInteger c = GSIArrayCount(&array);
NSUInteger e = NSMaxRange(aRange);
GS_RANGE_CHECK(aRange, c);
for (i = aRange.location; i < e; i++)
{
GSIArrayItem item = GSIArrayItemAtIndex(&array, i);
aBuffer[j++] = item.obj;
}
}
/* Designated initialiser */
- (id) initWithObjects: (const id*)objs count: (NSUInteger)c
{
@ -345,4 +360,33 @@ static Class mutableSetClass;
return self;
}
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state
objects: (__unsafe_unretained id[])stackbuf
count: (NSUInteger)len
{
NSInteger count;
/* This is cached in the caller at the start and compared at each
* iteration. If it changes during the iteration then
* objc_enumerationMutation() will be called, throwing an exception.
*/
state->mutationsPtr = &_version;
count = MIN(len, [self count] - state->state);
/* If a mutation has occurred then it's possible that we are being asked to
* get objects from after the end of the array. Don't pass negative values
* to memcpy.
*/
if (count > 0)
{
[self getObjects: stackbuf range: NSMakeRange(state->state, count)];
state->state += count;
}
else
{
count = 0;
}
state->itemsPtr = stackbuf;
return count;
}
@end

View file

@ -1263,14 +1263,12 @@ static SEL remSel;
- (NSArray *) array
{
NSEnumerator *en = [self objectEnumerator];
NSMutableArray *result = [NSMutableArray arrayWithCapacity: [self count]];
id o = nil;
id<NSFastEnumeration> enumerator = self;
while((o = [en nextObject]) != nil)
{
FOR_IN(id, o, enumerator)
[result addObject: o];
}
END_FOR_IN(enumerator)
return GS_IMMUTABLE(result);
}