Skip to content
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

Merged
merged 8 commits into from
Mar 23, 2017

Conversation

aballway
Copy link
Contributor

fixes #2070
fixes #2072

@@ -965,33 +941,44 @@ - (NSString*)descriptionWithLocale:(id)locale indent:(NSUInteger)level {
}

/**
@Status Stub
@Status Interoperable
@Notes

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

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]];

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

Copy link
Contributor Author

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?

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 :)

Copy link
Contributor Author

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

format:@"Range {%d, %d} larger than array of size %d.", range.location, range.length, [self count]];
}

NSUInteger end = NSMaxRange(range);

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(...)


NSUInteger end = NSMaxRange(range);
for (NSUInteger i = range.location; i < end; ++i) {
if ([self objectAtIndex:i] == anObject) {

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.

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.

Copy link
Contributor Author

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

@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];
Copy link

@DHowett-MSFT DHowett-MSFT Mar 15, 2017

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

Copy link
Contributor Author

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.

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.

@aballway aballway changed the base branch from packaging to develop March 16, 2017 15:51
@@ -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) {

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?

Copy link
Contributor Author

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

NSUInteger end = NSMaxRange(range);
if (end > [self count]) {
[NSException raise:NSRangeException
format:@"[%s %s]: range {%d, %d} extends beyond bounds [ 0 .. %d]",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: missing - before [%s

@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];

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.

@aballway aballway merged commit cd1c143 into microsoft:develop Mar 23, 2017
@aballway aballway deleted the nsarray branch April 25, 2017 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants