mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
268 lines
8.1 KiB
Swift
268 lines
8.1 KiB
Swift
// -*- swift -*-
|
|
// RUN: rm -rf %t ; mkdir -p %t
|
|
// RUN: %S/../../utils/gyb %s -o %t/Slice.swift
|
|
// RUN: %S/../../utils/line-directive %t/Slice.swift -- %target-build-swift %t/Slice.swift -o %t/a.out
|
|
// RUN: %S/../../utils/line-directive %t/Slice.swift -- %target-run %t/a.out
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
import StdlibCollectionUnittest
|
|
import SwiftPrivate
|
|
|
|
// Also import modules which are used by StdlibUnittest internally. This
|
|
// workaround is needed to link all required libraries in case we compile
|
|
// StdlibUnittest with -sil-serialize-all.
|
|
#if _runtime(_ObjC)
|
|
import ObjectiveC
|
|
#endif
|
|
|
|
var SliceTests = TestSuite("Collection")
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Slice<Base>
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
SliceTests.test("Slice/AssociatedTypes") {
|
|
%for traversal in [ 'Forward', 'Bidirectional', 'RandomAccess' ]:
|
|
do {
|
|
typealias Base = Minimal${traversal}Collection<OpaqueValue<Int>>
|
|
typealias ${traversal}Slice = Slice<Base>
|
|
expectSliceType(${traversal}Slice.self)
|
|
expectCollectionAssociatedTypes(
|
|
collectionType: ${traversal}Slice.self,
|
|
iteratorType: IndexingIterator<${traversal}Slice>.self,
|
|
subSequenceType: ${traversal}Slice.self,
|
|
indexType: Minimal${traversal}Index.self)
|
|
}
|
|
%end
|
|
|
|
func checkStaticTypealiases<Base : Collection>(_: Base) {
|
|
expectEqualType(Base.Index.self, Slice<Base>.Index.self)
|
|
}
|
|
}
|
|
|
|
SliceTests.test("Slice/init(_base:bounds:)") {
|
|
for test in subscriptRangeTests {
|
|
let base = MinimalForwardCollection(elements: test.collection)
|
|
var result = Slice(_base: base, bounds: test.boundsIn(base))
|
|
expectType(
|
|
Slice<MinimalForwardCollection<OpaqueValue<Int>>>.self,
|
|
&result)
|
|
|
|
checkForwardCollection(
|
|
test.expected,
|
|
result,
|
|
stackTrace: SourceLocStack().with(test.loc))
|
|
{ $0.value == $1.value }
|
|
}
|
|
}
|
|
|
|
SliceTests.test("Slice.{startIndex,endIndex}") {
|
|
for test in subscriptRangeTests {
|
|
let base = MinimalForwardCollection(elements: test.collection)
|
|
let bounds = test.boundsIn(base)
|
|
var slice = Slice(_base: base, bounds: bounds)
|
|
expectType(
|
|
Slice<MinimalForwardCollection<OpaqueValue<Int>>>.self,
|
|
&slice)
|
|
|
|
expectEqual(bounds.startIndex, slice.startIndex)
|
|
expectEqual(bounds.endIndex, slice.endIndex)
|
|
}
|
|
}
|
|
|
|
SliceTests.test("Slice.subscript(_: Index)") {
|
|
for test in subscriptRangeTests {
|
|
typealias Base = MinimalForwardCollection<OpaqueValue<Int>>
|
|
Base.Index.trapOnRangeCheckFailure.value = false
|
|
let base = Base(elements: test.collection)
|
|
let bounds = test.boundsIn(base)
|
|
var slice = Slice(_base: base, bounds: bounds)
|
|
expectType(Slice<Base>.self, &slice)
|
|
|
|
for i in bounds {
|
|
var element = slice[i]
|
|
expectType(OpaqueValue<Int>.self, &element)
|
|
expectEqual(base[i].value, element.value)
|
|
}
|
|
|
|
for (i, index) in base.indices.enumerated() {
|
|
if test.bounds.contains(i) {
|
|
expectEqual(base[index].value, slice[index].value)
|
|
} else {
|
|
// `Slice` disallows out-of-bounds indices when the underlying index
|
|
// type can perform a range check.
|
|
expectFailure {
|
|
_blackHole(slice[index])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SliceTests.test("Slice.subscript(_: Range<Index>)") {
|
|
for test in subscriptRangeTests {
|
|
typealias Base = MinimalForwardCollection<OpaqueValue<Int>>
|
|
Base.Index.trapOnRangeCheckFailure.value = false
|
|
let base = Base(elements: test.collection)
|
|
var slice = Slice(_base: base, bounds: base.indices)
|
|
expectType(Slice<Base>.self, &slice)
|
|
|
|
var result = slice[test.boundsIn(slice)]
|
|
expectType(Slice<Base>.self, &result)
|
|
|
|
checkForwardCollection(test.expected, result) { $0.value == $1.value }
|
|
|
|
if test.bounds == test.collection.indices {
|
|
let reSliced = result[base.indices]
|
|
checkForwardCollection(
|
|
test.collection,
|
|
reSliced,
|
|
stackTrace: SourceLocStack().with(test.loc))
|
|
{ $0.value == $1.value }
|
|
} else {
|
|
// `Slice` disallows out-of-bounds slicing when the underlying index type
|
|
// can perform a range check.
|
|
expectFailure {
|
|
_blackHole(result[base.indices])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// MutableSlice<Base>
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
SliceTests.test("MutableSlice/AssociatedTypes") {
|
|
%for traversal in [ 'Forward', 'Bidirectional', 'RandomAccess' ]:
|
|
do {
|
|
typealias Base =
|
|
Minimal${traversal}MutableCollection<OpaqueValue<Int>>
|
|
typealias ${traversal}MutableSlice = MutableSlice<Base>
|
|
expectMutableSliceType(${traversal}MutableSlice.self)
|
|
expectCollectionAssociatedTypes(
|
|
collectionType: ${traversal}MutableSlice.self,
|
|
iteratorType: IndexingIterator<${traversal}MutableSlice>.self,
|
|
subSequenceType: ${traversal}MutableSlice.self,
|
|
indexType: Minimal${traversal}Index.self)
|
|
}
|
|
%end
|
|
|
|
func checkStaticTypealiases<
|
|
Base : MutableCollection
|
|
>(_: Base) {
|
|
expectEqualType(Base.Index.self, MutableSlice<Base>.Index.self)
|
|
}
|
|
}
|
|
|
|
/*
|
|
FIXME: uncomment this test when the following bug is fixed:
|
|
|
|
<rdar://problem/21935030> Recast Slice and MutableSlice in terms of Collection
|
|
and MutableCollection
|
|
|
|
extension MutableSlice {
|
|
func _checkBaseSubSequenceElementIsElement() {
|
|
Element.self,
|
|
Iterator.Element.self)
|
|
expectEqualType(
|
|
Element.self,
|
|
Iterator.Element.self,
|
|
Base.Iterator.Element.self)
|
|
expectEqualType(
|
|
Element.self,
|
|
Iterator.Element.self,
|
|
Base.SubSequence.Iterator.Element.self)
|
|
}
|
|
}
|
|
*/
|
|
|
|
SliceTests.test("MutableSlice/init(_base:bounds:)") {
|
|
for test in subscriptRangeTests {
|
|
let c = MinimalForwardMutableCollection(elements: test.collection)
|
|
var result = MutableSlice(_base: c, bounds: test.boundsIn(c))
|
|
expectType(
|
|
MutableSlice<MinimalForwardMutableCollection<OpaqueValue<Int>>>.self,
|
|
&result)
|
|
|
|
checkForwardCollection(
|
|
test.expected,
|
|
result,
|
|
stackTrace: SourceLocStack().with(test.loc))
|
|
{ $0.value == $1.value }
|
|
}
|
|
}
|
|
|
|
SliceTests.test("MutableSlice.{startIndex,endIndex}") {
|
|
for test in subscriptRangeTests {
|
|
let c = MinimalForwardMutableCollection(elements: test.collection)
|
|
let bounds = test.boundsIn(c)
|
|
var slice = MutableSlice(_base: c, bounds: bounds)
|
|
expectType(
|
|
MutableSlice<MinimalForwardMutableCollection<OpaqueValue<Int>>>.self,
|
|
&slice)
|
|
|
|
expectEqual(bounds.startIndex, slice.startIndex)
|
|
expectEqual(bounds.endIndex, slice.endIndex)
|
|
}
|
|
}
|
|
|
|
SliceTests.test("MutableSlice.subscript(_: Index)/{get,set}") {
|
|
for test in subscriptRangeTests {
|
|
typealias Base = MinimalForwardMutableCollection<OpaqueValue<Int>>
|
|
Base.Index.trapOnRangeCheckFailure.value = false
|
|
let base = Base(elements: test.collection)
|
|
let bounds = test.boundsIn(base)
|
|
var slice = MutableSlice(_base: base, bounds: bounds)
|
|
expectType(MutableSlice<Base>.self, &slice)
|
|
|
|
for i in bounds {
|
|
// Test getter.
|
|
var element = slice[i]
|
|
expectType(OpaqueValue<Int>.self, &element)
|
|
expectEqual(base[i].value, element.value)
|
|
}
|
|
|
|
do {
|
|
var sliceForSetter = slice
|
|
for i in bounds {
|
|
// Test setter.
|
|
sliceForSetter[i].value += 1
|
|
expectEqual(base[i].value + 1, sliceForSetter[i].value)
|
|
}
|
|
}
|
|
|
|
var sliceForSetter = slice
|
|
for (i, index) in base.indices.enumerated() {
|
|
if test.bounds.contains(i) {
|
|
// Test getter.
|
|
expectEqual(base[index].value, slice[index].value)
|
|
|
|
// Test setter.
|
|
sliceForSetter[index].value += 1
|
|
expectEqual(base[index].value + 1, sliceForSetter[index].value)
|
|
} else {
|
|
// `MutableSlice` disallows out-of-bounds indices when the underlying
|
|
// index type can perform a range check.
|
|
|
|
// Test getter.
|
|
expectFailure {
|
|
_blackHole(slice[index])
|
|
}
|
|
|
|
// Test setter.
|
|
expectFailure {
|
|
sliceForSetter[index].value += 1
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check that none of the mutations above affected the original collection.
|
|
expectEqualSequence(test.collection, base) { $0.value == $1.value }
|
|
}
|
|
}
|
|
|
|
runAllTests()
|