Skip to content

Commit 5769b00

Browse files
authored
Merge pull request #2271 from millenomi/nsarray-sortedarray
Parity: NSArray.sortedArray(…)
2 parents f318356 + 4f67192 commit 5769b00

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

CoreFoundation/Base.subproj/CFSortFunctions.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,14 @@ static void __CFSortIndexesN(VALUE_TYPE listp[], INDEX_TYPE count, int32_t ncore
271271
}
272272
#endif
273273

274+
#if DEPLOYMENT_RUNTIME_SWIFT
275+
#define _CF_SORT_INDEXES_EXPORT CF_CROSS_PLATFORM_EXPORT
276+
#else
277+
#define _CF_SORT_INDEXES_EXPORT
278+
#endif
279+
274280
// fills an array of indexes (of length count) giving the indexes 0 - count-1, as sorted by the comparator block
275-
void CFSortIndexes(CFIndex *indexBuffer, CFIndex count, CFOptionFlags opts, CFComparisonResult (^cmp)(CFIndex, CFIndex)) {
281+
_CF_SORT_INDEXES_EXPORT void CFSortIndexes(CFIndex *indexBuffer, CFIndex count, CFOptionFlags opts, CFComparisonResult (^cmp)(CFIndex, CFIndex)) {
276282
if (count < 1) return;
277283
if (INTPTR_MAX / sizeof(CFIndex) < count) return;
278284
int32_t ncores = 0;

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,8 @@ CF_EXPORT _CFThreadRef _CFMainPThread;
394394

395395
CF_EXPORT CFHashCode __CFHashDouble(double d);
396396

397+
CF_CROSS_PLATFORM_EXPORT void CFSortIndexes(CFIndex *indexBuffer, CFIndex count, CFOptionFlags opts, CFComparisonResult (^cmp)(CFIndex, CFIndex));
398+
397399
CF_EXPORT CFTypeRef _Nullable _CFThreadSpecificGet(_CFThreadSpecificKey key);
398400
CF_EXPORT void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value);
399401
CF_EXPORT _CFThreadSpecificKey _CFThreadSpecificKeyCreate(void);

Foundation/NSArray.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -525,20 +525,35 @@ open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCo
525525
}
526526

527527
internal func sortedArray(from range: NSRange, options: NSSortOptions, usingComparator cmptr: (Any, Any) -> ComparisonResult) -> [Any] {
528-
// The sort options are not available. We use the Array's sorting algorithm. It is not stable neither concurrent.
529-
guard options.isEmpty else {
530-
NSUnimplemented()
531-
}
532-
533528
let count = self.count
534529
if range.length == 0 || count == 0 {
535530
return []
536531
}
537532

538-
let swiftRange = Range(range)!
539-
return allObjects[swiftRange].sorted { lhs, rhs in
540-
return cmptr(lhs, rhs) == .orderedAscending
533+
let objects = subarray(with: range)
534+
535+
let indexes = UnsafeMutableBufferPointer<CFIndex>.allocate(capacity: range.length)
536+
withoutActuallyEscaping(cmptr) { (cmptr) in
537+
CFSortIndexes(indexes.baseAddress!, range.length, CFOptionFlags(options.rawValue)) { (a, b) -> CFComparisonResult in
538+
switch cmptr(objects[a], objects[b]) {
539+
case .orderedAscending: return kCFCompareLessThan
540+
case .orderedDescending: return kCFCompareGreaterThan
541+
case .orderedSame: return kCFCompareEqualTo
542+
}
543+
}
544+
}
545+
546+
let result = Array<Any>(unsafeUninitializedCapacity: range.length) { (buffer, initializedCount) in
547+
var destinationIndex = 0
548+
for index in indexes {
549+
buffer.baseAddress?.advanced(by: destinationIndex).initialize(to: objects[index])
550+
destinationIndex += 1
551+
}
552+
initializedCount = range.length
541553
}
554+
555+
indexes.deallocate()
556+
return result
542557
}
543558

544559
open func sortedArray(comparator cmptr: (Any, Any) -> ComparisonResult) -> [Any] {
@@ -828,7 +843,7 @@ open class NSMutableArray : NSArray {
828843
if type(of: self) === NSMutableArray.self {
829844
_storage.swapAt(idx1, idx2)
830845
} else {
831-
NSUnimplemented()
846+
NSRequiresConcreteImplementation()
832847
}
833848
}
834849

@@ -906,7 +921,7 @@ open class NSMutableArray : NSArray {
906921
_storage.insert(__SwiftValue.store(otherArray[idx]), at: idx + range.location)
907922
}
908923
} else {
909-
NSUnimplemented()
924+
NSRequiresConcreteImplementation()
910925
}
911926
}
912927

0 commit comments

Comments
 (0)