mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
stdlib: change sort() and sorted() into methods
Swift SVN r27876
This commit is contained in:
@@ -2924,6 +2924,128 @@ SequenceTypeAlgorithms.test("indices") {
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MutableCollectionType
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// _withUnsafeMutableBufferPointerIfSupported()
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
var _timesWithUnsafeMutableBufferPointerIfSupportedWasCalled: Int = 0
|
||||
|
||||
% for Implementation in [ 'Default', 'Custom' ]:
|
||||
|
||||
struct MinimalMutableCollectionWith${Implementation}WithUnsafeMutableBufferPointerIfSupported<T>
|
||||
: MutableCollectionType {
|
||||
|
||||
init(_ data: [T]) {
|
||||
self._data = data
|
||||
}
|
||||
|
||||
var startIndex: MinimalForwardIndex {
|
||||
return MinimalForwardIndex(
|
||||
position: 0,
|
||||
startIndex: 0,
|
||||
endIndex: _data.count)
|
||||
}
|
||||
|
||||
var endIndex: MinimalForwardIndex {
|
||||
return MinimalForwardIndex(
|
||||
position: _data.count,
|
||||
startIndex: 0,
|
||||
endIndex: _data.count)
|
||||
}
|
||||
|
||||
subscript(i: MinimalForwardIndex) -> T {
|
||||
get {
|
||||
return _data[i.position]
|
||||
}
|
||||
set {
|
||||
_data[i.position] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
var _data: [T]
|
||||
|
||||
% if Implementation == 'Custom':
|
||||
|
||||
static var timesWithUnsafeMutableBufferPointerIfSupportedWasCalled: Int {
|
||||
get {
|
||||
return _timesWithUnsafeMutableBufferPointerIfSupportedWasCalled
|
||||
}
|
||||
set {
|
||||
_timesWithUnsafeMutableBufferPointerIfSupportedWasCalled = newValue
|
||||
}
|
||||
}
|
||||
|
||||
mutating func _withUnsafeMutableBufferPointerIfSupported<R>(
|
||||
@noescape body: (inout UnsafeMutableBufferPointer<T>) -> R
|
||||
) -> R? {
|
||||
++MinimalMutableCollectionWith${Implementation}WithUnsafeMutableBufferPointerIfSupported.timesWithUnsafeMutableBufferPointerIfSupportedWasCalled
|
||||
return _data._withUnsafeMutableBufferPointerIfSupported(body)
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
func callGenericWithUnsafeMutableBufferPointerIfSupported<
|
||||
C : MutableCollectionType, R
|
||||
>(
|
||||
inout collection: C,
|
||||
@noescape body: (inout UnsafeMutableBufferPointer<C.Generator.Element>) -> R
|
||||
) -> R? {
|
||||
return collection._withUnsafeMutableBufferPointerIfSupported(body)
|
||||
}
|
||||
|
||||
% for Implementation in [ 'Default', 'Custom' ]:
|
||||
|
||||
func callStaticWithUnsafeMutableBufferPointerIfSupported<R>(
|
||||
inout collection: MinimalMutableCollectionWith${Implementation}WithUnsafeMutableBufferPointerIfSupported<OpaqueValue<Int>>,
|
||||
@noescape body: (inout UnsafeMutableBufferPointer<OpaqueValue<Int>>) -> R
|
||||
) -> R? {
|
||||
return collection._withUnsafeMutableBufferPointerIfSupported(body)
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
% for Implementation in [ 'Default', 'Custom' ]:
|
||||
|
||||
% for dispatch in [ 'Static', 'Generic' ]:
|
||||
|
||||
SequenceTypeAlgorithms.test("MutableCollectionType._withUnsafeMutableBufferPointerIfSupported()/${Implementation}Implementation/${dispatch}") {
|
||||
let data = [ 1, 2, 3, 4, 5 ]
|
||||
var collection = MinimalMutableCollectionWith${Implementation}WithUnsafeMutableBufferPointerIfSupported(
|
||||
data._prext_map { OpaqueValue($0) })
|
||||
if true {
|
||||
% if Implementation == 'Custom':
|
||||
MinimalMutableCollectionWith${Implementation}WithUnsafeMutableBufferPointerIfSupported<OpaqueValue<Int>>.timesWithUnsafeMutableBufferPointerIfSupportedWasCalled = 0
|
||||
var result = collection._withUnsafeMutableBufferPointerIfSupported {
|
||||
(inout buffer: UnsafeMutableBufferPointer<OpaqueValue<Int>>) in
|
||||
return OpaqueValue(Array(buffer))
|
||||
}
|
||||
expectType(Optional<OpaqueValue<Array<OpaqueValue<Int>>>>.self, &result)
|
||||
expectEqual(data, result!.value._prext_map { $0.value })
|
||||
expectEqual(1, MinimalMutableCollectionWith${Implementation}WithUnsafeMutableBufferPointerIfSupported<OpaqueValue<Int>>.timesWithUnsafeMutableBufferPointerIfSupportedWasCalled)
|
||||
% else:
|
||||
var result = collection._withUnsafeMutableBufferPointerIfSupported {
|
||||
(inout buffer: UnsafeMutableBufferPointer<OpaqueValue<Int>>) -> OpaqueValue<Int> in
|
||||
expectUnreachable()
|
||||
return OpaqueValue(42)
|
||||
}
|
||||
expectType(Optional<OpaqueValue<Int>>.self, &result)
|
||||
expectEmpty(result)
|
||||
% end
|
||||
}
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
% end
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// partition()
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -3077,6 +3199,7 @@ public func < (
|
||||
return CustomComparableValue.lessImpl(lhs.value, rhs.value)
|
||||
}
|
||||
|
||||
// These tests are shared between partition() and sort().
|
||||
struct PartitionExhaustiveTest {
|
||||
let sequence: [Int]
|
||||
let loc: SourceLoc
|
||||
@@ -3172,7 +3295,7 @@ SequenceTypeAlgorithms.test("partition/${'Predicate' if predicate else 'WhereEle
|
||||
let pivot = s._prext_partition(indices)
|
||||
% end
|
||||
|
||||
// Check that we didn't lose any values.
|
||||
// Check that we didn't lose any elements.
|
||||
% if slice:
|
||||
expectEqual(0xfffe, s._prext_first!.identity)
|
||||
expectEqual(0xffff, s._prext_last!.identity)
|
||||
@@ -3227,7 +3350,7 @@ SequenceTypeAlgorithms.test("partition/${'Predicate' if predicate else 'WhereEle
|
||||
let pivot = s._prext_partition(s._prext_indices)
|
||||
% end
|
||||
|
||||
// Weak postcondition: we didn't lose any values.
|
||||
// Weak postcondition: we didn't lose any elements.
|
||||
expectEqualsUnordered(0..<i, s._prext_map { $0.value })
|
||||
|
||||
expectTrue(0 <= s[pivot].value && s[pivot].value < i)
|
||||
@@ -3238,5 +3361,201 @@ SequenceTypeAlgorithms.test("partition/${'Predicate' if predicate else 'WhereEle
|
||||
|
||||
% end
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// sort()
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
% for predicate in [ False, True ]:
|
||||
|
||||
SequenceTypeAlgorithms.test("sort/${'Predicate' if predicate else 'WhereElementIsEquatable'}") {
|
||||
% if not predicate:
|
||||
CustomComparableValue.equalImpl = { $0 == $1 }
|
||||
CustomComparableValue.lessImpl = { $0 < $1 }
|
||||
% end
|
||||
|
||||
for test in partitionExhaustiveTests {
|
||||
forAllPermutations(test.sequence) { (sequence) in
|
||||
if true {
|
||||
% if predicate:
|
||||
var sequenceAsArray: [OpaqueValue<Int>] =
|
||||
zip(sequence, 0..<sequence.count)._prext_map {
|
||||
OpaqueValue($0, identity: $1)
|
||||
}
|
||||
|
||||
var s = MinimalMutableRandomAccessCollection<OpaqueValue<Int>>(
|
||||
sequenceAsArray)
|
||||
|
||||
let result = s._prext_sort { $0.value < $1.value }
|
||||
% else:
|
||||
var sequenceAsArray: [CustomComparableValue] =
|
||||
zip(sequence, 0..<sequence.count)._prext_map {
|
||||
CustomComparableValue($0, identity: $1)
|
||||
}
|
||||
|
||||
var s = MinimalMutableRandomAccessCollection<CustomComparableValue>(
|
||||
sequenceAsArray)
|
||||
|
||||
let result = s._prext_sort()
|
||||
% end
|
||||
|
||||
// Check that we didn't lose any elements.
|
||||
expectEqualsUnordered(0..<sequence.count, result._prext_map { $0.identity })
|
||||
|
||||
// Check that the elements are sorted.
|
||||
if result._prext_count() >= 2 {
|
||||
for i in result.startIndex..<result.endIndex.predecessor() {
|
||||
expectLE(result[i].value, result[i.successor()].value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SequenceTypeAlgorithms.test("sort/CustomImplementation/${'Predicate' if predicate else 'WhereElementIsEquatable'}") {
|
||||
% if not predicate:
|
||||
CustomComparableValue.equalImpl = { $0 == $1 }
|
||||
CustomComparableValue.lessImpl = { $0 < $1 }
|
||||
% end
|
||||
|
||||
let data = [ 5, 4, 3, 2, 1 ]
|
||||
% if predicate:
|
||||
var collection = MinimalMutableCollectionWithCustomWithUnsafeMutableBufferPointerIfSupported(
|
||||
data._prext_map { MinimalComparableValue($0) })
|
||||
% else:
|
||||
var collection = MinimalMutableCollectionWithCustomWithUnsafeMutableBufferPointerIfSupported(
|
||||
data._prext_map { OpaqueValue($0) })
|
||||
% end
|
||||
MinimalMutableCollectionWithCustomWithUnsafeMutableBufferPointerIfSupported<OpaqueValue<Int>>.timesWithUnsafeMutableBufferPointerIfSupportedWasCalled = 0
|
||||
% if predicate:
|
||||
let result = collection._prext_sort()
|
||||
% else:
|
||||
let result = collection._prext_sort { $0.value < $1.value }
|
||||
% end
|
||||
// The collection is copied into an array before sorting.
|
||||
expectEqual(0, MinimalMutableCollectionWithCustomWithUnsafeMutableBufferPointerIfSupported<OpaqueValue<Int>>.timesWithUnsafeMutableBufferPointerIfSupportedWasCalled)
|
||||
|
||||
expectEqual([ 1, 2, 3, 4, 5 ], result._prext_map { $0.value })
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
% for predicate in [ False, True ]:
|
||||
|
||||
SequenceTypeAlgorithms.test("sort/${'Predicate' if predicate else 'WhereElementIsEquatable'}/InvalidOrderings") {
|
||||
withInvalidOrderings { (comparisonPredicate) in
|
||||
for i in 0..<7 {
|
||||
forAllPermutations(i) { (sequence) in
|
||||
% if predicate:
|
||||
var s = MinimalMutableRandomAccessCollection<OpaqueValue<Int>>(
|
||||
sequence._prext_map { OpaqueValue($0) })
|
||||
let result = s._prext_sort {
|
||||
comparisonPredicate($0.value, $1.value)
|
||||
}
|
||||
% else:
|
||||
var s = MinimalMutableRandomAccessCollection<CustomComparableValue>(
|
||||
sequence._prext_map { CustomComparableValue($0) })
|
||||
CustomComparableValue.equalImpl = {
|
||||
!comparisonPredicate($0, $1) &&
|
||||
!comparisonPredicate($1, $0)
|
||||
}
|
||||
CustomComparableValue.lessImpl = {
|
||||
comparisonPredicate($0, $1)
|
||||
}
|
||||
let result = s._prext_sort()
|
||||
% end
|
||||
|
||||
// Weak postcondition: we didn't lose any elements.
|
||||
expectEqualsUnordered(0..<i, result._prext_map { $0.value })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
% for predicate in [ False, True ]:
|
||||
|
||||
SequenceTypeAlgorithms.test("sortInPlace/${'Predicate' if predicate else 'WhereElementIsEquatable'}") {
|
||||
% if not predicate:
|
||||
CustomComparableValue.equalImpl = { $0 == $1 }
|
||||
CustomComparableValue.lessImpl = { $0 < $1 }
|
||||
% end
|
||||
|
||||
for test in partitionExhaustiveTests {
|
||||
forAllPermutations(test.sequence) { (sequence) in
|
||||
if true {
|
||||
% if predicate:
|
||||
var sequenceAsArray: [OpaqueValue<Int>] =
|
||||
zip(sequence, 0..<sequence.count)._prext_map {
|
||||
OpaqueValue($0, identity: $1)
|
||||
}
|
||||
|
||||
var s = MinimalMutableRandomAccessCollection<OpaqueValue<Int>>(
|
||||
sequenceAsArray)
|
||||
|
||||
s._prext_sortInPlace { $0.value < $1.value }
|
||||
% else:
|
||||
var sequenceAsArray: [CustomComparableValue] =
|
||||
zip(sequence, 0..<sequence.count)._prext_map {
|
||||
CustomComparableValue($0, identity: $1)
|
||||
}
|
||||
|
||||
var s = MinimalMutableRandomAccessCollection<CustomComparableValue>(
|
||||
sequenceAsArray)
|
||||
|
||||
s._prext_sortInPlace()
|
||||
% end
|
||||
|
||||
// Check that we didn't lose any elements.
|
||||
expectEqualsUnordered(0..<sequence.count, s._prext_map { $0.identity })
|
||||
|
||||
// Check that the elements are sorted.
|
||||
if s._prext_count() >= 2 {
|
||||
for i in s.startIndex..<s.endIndex.predecessor() {
|
||||
expectLE(s[i].value, s[i.successor()].value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
% for predicate in [ False, True ]:
|
||||
|
||||
SequenceTypeAlgorithms.test("sortInPlace/${'Predicate' if predicate else 'WhereElementIsEquatable'}/InvalidOrderings") {
|
||||
withInvalidOrderings { (comparisonPredicate) in
|
||||
for i in 0..<7 {
|
||||
forAllPermutations(i) { (sequence) in
|
||||
% if predicate:
|
||||
var s = MinimalMutableRandomAccessCollection<OpaqueValue<Int>>(
|
||||
sequence._prext_map { OpaqueValue($0) })
|
||||
s._prext_sortInPlace {
|
||||
comparisonPredicate($0.value, $1.value)
|
||||
}
|
||||
% else:
|
||||
var s = MinimalMutableRandomAccessCollection<CustomComparableValue>(
|
||||
sequence._prext_map { CustomComparableValue($0) })
|
||||
CustomComparableValue.equalImpl = {
|
||||
!comparisonPredicate($0, $1) &&
|
||||
!comparisonPredicate($1, $0)
|
||||
}
|
||||
CustomComparableValue.lessImpl = {
|
||||
comparisonPredicate($0, $1)
|
||||
}
|
||||
s._prext_sortInPlace()
|
||||
% end
|
||||
|
||||
// Weak postcondition: we didn't lose any elements.
|
||||
expectEqualsUnordered(0..<i, s._prext_map { $0.value })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
runAllTests()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user