Index: src/OFArray.h ================================================================== --- src/OFArray.h +++ src/OFArray.h @@ -403,10 +403,24 @@ */ - (OFArray OF_GENERIC(ObjectType) *) sortedArrayUsingSelector: (SEL)selector options: (OFArraySortOptions)options; +/** + * @brief Returns a copy of the array sorted using the specified function and + * options. + * + * @param compare The function to use to sort the array + * @param context Context passed to the function to compare + * @param options The options to use when sorting the array + * @return A sorted copy of the array + */ +- (OFArray OF_GENERIC(ObjectType) *) + sortedArrayUsingFunction: (OFCompareFunction)compare + context: (void *)context + options: (OFArraySortOptions)options; + #ifdef OF_HAVE_BLOCKS /** * @brief Returns a copy of the array sorted using the specified selector and * options. * Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -723,10 +723,20 @@ OFMutableArray *new = [[self mutableCopy] autorelease]; [new sortUsingSelector: selector options: options]; [new makeImmutable]; return new; } + +- (OFArray *)sortedArrayUsingFunction: (OFCompareFunction)compare + context: (void *)context + options: (OFArraySortOptions)options +{ + OFMutableArray *new = [[self mutableCopy] autorelease]; + [new sortUsingFunction: compare context: context options: options]; + [new makeImmutable]; + return new; +} #ifdef OF_HAVE_BLOCKS - (OFArray *)sortedArrayUsingComparator: (OFComparator)comparator options: (OFArraySortOptions)options { Index: src/OFMutableArray.h ================================================================== --- src/OFMutableArray.h +++ src/OFMutableArray.h @@ -200,10 +200,21 @@ * should be the same as that of -[compare:]. * @param options The options to use when sorting the array */ - (void)sortUsingSelector: (SEL)selector options: (OFArraySortOptions)options; +/** + * @brief Sorts the array using the specified function and options. + * + * @param compare The function to use to sort the array + * @param context Context passed to the function to compare + * @param options The options to use when sorting the array + */ +- (void)sortUsingFunction: (OFCompareFunction)compare + context: (void *)context + options: (OFArraySortOptions)options; + #ifdef OF_HAVE_BLOCKS /** * @brief Sorts the array using the specified comparator and options. * * @param comparator The comparator to use to sort the array Index: src/OFMutableArray.m ================================================================== --- src/OFMutableArray.m +++ src/OFMutableArray.m @@ -85,14 +85,13 @@ left = i + 1; } } -#ifdef OF_HAVE_BLOCKS static void -quicksortWithBlock(OFMutableArray *array, size_t left, size_t right, - OFComparator comparator, OFArraySortOptions options) +quicksortWithFunction(OFMutableArray *array, size_t left, size_t right, + OFCompareFunction compare, void *context, OFArraySortOptions options) { OFComparisonResult ascending, descending; if (options & OFArraySortDescending) { ascending = OFOrderedDescending; @@ -106,35 +105,35 @@ size_t i = left; size_t j = right - 1; id pivot = [array objectAtIndex: right]; do { - while (comparator([array objectAtIndex: i], pivot) != - descending && i < right) + while (compare([array objectAtIndex: i], pivot, + context) != descending && i < right) i++; - while (comparator([array objectAtIndex: j], pivot) != - ascending && j > left) + while (compare([array objectAtIndex: j], pivot, + context) != ascending && j > left) j--; if (i < j) [array exchangeObjectAtIndex: i withObjectAtIndex: j]; } while (i < j); - if (comparator([array objectAtIndex: i], pivot) == descending) + if (compare([array objectAtIndex: i], pivot, context) == + descending) [array exchangeObjectAtIndex: i withObjectAtIndex: right]; if (i > 0) - quicksortWithBlock(array, left, i - 1, comparator, - options); + quicksortWithFunction(array, left, i - 1, compare, + context, options); left = i + 1; } } -#endif @implementation OFMutableArrayPlaceholder - (instancetype)init { return (id)[[OFMutableAdjacentArray alloc] init]; @@ -422,21 +421,42 @@ if (count == 0 || count == 1) return; quicksort(self, 0, count - 1, selector, options); } + +- (void)sortUsingFunction: (OFCompareFunction)compare + context: (void *)context + options: (OFArraySortOptions)options +{ + size_t count = self.count; + + if (count == 0 || count == 1) + return; + + quicksortWithFunction(self, 0, count - 1, compare, context, options); +} #ifdef OF_HAVE_BLOCKS +static OFComparisonResult +blockCompare(id left, id right, void *context) +{ + OFComparator block = (OFComparator)context; + + return block(left, right); +} + - (void)sortUsingComparator: (OFComparator)comparator options: (OFArraySortOptions)options { size_t count = self.count; if (count == 0 || count == 1) return; - quicksortWithBlock(self, 0, count - 1, comparator, options); + quicksortWithFunction(self, 0, count - 1, blockCompare, comparator, + options); } #endif - (void)reverse { Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -61,10 +61,21 @@ OFOrderedSame = 0, /** The left object is bigger than the right */ OFOrderedDescending = 1 } OFComparisonResult; +/** + * @brief A function to compare two objects. + * + * @param left The left object + * @param right The right object + * @param context Context passed along for comparing + * @return The order of the objects + */ +typedef OFComparisonResult (*OFCompareFunction)(id _Nonnull left, + id _Nonnull right, void *context); + #ifdef OF_HAVE_BLOCKS /** * @brief A comparator to compare two objects. * * @param left The left object