mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
150 lines
4.4 KiB
Plaintext
150 lines
4.4 KiB
Plaintext
// RUN: rm -f %t.swift %t.out
|
|
|
|
// RUN: %S/../../utils/gyb %s -o %t.swift
|
|
// RUN: %S/../../utils/line-directive %t.swift -- %target-build-swift -Xfrontend -disable-access-control %t.swift -o %t.out
|
|
// RUN: %S/../../utils/line-directive %t.swift -- %target-run %t.out
|
|
// XFAIL: linux
|
|
|
|
import StdlibUnittest
|
|
|
|
var Algorithm = TestSuite("Algorithm")
|
|
|
|
@asmname("random") func random() -> UInt32
|
|
|
|
|
|
// Check if one array is a correctly sorted version of another array.
|
|
// We can't simply sort both arrays and compare them, because it is needed to
|
|
// check correctness of sorting itself.
|
|
func expectSortedCollection(sortedAry: [Int], originalAry: [Int]) {
|
|
expectEqual(sortedAry.count, originalAry.count)
|
|
var sortedVals = [Int:Int]()
|
|
var originalVals = [Int:Int]()
|
|
// Keep track of what values we have in sortedAry.
|
|
for e in sortedAry {
|
|
if let v = sortedVals[e] {
|
|
sortedVals[e] = v + 1
|
|
} else {
|
|
sortedVals[e] = 0
|
|
}
|
|
}
|
|
// And do the same for originalAry.
|
|
for e in originalAry {
|
|
if let v = originalVals[e] {
|
|
originalVals[e] = v + 1
|
|
} else {
|
|
originalVals[e] = 0
|
|
}
|
|
}
|
|
// Now check if sets of elements are the same in both arrays.
|
|
for (key, value) in sortedVals {
|
|
expectNotEmpty(originalVals[key])
|
|
expectEqual(originalVals[key]!, value)
|
|
}
|
|
|
|
// Check if values in sortedAry are actually sorted.
|
|
for i in 1..<sortedAry.count {
|
|
expectTrue(sortedAry[i - 1] <= sortedAry[i])
|
|
}
|
|
}
|
|
|
|
func expectSortedCollection(
|
|
sortedAry: [Int],
|
|
originalAry: ContiguousArray<Int>
|
|
) {
|
|
expectSortedCollection(sortedAry, Array(originalAry))
|
|
}
|
|
|
|
func expectSortedCollection(sortedAry: Slice<Int>, originalAry: Slice<Int>) {
|
|
expectSortedCollection([Int](sortedAry), [Int](originalAry))
|
|
}
|
|
|
|
class OffsetCollection : MutableCollectionType {
|
|
let offset: Int
|
|
var data: [Int] = []
|
|
let forward: Bool
|
|
var startIndex: Int { return forward ? offset : offset - data.count }
|
|
var endIndex: Int { return forward ? offset + data.count : offset }
|
|
subscript (i: Int) -> Int {
|
|
get { return data[i - startIndex] }
|
|
set { data[i - startIndex] = newValue }
|
|
}
|
|
func generate() -> IndexingGenerator<[Int]> {
|
|
return IndexingGenerator<[Int]>(data)
|
|
}
|
|
func toArray() -> [Int] {
|
|
return data
|
|
}
|
|
var count: Int { return data.count }
|
|
init(_ ary: [Int], offset: Int, forward: Bool) {
|
|
data = ary
|
|
self.offset = offset
|
|
self.forward = forward
|
|
}
|
|
}
|
|
|
|
|
|
// Generate two versions of tests: one for sort with explicitly passed
|
|
// predicate and the other using default comparison operator.
|
|
% withArrayTypeNames = ["Array", "ContiguousArray"]
|
|
% withPredicateValues = [True, False]
|
|
% for t in withArrayTypeNames:
|
|
|
|
func random${t}(count: Int) -> ${t}<Int> {
|
|
var a: ${t}<Int> = []
|
|
a.reserveCapacity(Int(count))
|
|
for i in 0..<count {
|
|
a.append(Int(random()))
|
|
}
|
|
return a
|
|
}
|
|
% for p in withPredicateValues:
|
|
% comparePredicate = ", <" if p else ""
|
|
% name = "lessPredicate" if p else "noPredicate"
|
|
|
|
Algorithm.test("sorted/${name}") {
|
|
let count = 1000
|
|
var ary = random${t}(count)
|
|
var sortedAry1 = [Int]()
|
|
var sortedAry2 = ${t}<Int>()
|
|
|
|
// Similar test for sorting with predicate
|
|
sortedAry1 = sorted(ary${comparePredicate})
|
|
expectSortedCollection(sortedAry1, ary)
|
|
|
|
// Check that sorting works well on intervals
|
|
let i1 = 400
|
|
let i2 = 700
|
|
sortedAry2 = ary
|
|
_introSort(&sortedAry2, i1..<i2${comparePredicate})
|
|
|
|
expectEqual(ary[0..<i1], sortedAry2[0..<i1])
|
|
expectSortedCollection(sortedAry2[i1..<i2], ary[i1..<i2])
|
|
expectEqual(ary[i2..<count], sortedAry2[i2..<count])
|
|
}
|
|
% end
|
|
|
|
Algorithm.test("sort/CollectionsWithUnusualIndices") {
|
|
let count = 1000
|
|
var ary = randomArray(count)
|
|
|
|
// Check if sorting routines work well on collections with startIndex != 0.
|
|
var offsetAry = OffsetCollection(ary, offset: 500, forward: false)
|
|
sort(&offsetAry${comparePredicate})
|
|
expectSortedCollection(offsetAry.toArray(), ary)
|
|
|
|
// Check if sorting routines work well on collections with endIndex = Int.max.
|
|
// That could expose overflow errors in index computations.
|
|
offsetAry = OffsetCollection(ary, offset: Int.max, forward: false)
|
|
sort(&offsetAry${comparePredicate})
|
|
expectSortedCollection(offsetAry.toArray(), ary)
|
|
|
|
// Check if sorting routines work well on collections with
|
|
// startIndex = Int.min.
|
|
offsetAry = OffsetCollection(ary, offset: Int.min, forward: true)
|
|
sort(&offsetAry${comparePredicate})
|
|
expectSortedCollection(offsetAry.toArray(), ary)
|
|
|
|
}
|
|
|
|
runAllTests()
|