stdlib: change sort() and sorted() into methods

Swift SVN r27876
This commit is contained in:
Dmitri Hrybenko
2015-04-28 18:05:37 +00:00
parent 7dafdf873c
commit b05c372c4f
7 changed files with 602 additions and 23 deletions

View File

@@ -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()