Merge branch 'master' into slevenbits

This commit is contained in:
Alexander Ljungberg
2012-07-08 21:29:08 +01:00
4 changed files with 256 additions and 12 deletions
+146 -4
View File
@@ -315,7 +315,7 @@
var range = _ranges[rangeIndex];
// Check if it's actually in this range.
if (CPLocationInRange(anIndex, range))
if (_CPLocationInRange(anIndex, range))
return anIndex;
// If not, it must be the first element of this range.
@@ -346,7 +346,7 @@
var range = _ranges[rangeIndex];
// Check if it's actually in this range.
if (CPLocationInRange(anIndex, range))
if (_CPLocationInRange(anIndex, range))
return anIndex;
// If not, it must be the first element of this range.
@@ -495,7 +495,7 @@
- (void)enumerateIndexesInRange:(CPRange)enumerationRange options:(CPEnumerationOptions)options usingBlock:(Function /*(int idx, @ref BOOL stop)*/)aFunction
{
if (!_count || CPEmptyRange(enumerationRange))
if (!_count || _CPEmptyRange(enumerationRange))
return;
var shouldStop = NO,
@@ -539,7 +539,7 @@
for (; rangeIndex !== rangeStop; rangeIndex += rangeIncrement)
{
if (CPLocationInRange(rangeIndex, enumerationRange))
if (_CPLocationInRange(rangeIndex, enumerationRange))
{
aFunction(rangeIndex, AT_REF(shouldStop));
if (shouldStop)
@@ -549,6 +549,148 @@
}
}
- (unsigned)indexPassingTest:(Function /*(int anIndex)*/)aPredicate
{
return [self indexWithOptions:CPEnumerationNormal passingTest:aPredicate];
}
- (CPIndexSet)indexesPassingTest:(Function /*(int anIndex)*/)aPredicate
{
return [self indexesWithOptions:CPEnumerationNormal passingTest:aPredicate];
}
- (unsigned)indexWithOptions:(CPEnumerationOptions)anOptions passingTest:(Function /*(int anIndex)*/)aPredicate
{
if (!_count)
return CPNotFound;
return [self indexInRange:_CPMakeRange(0, _CPMaxRange(_ranges[_ranges.length - 1])) options:anOptions passingTest:aPredicate];
}
- (CPIndexSet)indexesWithOptions:(CPEnumerationOptions)anOptions passingTest:(Function /*(int anIndex)*/)aPredicate
{
if (!_count)
return [CPIndexSet indexSet];
return [self indexesInRange:_CPMakeRange(0, _CPMaxRange(_ranges[_ranges.length - 1])) options:anOptions passingTest:aPredicate];
}
- (unsigned)indexInRange:(CPRange)aRange options:(CPEnumerationOptions)anOptions passingTest:(Function /*(int anIndex)*/)aPredicate
{
if (!_count || _CPEmptyRange(aRange))
return CPNotFound;
var shouldStop = NO,
index,
stop,
increment;
if (anOptions & CPEnumerationReverse)
{
index = _ranges.length - 1,
stop = -1,
increment = -1;
}
else
{
index = 0;
stop = _ranges.length;
increment = 1;
}
for (; index !== stop; index += increment)
{
var range = _ranges[index],
rangeIndex,
rangeStop,
rangeIncrement;
if (anOptions & CPEnumerationReverse)
{
rangeIndex = _CPMaxRange(range) - 1;
rangeStop = range.location - 1;
rangeIncrement = -1;
}
else
{
rangeIndex = range.location;
rangeStop = _CPMaxRange(range);
rangeIncrement = 1;
}
for (; rangeIndex !== rangeStop; rangeIndex += rangeIncrement)
{
if (_CPLocationInRange(rangeIndex, aRange))
{
if (aPredicate(rangeIndex, AT_REF(shouldStop)))
return rangeIndex;
if (shouldStop)
return CPNotFound;
}
}
}
return CPNotFound;
}
- (CPIndexSet)indexesInRange:(CPRange)aRange options:(CPEnumerationOptions)anOptions passingTest:(Function /*(int anIndex)*/)aPredicate
{
if (!_count || _CPEmptyRange(aRange))
return [CPIndexSet indexSet];
var shouldStop = NO,
index,
stop,
increment;
if (anOptions & CPEnumerationReverse)
{
index = _ranges.length - 1,
stop = -1,
increment = -1;
}
else
{
index = 0;
stop = _ranges.length;
increment = 1;
}
var indexesPassingTest = [CPMutableIndexSet indexSet];
for (; index !== stop; index += increment)
{
var range = _ranges[index],
rangeIndex,
rangeStop,
rangeIncrement;
if (anOptions & CPEnumerationReverse)
{
rangeIndex = _CPMaxRange(range) - 1;
rangeStop = range.location - 1;
rangeIncrement = -1;
}
else
{
rangeIndex = range.location;
rangeStop = _CPMaxRange(range);
rangeIncrement = 1;
}
for (; rangeIndex !== rangeStop; rangeIndex += rangeIncrement)
{
if (_CPLocationInRange(rangeIndex, aRange))
{
if (aPredicate(rangeIndex, AT_REF(shouldStop)))
[indexesPassingTest addIndex:rangeIndex];
if (shouldStop)
return indexesPassingTest;
}
}
}
return indexesPassingTest;
}
@end
+2
View File
@@ -23,3 +23,5 @@
#define _CPMaxRange(aRange) ((aRange).location + (aRange).length)
#define _CPMakeRange(aLocation, aLength) { location:(aLocation), length:aLength }
#define _CPMakeRangeCopy(aRange) { location:(aRange).location, length:(aRange).length }
#define _CPEmptyRange(aRange) ((aRange).length === 0)
#define _CPLocationInRange(aLocation, aRange) (((aLocation) >= (aRange).location) && ((aLocation) < _CPMaxRange(aRange)))
+2 -8
View File
@@ -52,10 +52,7 @@ _function(CPMakeRangeCopy(aRange))
@group CPRange
@return YES if the range is empty
*/
function CPEmptyRange(aRange)
{
return aRange.length === 0;
}
_function(CPEmptyRange(aRange))
/*!
Finds the range maximum. (\c location + length)
@@ -83,10 +80,7 @@ function CPEqualRanges(lhsRange, rhsRange)
@group CPRange
@return BOOL \c YES if \c aLocation is within the range
*/
function CPLocationInRange(aLocation, aRange)
{
return (aLocation >= aRange.location) && (aLocation < CPMaxRange(aRange));
}
_function(CPLocationInRange(aLocation, aRange))
/*!
Creates a new range with the minimum \c location and a \c length
+106
View File
@@ -543,6 +543,112 @@ function descriptionWithoutEntity(aString)
[self assert:[0, 3] equals:visitedIndexes message:"enumeration should stop after 2 results"];
}
- (void)testIndexPassingTest
{
var set0 = [CPMutableIndexSet indexSet],
index = [set0 indexPassingTest:function(anIndex)
{
return anIndex % 2 === 0;
}];
[self assertTrue:index === CPNotFound message:"must be equal to CPNotFound, was " + index];
[set0 addIndexesInRange:CPMakeRange(1, 10)];
index = [set0 indexPassingTest:function(anIndex)
{
return anIndex % 2 === 0;
}];
[self assertTrue:index === 2 message:"index must be equal to 2"];
index = [set0 indexPassingTest:function(anIndex)
{
return anIndex === 1000;
}];
[self assertTrue:index === CPNotFound message:"must be equal to CPNotFound, was " + index];
}
- (void)testIndexesPassingTest
{
var set0 = [CPMutableIndexSet indexSet],
set1 = [CPMutableIndexSet indexSet],
indexes = [set0 indexesPassingTest:function(anIndex)
{
return anIndex % 2 === 0;
}];
[self assertTrue:[indexes isEqualToIndexSet:set1] message:"must be equal to " + [set1 description] + ", was " + [indexes description]];
[set0 addIndexesInRange:CPMakeRange(1, 10)];
[set1 addIndex:2];
[set1 addIndex:4];
[set1 addIndex:6];
[set1 addIndex:8];
[set1 addIndex:10];
indexes = [set0 indexesPassingTest:function(anIndex)
{
return anIndex % 2 === 0;
}];
[self assertTrue:[indexes isEqualToIndexSet:set1] message:"must be equal to " + [set1 description] + ", was " + [indexes description]];
}
- (void)testIndexPassingTest_options
{
var set0 = [CPMutableIndexSet indexSetWithIndexesInRange:CPMakeRange(1, 10)],
index = [set0 indexWithOptions:CPEnumerationReverse
passingTest:function(anIndex)
{
return anIndex % 2 === 0;
}];
[self assertTrue:index === 10 message:"index must be equal to 10"];
}
- (void)testIndexesPassingTest_options
{
var set0 = [CPMutableIndexSet indexSetWithIndexesInRange:CPMakeRange(1, 5)],
set1 = [CPMutableIndexSet indexSet],
visitedIndexes = [],
indexes = [set0 indexesWithOptions:CPEnumerationReverse
passingTest:function(anIndex)
{
visitedIndexes.push(anIndex);
return anIndex % 2 === 0;
}];
[set1 addIndex:2];
[set1 addIndex:4];
[self assertTrue:[indexes isEqualToIndexSet:set1] message:"must be equal to " + [set1 description] + ", was " + [indexes description]];
[self assert:[5, 4, 3, 2, 1] equals:visitedIndexes message:"enumeration should be done in reverse"];
}
- (void)testIndexPassingTest_options_range
{
var set0 = [CPMutableIndexSet indexSetWithIndexesInRange:CPMakeRange(1, 10)],
index = [set0 indexInRange:CPMakeRange(3, 4)
options:CPEnumerationReverse
passingTest:function(anIndex)
{
return anIndex % 2 === 0;
}];
[self assertTrue:index === 6 message:"index must be equal to 6"];
}
- (void)testIndexesPassingTest_options_range
{
var set0 = [CPMutableIndexSet indexSetWithIndexesInRange:CPMakeRange(1, 5)],
set1 = [CPMutableIndexSet indexSet],
visitedIndexes = [],
indexes = [set0 indexesInRange:CPMakeRange(3, 4)
options:CPEnumerationReverse
passingTest:function(anIndex)
{
visitedIndexes.push(anIndex);
return anIndex % 2 === 0;
}];
[set1 addIndex:4];
[self assertTrue:[indexes isEqualToIndexSet:set1] message:"must be equal to " + [set1 description] + ", was " + [indexes description]];
[self assert:[5, 4, 3] equals:visitedIndexes message:"enumeration should be done in reverse"];
}
- (void)tearDown
{
_set = nil;