Skip to content

Instantly share code, notes, and snippets.

@dabrahams
Last active October 22, 2020 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dabrahams/bbcd508197b7dd09c83a997dbc6ca150 to your computer and use it in GitHub Desktop.
Save dabrahams/bbcd508197b7dd09c83a997dbc6ca150 to your computer and use it in GitHub Desktop.
Property wrappers that emulate C++ references
@propertyWrapper
struct UnsafeReference<T> {
public let address: UnsafePointer<T>
var projectedValue: Self { self }
init(_ address: UnsafePointer<T>) {
self.address = address
}
var wrappedValue: T {
get { address.pointee }
}
}
@propertyWrapper
struct UnsafeMutableReference<T> {
public let address: UnsafeMutablePointer<T>
var projectedValue: Self { self }
init(_ address: UnsafeMutablePointer<T>) {
self.address = address
}
var wrappedValue: T {
get { address.pointee }
nonmutating _modify { yield &address.pointee }
nonmutating set { address.pointee = newValue }
}
}
struct W {
init(a: UnsafePointer<Int>, b: UnsafeMutablePointer<Int>) {
self._a = UnsafeReference(a)
self._b = UnsafeMutableReference(b)
}
@UnsafeReference var a: Int
@UnsafeMutableReference var b: Int
}
var x = 3
var y = 4
let z = W(a: &x, b: &y)
print(z.a, z.b)
z.b = 5
print(z.a, z.b)
func f(_ p: UnsafePointer<Int>) { print(p.pointee) }
print(z.$a)
print(z.$b)
f(z.$a.address)
f(&z.b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment