NSIndexSet: Implement enumerateRangesInRange convenience methods

This commit is contained in:
hmelder 2024-05-06 16:46:05 +02:00 committed by Hugo Melder
parent 2a5287f878
commit 6155329b64
2 changed files with 111 additions and 0 deletions

View file

@ -113,6 +113,19 @@ DEFINE_BLOCK_TYPE(GSIndexSetEnumerationBlock, void, NSUInteger, BOOL*);
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_7,GS_API_LATEST)
DEFINE_BLOCK_TYPE(GSIndexSetRangeEnumerationBlock, void, NSRange, BOOL*);
- (void)enumerateRangesInRange:(NSRange)range
options:(NSEnumerationOptions)opts
usingBlock:(GSIndexSetRangeEnumerationBlock)aBlock;
- (void)enumerateRangesUsingBlock:(GSIndexSetRangeEnumerationBlock)aBlock;
- (void)enumerateRangesWithOptions:(NSEnumerationOptions)opts
usingBlock:(GSIndexSetRangeEnumerationBlock)aBlock;
#endif
/**
* Returns the first index value in the receiver or NSNotFound if the
* receiver is empty.

View file

@ -852,6 +852,104 @@ static NSUInteger posForIndex(GSIArray array, NSUInteger index)
return [c initWithIndexSet: self];
}
- (void)enumerateRangesInRange:(NSRange)range
options:(NSEnumerationOptions)opts
usingBlock:(GSIndexSetRangeEnumerationBlock)aBlock
{
NSUInteger startArrayIndex;
NSUInteger endArrayIndex;
NSUInteger lastInRange;
NSUInteger i;
NSUInteger c;
BOOL isReverse = opts & NSEnumerationReverse;
BLOCK_SCOPE BOOL shouldStop = NO;
if ((0 == [self count]) || (NSNotFound == range.location))
{
return;
}
startArrayIndex = posForIndex(_array, range.location);
if (NSNotFound == startArrayIndex)
{
// FIXME: Should we error out?
startArrayIndex = 0;
}
lastInRange = (NSMaxRange(range) - 1);
endArrayIndex = MIN(posForIndex(_array, lastInRange),
(GSIArrayCount(_array) - 1));
if (NSNotFound == endArrayIndex)
{
// FIXME: Should we error out?
endArrayIndex = GSIArrayCount(_array) - 1;
}
if (isReverse)
{
i = endArrayIndex;
c = startArrayIndex;
}
else
{
i = startArrayIndex;
c = endArrayIndex;
}
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
while (isReverse ? i >= c : i <= c)
{
NSRange r = GSIArrayItemAtIndex(_array, i).ext;
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue,
if (shouldStop == NO) {, },
aBlock, r, &shouldStop);
if (shouldStop)
{
break;
}
if (isReverse)
{
if (0 == i)
{
break;
}
i--;
}
else
{
i++;
}
}
GS_DISPATCH_TEARDOWN_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
}
- (void)enumerateRangesUsingBlock:(GSIndexSetRangeEnumerationBlock)aBlock
{
[self enumerateRangesWithOptions: 0 usingBlock: aBlock];
}
- (void)enumerateRangesWithOptions:(NSEnumerationOptions)opts
usingBlock:(GSIndexSetRangeEnumerationBlock)aBlock
{
NSUInteger firstIndex;
NSUInteger lastIndex;
NSRange range;
firstIndex = [self firstIndex];
if (NSNotFound == firstIndex)
{
return;
}
lastIndex = [self lastIndex];
range = NSMakeRange(firstIndex, ((lastIndex - firstIndex) + 1));
[self enumerateRangesInRange: range options: opts usingBlock: aBlock];
}
- (void) enumerateIndexesInRange: (NSRange)range
options: (NSEnumerationOptions)opts