mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
* [stdlib] Slice: customize withContiguous[Mutable]StorageIfAvailable We can easily make an UnsafeBufferPointer that slices another UnsafeBufferPointer, so let’s allow Slice to vend a slice of the base collection’s contiguous storage, if it provides access to one. We need to do some index distance calculations to implement this, but those will be constant-time in the usual case where the base collection is a RAC. https://bugs.swift.org/browse/SR-11957 rdar://58090587 * [test] UnsafeBufferPointer: fix some warnings * [stdlib] Slice: don’t calculate index distances unless the base provides contiguous mutable storage
148 lines
4.0 KiB
Swift
148 lines
4.0 KiB
Swift
// -*- swift -*-
|
|
// RUN: %target-run-simple-swiftgyb
|
|
// REQUIRES: executable_test
|
|
|
|
%{
|
|
from gyb_stdlib_support import (
|
|
TRAVERSALS,
|
|
collectionTypeName
|
|
)
|
|
}%
|
|
|
|
import StdlibUnittest
|
|
import StdlibCollectionUnittest
|
|
|
|
|
|
/// Reference-type collection for testing the `base` property.
|
|
class ReferenceCollection : RandomAccessCollection {
|
|
typealias Index = Int
|
|
|
|
var startIndex: Int {
|
|
return 0
|
|
}
|
|
|
|
var endIndex: Int {
|
|
return 1
|
|
}
|
|
|
|
subscript(index: Int) -> String {
|
|
return ""
|
|
}
|
|
|
|
func index(after i: Int) -> Int {
|
|
return 1
|
|
}
|
|
|
|
func index(before i: Int) -> Int {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
var SliceTests = TestSuite("Collection")
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Slice<Base>
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
% for Traversal in TRAVERSALS:
|
|
% for Mutable in [ False, True ]:
|
|
% for RangeReplaceable in [ False, True ]:
|
|
% Collection = 'Minimal' + collectionTypeName(traversal=Traversal, mutable=Mutable, rangeReplaceable=RangeReplaceable)
|
|
|
|
SliceTests.test("${Collection}.Slice/AssociatedTypes") {
|
|
do {
|
|
typealias Collection = ${Collection}<OpaqueValue<Int>>
|
|
typealias CollectionSlice = Slice<Collection>
|
|
expectSliceType(CollectionSlice.self)
|
|
expectCollectionAssociatedTypes(
|
|
collectionType: CollectionSlice.self,
|
|
iteratorType: IndexingIterator<CollectionSlice>.self,
|
|
subSequenceType: CollectionSlice.self,
|
|
indexType: MinimalIndex.self,
|
|
indicesType: Collection.Indices.self)
|
|
}
|
|
|
|
func checkStaticTypealiases1<Base : Collection>(_: Base) {
|
|
expectEqualType(Base.Index.self, Slice<Base>.Index.self)
|
|
}
|
|
|
|
func checkStaticTypealiases2<
|
|
Base : MutableCollection
|
|
>(_: Base) {
|
|
expectEqualType(Base.Index.self, Slice<Base>.Index.self)
|
|
}
|
|
}
|
|
|
|
SliceTests.test("${Collection}.Slice/init(base:bounds:)") {
|
|
for test in subscriptRangeTests {
|
|
let base = ${Collection}(elements: test.collection)
|
|
var slice = Slice(base: base, bounds: test.bounds(in: base))
|
|
expectType(Slice<${Collection}<OpaqueValue<Int>>>.self, &slice)
|
|
expectType(${Collection}<OpaqueValue<Int>>.SubSequence.self, &slice)
|
|
|
|
checkCollection(
|
|
test.expected,
|
|
slice,
|
|
stackTrace: SourceLocStack().with(test.loc))
|
|
{ $0.value == $1.value }
|
|
}
|
|
}
|
|
|
|
% if RangeReplaceable == False and Mutable == False:
|
|
SliceTests.test("${Collection}.Slice/baseProperty") {
|
|
let referenceCollection = ReferenceCollection()
|
|
let testSlice = Slice(base: referenceCollection, bounds: 0..<1)
|
|
expectTrue(testSlice.base === referenceCollection)
|
|
}
|
|
% end
|
|
|
|
SliceTests.test("${Collection}.Slice.{startIndex,endIndex}") {
|
|
for test in subscriptRangeTests {
|
|
let c = ${Collection}(elements: test.collection)
|
|
let bounds = test.bounds(in: c)
|
|
var slice = Slice(base: c, bounds: bounds)
|
|
expectType(Slice<${Collection}<OpaqueValue<Int>>>.self, &slice)
|
|
expectType(${Collection}<OpaqueValue<Int>>.SubSequence.self, &slice)
|
|
|
|
expectEqual(bounds.lowerBound, slice.startIndex)
|
|
expectEqual(bounds.upperBound, slice.endIndex)
|
|
}
|
|
}
|
|
|
|
% end
|
|
% end
|
|
% end
|
|
|
|
SliceTests.test("${Collection}.Slice.withContiguousStorageIfAvailable") {
|
|
for test in subscriptRangeTests {
|
|
let c = ${Collection}(elements: test.collection)
|
|
let bounds = test.bounds(in: c)
|
|
var slice = Slice(base: c, bounds: bounds)
|
|
let r = slice.withContiguousStorageIfAvailable { _ in }
|
|
expectNil(r) // None of the minimal collection types implement this.
|
|
}
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// MutableSlice<Base>
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
extension Slice {
|
|
func _checkBaseSubSequenceElementIsElement() {
|
|
expectEqualType(
|
|
Element.self,
|
|
Iterator.Element.self)
|
|
expectEqualType(
|
|
Element.self,
|
|
Base.Iterator.Element.self)
|
|
expectEqualType(
|
|
Element.self,
|
|
Iterator.Element.self)
|
|
expectEqualType(
|
|
Element.self,
|
|
Base.SubSequence.Iterator.Element.self)
|
|
}
|
|
}
|
|
|
|
runAllTests()
|