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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// RUN: %target-run-simple-swift(-Xfrontend -sil-verify-all)
// RUN: %target-run-simple-swift(-O -Xfrontend -sil-verify-all)
// RUN: %target-run-simple-swift(-O -Xfrontend -sil-verify-all -Xfrontend -enable-ossa-modules)
// REQUIRES: executable_test
/// A class that we use as a box to store the memory for one of our linked list
/// nodes. It is on purpose fileprivate since it is an implementation detail of
/// \p NodeBox.
fileprivate final class _Box<T> {
var value: _Node<T>
init(_ value: consuming _Node<T>) { self.value = value }
}
struct _Node<T> : ~Copyable {
var value: T
var _next: ListEntry<T> = ListEntry<T>()
init(_ newValue: T) {
value = newValue
}
}
/// A noncopyable box that contains the memory for a linked list node. Can be
/// embedded within other noncopyable data structures to point at a Node data
/// structure.
///
/// Internally uses a class as the actual box.
struct ListEntry<T> : ~Copyable {
private var innerBox: _Box<T>?
init() { innerBox = nil }
init(initialValue value: consuming T) {
innerBox = _Box<T>(_Node(value))
}
mutating func push(value newValue: consuming T) {
if innerBox == nil {
// If we do not already have a head, just take on this value and return.
innerBox = _Box<T>(_Node(newValue))
return
}
// Otherwise, we need to create a new node and fix things up.
var nodeEntry = ListEntry<T>(initialValue: newValue)
nodeEntry.next = self
self = nodeEntry
}
mutating func pop() -> T? {
guard let innerBox = innerBox else {
return nil
}
let result = innerBox.value.value
func fixNext(_ lhs: inout ListEntry<T>, _ rhs: inout ListEntry<T>) {
lhs = rhs
rhs = ListEntry<T>()
}
fixNext(&self, &innerBox.value._next)
return result
}
var hasNext: Bool {
return innerBox != nil
}
var next: ListEntry<T> {
_modify {
yield &innerBox!.value._next
}
_read {
yield innerBox!.value._next
}
}
var value: T? {
return innerBox?.value.value
}
}
let target = "ogyfbssvlh"
let strings = [
"nulbhqylps",
"hpdovhuybl",
"bjjvpakqbm",
"rqyozjzkyz",
"qpzghmdcag",
"lqefxvulvn",
"wtokfqarxm",
"acdcrzxpdg",
"bxgfacpjic",
"acblrvoego",
"msevhriohn",
"bamfcnbqvx",
"wimkkqhryd",
"dounctqkiw",
"zxmyxcabhq",
"ljerkuhlgy",
"cettadahue",
"cuummvmwly",
"kdebludzsh",
"ogyfbssvlh",
"lrowrxwufj",
"rftifkqggr",
"ktjeeeobca",
"xqlbnswmjr",
"zpuxfbtmip",
"rljcxrvdgh",
"twkgardobr",
"zrogczpzem",
"bkuzjugksg",
"eqanimdywo"
]
func buildList() -> ListEntry<String> {
var head = ListEntry<String>()
for i in strings {
head.push(value: i)
}
return head
}
func main() {
var head = buildList()
var count = 0
var strCount = strings.count
while let x = head.pop() {
assert(x == strings[strCount - count - 1])
count = count + 1
}
}
main()
|