mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[stdlib] Update partition tests with feedback
This commit is contained in:
@@ -879,15 +879,12 @@ self.test("\(testNamePrefix).sort/${'Predicate' if predicate else 'WhereElementI
|
|||||||
// partition()
|
// partition()
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
% for predicate in [False, True]:
|
func checkPartition(
|
||||||
|
|
||||||
func checkPartition_${'Predicate' if predicate else 'WhereElementIsComparable'}(
|
|
||||||
sequence: [Int],
|
sequence: [Int],
|
||||||
equalImpl: ((Int, Int) -> Bool),
|
pivotValue: Int,
|
||||||
lessImpl: ((Int, Int) -> Bool),
|
lessImpl: ((Int, Int) -> Bool),
|
||||||
verifyOrder: Bool
|
verifyOrder: Bool
|
||||||
) {
|
) {
|
||||||
% if predicate:
|
|
||||||
let extract = extractValue
|
let extract = extractValue
|
||||||
let elements: [OpaqueValue<Int>] =
|
let elements: [OpaqueValue<Int>] =
|
||||||
zip(sequence, 0..<sequence.count).map {
|
zip(sequence, 0..<sequence.count).map {
|
||||||
@@ -895,33 +892,11 @@ func checkPartition_${'Predicate' if predicate else 'WhereElementIsComparable'}(
|
|||||||
}
|
}
|
||||||
|
|
||||||
var c = makeWrappedCollection(elements)
|
var c = makeWrappedCollection(elements)
|
||||||
% else:
|
|
||||||
MinimalComparableValue.equalImpl.value = equalImpl
|
|
||||||
MinimalComparableValue.lessImpl.value = lessImpl
|
|
||||||
|
|
||||||
let extract = extractValueFromComparable
|
|
||||||
let elements: [MinimalComparableValue] =
|
|
||||||
zip(sequence, 0..<sequence.count).map {
|
|
||||||
MinimalComparableValue($0, identity: $1)
|
|
||||||
}
|
|
||||||
|
|
||||||
var c = makeWrappedCollectionWithComparableElement(elements)
|
|
||||||
% end
|
|
||||||
let pivotElt = c.first
|
|
||||||
var pivot = c.startIndex
|
|
||||||
% if predicate:
|
|
||||||
let closureLifetimeTracker = LifetimeTracked(0)
|
let closureLifetimeTracker = LifetimeTracked(0)
|
||||||
if let first = pivotElt {
|
let pivot = c.partition(by: { val in
|
||||||
pivot = c.partition(by: {
|
|
||||||
val in
|
|
||||||
_blackHole(closureLifetimeTracker)
|
_blackHole(closureLifetimeTracker)
|
||||||
return !(extract(val).value < extract(first).value) })
|
return !lessImpl(extract(val).value, pivotValue)
|
||||||
}
|
})
|
||||||
% else:
|
|
||||||
if let first = c.first {
|
|
||||||
pivot = c.partition(by: { !($0 < first) })
|
|
||||||
}
|
|
||||||
% end
|
|
||||||
|
|
||||||
// Check that we didn't lose any elements.
|
// Check that we didn't lose any elements.
|
||||||
let identities = c.map { extract($0).identity }
|
let identities = c.map { extract($0).identity }
|
||||||
@@ -931,38 +906,49 @@ func checkPartition_${'Predicate' if predicate else 'WhereElementIsComparable'}(
|
|||||||
// All the elements in the first partition are less than the pivot
|
// All the elements in the first partition are less than the pivot
|
||||||
// value.
|
// value.
|
||||||
for i in c[c.startIndex..<pivot].indices {
|
for i in c[c.startIndex..<pivot].indices {
|
||||||
expectLT(extract(c[i]).value, extract(pivotElt!).value)
|
expectLT(extract(c[i]).value, pivotValue)
|
||||||
}
|
}
|
||||||
// All the elements in the second partition are greater or equal to
|
// All the elements in the second partition are greater or equal to
|
||||||
// the pivot value.
|
// the pivot value.
|
||||||
for i in c[pivot..<c.endIndex].indices {
|
for i in c[pivot..<c.endIndex].indices {
|
||||||
expectLE(extract(pivotElt!).value, extract(c[i]).value)
|
expectGE(extract(c[i]).value, pivotValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.test("\(testNamePrefix).partition/${'Predicate' if predicate else 'WhereElementIsComparable'}") {
|
self.test("\(testNamePrefix).partition") {
|
||||||
for test in partitionExhaustiveTests {
|
for test in partitionExhaustiveTests {
|
||||||
forAllPermutations(test.sequence) { (sequence) in
|
forAllPermutations(test.sequence) { (sequence) in
|
||||||
checkPartition_${'Predicate' if predicate else 'WhereElementIsComparable'}(
|
checkPartition(
|
||||||
sequence: sequence,
|
sequence: sequence,
|
||||||
equalImpl: { $0 == $1 },
|
pivotValue: sequence.first ?? 0,
|
||||||
|
lessImpl: { $0 < $1 },
|
||||||
|
verifyOrder: true)
|
||||||
|
|
||||||
|
// Pivot value where all elements will pass the partitioning predicate
|
||||||
|
checkPartition(
|
||||||
|
sequence: sequence,
|
||||||
|
pivotValue: Int.min,
|
||||||
|
lessImpl: { $0 < $1 },
|
||||||
|
verifyOrder: true)
|
||||||
|
|
||||||
|
// Pivot value where no element will pass the partitioning predicate
|
||||||
|
checkPartition(
|
||||||
|
sequence: sequence,
|
||||||
|
pivotValue: Int.max,
|
||||||
lessImpl: { $0 < $1 },
|
lessImpl: { $0 < $1 },
|
||||||
verifyOrder: true)
|
verifyOrder: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.test("\(testNamePrefix).partition/${'Predicate' if predicate else 'WhereElementIsComparable'}/InvalidOrderings") {
|
self.test("\(testNamePrefix).partition/InvalidOrderings") {
|
||||||
withInvalidOrderings { (comparisonPredicate) in
|
withInvalidOrderings { (comparisonPredicate) in
|
||||||
for i in 0..<7 {
|
for i in 0..<7 {
|
||||||
forAllPermutations(i) { (sequence) in
|
forAllPermutations(i) { (sequence) in
|
||||||
checkPartition_${'Predicate' if predicate else 'WhereElementIsComparable'}(
|
checkPartition(
|
||||||
sequence: sequence,
|
sequence: sequence,
|
||||||
equalImpl: {
|
pivotValue: sequence.first ?? 0,
|
||||||
!comparisonPredicate($0, $1) &&
|
|
||||||
!comparisonPredicate($1, $0)
|
|
||||||
},
|
|
||||||
lessImpl: comparisonPredicate,
|
lessImpl: comparisonPredicate,
|
||||||
verifyOrder: false)
|
verifyOrder: false)
|
||||||
}
|
}
|
||||||
@@ -970,41 +956,23 @@ self.test("\(testNamePrefix).partition/${'Predicate' if predicate else 'WhereEle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.test("\(testNamePrefix).partition/DispatchesThrough_withUnsafeMutableBufferPointerIfSupported/${'Predicate' if predicate else 'WhereElementIsComparable'}") {
|
self.test("\(testNamePrefix).partition/DispatchesThrough_withUnsafeMutableBufferPointerIfSupported") {
|
||||||
let sequence = [ 5, 4, 3, 2, 1 ]
|
let sequence = [ 5, 4, 3, 2, 1 ]
|
||||||
% if predicate:
|
|
||||||
let extract = extractValue
|
let extract = extractValue
|
||||||
let elements: [OpaqueValue<Int>] =
|
let elements: [OpaqueValue<Int>] =
|
||||||
zip(sequence, 0..<sequence.count).map {
|
zip(sequence, 0..<sequence.count).map {
|
||||||
OpaqueValue($0, identity: $1)
|
OpaqueValue($0, identity: $1)
|
||||||
}
|
}
|
||||||
let c = makeWrappedCollection(elements)
|
let c = makeWrappedCollection(elements)
|
||||||
% else:
|
|
||||||
let extract = extractValueFromComparable
|
|
||||||
let elements: [MinimalComparableValue] =
|
|
||||||
zip(sequence, 0..<sequence.count).map {
|
|
||||||
MinimalComparableValue($0, identity: $1)
|
|
||||||
}
|
|
||||||
let c = makeWrappedCollectionWithComparableElement(elements)
|
|
||||||
% end
|
|
||||||
|
|
||||||
var lc = LoggingMutableRandomAccessCollection(wrapping: c)
|
var lc = LoggingMutableRandomAccessCollection(wrapping: c)
|
||||||
|
|
||||||
% if predicate:
|
|
||||||
let closureLifetimeTracker = LifetimeTracked(0)
|
let closureLifetimeTracker = LifetimeTracked(0)
|
||||||
var pivot = lc.startIndex
|
let first = c.first
|
||||||
if let first = c.first {
|
let pivot = lc.partition(by: { val in
|
||||||
pivot = lc.partition(by: {
|
|
||||||
val in
|
|
||||||
_blackHole(closureLifetimeTracker)
|
_blackHole(closureLifetimeTracker)
|
||||||
return !(extract(val).value < extract(first).value) })
|
return !(extract(val).value < extract(first!).value)
|
||||||
}
|
})
|
||||||
% else:
|
|
||||||
var pivot = lc.startIndex
|
|
||||||
if let first = lc.first {
|
|
||||||
pivot = lc.partition(by: { !($0 < first) })
|
|
||||||
}
|
|
||||||
% end
|
|
||||||
|
|
||||||
expectEqual(
|
expectEqual(
|
||||||
1, lc.log._withUnsafeMutableBufferPointerIfSupported[lc.dynamicType])
|
1, lc.log._withUnsafeMutableBufferPointerIfSupported[lc.dynamicType])
|
||||||
@@ -1016,8 +984,6 @@ self.test("\(testNamePrefix).partition/DispatchesThrough_withUnsafeMutableBuffer
|
|||||||
expectEqualSequence([ 1, 4, 3, 2, 5 ], lc.map { extract($0).value })
|
expectEqualSequence([ 1, 4, 3, 2, 5 ], lc.map { extract($0).value })
|
||||||
}
|
}
|
||||||
|
|
||||||
% end
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
} // addMutableRandomAccessCollectionTests
|
} // addMutableRandomAccessCollectionTests
|
||||||
|
|||||||
@@ -78,17 +78,14 @@ print("Test1 - Done")
|
|||||||
|
|
||||||
let partition_verifier: ([Int]) -> Void = {
|
let partition_verifier: ([Int]) -> Void = {
|
||||||
var y = $0
|
var y = $0
|
||||||
// Partition() returns the index to the pivot value.
|
// partition(by:) returns the index to the pivot value.
|
||||||
var idx = y.startIndex
|
let first = y.first
|
||||||
var pivot = -1
|
let idx = y.partition(by: { $0 >= first! })
|
||||||
if let first = y.first {
|
|
||||||
pivot = first
|
|
||||||
idx = y.partition(by: { $0 >= first })
|
|
||||||
}
|
|
||||||
// Check that all of the elements in the first partition are smaller than
|
// Check that all of the elements in the first partition are smaller than
|
||||||
// the pivot value.
|
// the pivot value.
|
||||||
for i in 0..<idx {
|
for i in 0..<idx {
|
||||||
if y[i] >= pivot {
|
if y[i] >= first! {
|
||||||
print("Error!\n", terminator: "")
|
print("Error!\n", terminator: "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -96,7 +93,7 @@ let partition_verifier: ([Int]) -> Void = {
|
|||||||
// Check that all of the elements in the second partition are greater or
|
// Check that all of the elements in the second partition are greater or
|
||||||
// equal to the pivot value.
|
// equal to the pivot value.
|
||||||
for i in idx..<y.count - 1 {
|
for i in idx..<y.count - 1 {
|
||||||
if y[i] < pivot {
|
if y[i] < first! {
|
||||||
print("Error!\n", terminator: "")
|
print("Error!\n", terminator: "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,10 +76,8 @@ extension MutableCollection
|
|||||||
where Self: RandomAccessCollection, Self.Iterator.Element : Comparable {
|
where Self: RandomAccessCollection, Self.Iterator.Element : Comparable {
|
||||||
|
|
||||||
public final mutating func myPartition() -> Index {
|
public final mutating func myPartition() -> Index {
|
||||||
if let first = self.first {
|
let first = self.first
|
||||||
return self.partition(by: { $0 >= first})
|
return self.partition(by: { $0 >= first! })
|
||||||
}
|
|
||||||
return self.startIndex
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,9 +150,8 @@ Algorithm.test("invalidOrderings") {
|
|||||||
var a: A<Int>
|
var a: A<Int>
|
||||||
a = randomArray()
|
a = randomArray()
|
||||||
let lt = $0
|
let lt = $0
|
||||||
if let first = a.first {
|
let first = a.first
|
||||||
_ = a.partition(by: { !lt($0, first) })
|
_ = a.partition(by: { !lt($0, first!) })
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
// FIXME: Disabled due to <rdar://problem/17734737> Unimplemented:
|
// FIXME: Disabled due to <rdar://problem/17734737> Unimplemented:
|
||||||
|
|||||||
Reference in New Issue
Block a user