mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Find all the usages of `--enable-experimental-feature` or `--enable-upcoming-feature` in the tests and replace some of the `REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which should correctly apply to depending on the asserts/noasserts mode of the toolchain for each feature. Remove some comments that talked about enabling asserts since they don't apply anymore (but I might had miss some). All this was done with an automated script, so some formatting weirdness might happen, but I hope I fixed most of those. There might be some tests that were `REQUIRES: asserts` that might run in `noasserts` toolchains now. This will normally be because their feature went from experimental to upcoming/base and the tests were not updated.
406 lines
10 KiB
Swift
406 lines
10 KiB
Swift
|
|
// RUN: %target-run-simple-swift(%S/Inputs/ExperimentalFixedArray.swift -enable-experimental-feature Embedded -enable-experimental-feature FixedArrays -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
|
|
// RUN: %target-run-simple-swift(-O %S/Inputs/ExperimentalFixedArray.swift -enable-experimental-feature Embedded -enable-experimental-feature FixedArrays -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
|
|
|
|
// Also test in non-embedded mode
|
|
|
|
// RUN: %target-run-simple-swift(-target %target-cpu-apple-macosx10.13 %S/Inputs/ExperimentalFixedArray.swift -enable-experimental-feature FixedArrays -parse-as-library -wmo) | %FileCheck %s
|
|
// RUN: %target-run-simple-swift(-target %target-cpu-apple-macosx10.13 -O %S/Inputs/ExperimentalFixedArray.swift -enable-experimental-feature FixedArrays -parse-as-library -wmo) | %FileCheck %s
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: optimized_stdlib
|
|
// REQUIRES: VENDOR=apple
|
|
// REQUIRES: OS=macosx
|
|
// REQUIRES: swift_feature_Embedded
|
|
// REQUIRES: swift_feature_FixedArrays
|
|
|
|
func simpleStackAllocated() {
|
|
var a = FixedArray<Int>(capacity: 10)
|
|
a.append(27)
|
|
a.append(28)
|
|
a.append(29)
|
|
a.append(30)
|
|
printit(a)
|
|
}
|
|
|
|
func testDestroyOfElements() {
|
|
var a = FixedArray<CheckLifetime>(capacity: 10)
|
|
a.append(CheckLifetime(27))
|
|
a.append(CheckLifetime(28))
|
|
a.append(CheckLifetime(29))
|
|
a.append(CheckLifetime(30))
|
|
|
|
// The `*` is a prefix operator and serves as syntatic sugar for FixedArray.view.
|
|
printit(*a)
|
|
}
|
|
|
|
struct IntByte: Printable {
|
|
let i: Int32
|
|
let b: Int8
|
|
|
|
func print() {
|
|
Swift.print(i, terminator: "")
|
|
Swift.print(",", terminator: "")
|
|
Swift.print(b, terminator: "")
|
|
}
|
|
}
|
|
|
|
extension Optional: Printable where Wrapped == Int64 {
|
|
func print() {
|
|
if let x = self {
|
|
Swift.print(x, terminator: "")
|
|
} else {
|
|
Swift.print("nil", terminator: "")
|
|
}
|
|
}
|
|
}
|
|
|
|
struct S {
|
|
// Space for elements is reserved in the data section, but not initialized, yet
|
|
static var a = FixedArray<Int>(capacity: 10)
|
|
|
|
// Elements are initialized in the data section.
|
|
// The `^` is a prefix operator and serves as syntatic sugar to create a FixedArray literal.
|
|
static let b = ^[1, 2, 3]
|
|
|
|
static let c: FixedArray<Int64?> = ^[10, 20, 30]
|
|
static let d: FixedArray<IntByte> = ^[IntByte(i: 1, b: 2), IntByte(i: 3, b: 4), IntByte(i: 5, b: 6)]
|
|
static var e = FixedArray<Int64?>(capacity: 3)
|
|
static var f = FixedArray<IntByte>(capacity: 3)
|
|
}
|
|
|
|
func globalWithAppend() {
|
|
S.a.append(27)
|
|
S.a.append(28)
|
|
S.a.append(29)
|
|
S.a.append(30)
|
|
printit(S.a)
|
|
}
|
|
|
|
// First method to pass a FixedArray to a function: as `borrowing` parameter
|
|
func printit<T: Printable>(_ a: borrowing FixedArray<T>) {
|
|
// Currently FixedArray cannot conform to Collection, yet.
|
|
// For iteration, we need to take the detour through BufferView.
|
|
for x in *a {
|
|
x.print()
|
|
print("")
|
|
}
|
|
}
|
|
|
|
// Second method to pass a FixedArray to a function: pass a view to its elements
|
|
func printit<T: Printable>(_ a: BufferView<T>) {
|
|
for x in a {
|
|
x.print()
|
|
print("")
|
|
}
|
|
}
|
|
|
|
extension FixedArray {
|
|
// Functions _can_ return a FixedArray, but must be declared as `@_transparent`.
|
|
@_transparent
|
|
func map<V>(_ c: (T) -> V) -> FixedArray<V> {
|
|
var newArray = FixedArray<V>(capacity: self.count)
|
|
for element in view() {
|
|
newArray.append(c(element))
|
|
}
|
|
return newArray
|
|
}
|
|
}
|
|
|
|
func testMap() {
|
|
let a = ^[1, 2, 3]
|
|
|
|
printit(a.map { $0 + 100 })
|
|
}
|
|
|
|
|
|
// A somehow more complex exmample, where FixedArray is used in another struct
|
|
|
|
struct Matrix<T: Printable>: ~Copyable {
|
|
var elements: FixedArray<T>
|
|
let rows: Int
|
|
let columns: Int
|
|
|
|
@_transparent
|
|
init(rows: Int, columns: Int, _ elements: [T]) {
|
|
self.rows = rows
|
|
self.columns = columns
|
|
precondition(rows * columns == elements.count)
|
|
self.elements = FixedArray(elements: elements)
|
|
}
|
|
|
|
@_transparent
|
|
init(rows: Int, columns: Int, initialValue: T) {
|
|
self.rows = rows
|
|
self.columns = columns
|
|
self.elements = FixedArray(repeating: initialValue, count: rows * columns)
|
|
}
|
|
|
|
subscript(row: Int, col: Int) -> T {
|
|
get {
|
|
return elements[row * columns + col]
|
|
}
|
|
set {
|
|
elements[row * columns + col] = newValue
|
|
}
|
|
}
|
|
|
|
func rowView(for row: Int) -> BufferView<T> {
|
|
let start = elements.view().startIndex.advanced(by: row * columns)
|
|
let end = start.advanced(by: columns)
|
|
return elements.view()[start..<end]
|
|
}
|
|
|
|
func print() {
|
|
for r in 0..<rows {
|
|
Swift.print("(", terminator: "")
|
|
for c in 0..<columns {
|
|
self[r, c].print()
|
|
if c < columns - 1 {
|
|
Swift.print(",", terminator: "")
|
|
} else {
|
|
Swift.print(")")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Functions _can_ return a struct containing a FixedArray, but must be declared as `@_transparent`.
|
|
@_transparent
|
|
func +(lhs: borrowing Matrix<Int>, rhs: borrowing Matrix<Int>) -> Matrix<Int> {
|
|
var result = Matrix(rows: lhs.rows, columns: lhs.columns, initialValue: 0)
|
|
for i in 0..<lhs.rows {
|
|
for j in 0..<lhs.columns {
|
|
result[i, j] = lhs[i, j] + rhs[i, j]
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
struct MatricConsts {
|
|
// A Matrix, containing a FixedArray, initialized with an Array literal -> elements are allocated in the data section.
|
|
static let c = Matrix(rows: 2, columns: 3,
|
|
[ 10, 20, 30,
|
|
40, 50, 60 ])
|
|
}
|
|
|
|
func testMatrixAdd() {
|
|
let x = Matrix(rows: 2, columns: 3,
|
|
[ 1, 2, 3,
|
|
4, 5, 6 ])
|
|
|
|
let y = x + MatricConsts.c
|
|
|
|
y.print()
|
|
}
|
|
|
|
|
|
// Example of another type, using the basic non-allocating buffer utilities (allocateVector).
|
|
// It's possible to implement such a type outside of the stdlib.
|
|
|
|
struct RingBuffer<Element>: ~Copyable {
|
|
private let buffer: UnsafeMutablePointer<Element>
|
|
private let capacity: Int
|
|
private var writeIndex: Int
|
|
private var readIndex = 0
|
|
|
|
@_transparent
|
|
public init(capacity: Int) {
|
|
self.capacity = capacity
|
|
self.buffer = _allocateVector(elementType: Element.self, capacity: capacity)
|
|
self.writeIndex = 0
|
|
}
|
|
|
|
@_transparent
|
|
init(repeating repeatedValue: Element, count: Int) {
|
|
self.capacity = count + 1
|
|
self.buffer = _allocateVector(elementType: Element.self, capacity: capacity)
|
|
self.writeIndex = count
|
|
for i in 0..<count {
|
|
(buffer + i).initialize(to: repeatedValue)
|
|
}
|
|
}
|
|
|
|
var isEmpty: Bool { readIndex == writeIndex }
|
|
|
|
mutating func push(_ element: Element) -> Bool {
|
|
guard (writeIndex + 1) % capacity != readIndex else {
|
|
return false
|
|
}
|
|
(buffer + writeIndex).initialize(to: element)
|
|
writeIndex = (writeIndex + 1) % capacity
|
|
return true
|
|
}
|
|
|
|
mutating func next() -> Element? {
|
|
if isEmpty {
|
|
return nil
|
|
}
|
|
let value = (buffer + readIndex).move()
|
|
readIndex = (readIndex + 1) % capacity
|
|
return value
|
|
}
|
|
|
|
deinit {
|
|
var idx = readIndex
|
|
while idx != writeIndex {
|
|
_ = (buffer + idx).move()
|
|
idx = (idx + 1) % capacity
|
|
}
|
|
}
|
|
}
|
|
|
|
func testRingBuffer() {
|
|
var rb = RingBuffer<Int>(capacity: 3)
|
|
|
|
print(rb.push(1))
|
|
print(rb.push(2))
|
|
print(rb.next())
|
|
print(rb.push(3))
|
|
print(rb.push(4))
|
|
print(rb.next())
|
|
print(rb.next())
|
|
print(rb.next())
|
|
}
|
|
|
|
|
|
// Test utilities
|
|
|
|
protocol Printable {
|
|
func print()
|
|
}
|
|
|
|
extension Int: Printable {
|
|
func print() {
|
|
Swift.print(self, terminator: "")
|
|
}
|
|
}
|
|
|
|
func print(_ i: Int?) {
|
|
if let i = i {
|
|
print(i)
|
|
} else {
|
|
print("nil")
|
|
}
|
|
}
|
|
|
|
final class CheckLifetime: Printable {
|
|
let x: Int
|
|
init(_ x: Int) {
|
|
self.x = x
|
|
}
|
|
|
|
deinit {
|
|
Swift.print("deinit ", terminator: "")
|
|
Swift.print(x)
|
|
}
|
|
|
|
func print() {
|
|
Swift.print("CheckLifetime(", terminator: "")
|
|
Swift.print(x, terminator: ")")
|
|
}
|
|
}
|
|
|
|
// Check for correctness
|
|
|
|
@main
|
|
struct Main {
|
|
static func main() {
|
|
// CHECK-LABEL: ### simpleStackAllocated
|
|
// CHECK-NEXT: 27
|
|
// CHECK-NEXT: 28
|
|
// CHECK-NEXT: 29
|
|
// CHECK-NEXT: 30
|
|
print("### simpleStackAllocated")
|
|
simpleStackAllocated()
|
|
|
|
// CHECK-LABEL: ### testDestroyOfElements
|
|
// CHECK-NEXT: CheckLifetime(27)
|
|
// CHECK-NEXT: CheckLifetime(28)
|
|
// CHECK-NEXT: CheckLifetime(29)
|
|
// CHECK-NEXT: CheckLifetime(30)
|
|
// CHECK-NEXT: deinit 27
|
|
// CHECK-NEXT: deinit 28
|
|
// CHECK-NEXT: deinit 29
|
|
// CHECK-NEXT: deinit 30
|
|
print("### testDestroyOfElements")
|
|
testDestroyOfElements()
|
|
|
|
// CHECK-LABEL: ### globalWithAppend
|
|
// CHECK-NEXT: 27
|
|
// CHECK-NEXT: 28
|
|
// CHECK-NEXT: 29
|
|
// CHECK-NEXT: 30
|
|
print("### globalWithAppend")
|
|
globalWithAppend()
|
|
|
|
// CHECK-LABEL: ### globalLiteral
|
|
// CHECK-NEXT: 1
|
|
// CHECK-NEXT: 2
|
|
// CHECK-NEXT: 3
|
|
print("### globalLiteral")
|
|
printit(S.b)
|
|
|
|
// CHECK-LABEL: ### globalOptional
|
|
// CHECK-NEXT: 10
|
|
// CHECK-NEXT: 20
|
|
// CHECK-NEXT: 30
|
|
print("### globalOptional")
|
|
printit(S.c)
|
|
|
|
// CHECK-LABEL: ### globalStruct
|
|
// CHECK-NEXT: 1,2
|
|
// CHECK-NEXT: 3,4
|
|
// CHECK-NEXT: 5,6
|
|
print("### globalStruct")
|
|
printit(S.d)
|
|
|
|
// CHECK-LABEL: ### globalUninitOptional
|
|
// CHECK-NEXT: 100
|
|
// CHECK-NEXT: 200
|
|
// CHECK-NEXT: 300
|
|
print("### globalUninitOptional")
|
|
S.e.append(100)
|
|
S.e.append(200)
|
|
S.e.append(300)
|
|
printit(S.e)
|
|
|
|
// CHECK-LABEL: ### globalUninitStruct
|
|
// CHECK-NEXT: 11,21
|
|
// CHECK-NEXT: 31,41
|
|
// CHECK-NEXT: 51,61
|
|
print("### globalUninitStruct")
|
|
S.f.append(IntByte(i: 11, b: 21))
|
|
S.f.append(IntByte(i: 31, b: 41))
|
|
S.f.append(IntByte(i: 51, b: 61))
|
|
printit(S.f)
|
|
|
|
// CHECK-LABEL: ### testMap
|
|
// CHECK-NEXT: 101
|
|
// CHECK-NEXT: 102
|
|
// CHECK-NEXT: 103
|
|
print("### testMap")
|
|
testMap()
|
|
|
|
// CHECK-LABEL: ### testMatrixAdd
|
|
// CHECK-NEXT: (11,22,33)
|
|
// CHECK-NEXT: (44,55,66)
|
|
print("### testMatrixAdd")
|
|
testMatrixAdd()
|
|
|
|
// CHECK-LABEL: ### testRingBuffer
|
|
// CHECK-NEXT: true
|
|
// CHECK-NEXT: true
|
|
// CHECK-NEXT: 1
|
|
// CHECK-NEXT: true
|
|
// CHECK-NEXT: false
|
|
// CHECK-NEXT: 2
|
|
// CHECK-NEXT: 3
|
|
// CHECK-NEXT: nil
|
|
print("### testRingBuffer")
|
|
testRingBuffer()
|
|
}
|
|
}
|
|
|