File: moveonly_linkedlist.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (137 lines) | stat: -rw-r--r-- 2,921 bytes parent folder | download
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()