Skip to content

Commit 268cd76

Browse files
committed
[move-only] Add the moveonly_linkedlist.swift interpreter test.
Both of the previous fixes in this PR were found via this test.
1 parent 0e383cd commit 268cd76

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -sil-verify-all)
2+
// RUN: %target-run-simple-swift(-O -Xfrontend -sil-verify-all)
3+
4+
// REQUIRES: executable_test
5+
6+
/// A class that we use as a box to store the memory for one of our linked list
7+
/// nodes. It is on purpose fileprivate since it is an implementation detail of
8+
/// \p NodeBox.
9+
fileprivate final class _Box<T> {
10+
var value: _Node<T>
11+
12+
init(_ value: consuming _Node<T>) { self.value = value }
13+
}
14+
15+
struct _Node<T> : ~Copyable {
16+
var value: T
17+
var _next: ListEntry<T> = ListEntry<T>()
18+
19+
init(_ newValue: T) {
20+
value = newValue
21+
}
22+
}
23+
24+
/// A noncopyable box that contains the memory for a linked list node. Can be
25+
/// embedded within other noncopyable data structures to point at a Node data
26+
/// structure.
27+
///
28+
/// Internally uses a class as the actual box.
29+
struct ListEntry<T> : ~Copyable {
30+
private var innerBox: _Box<T>?
31+
32+
init() { innerBox = nil }
33+
init(initialValue value: consuming T) {
34+
innerBox = _Box<T>(_Node(value))
35+
}
36+
37+
mutating func push(value newValue: consuming T) {
38+
if innerBox == nil {
39+
// If we do not already have a head, just take on this value and return.
40+
innerBox = _Box<T>(_Node(newValue))
41+
return
42+
}
43+
44+
// Otherwise, we need to create a new node and fix things up.
45+
var nodeEntry = ListEntry<T>(initialValue: newValue)
46+
nodeEntry.next = self
47+
self = nodeEntry
48+
}
49+
50+
mutating func pop() -> T? {
51+
guard let innerBox = innerBox else {
52+
return nil
53+
}
54+
55+
let result = innerBox.value.value
56+
func fixNext(_ lhs: inout ListEntry<T>, _ rhs: inout ListEntry<T>) {
57+
lhs = rhs
58+
rhs = ListEntry<T>()
59+
}
60+
fixNext(&self, &innerBox.value._next)
61+
return result
62+
}
63+
64+
var hasNext: Bool {
65+
return innerBox != nil
66+
}
67+
var next: ListEntry<T> {
68+
_modify {
69+
yield &innerBox!.value._next
70+
}
71+
_read {
72+
yield innerBox!.value._next
73+
}
74+
}
75+
76+
var value: T? {
77+
return innerBox?.value.value
78+
}
79+
}
80+
81+
let target = "ogyfbssvlh"
82+
let strings = [
83+
"nulbhqylps",
84+
"hpdovhuybl",
85+
"bjjvpakqbm",
86+
"rqyozjzkyz",
87+
"qpzghmdcag",
88+
"lqefxvulvn",
89+
"wtokfqarxm",
90+
"acdcrzxpdg",
91+
"bxgfacpjic",
92+
"acblrvoego",
93+
"msevhriohn",
94+
"bamfcnbqvx",
95+
"wimkkqhryd",
96+
"dounctqkiw",
97+
"zxmyxcabhq",
98+
"ljerkuhlgy",
99+
"cettadahue",
100+
"cuummvmwly",
101+
"kdebludzsh",
102+
"ogyfbssvlh",
103+
"lrowrxwufj",
104+
"rftifkqggr",
105+
"ktjeeeobca",
106+
"xqlbnswmjr",
107+
"zpuxfbtmip",
108+
"rljcxrvdgh",
109+
"twkgardobr",
110+
"zrogczpzem",
111+
"bkuzjugksg",
112+
"eqanimdywo"
113+
]
114+
115+
func buildList() -> ListEntry<String> {
116+
var head = ListEntry<String>()
117+
118+
for i in strings {
119+
head.push(value: i)
120+
}
121+
122+
return head
123+
}
124+
125+
func main() {
126+
var head = buildList()
127+
var count = 0
128+
129+
var strCount = strings.count
130+
while let x = head.pop() {
131+
assert(x == strings[strCount - count - 1])
132+
count = count + 1
133+
}
134+
}
135+
136+
main()

0 commit comments

Comments
 (0)