|
| 1 | +// RUN: %target-swift-frontend %s -emit-sil \ |
| 2 | +// RUN: -disable-experimental-parser-round-trip \ |
| 3 | +// RUN: -enable-experimental-feature NonescapableTypes \ |
| 4 | +// RUN: -enable-experimental-feature NoncopyableGenerics \ |
| 5 | +// RUN: -enable-experimental-lifetime-dependence-inference \ |
| 6 | +// RUN: -Xllvm -enable-lifetime-dependence-diagnostics |
| 7 | +// REQUIRES: noncopyable_generics |
| 8 | + |
| 9 | +public struct BufferView<Element> : ~Escapable { |
| 10 | + public typealias Index = Int |
| 11 | + public typealias Pointer = UnsafePointer<Element> |
| 12 | + public let baseAddress: Pointer |
| 13 | + public let count: Int |
| 14 | + |
| 15 | + // TODO: This should be a failable initializer |
| 16 | + // Currently optional is Escapable, so we cant yet write it. |
| 17 | + public init<Storage>(unsafeBuffer: UnsafeBufferPointer<Element>, |
| 18 | + storage: borrowing Storage) |
| 19 | + -> _borrow(storage) Self { |
| 20 | + let baseAddress = unsafeBuffer.baseAddress! |
| 21 | + self = BufferView<Element>(baseAddress: baseAddress, |
| 22 | + count: unsafeBuffer.count) |
| 23 | + return self |
| 24 | + } |
| 25 | + // unsafe private API |
| 26 | + @_unsafeNonescapableResult |
| 27 | + init(baseAddress: Pointer, count: Int) { |
| 28 | + precondition(count >= 0, "Count must not be negative") |
| 29 | + self.baseAddress = baseAddress |
| 30 | + self.count = count |
| 31 | + } |
| 32 | + subscript(_ index: Index) -> Element? { |
| 33 | + if (index < 0 || index >= count) { |
| 34 | + return nil |
| 35 | + } |
| 36 | + return baseAddress[index] |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +extension Array { |
| 41 | + // var view: BufferView<Element> { |
| 42 | + // withUnsafeBufferPointer { |
| 43 | + // return BufferView(unsafeBuffer: $0, storage: self) |
| 44 | + // } |
| 45 | + // } |
| 46 | + // TODO: Implementation of getter should not need a temporary |
| 47 | + // rdar://123071321 |
| 48 | + var view: BufferView<Element> { |
| 49 | + var _view : BufferView<Element>? |
| 50 | + withUnsafeBufferPointer { |
| 51 | + _view = BufferView(unsafeBuffer: $0, storage: self) |
| 52 | + } |
| 53 | + return _view! |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +public func array_view_element(a: [Int] , i: Int) -> Int { |
| 58 | + a.view[i]! |
| 59 | +} |
| 60 | + |
0 commit comments