1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
// RUN: %target-swift-frontend -parse-as-library -O -emit-sil -verify %s -disable-availability-checking
extension List {
var peek: Element {
_read {
switch self.head {
case .empty: fatalError()
case .more(let box):
yield box.wrapped.element
}
//yield head.peek
}
}
}
struct Box<Wrapped: ~Copyable>: ~Copyable {
private let _pointer: UnsafeMutablePointer<Wrapped>
init(_ element: consuming Wrapped) {
_pointer = .allocate(capacity: 1)
print("allocatin", _pointer)
_pointer.initialize(to: element)
}
deinit {
print("not deallocatin", _pointer)
_pointer.deinitialize(count: 1)
_pointer.deallocate()
}
consuming func move() -> Wrapped {
let wrapped = _pointer.move()
print("deallocatin", _pointer)
_pointer.deallocate()
discard self
return wrapped
}
var wrapped: Wrapped {
_read { yield _pointer.pointee }
}
}
struct List<Element>: ~Copyable {
var head: Link<Element> = .empty
var bool = false
}
enum Link<Element>: ~Copyable {
case empty
case more(Box<Node<Element>>)
var peek: Element {
_read {
switch self {
case .empty: fatalError()
case .more(let box):
yield box.wrapped.element
}
}
}
}
struct Node<Element>: ~Copyable {
let element: Element
let next: Link<Element>
var bool = true
}
extension List {
mutating func append(_ element: consuming Element) {
self = List(head: .more(Box(Node(element: element, next: self.head))))
}
var isEmpty: Bool {
switch self.head {
case .empty: true
default: false
}
}
mutating func pop() -> Element {
let h = self.head
switch consume h {
case .empty: fatalError()
case .more(let box):
let node = box.move()
self = .init(head: node.next)
return node.element
}
}
}
@main
struct Main {
static func main() {
var l: List<Int> = .init()
l.append(1)
l.append(2)
l.append(3)
print(l.pop())
print(l.pop())
print(l.pop())
print(l.isEmpty)
}
}
|