Skip to content

Instantly share code, notes, and snippets.

@pookjw
Created April 20, 2024 15:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pookjw/883be3525558457c228bba4a4b4acaf5 to your computer and use it in GitHub Desktop.
Save pookjw/883be3525558457c228bba4a4b4acaf5 to your computer and use it in GitHub Desktop.
#import <Foundation/Foundation.h>
@interface NSIndexSet (FastEnumeration) <NSFastEnumeration>
@end
@implementation NSIndexSet (FastEnumeration)
- (NSUInteger)countByEnumeratingWithState:(nonnull NSFastEnumerationState *)state objects:(id _Nullable * _Nonnull)buffer count:(NSUInteger)len {
/*
state
- 0 : remaining count
- 1 : hash (mutationsPtr)
*/
NSUInteger count = self.count;
if (state->state == 0) {
// setup initial state
state->state = 1;
state->mutationsPtr = &state->extra[1];
state->extra[0] = count;
}
state->extra[1] = self.hash;
state->itemsPtr = buffer;
if (len == 0) {
return 0;
}
unsigned long remaining = state->extra[0];
if (remaining == 0) {
return 0;
}
NSRange indexRange = NSMakeRange(count - remaining, len);
NSUInteger *indexes = malloc(sizeof(NSUInteger) * len);
NSUInteger indexesCount = [self getIndexes:indexes maxCount:len inIndexRange:&indexRange];
for (NSUInteger i = 0; i < len; i++) {
if (indexesCount <= i) {
buffer[i] = nil;
} else {
buffer[i] = [NSNumber numberWithUnsignedInteger:indexes[i]];
}
}
free(indexes);
NSUInteger newRemaining = remaining - indexesCount;
if (newRemaining > 0) {
state->extra[0] = newRemaining;
return indexesCount;
} else {
// final
state->extra[0] = 0;
return remaining;
}
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 10)];
[indexSet addIndexesInRange:NSMakeRange(10, 10)];
// https://mikeash.com/pyblog/friday-qa-2010-04-16-implementing-fast-enumeration.html
NSAutoreleasePool *pool = [NSAutoreleasePool new];
for (NSNumber *index in indexSet) {
NSLog(@"%@", index);
[pool release];
pool = [NSAutoreleasePool new];
}
[pool release];
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment