Skip to content

Commit 483f4eb

Browse files
authored
Merge pull request swiftlang#21135 from airspeedswift/test-contiguous-storage
2 parents 18c7e92 + 11769d2 commit 483f4eb

File tree

5 files changed

+79
-7
lines changed

5 files changed

+79
-7
lines changed

stdlib/private/StdlibCollectionUnittest/LoggingWrappers.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public class SequenceLog {
8383
public static var prefixWhile = TypeIndexed(0)
8484
public static var prefixMaxLength = TypeIndexed(0)
8585
public static var suffixMaxLength = TypeIndexed(0)
86+
public static var withContiguousStorageIfAvailable = TypeIndexed(0)
8687
public static var _customContainsEquatableElement = TypeIndexed(0)
8788
public static var _copyToContiguousArray = TypeIndexed(0)
8889
public static var _copyContents = TypeIndexed(0)
@@ -213,6 +214,13 @@ extension LoggingSequence: Sequence {
213214
SequenceLog.underestimatedCount[selfType] += 1
214215
return base.underestimatedCount
215216
}
217+
218+
public func withContiguousStorageIfAvailable<R>(
219+
_ body: (UnsafeBufferPointer<Element>) throws -> R
220+
) rethrows -> R? {
221+
SequenceLog.withContiguousStorageIfAvailable[selfType] += 1
222+
return try base.withContiguousStorageIfAvailable(body)
223+
}
216224

217225
public func _customContainsEquatableElement(_ element: Element) -> Bool? {
218226
SequenceLog._customContainsEquatableElement[selfType] += 1

stdlib/public/core/Sequence.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,6 @@ public protocol Sequence {
363363
initializing ptr: UnsafeMutableBufferPointer<Element>
364364
) -> (Iterator,UnsafeMutableBufferPointer<Element>.Index)
365365

366-
@inlinable
367366
func withContiguousStorageIfAvailable<R>(
368367
_ body: (UnsafeBufferPointer<Element>) throws -> R
369368
) rethrows -> R?

test/stdlib/Inputs/CommonArrayTests.gyb

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,48 @@ ${Suite}.test("${ArrayType}/_withUnsafeMutableBufferPointerIfSupported/Replacing
325325
}
326326

327327
//===----------------------------------------------------------------------===//
328-
// _withUnsafeMutableBufferPointerIfSupported()
328+
// withContiguousStorageIfAvailableTests()
329+
//===----------------------------------------------------------------------===//
330+
331+
struct WithContiguousStorageIfAvailableTest {
332+
let sequence: [Int]
333+
let loc: SourceLoc
334+
335+
init(
336+
_ sequence: [Int],
337+
file: String = #file, line: UInt = #line
338+
) {
339+
self.sequence = sequence
340+
self.loc = SourceLoc(file, line, comment: "test data")
341+
}
342+
}
343+
344+
let withContiguousStorageIfAvailableTests = [
345+
WithContiguousStorageIfAvailableTest([]),
346+
WithContiguousStorageIfAvailableTest([ 10 ]),
347+
WithContiguousStorageIfAvailableTest([ 10, 20, 30, 40, 50 ]),
348+
]
349+
350+
${Suite}.test("${ArrayType}/withContiguousStorageIfAvailable")
351+
.code {
352+
for test in withContiguousStorageIfAvailableTests {
353+
var a = getFresh${ArrayType}(test.sequence.map(OpaqueValue.init))
354+
do {
355+
// Read.
356+
var result = a.withContiguousStorageIfAvailable {
357+
(bufferPointer) -> OpaqueValue<[OpaqueValue<Int>]> in
358+
return OpaqueValue(Array(bufferPointer))
359+
}
360+
expectType(Optional<OpaqueValue<Array<OpaqueValue<Int>>>>.self, &result)
361+
expectEqualSequence(test.sequence, result!.value.map { $0.value })
362+
expectEqualSequence(test.sequence, a.map { $0.value })
363+
}
364+
}
365+
// FIXME: tests for arrays bridged from Objective-C.
366+
}
367+
368+
//===----------------------------------------------------------------------===//
369+
// withContiguousMutableStorageIfAvailableTests()
329370
//===----------------------------------------------------------------------===//
330371

331372
struct WithContiguousMutableStorageIfAvailableTest {

validation-test/stdlib/SequenceType.swift.gyb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,20 @@ SequenceTypeTests.test("underestimatedCount/Sequence/CustomImplementation") {
10491049
}
10501050
}
10511051

1052+
//===----------------------------------------------------------------------===//
1053+
// withContiguousStorageIfAvailable()
1054+
//===----------------------------------------------------------------------===//
1055+
SequenceTypeTests.test("withContiguousMutableStorageIfAvailable")
1056+
.code {
1057+
let s = [ 1, 2, 3 ].map(OpaqueValue.init)
1058+
let tester = SequenceLog.dispatchTester(s)
1059+
let result = tester.withContiguousStorageIfAvailable { buf in
1060+
buf.reduce(0) { $0 + $1.value }
1061+
}
1062+
expectEqual(6, result)
1063+
expectCustomizable(tester, tester.log.withContiguousStorageIfAvailable)
1064+
}
1065+
10521066
//===----------------------------------------------------------------------===//
10531067
// _copyToContiguousArray()
10541068
//===----------------------------------------------------------------------===//

validation-test/stdlib/UnsafeBufferPointer.swift.gyb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,17 +325,27 @@ UnsafeMutableBufferPointerTestSuite.test("changeElementViaBuffer") {
325325
expectEqual(-1.0, allocated[count-1])
326326
}
327327

328-
UnsafeMutableBufferPointerTestSuite.test("withContiguousMutableStorageIfAvailable") {
328+
UnsafeMutableBufferPointerTestSuite.test("withContiguous(Mutable)StorageIfAvailable") {
329329
let count = 4
330330
let allocated = UnsafeMutablePointer<Int>.allocate(capacity: count)
331331
defer { allocated.deallocate() }
332332
allocated.initialize(repeating: 1, count: count)
333333

334-
var buffer = UnsafeMutableBufferPointer(start: allocated, count: count)
335-
let result = buffer.withContiguousMutableStorageIfAvailable { buffer in
336-
return buffer.reduce(0, +)
334+
var mutableBuffer = UnsafeMutableBufferPointer(start: allocated, count: count)
335+
let executed: ()? = mutableBuffer.withContiguousMutableStorageIfAvailable { buf in
336+
for i in 0..<buf.count { buf[i] *= 2 }
337337
}
338-
expectEqual(count, result)
338+
expectNotNil(executed)
339+
let result1 = mutableBuffer.withContiguousStorageIfAvailable { buf in
340+
return buf.reduce(0, +)
341+
}
342+
expectEqual(count*2, result1)
343+
344+
let immutableBuffer = UnsafeBufferPointer(start: allocated, count: count)
345+
let result2 = immutableBuffer.withContiguousStorageIfAvailable { buf in
346+
return buf.reduce(0, +)
347+
}
348+
expectEqual(result1, result2)
339349
}
340350

341351
UnsafeMutableBufferPointerTestSuite.test("sort") {

0 commit comments

Comments
 (0)