Index: src/OFArray.h ================================================================== --- src/OFArray.h +++ src/OFArray.h @@ -260,10 +260,17 @@ * array */ - (void)makeObjectsPerformSelector: (SEL)selector withObject: (id)object; +/** + * \brief Returns a sorted copy of the array. + * + * \return A sorted copy of the array + */ +- (OFArray*)sortedArray; + /** * \brief Returns a copy of the array with the order reversed. * * \return A copy of the array with the order reversed */ Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -551,10 +551,21 @@ for (i = 0; i < count; i++) ((void(*)(id, SEL, id))[cArray[i] methodForSelector: selector])(cArray[i], selector, object); } + +- (OFArray*)sortedArray +{ + OFMutableArray *new = [[self mutableCopy] autorelease]; + + [new sort]; + + [new makeImmutable]; + + return new; +} - (OFArray*)reversedArray { OFMutableArray *new = [[self mutableCopy] autorelease]; Index: src/OFMutableArray.h ================================================================== --- src/OFMutableArray.h +++ src/OFMutableArray.h @@ -127,10 +127,15 @@ * \param index2 The index of the second object to swap */ - (void)swapObjectAtIndex: (size_t)index1 withObjectAtIndex: (size_t)index2; +/** + * \brief Sorts the array. + */ +- (void)sort; + /** * \brief Reverts the order of the objects in the array. */ - (void)reverse; Index: src/OFMutableArray.m ================================================================== --- src/OFMutableArray.m +++ src/OFMutableArray.m @@ -33,10 +33,46 @@ Class isa; } placeholder; @interface OFMutableArray_placeholder: OFMutableArray @end + +static void +quicksort(OFMutableArray *array, size_t left, size_t right) +{ + size_t i, j; + id pivot; + + if (left >= right) + return; + + i = left; + j = right - 1; + pivot = [array objectAtIndex: right]; + + do { + while ([[array objectAtIndex: i] compare: pivot] != + OF_ORDERED_DESCENDING && i < right) + i++; + + while ([[array objectAtIndex: j] compare: pivot] != + OF_ORDERED_ASCENDING && j > left) + j--; + + if (i < j) + [array swapObjectAtIndex: i + withObjectAtIndex: j]; + } while (i < j); + + if ([[array objectAtIndex: i] compare: pivot] == OF_ORDERED_DESCENDING) + [array swapObjectAtIndex: i + withObjectAtIndex: right]; + + if (i > 0) + quicksort(array, left, i - 1); + quicksort(array, i + 1, right); +} @implementation OFMutableArray_placeholder - init { return (id)[[OFMutableArray_adjacent alloc] init]; @@ -270,10 +306,20 @@ withObject: object1]; } @finally { [object1 release]; } } + +- (void)sort +{ + size_t count = [self count]; + + if (count == 0 || count == 1) + return; + + quicksort(self, 0, count - 1); +} - (void)reverse { size_t i, j, count = [self count]; Index: tests/OFArrayTests.m ================================================================== --- tests/OFArrayTests.m +++ tests/OFArrayTests.m @@ -152,10 +152,18 @@ [m[1] addObject: @"last"]; TEST(@"-[reversedArray]", [[m[1] reversedArray] isEqual: ([OFArray arrayWithObjects: @"last", @"qux", @"Baz", @"Bar", @"Foo", nil])]) + m[1] = [[a[0] mutableCopy] autorelease]; + [m[1] addObject: @"0"]; + [m[1] addObject: @"z"]; + TEST(@"-[sortedArray]", + [[m[1] sortedArray] isEqual: ([OFArray arrayWithObjects: + @"0", @"Bar", @"Baz", @"Foo", @"z", nil])]) + puts([[[m[1] sortedArray] description] UTF8String]); + EXPECT_EXCEPTION(@"Detect out of range in -[objectAtIndex:]", OFOutOfRangeException, [a[0] objectAtIndex: [a[0] count]]) EXPECT_EXCEPTION(@"Detect out of range in -[removeNObjects:]", OFOutOfRangeException, [m[0] removeNObjects: [m[0] count] + 1])