Created
April 20, 2024 15:10
-
-
Save pookjw/883be3525558457c228bba4a4b4acaf5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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