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
|
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking)
// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: concurrency_runtime
// UNSUPPORTED: back_deployment_runtime
actor Page {
let initialNumWords : Int
private let numWordsMem: UnsafeMutablePointer<Int>
nonisolated
var numWords : Int {
get { numWordsMem.pointee }
set { numWordsMem.pointee = newValue }
}
private init(withWords words : Int) {
initialNumWords = words
numWordsMem = .allocate(capacity: 1)
numWordsMem.initialize(to: words)
}
convenience init(_ words: Int) {
self.init(withWords: words)
numWords = words
}
deinit {
numWordsMem.deallocate()
}
}
actor Book {
let pages : [Page]
init(_ numPages : Int) {
var stack : [Page] = []
for i in 0 ..< numPages {
stack.append(Page(i))
}
pages = stack
}
nonisolated
subscript(_ page : Int) -> Page {
return pages[page]
}
}
func bookHasChanged(_ b : Book,
currentGetter : KeyPath<Page, Int>,
initialGetter : (Page) -> Int) -> Bool {
let numPages = b[keyPath: \.pages.count]
for i in 0 ..< numPages {
let pageGetter = \Book.[i]
let currentWords = pageGetter.appending(path: currentGetter)
if (b[keyPath: currentWords] != initialGetter(b[keyPath: pageGetter])) {
return true
}
}
return false
}
func enumeratePageKeys(from : Int, to : Int) -> [KeyPath<Book, Page>] {
var keys : [KeyPath<Book, Page>] = []
for i in from ..< to {
keys.append(\Book.[i])
}
return keys
}
func erasePages(_ book : Book, badPages: [KeyPath<Book, Page>]) {
for page in badPages {
book[keyPath: page].numWords = 0
}
}
let book = Book(100)
if bookHasChanged(book, currentGetter: \Page.numWords, initialGetter: \Page.initialNumWords) {
fatalError("book should not be changed")
}
erasePages(book, badPages: enumeratePageKeys(from: 0, to: 100))
guard bookHasChanged(book, currentGetter: \Page.numWords, initialGetter: \Page.initialNumWords) else {
fatalError("book should be wiped!")
}
|