-
Notifications
You must be signed in to change notification settings - Fork 806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement NSArray index(es)Of* and enumerateObjectsAtIndexes methods #2236
Conversation
Frameworks/Foundation/NSArray.mm
Outdated
@@ -965,33 +941,44 @@ - (NSString*)descriptionWithLocale:(id)locale indent:(NSUInteger)level { | |||
} | |||
|
|||
/** | |||
@Status Stub | |||
@Status Interoperable | |||
@Notes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove empty notes. <ESC>:g/@Notes$/d
Frameworks/Foundation/NSArray.mm
Outdated
return StubReturn(); | ||
if (range.location + range.length > [self count]) { | ||
[NSException raise:NSRangeException | ||
format:@"Range {%d, %d} larger than array of size %d.", range.location, range.length, [self count]]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't match the other exception formats NSArray uses
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reference platform throws an NSRangeException for invalid ranges, should I opt for consistency here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant the wording was inconsistent :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to reflect exception generated on reference platform
Frameworks/Foundation/NSArray.mm
Outdated
format:@"Range {%d, %d} larger than array of size %d.", range.location, range.length, [self count]]; | ||
} | ||
|
||
NSUInteger end = NSMaxRange(range); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this above 1035 and use end
in the if(...)
Frameworks/Foundation/NSArray.mm
Outdated
|
||
NSUInteger end = NSMaxRange(range); | ||
for (NSUInteger i = range.location; i < end; ++i) { | ||
if ([self objectAtIndex:i] == anObject) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is curious; if you prefer getObjects:range:
, a "fast" NSArray implementation can turn that into an n
-wide buffer copy into your provided buffer. Right now, _NSCFArray doesn't do that... but it could!
Arguably, it should, for optimization purposes. It would call CFArrayGetValues
under the hood.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can apply anywhere you iterate manually over a range.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should I make that part of these changes? I'm wary of changing too much in NSArray for possibly unnecessary optimization
Frameworks/Foundation/NSArray.mm
Outdated
@Notes | ||
*/ | ||
- (NSUInteger)indexOfObjectAtIndexes:(NSIndexSet*)indexSet | ||
options:(NSEnumerationOptions)opts | ||
passingTest:(BOOL (^)(id, NSUInteger, BOOL*))predicate { | ||
UNIMPLEMENTED(); | ||
return StubReturn(); | ||
NSIndexSet* matching = [self indexesOfObjectsAtIndexes:indexSet options:opts passingTest:predicate]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimization:
If you add another level of block here, you can stop enumeration on the first hit instead of continuing to aggregate every index and then discarding the rest of them. #ByDesign
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reference platform will blow up on invalid ranges, even if a valid element is found, and this gives us that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fail to see what that has to do with this; using *stop = YES;
to abort the iteration inside the block still has us calling indexesOfObjects...
and getting the blowing-up behaviour.
Frameworks/Foundation/NSArray.mm
Outdated
@@ -1031,8 +1031,10 @@ - (NSUInteger)indexOfObjectIdenticalTo:(id)anObject inRange:(NSRange)range { | |||
[self count]]; | |||
} | |||
|
|||
id objects[range.length]; | |||
[self getObjects:objects range:range]; | |||
for (NSUInteger i = range.location; i < end; ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: why not i=0, < range.length
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considered it but this was the path of least change, didn't think it made a substantial difference in readability or perf
Frameworks/Foundation/NSArray.mm
Outdated
NSUInteger end = NSMaxRange(range); | ||
if (end > [self count]) { | ||
[NSException raise:NSRangeException | ||
format:@"[%s %s]: range {%d, %d} extends beyond bounds [ 0 .. %d]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: missing -
before [%s
Frameworks/Foundation/NSArray.mm
Outdated
@Notes | ||
*/ | ||
- (NSUInteger)indexOfObjectAtIndexes:(NSIndexSet*)indexSet | ||
options:(NSEnumerationOptions)opts | ||
passingTest:(BOOL (^)(id, NSUInteger, BOOL*))predicate { | ||
UNIMPLEMENTED(); | ||
return StubReturn(); | ||
NSIndexSet* matching = [self indexesOfObjectsAtIndexes:indexSet options:opts passingTest:predicate]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fail to see what that has to do with this; using *stop = YES;
to abort the iteration inside the block still has us calling indexesOfObjects...
and getting the blowing-up behaviour.
fixes #2070
fixes #2072