Fix remaining failing tests and add indexOfObject:inSortedRange:options:usingComparator:, and removed non-standard methods:

- indexOfObject:sortedBySelector:
- indexOfObject:sortedByFunction:
- indexOfObject:sortedByDescriptors:
- indexOfObject:sortedByFunction:context:

Reviewed by me.
This commit is contained in:
Francisco Ryan Tolmasky I
2010-12-25 21:10:32 -08:00
parent f79c2346a5
commit e45ed19dc7
7 changed files with 113 additions and 182 deletions
+6 -2
View File
@@ -1714,7 +1714,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_heightOfRow_)
{
return idx = [_cachedRowHeights indexOfObject:aPoint sortedByFunction:function(aPoint, rowCache) {
return idx = [_cachedRowHeights indexOfObject:aPoint
inSortedRange:nil
options:0
usingComparator:function(aPoint, rowCache)
{
var upperBound = rowCache.heightAboveRow;
if (aPoint.y < upperBound)
@@ -1724,7 +1728,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
return CPOrderedDescending;
return CPOrderedSame;
}];
}];
}
var y = aPoint.y,
+50 -122
View File
@@ -26,9 +26,15 @@
@import "CPRange.j"
@import "CPSortDescriptor.j"
CPEnumerationNormal = 0;
CPEnumerationConcurrent = 1 << 0;
CPEnumerationReverse = 1 << 1;
CPEnumerationNormal = 0;
CPEnumerationConcurrent = 1 << 0;
CPEnumerationReverse = 1 << 1;
CPBinarySearchingFirstEqual = 1 << 8;
CPBinarySearchingLastEqual = 1 << 9;
CPBinarySearchingInsertionIndex = 1 << 10;
#define FORWARD_TO_CONCRETE_CLASS()\
if (self === _CPSharedPlaceholderArray)\
@@ -393,145 +399,67 @@ CPEnumerationReverse = 1 << 1;
return CPNotFound;
}
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
calling sortUsingSelector: with the selector passed to this method would result in.
@param anObject the object to search for
@param aSelector the comparison selector to call on each item in the list, the same
selector should have been used to sort the array (or to maintain its sorted order).
@return the index of the object, or \c CPNotFound if it was not found.
*/
- (unsigned)indexOfObject:(id)anObject sortedBySelector:(SEL)aSelector
- (CPUInteger)indexOfObject:(id)anObject
inSortedRange:(CPRange)aRange
options:(CPBinarySearchingOptions)options
usingComparator:(Function)aComparator
{
return [self indexOfObject:anObject sortedByFunction:function(lhs, rhs)
{
return objj_msgSend(lhs, aSelector, rhs);
}];
}
// FIXME: comparator is not a function
if (!aComparator)
_CPRaiseInvalidArgumentException(self, _cmd, "comparator is nil");
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
calling sortUsingFunction: with the selector passed to this method would result in.
The function will be called like so:
<pre>
aFunction(anObject, currentObjectInArrayForComparison)
</pre>
@param anObject the object to search for
@param aFunction the comparison function to call on each item in the array that we search. the same
selector should have been used to sort the array (or to maintain its sorted order).
@return the index of the object, or \c CPNotFound if it was not found.
*/
- (unsigned)indexOfObject:(id)anObject sortedByFunction:(Function)aFunction
{
return [self indexOfObject:anObject sortedByFunction:aFunction context:nil];
}
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
calling sortUsingFunction: with the selector passed to this method would result in.
The function will be called like so:
<pre>
aFunction(anObject, currentObjectInArrayForComparison, context)
</pre>
@param anObject the object to search for
@param aFunction the comparison function to call on each item in the array that we search. the same
function should have been used to sort the array (or to maintain its sorted order).
@param aContext a context object that will be passed to the sort function
@return the index of the object, or \c CPNotFound if it was not found.
*/
- (CPUInteger)indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext
{
if (!aFunction)
return CPNotFound;
if ((options & CPBinarySearchingFirstEqual) && (options & CPBinarySearchingLastEqual))
_CPRaiseInvalidArgumentException(self, _cmd,
"both CPBinarySearchingFirstEqual and CPBinarySearchingLastEqual options cannot be specified");
var count = [self count];
if (count <= 0)
return CPNotFound;
return (options & CPBinarySearchingInsertionIndex) ? 0 : CPNotFound;
var mid,
c,
first = 0,
last = count - 1;
var first = aRange ? aRange.location : 0,
last = aRange ? CPMaxRange(aRange) : [self count] - 1;
if (first < 0)
_CPRaiseRangeException(self, _cmd, first, count);
if (last >= count)
_CPRaiseRangeException(self, _cmd, last, count);
while (first <= last)
{
mid = FLOOR((first + last) / 2);
c = aFunction(anObject, [self objectAtIndex:mid], aContext);
var middle = FLOOR((first + last) / 2),
result = aComparator(anObject, [self objectAtIndex:middle]);
if (c > 0)
first = mid + 1;
if (result > 0)
first = middle + 1;
else if (c < 0)
last = mid - 1;
else if (result < 0)
last = middle - 1;
else
{
while (mid < count - 1 &&
aFunction(anObject, [self objectAtIndex:mid + 1], aContext) === CPOrderedSame)
mid++;
if (options & CPBinarySearchingFirstEqual)
while (middle++ < count - 1 &&
aComparator(anObject, [self objectAtIndex:middle]) === CPOrderedSame);
return mid;
else if (options & CPBinarySearchingLastEqual)
{
while (middle-- > 0 &&
aComparator(anObject, [self objectAtIndex:middle]) === CPOrderedSame);
if (options & CPBinarySearchingInsertionIndex)
++middle;
}
return middle;
}
}
var result = -first - 1;
if (options & CPBinarySearchingInsertionIndex)
return MAX(first, 0);
if (result < 0)
return CPNotFound;
return result;
}
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
calling sortUsingDescriptors: with the descriptors passed to this method would result in.
@param anObject the object to search for
@param descriptors the array of descriptors to use to compare each item in the array that we search. the same
descriptors should have been used to sort the array (or to maintain its sorted order).
@return the index of the object, or \c CPNotFound if it was not found.
*/
- (unsigned)indexOfObject:(id)anObject sortedByDescriptors:(CPArray)descriptors
{
var count = [descriptors count];
return [self indexOfObject:anObject sortedByFunction:function(lhs, rhs)
{
var index = 0,
result = CPOrderedSame;
while (index < count && (result = [[descriptors objectAtIndex:index++] compareObject:lhs withObject:rhs]) === CPOrderedSame);
return result;
}];
}
- (unsigned)insertObject:(id)anObject inArraySortedByDescriptors:(CPArray)descriptors
{
if (!descriptors || ![descriptors count])
{
[self addObject:anObject];
return [self count] - 1;
}
var index = [self _insertObject:anObject sortedByFunction:function(lhs, rhs)
{
var i = 0,
count = [descriptors count],
result = CPOrderedSame;
while (i < count)
if ((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame)
return result;
return result;
} context:nil];
if (index < 0)
index = -result-1;
[self insertObject:anObject atIndex:index];
return index;
return CPNotFound;
}
// Sending messages to elements
+12 -14
View File
@@ -90,31 +90,29 @@
- (unsigned)insertObject:(id)anObject inArraySortedByDescriptors:(CPArray)descriptors
{
var count = [descriptors count],
index;
var index,
count = [descriptors count];
if (count)
{
// FIXME: UGH
index = [self indexOfObject:anObject sortedByFunction:function(lhs, rhs)
index = [self indexOfObject:anObject
inSortedRange:nil
options:CPBinarySearchingInsertionIndex
usingComparator:function(lhs, rhs)
{
var i = 0,
var index = 0,
result = CPOrderedSame;
while (i < count)
if ((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame)
return result;
while (index < count && ((result = [[descriptors objectAtIndex:index] compareObject:lhs withObject:rhs]) === CPOrderedSame))
++index;
return result;
} context:nil];
}];
if (index < 0)
index = -index - 1;
}
else
index = self.length;
index = [self count];
[self insertObject:anObject atIndex:index];
return index;
}
+1 -2
View File
@@ -101,8 +101,7 @@
- (id)objectAtIndex:(CPUInteger)anIndex
{
if (anIndex >= self.length || anIndex < 0)
[CPException raise:CPRangeException
reason:@"index (" + anIndex + @") beyond bounds (" + self.length + @")"];
_CPRaiseRangeException(self, _cmd, anIndex, self.length);
return self[anIndex];
}
+1 -1
View File
@@ -146,7 +146,7 @@
return CPOrderedAscending;
}
return [_rangeEntries indexOfObject:anIndex sortedByFunction:sortFunction];
return [_rangeEntries indexOfObject:anIndex inSortedRange:nil options:0 usingComparator:sortFunction];
}
//Retrieving Attribute Information
+15
View File
@@ -205,11 +205,26 @@ Error.prototype._userInfo = null;
[CPException initialize];
#define METHOD_CALL_STRING()\
((class_isMetaClass(anObject.isa) ? "+" : "-") + "[" + [anObject className] + " " + aSelector + "]: ")
function _CPRaiseInvalidAbstractInvocation(anObject, aSelector)
{
[CPException raise:CPInvalidArgumentException reason:@"*** -" + sel_getName(aSelector) + @" cannot be sent to an abstract object of class " + [anObject className] + @": Create a concrete instance!"];
}
function _CPRaiseInvalidArgumentException(anObject, aSelector, aMessage)
{
[CPException raise:CPInvalidArgumentException
reason:METHOD_CALL_STRING() + aMessage];
}
function _CPRaiseRangeException(anObject, aSelector, anIndex, aCount)
{
[CPException raise:CPRangeException
reason:METHOD_CALL_STRING() + "index (" + anIndex + ") beyond bounds (" + aCount + ")"];
}
function _CPReportLenientDeprecation(/*Class*/ aClass, /*SEL*/ oldSelector, /*SEL*/ newSelector)
{
CPLog.warn("[" + CPStringFromClass(aClass) + " " + CPStringFromSelector(oldSelector) + "] is deprecated, using " + CPStringFromSelector(newSelector) + " instead.");
+28 -41
View File
@@ -38,8 +38,8 @@
[self assert:array equals:[@"one", @"two", @"three", @"four", @"a", @"b"]];
var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c"],
var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects:@"a", @"b", @"c"],
indexes = [CPMutableIndexSet indexSetWithIndex:1];
[indexes addIndex:2];
@@ -50,8 +50,8 @@
[self assert:array equals:[@"one", @"a", @"b", @"two", @"c", @"three", @"four"]];
var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c"],
var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects:@"a", @"b", @"c"],
indexes = [CPMutableIndexSet indexSetWithIndex:1];
[indexes addIndex:2];
@@ -140,25 +140,12 @@
[self assert:[array indexOfObjectWithOptions:CPEnumerationReverse passingTest:agePredicate context:7] equals:3];
}
- (void)testIndexOfObjectSortedByFunction
- (void)testIndexOfObject_inSortedRange_options_usingComparator_
{
var array = [0, 1, 2, 3, 4, 7];
[self assert:[array indexOfObject:3 sortedByFunction:function(a, b){ return a - b; }] equals:3];
[self assert:[[array arrayByReversingArray] indexOfObject:3 sortedByFunction:function(a, b){ return b - a; }] equals:2];
}
- (void)testIndexOfObjectSortedByDescriptors
{
var array = [0, 1, 2, 3, 4, 7];
[self assert:[array indexOfObject:3
sortedByDescriptors:[[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:YES]]]
equals:3];
[self assert:[[array arrayByReversingArray] indexOfObject:3
sortedByDescriptors:[[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]]]
equals:2];
[self assert:[array indexOfObject:3 inSortedRange:nil options:0 usingComparator:function(a, b){ return a - b; }] equals:3];
[self assert:[[array arrayByReversingArray] indexOfObject:3 inSortedRange:nil options:0 usingComparator:function(a, b){ return a - b; }] equals:2];
}
- (void)testIndexOutOfBounds
@@ -171,7 +158,7 @@
catch (anException)
{
[self assert:[anException name] equals:CPRangeException];
[self assert:[anException reason] equals:@"index (0) beyond bounds (0)"];
[self assertTrue:[[anException reason] rangeOfString:(@"index (0) beyond bounds (0)")].location !== CPNotFound];
}
[[0, 1, 2] objectAtIndex:0];
@@ -186,7 +173,7 @@
catch (anException)
{
[self assert:[anException name] equals:CPRangeException];
[self assert:[anException reason] equals:@"index (3) beyond bounds (3)"];
[self assertTrue:[[anException reason] rangeOfString:(@"index (3) beyond bounds (3)")].location !== CPNotFound];
}
try
@@ -197,7 +184,7 @@
catch (anException)
{
[self assert:[anException name] equals:CPRangeException];
[self assert:[anException reason] equals:@"index (4) beyond bounds (3)"];
[self assertTrue:[[anException reason] rangeOfString:(@"index (4) beyond bounds (3)")].location !== CPNotFound];
}
}
@@ -206,79 +193,79 @@
var descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:YES]];
var array = [1, 3, 5];
[array insertObject: 0 inArraySortedByDescriptors:descriptors];
[array insertObject:0 inArraySortedByDescriptors:descriptors];
[self assert:[0, 1, 3, 5] equals:array];
array = [1, 3, 5];
[array insertObject: 2 inArraySortedByDescriptors:descriptors];
[array insertObject:2 inArraySortedByDescriptors:descriptors];
[self assert:[1, 2, 3, 5] equals:array];
array = [1, 3, 5];
[array insertObject: 1 inArraySortedByDescriptors:descriptors];
[array insertObject:1 inArraySortedByDescriptors:descriptors];
[self assert:[1, 1, 3, 5] equals:array];
array = [1, 3, 5];
[array insertObject: 6 inArraySortedByDescriptors:descriptors];
[array insertObject:6 inArraySortedByDescriptors:descriptors];
[self assert:[1, 3, 5, 6] equals:array];
array = [1, 3, 5];
[array insertObject: 3 inArraySortedByDescriptors:descriptors];
[array insertObject:3 inArraySortedByDescriptors:descriptors];
[self assert:[1, 3, 3, 5] equals:array];
array = [];
[array insertObject: 3 inArraySortedByDescriptors:descriptors];
[array insertObject:3 inArraySortedByDescriptors:descriptors];
[self assert:[3] equals:array];
descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]];
array = [5, 3, 1];
[array insertObject: 0 inArraySortedByDescriptors:descriptors];
[array insertObject:0 inArraySortedByDescriptors:descriptors];
[self assert:[5, 3, 1, 0] equals:array];
array = [5, 3, 1];
[array insertObject: 2 inArraySortedByDescriptors:descriptors];
[array insertObject:2 inArraySortedByDescriptors:descriptors];
[self assert:[5, 3, 2, 1] equals:array];
array = [5, 3, 1];
[array insertObject: 1 inArraySortedByDescriptors:descriptors];
[array insertObject:1 inArraySortedByDescriptors:descriptors];
[self assert:[5, 3, 1, 1] equals:array];
array = [5, 3, 1];
[array insertObject: 6 inArraySortedByDescriptors:descriptors];
[array insertObject:6 inArraySortedByDescriptors:descriptors];
[self assert:[6, 5, 3, 1] equals:array];
array = [5, 3, 1];
[array insertObject: 3 inArraySortedByDescriptors:descriptors];
[array insertObject:3 inArraySortedByDescriptors:descriptors];
[self assert:[5, 3, 3, 1] equals:array];
array = [];
[array insertObject: 3 inArraySortedByDescriptors:descriptors];
[array insertObject:3 inArraySortedByDescriptors:descriptors];
[self assert:[3] equals:array];
descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]];
array = [5, 3, 1];
[array insertObject: 0 inArraySortedByDescriptors:descriptors];
[array insertObject:0 inArraySortedByDescriptors:descriptors];
[self assert:[5, 3, 1, 0] equals:array];
array = [5, 3, 1];
[array insertObject: 2 inArraySortedByDescriptors:descriptors];
[array insertObject:2 inArraySortedByDescriptors:descriptors];
[self assert:[5, 3, 2, 1] equals:array];
array = [5, 3, 1];
[array insertObject: 1 inArraySortedByDescriptors:descriptors];
[array insertObject:1 inArraySortedByDescriptors:descriptors];
[self assert:[5, 3, 1, 1] equals:array];
array = [5, 3, 1];
[array insertObject: 6 inArraySortedByDescriptors:descriptors];
[array insertObject:6 inArraySortedByDescriptors:descriptors];
[self assert:[6, 5, 3, 1] equals:array];
array = [5, 3, 1];
[array insertObject: 3 inArraySortedByDescriptors:descriptors];
[array insertObject:3 inArraySortedByDescriptors:descriptors];
[self assert:[5, 3, 3, 1] equals:array];
array = [];
[array insertObject: 3 inArraySortedByDescriptors:descriptors];
[array insertObject:3 inArraySortedByDescriptors:descriptors];
[self assert:[3] equals:array];
}